pax_global_header00006660000000000000000000000064126753233040014517gustar00rootroot0000000000000052 comment=094924f7f882da1f32395d4c982db6ad8e0f609f xserver-xorg-video-intel-2.99.917+git20160325/000077500000000000000000000000001267532330400202735ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/.gitignore000066400000000000000000000020441267532330400222630ustar00rootroot00000000000000# # X.Org module default exclusion patterns # The next section if for module specific patterns # # Do not edit the following section # GNU Build System (Autotools) aclocal.m4 autom4te.cache/ autoscan.log ChangeLog compile config.guess config.h config.h.in config.log config-ml.in config.py config.status config.status.lineno config.sub configure configure.scan depcomp .deps/ INSTALL install-sh .libs/ libtool libtool.m4 ltmain.sh lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 Makefile Makefile.in mdate-sh missing mkinstalldirs *.pc py-compile stamp-h? symlink-tree texinfo.tex ylwrap src/sna/git_version.h src/sna/brw/brw_test # Do not edit the following section # Edit Compile Debug Document Distribute *~ *.[0-9] *.[0-9]x *.bak *.bin core *.dll *.exe *-ISO*.bdf *-JIS*.bdf *-KOI8*.bdf *.kld *.ko *.ko.cmd *.lai *.l[oa] *.[oa] *.obj *.patch *.so *.pcf.gz *.pdb *.tar.bz2 *.tar.gz # # Add & Override patterns for xf86-video-intel # # Edit the following section as needed # For example, !report.pc overrides *.pc. See 'man gitignore' # cscope* xserver-xorg-video-intel-2.99.917+git20160325/AUTHORS000066400000000000000000000023311267532330400213420ustar00rootroot00000000000000Authors of xf86-video-intel (since 2003-11-14 when revision-control history begins, sorted roughly by number of commits, descending): Eric Anholt Keith Packard Zhenyu Wang Jesse Barnes Alan Hourihane Carl Worth Dave Airlie Michel Dänzer Zou Nan Hai Kristian Høgsberg Adam Jackson Nian Wu Xian, Haihao Egbert Eich Kevin E Martin Alan Coopersmith Hong Liu Julien Cristau Ma Ling Bryce Harrington Daniel Stone Robert Lowery Kaleb Keithley Paulo Cesar Pereira de Andrade Eamon Walsh Matthieu Herrb Owain G. Ainsworth Søren Sandmann Pedersen Brice Goglin Ian Romanick Lukáš Hejtmánek Matthias Hopf Olivier Fourdan Robert Noland Rémi Cardona Shuang He Wu Fengguang and many others (with 1 or 2 commits) Other authors (from before revision-control history begins): Keith Whitwell Jonathan Bian Matthew J Sottek Jeff Hartmann Mark Vojkovich H. J. Lu David Dawes If the above list is missing anyone, please accept our apologies and let us know. The X.Org version of this driver is maintained by Intel Corporation: https://01.org/linuxgraphics/ The X11R6 version of this driver originally came from XFree86 4.4 rc2. The XFree86 version of this driver was donated to The XFree86 Project by Precision Insight, Inc.; Cedar Park, TX; USA xserver-xorg-video-intel-2.99.917+git20160325/COPYING000066400000000000000000000202631267532330400213310ustar00rootroot00000000000000Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN 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. Copyright (c) 2005 Jesse Barnes Copyright © 2002 David Dawes Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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. Copyright © 2006 Intel Corporation Copyright © 2006,2010 Intel Corporation Copyright © 2007 Intel Corporation Copyright © 2008 Intel Corporation Copyright © 2009 Intel Corporation Copyright © 2007 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. 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, and that the name of Alan Hourihane not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Alan Hourihane makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Copyright 2000 Intel Corporation. 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 INTEL, 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. Copyright 2001 VA Linux Systems Inc., Fremont, California. Copyright © 2002 by David Dawes 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 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 ATI, VA LINUX SYSTEMS AND/OR THEIR 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. Copyright © 1999 Keith Packard Copyright ® 2001 Keith Packard Copyright © 2000, 2008 Keith Packard 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, and that the name of Keith Packard not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Keith Packard makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. xserver-xorg-video-intel-2.99.917+git20160325/Makefile.am000066400000000000000000000027231267532330400223330ustar00rootroot00000000000000# 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. #Having problems passing through user flags as libtool complains #ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 ACLOCAL_AMFLAGS = -I m4 SUBDIRS = man libobj xvmc src tools MAINTAINERCLEANFILES = ChangeLog INSTALL if HAVE_X11 SUBDIRS += test benchmarks endif .PHONY: ChangeLog INSTALL INSTALL: $(INSTALL_CMD) ChangeLog: $(CHANGELOG_CMD) dist-hook: ChangeLog INSTALL xserver-xorg-video-intel-2.99.917+git20160325/NEWS000066400000000000000000003176431267532330400210100ustar00rootroot00000000000000Snapshot 2.99.917 (2014-12-21) ============================== 3 months drifted by whilst I looked elsewhere for bugs.. The highlight of bugs fixed here are a couple of workarounds required for Broadwell and making sure that the rasterisation code is symmetric under inversions. However, as a couple of crashers slipped through into 2.99.916 (though not actual regressions in 2.99.916 per se) and 3 months have passed, we should make one more snapshot before an imminent release. * Beware of recomputing the clear hint in the middle of MI recursion https://bugs.freedesktop.org/show_bug.cgi?id=77074 * Fix crash from rendering an empty Glyph string under PRIME as the secondary driver * Restore application of default monitor options to the first output, a regression in 2.99.915 and the MST support https://bugs.gentoo.org/show_bug.cgi?id=522500 * Finally fix ZaphodHeads blocking on waiting for flip completion events. Before kernel 3.19, O_NONBLOCK support is broken and so we must avoid reading if we are not expecting an event. * Backwards compatibility fix for fake triple buffering with PRIME and Xorg-1.15 https://bugs.freedesktop.org/show_bug.cgi?id=85144#c12 * Fix a rendering issue with output rotation and software fallbacks. https://bugs.freedesktop.org/show_bug.cgi?id=84653 * Enable MST discovery even without udev support https://bugs.freedesktop.org/show_bug.cgi?id=84718 * Fix TearFree operation after the GPU is wedged https://bugs.freedesktop.org/show_bug.cgi?id=85058 * Fix projective sampling on gen6+. * Fix rendering and corruption with gen8. https://bugs.freedesktop.org/show_bug.cgi?id=84958 https://bugs.freedesktop.org/show_bug.cgi?id=83207 https://bugs.freedesktop.org/show_bug.cgi?id=79053 https://bugs.freedesktop.org/show_bug.cgi?id=81583 * Fix crash when using Xinerama. https://bugs.freedesktop.org/show_bug.cgi?id=87207 * Fix rendering of right-to-left or bottom-to-top PolySegments in UXA Snapshot 2.99.916 (2014-09-08) ============================== Quick update for MST in UXA - we need to hook up the RandR outputs for dynamically added connectors. Snapshot 2.99.915 (2014-09-08) ============================== A significant change to UXA to enable MST and to keep it working on recent kernels needs some soaking before a major release, and the usual plethora of bugfixes. One other feature is the support for hardware rotations on very recent kernels. * Handle rotated scanouts that are all clear correctly. The region to update was not being computed correctly, overdrawing the wrong CRTC. https://bugs.freedesktop.org/show_bug.cgi?id=81820 * Reset cursor images after rotation and size changes https://bugs.freedesktop.org/show_bug.cgi?id=81886 https://bugs.freedesktop.org/show_bug.cgi?id=82273 https://bugs.freedesktop.org/show_bug.cgi?id=82337 * Handle stale DRI2 buffers and Client errors more gracefully * Fallback if we fail to render a glyph onto a too-large surface, e.g. direct rendering of glyphs onto extended desktops with gen2/gen3. https://bugs.archlinux.org/task/40949 * Further work to enable tiled rendering onto large surfaces in severely aperture and memory constrained devices (e.g. gen2/gen3) * Honour the Primary option from xorg.conf and mark that as the RandR primary. https://bugs.freedesktop.org/show_bug.cgi?id=82193 https://bugs.freedesktop.org/show_bug.cgi?id=82205 * Fix another Client-Window DRI2 close race https://bugs.freedesktop.org/show_bug.cgi?id=82979 * Fix incorrect discarding of GPU damage when copying over the TearFree scanout - which caused a flicker in rapidly updated elements (like simple video panes). https://bugs.freedesktop.org/show_bug.cgi?id=81973 Snapshot 2.99.914 (2014-07-23) ============================== And a brown paper bag to hide the rebuilding from the tarball with 'autoreconf -fi' error that arose from not distributing the libobj/ directory. Snapshot 2.99.913 (2014-07-23) ============================== This should be it... A few fixes from testing the new code, we should be ready for the final release. However, we do have one standout feature in this snapshot, we now officially recognise HD Graphics 5300/5500/5600, Iris Graphics 6100 and Iris Pro Graphics 6200/P6300 (formerly known as Broadwell). * Check the window actually covers the CRTC before doing a single CRTC flip, and then restore the right framebuffer after completing CRTC flips. Otherwise we would detect an error and disable an output under TearFree Regression in 2.99.912 https://bugs.freedesktop.org/show_bug.cgi?id=80191 * Fix framebuffer creation on kernels older than 3.11 Regression in 2.99.912 * Check that the damage still exists after implicit reduction Regression in 2.99.912 https://bugs.freedesktop.org/show_bug.cgi?id=77436 * Fix direction flags for fallback composited CopyAreas which caused scrolling corruption in a few configurations Regression from 2.20.0 https://bugs.freedesktop.org/show_bug.cgi?id=79843 * Do not throw away damage if there is no redundant copy https://bugs.freedesktop.org/show_bug.cgi?id=79992 * Check clipping on PolyRect before discarding the clipped damage Regression from 2.99.903 https://bugs.freedesktop.org/show_bug.cgi?id=79992 * Fix hints for GLXPixmapa, as these are never swapped and so miss invalidating the hints on SwapBuffers with the result that they are often presumed blank Regression in 2.99.912 https://bugs.freedesktop.org/show_bug.cgi?id=79999 * Fix incoherent choice of source bo when constructing 8x8 tiles, incorrect pattern origin when extracting, and then fix the alignment of colour patterns for BLT operations https://bugs.freedesktop.org/show_bug.cgi?id=80033 * Disable blending with the render engine on snoopable buffers https://bugs.freedesktop.org/show_bug.cgi?id=80253 * Restore throttling to prevent client lag under heavy GPU load Regression from 2.21.10 https://bugs.freedesktop.org/show_bug.cgi?id=77436 * Use ClientGone for notifications on shared DRI2 windows to prevent rare crashes due to use-after-free of the swap requests https://bugs.freedesktop.org/show_bug.cgi?id=80157 * Ensure the mmaped CPU bo is idle before migrating damage https://bugs.freedesktop.org/show_bug.cgi?id=80560 * Fix incorrect clipping by the render engine for large DRI2 windows * Ensure that the aperture tiling fallbacks are bounded * Validate parameter to xf86-video-intel-backlight-helper more carefully (CVE-2014-4910) * Fix slaved scanouts for reverse optimus, though rotated slaves will require further patches to Xorg. https://bugs.freedesktop.org/show_bug.cgi?id=81383 * Fix build without Composite extension. * Fix build without gettline(). * UXA: Allocate and resize frontbuffer consistently to pass sanity checks https://bugs.freedesktop.org/show_bug.cgi?id=80088 * UXA: Report cached backlight value when the output is off (like sna) https://bugzilla.redhat.com/show_bug.cgi?id=1032978 * UXA: Mark outputs as off before the kernel does (like sna) This will prevent the internal panel from starting up blank in some multi-monitor configurations https://bugzilla.redhat.com/show_bug.cgi?id=1103806 Note that the DRI2 exchange mechanism introduced in 2.99.912 exposes bugs in some compositors, at least kwin and comptom, which discard DRI2 buffer invalidates rather than resourcing their texture. For example, https://bugs.kde.org/show_bug.cgi?id=336589 Note that the improved triple buffering introduced in DRI2 requires a patch to Xorg (now released upstream) to prevent crashes with DRI_PRIME. https://bugs.freedesktop.org/show_bug.cgi?id=80001 Note that DRI3/Present require tracking the relevant development trees for mesa and the xserver as they are very much still under early testing. Also be aware that Mesa provides no support for explicit fencing so Damage tracking between compositors and clients is unserialised. Snapshot 2.99.912 (2014-06-10) ============================== A final round of features. We have everything from support for variable cursor sizes, support for the DRI3 and Present extensions, improved DRI2 support, support for Xserver 1.16, userptr from kernel 3.16, and precursory support for DP multistream transport, * Avoid discarding dirty pixels when promoting a migration to cover the whole pixmap. Regression in 2.99.911 https://bugs.freedesktop.org/show_bug.cgi?id=77063 https://bugs.freedesktop.org/show_bug.cgi?id=77178 * Avoid overextending degenerate lines (and consequentially accessing pixels outside of our damaged area). https://bugs.freedesktop.org/show_bug.cgi?id=77074 * Fix subpixel glyph rendering on gen2 devices (830-865 chipsets) Regression in 2.99.911 https://bugs.freedesktop.org/show_bug.cgi?id=77201 * Share the global pixman glyph cache between ZaphodHeads https://bugs.freedesktop.org/show_bug.cgi?id=54707 * Light up all connected outputs, even if their status is unknown, on takeover from fbcon. This prevents loss of display after a resume on recent kernels, for example. https://bugs.freedesktop.org/show_bug.cgi?id=77768 * Show the video overlay (when supported by the hardware) across all outputs. https://bugs.freedesktop.org/show_bug.cgi?id=77802 * Do not discard damage when performing "BLT" spans inplace with the CPU. Regression from 2.20.10 * Avoid discarding IO buffers too early during their preparation for a new batch https://bugs.freedesktop.org/show_bug.cgi?id=79238 * Fix fallback handling for displaying large scaled framebuffers (that are too large to be scaled by the GPU in a single pass) https://bugs.freedesktop.org/show_bug.cgi?id=79320 * Listen to external modifications of backlight value and propagate the notifications to RandR clients. This should make the GUI report ACPI keypresses to change the backlight correctly. https://bugs.freedesktop.org/show_bug.cgi?id=79699 * UXA: fix pageflips with 3 heads. * UXA: do not report a BadMatch error for DRI2GetMsc - as clients are often unprepared and die when they get the unexpected error. Snapshot 2.99.911 (2014-03-19) ============================== Hans de Geode has been working on making the Xserver work without privileges under the supervision of systemd/logind. This necessitated a few new features for us: server fds (where we are passed which fd to use to talk to our device by the Xserver who may in turn receive it from logind or other host) and a small backlight helper so that we can continue to provide a RandR backlight property when running without root privileges. * Flush when changing blend modes on Ironlake, or else single glyphs are sometimes rendered incorrectly Regression from 2.20.15 https://bugs.freedesktop.org/show_bug.cgi?id=74882 * Fix pixmap offsets for pixman fallbacks onto Composite redirected windows https://bugs.freedesktop.org/show_bug.cgi?id=73811 * Fix blending onto 8-bit destinations, typically used for generating masks in complex Render operations, on gen2 https://bugs.freedesktop.org/show_bug.cgi?id=75818 * Handle failure to create DRI bo more carefully. For example on gen3, the DDX supports pixmaps that are much, much larger than OpenGL can use and do not support the tiling modes that we request for OpenGL. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1289049 * Fix a bookkeeping bug with proxy buffers that are marked active but not actually inserted into a request (so they end up permanently active and confuse everybody). https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1289923 * Actually turn off displays with DPMS off for UXA. Regression from 2.99.903, but requires kernel commit c9976dcf55c8aaa7037427b239f15e5acfc01a3a Author: Chris Wilson Date: Sun Sep 29 19:15:07 2013 +0100 drm/i915: Only apply DPMS to the encoder if enabled instead for correct behaviour on Haswell. https://code.google.com/p/chromium/issues/detail?id=341135 Snapshot 2.99.910 (2014-02-10) ============================== Another latent bug exposed by recent changes merit another snapshot for final testing. * Only discard damage when overwriting the dirty CPU bo, instead of discarding damage that will be shown! * Reset operation state when switching between glyph caches. https://bugs.freedesktop.org/show_bug.cgi?id=74494 * Fully reinitialise pixmaps allocated from the freed cache. Fixes a potential issue (crash or misrendering) when using some compositors. https://bugs.freedesktop.org/show_bug.cgi?id=74550 * Do not expose the TexturedVideo adaptor in UXA when it is disabled either due to a hung GPU or explicitly disabled by the user. * Restore the pipe stall when changing CC state on gen6, otherwise the GPU may not flush intermediate results from all EU resulting in render corruption (usually the occasional black box). Regression from 2.99.906 https://bugs.freedesktop.org/show_bug.cgi?id=7237 Snapshot 2.99.909 (2014-02-01) ============================== Pass the brown paper bag. Ridiculously stupid bug in last minute coding. * Add Xv support using glamor acceleration in addition to adaptors provided by the UXA backend. * Fix overeager discarding of CPU damage Regression in 2.99.908 :( https://bugs.freedesktop.org/show_bug.cgi?id=74327 Snapshot 2.99.908 (2014-01-31) ============================== A couple of regressions dashed the hopes that .907 was to be the final release candidate, so time to start the cycle again after applying a few more bugfixes. * Fix invalid pageflipping of GLXPixmaps by UXA. https://bugs.freedesktop.org/show_bug.cgi?id=73282 * Consistently treat DPMS Suspend/Standy as Off, otherwise we may incorrectly restore the backlight in UXA. * Fix disabling the backlight in UXA when querying the value whilst off https://bugs.freedesktop.org/show_bug.cgi?id=73181. * Invalidate between every operation if rendering into the source or mask. Fixes regression in 2.99.907 on Ivybridge (seen in KDE) https://bugs.freedesktop.org/show_bug.cgi?id=73208 * Check for available batch buffer state before restoring state on gen4, otherwise we overwrite surface state with commands and cause a GPU hang. https://bugs.freedesktop.org/show_bug.cgi?id=73348 * Prevent an invalid free by TearFree https://bugs.freedesktop.org/show_bug.cgi?id=73469 * Fix confusion in TearFree when it tried to pageflip to a stale bo https://bugs.freedesktop.org/show_bug.cgi?id=70905 * Initialise TearFree contents with the current frontbuffer upon creation, otherwise old content may be visible for significant fractions of a second after resume or DPMS on https://bugs.freedesktop.org/show_bug.cgi?id=73842 * Nullify the old pointer into a CPU mmapping of the bo when promoting it on the GPU. Eventually that old pointer becomes invalid and will cause the Xserver to crash. Fixes regression in 2.99.906 https://bugs.freedesktop.org/show_bug.cgi?id=73351 * Restore the serialNumber on the GC correctly after falling back to software. This was seen to cause corruption with Wine. https://bugs.freedesktop.org/show_bug.cgi?id=73856 * Do not ignore CPU damage on a pixmap unless the Composite operation will completely overwrite it. This was observed in xfce4. https://bugs.freedesktop.org/show_bug.cgi?id=69528 * Skip fake outputs during initial probe as they can cause a NULL pointer dereference. https://bugs.freedesktop.org/show_bug.cgi?id=73981 * Fix rendering of dashed zero-width lines onto 24bit buffers https://bugzilla.redhat.com/show_bug.cgi?id=1059152 * Cap the freed Pixmap cache and reuse it more often Fixes a regression in 2.99.907 that caused the memory used by X to grow until it was cleaned up during server regreneration https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1272338 Snapshot 2.99.907 (2013-12-30) ============================== The highlight here is that things seem to be quietening down on the bug reporting front. All is not quiet as you will see below, and maybe it is just the holiday season that is approaching*, but there has been a remarkable falloff in bug reports. Lets hope this trend holds and we can make a stable release shortly! * This was intended to be sent a couple of weeks ago and the holiday season has been very quiet.... Oh, and acceleration support for Intel's next generation of integrated processor graphics has landed, codenamed Broadwell. * Fix potential X server infinite recursion (crash) from a gen2 bug fix Regression in 2.99.906 https://bugs.freedesktop.org/show_bug.cgi?id=71605 * Workaround a missing pipeline flush within Ivybridge, that would leave black rectangles randomly over the output https://bugs.freedesktop.org/show_bug.cgi?id=68410 * Fix tiled fills. gen2-3 and gen4+ had two different bugs that both broke rendering with small 8x8 patterns in some circumstances https://bugs.freedesktop.org/show_bug.cgi?id=71260 * Fix reads from a cropped video image using a packed pixel format. * Another clear the clear hint after DRI2 SwapBuffers, like the bug fixed in 2.99.903. Failure to clear the hint would cause read backs of the frontbuffer (Xvnc) to be blank. https://bugs.freedesktop.org/show_bug.cgi?id=72194 * Disable VSync on Baytrail https://bugs.freedesktop.org/show_bug.cgi?id=69869 * Handle partial uploads with TearFree correctly https://bugs.freedesktop.org/show_bug.cgi?id=72343 https://bugs.freedesktop.org/show_bug.cgi?id=72430 * Avoid recusing through DRI event handlers whilst processing TearFree, leading to a double free (and memory corruption) https://bugs.freedesktop.org/show_bug.cgi?id=72690 * Hide the gen4 render corruption by crippling the GPU https://bugs.freedesktop.org/show_bug.cgi?id=55500 Snapshot 2.99.906 (2013-11-13) ============================== Several stability fixes required after the recent tweaking of the core mechanics to handle the updated TearFree and attempting to make static analyzers happy. * Fix damage handling when rendering to a partially damaged GPU surface. Regression in 2.99.905 https://bugs.freedesktop.org/show_bug.cgi?id=70527 * Use asprintf() instead of sprintf() Regression in 2.99.905 https://bugs.freedesktop.org/show_bug.cgi?id=70835 * Improve accounting for fence overallocation on older gen2/3, and improve the tiling mechanism to fit into the same aperture constraints https://bugs.freedesktop.org/show_bug.cgi?id=70924 * Add an extra GPU flush on Sandybridge to fix some rare font corruption * Rasterise lines through all clip boxes https://bugs.freedesktop.org/show_bug.cgi?id=70802 * Fix regression from stricter handling of failures to move a GC to the GPU Regression in 2.99.905 https://bugs.freedesktop.org/show_bug.cgi?id=71415 * Fix various fail along the memcpy_xor paths, including inadequate error handling and integer overflow https://bugs.freedesktop.org/show_bug.cgi?id=70527 * Fix outside-of-target stipple uploads https://bugs.launchpad.net/bugs/1247785 * Fix clip detection for long glyphs Incomplete bug fix (causing a regression) in 2.99.905 https://bugs.freedesktop.org/show_bug.cgi?id=70527 * Fix VSync for the render engine (Xv) on Haswell https://bugs.freedesktop.org/show_bug.cgi?id=70527 Snapshot 2.99.905 (2013-10-23) ============================== The highlight for this snapshot is the extension of TearFree to support transformed outputs, along with some polishing to eliminate its impact upon input and output latency. As always, thanks to everyone who have been testing, reporting bugs and helping to improve the stability before release. * Prevent a crash when starting with a user specified mode or position * Prevent some crashes in UXA after allocation failure * Stop marking the user's preferred backlight value as 0 if the backlight property is queried whilst the connector is disabled https://bugs.freedesktop.org/show_bug.cgi?id=70406 * Pad GETCONNECTOR ioctl for compatibility between 32/64-bit userspace and kernel * Handle long glyph runs correctly https://bugs.freedesktop.org/show_bug.cgi?id=70541 * Fix clipping of stippled rectangles against clip regions https://bugs.freedesktop.org/show_bug.cgi?id=67865 * Support TearFree rendering of rotated outputs https://bugs.freedesktop.org/show_bug.cgi?id=22969 Snapshot 2.99.904 (2013-10-09) ============================== There is one more feature planned to be completed for 3.0, so time for a snapshot beforehand to push out the bug fixes from the last week. * Fix video output using sprites when changing the image size * Apply more restrictive tile constraints for 915g class devices https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1232546 * Ensure all overlapping rectangles are drawn for XRenderFillRectangles https://bugs.freedesktop.org/show_bug.cgi?id=66313 * Fix trapezoid clipping against the left-edge https://bugs.freedesktop.org/show_bug.cgi?id=69469 * Prevent discarding active upload buffers, causing glitches in chromium https://bugs.freedesktop.org/show_bug.cgi?id=66990 * Prevent specifying a negative timeout to select if the BlockHandler takes too long to update the display * Promote the Ironlake pipecontrol to be a full pipeline flush to prevent render cache corruption https://bugs.freedesktop.org/show_bug.cgi?id=51422 * Never pass an invalid trapezoid to pixman https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/1197921 * Prevent out-of-bounds access by overassigning work amongst threads https://bugs.freedesktop.org/show_bug.cgi?id=70204 * Make sure the current mode is always listed amongst the output modes https://bugs.freedesktop.org/show_bug.cgi?id=70132 * Build fixes for 1.14.99.2 Snapshot 2.99.903 (2013-09-28) ============================== Lots more stabilization work, not yet peaceful enough to christen 3.0. We have everything ranging from build fixes for systems like Suse Linux Enterprise Desktop that like to backport hardware enablement to ancient packages, to fixes for hardware enabling, and some more performance tuning. * Fix VSync on Haswell. https://bugs.freedesktop.org/show_bug.cgi?id=69119 * Disable Y-tiling on gen4 - it too frequently leads to instability. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1222203 * Disable same EDID detection based on property id - the kernel likes to reuse ids leading to a failure to detect the right modes on a monitor change. * Avoid issuing multiple DPMS requests to the same encoder (alised to multiple connectors) to avoid upsetting Haswell and leaving the screens blank. * Honour the user preferrence for the initial mode, even if they are being silly https://bugzilla.novell.com/show_bug.cgi?id=841696 * Clear the clear hint when apply DRI updates - to prevent some screenshots from GL windows being left blank. https://bugs.freedesktop.org/show_bug.cgi?id=69730 * Prevent a NULL dereference from trying to undo an non-existent buffer https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1228677 * Handle out-of-memory conditions far more gracefully. If the system is hard against the memory wall, then the kernel will start issuing SIGBUS even for CPU mmaps. Untrapped these will cause X to die. https://bugs.freedesktop.org/show_bug.cgi?id=67889 Snapshot 2.99.902 (2013-09-07) ============================== We do not condone or support Canonical in the course of action they have chosen, and will not carry XMir patches upstream. -The Management Snapshot 2.99.901 (2013-09-04) ============================== What's this? A pre-release snapshot of an upcoming 3.0 major release? What could be the big new feature about to land? SNA by default! Not only that, we also have a preview of the XMir integration patches. Whilst we consider the SNA acceleration method to be ready to take over from UXA (the current acceleration method), it still remains possible to switch over to the old method with the following xorg.conf snippet: Section "Device" Identifier "Device0" Driver "intel" Option "AccelMethod" "UXA" EndSection The promise of SNA is that it improves the user experience by providing a faster, more fluid, desktop, that is both more power efficient and less prone to crashes than UXA. If it still fails to meet your expections, please file bugs! Release 2.21.15 (2013-08-21) ============================ Some build fixes for the BSDs and alternate compiler, and conflicting configure options and a critcial fix for some PRIME setups. * Don't fail to configure if DRI1 is not available and the user asks for both DRI and KMS-only [Regression from 2.21.14] * Lots of miscellaneous fixes for older gcc, other compilers and BSD. * Initial framework support for hosted X. * Improve transition from fbcon to X with multiple outputs and extended desktops. * Ensure the framebuffer exists before checking it against the CRTC constraints. https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/121234 [Regression from 2.21.10] * Add RGB overlay support for Ironlake and later. * Don't release the overlay buffer too early, i.e. before the client disables the Xv image. * Tweak the ring switching logic to reduce use of semaphores on Sandybridge and later - a delicate balancing act between trying to use the faster engine for the task and preventing concurrent use of multiple rings. Release 2.21.14 (2013-08-04) ============================ A few updates for the top-end Haswell systems (notably GT3 and GT3e systems), in particular, setting the appropriate thread counts for the larger GPU and handling a few scaling issues with the emedded DRAM. More important than the performance tuning though is a fix for a critical issue encountered by a few people on gen4/gen5 systems. * Initial performance tuning for HSW:GT3e * Fix a crash with Planetary Annihilation * Disable triple buffering for compositors * Reserve space in the exec buffer array for deferred VBOs. https://bugs.freedesktop.org/show_bug.cgi?id=67504 Release 2.21.13 (2013-07-27) ============================ A minor release to repair the build for non-Linux systems, and to undo a few more regressions. * Avoid potential memory corruption with allocations of very small depth 1 bitmaps. * Fix source clipping whilst computing copy extents and exposures. [Regression from 2.21.12] https://bugs.freedesktop.org/show_bug.cgi?id=66970 * Use /proc/cpuinfo if cpuid4 is not available (old hardware or old gcc), and repair the build on systems without cpuid. [Regression from 2.21.12] * Fix performance regression on Ironlake from inadvertently flushing after every operation. [Regression from 2.21.11] https://bugs.freedesktop.org/show_bug.cgi?id=67157 * Fix conflict handling when probing initial KMS configuration for ZaphodHeads. [Regression from 2.21.11] https://bugs.freedesktop.org/show_bug.cgi?id=67176 * Stop being overly restrictive and rejecting stale DRI2 buffers. (DRI2 is inherently racy in that the client may have completed and submitted rendering to buffers that are now invalid on the server. This race is magnified by bugs within the Xserver where it forgets to notify the DRI2 clients of certain invalidation events.) https://bugs.freedesktop.org/show_bug.cgi?id=67210 * Handle a failure to use a GTT mmap for a pixmap upload and try an alternative method before giving up. Release 2.21.12 (2013-07-14) ============================ In this release, we clear up the teething troubles from preserving the KMS configuration, notably external connections on Haswell and plugging in new outputs after startup were broken. Besides these regression fixes, there are a couple of fixes for some long standing issues, such as incorrect rendering on gen2, an infinite loop with very, very large pixmaps and a slight improvement to the tempermental gen4. * Allow untiled scanouts again (required for large extended desktops on gen2 and gen3). [Regression from 2.21.11] * Use the correct count of the number of dirty damage boxes for the quick check on whether the existing damage contains the requested area. The danger is that we may get a false result and skip migration and so cause pixmap corruption (in the unlikely event that the application frequently causes fallbacks). [Regression from 2.21.11] https://bugs.freedesktop.org/show_bug.cgi?id=66430 * Fix initial connection probing for multi-function encoders, such as the external connections on Haswell. [Regression from 2.21.11, initial connection probing] https://bugs.freedesktop.org/show_bug.cgi?id=66488 * Fix gen2 rendercopy into a8 surfaces, for example, glyph uploads into the glyph cache. * Fix detection of user overrides for initial connection configuration. The code used the xorg-server-1.15 values, having missed the introduction of ZoomModes into that release. [Regression from 2.21.11, initial connection probing] * Always initialise the gamma ramp, even on unconnected CRTCs. https://bugs.freedesktop.org/show_bug.cgi?id=66563 [Regression from 2.21.11, initial connection probing] * Some more tuning of the gen4 vertex corruption workaround. The root cause behind the GPU using incorrect texture coordinates is still not solved, but by reducing the maximum number or rectangles in flight through the GPU we reduce the likelihood of corruption. * Fix compilation with gcc-4.5 [Regression from 2.21.11] * Avoid integer overflow when performing tiled uploads and operations on very large (>28k pixels wide or tall pixmaps) https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1200766 Release 2.21.11 (2013-06-30) ============================ An eventful week. What started with a regression with some builds of firefox on some machines lead ultimately to the discovery of an older kernel bug. Aside from the work to fix the image bug and a few other older bugs that were reported and resolved this week, there is also a (hopefully) subtle change to the initial configuration of displays. In the absence of user overrides in xorg.conf, the DDX will try to preserve the same display configuration as used by the kernel, which hopefully will be the same configuration as setup by the BIOS. The result should be a boot sequence that does not resize at all (aka fastboot) - until the display manager takes over and loads a completely different configuration! * Add reference counting of drmMaster for ZaphodHeads https://bugs.freedesktop.org/show_bug.cgi?id=66041 * Add a GPU flush before changing blend modes on Ironlake https://bugs.freedesktop.org/show_bug.cgi?id=51422 * Fix occasional missing images for inplace uploads [regression from 2.21.10] https://bugs.freedesktop.org/show_bug.cgi?id=66059 * Add missing utility files to the tarball and remove a few unused ones * Initialise PolyPoint operand state before calling miWideDash https://bugs.freedesktop.org/show_bug.cgi?id=66104 * Fix redirection handling for rendering into large surfaces https://bugs.freedesktop.org/show_bug.cgi?id=66168 https://bugs.freedesktop.org/show_bug.cgi?id=66249 * Fix compilation of UXA with xorg-xserver < 1.10 [regression from 2.20.0] * Fix consideration of gradients for deciding when to migrate render operations [performance regression from 2.21.10, the bug itself is older] https://bugs.freedesktop.org/show_bug.cgi?id=66297 Also fixed this week was: commit 22fd5ca947b58901927d100d2b1aa0f1672b3435 Author: Chris Wilson Date: Fri Jun 28 16:54:08 2013 +0100 drm/i915: Only clear write-domains after a successful wait-seqno which affects kernels 3.7 - 3.10, coming to a stable kernel near you soon. Release 2.21.10 (2013-06-22) ============================ Fixes missing support for Xv (with the textured video adaptor) on Haswell, and an old bug with wide monitors on various generation. Along with a few other regression fixes and performance tweaks for various corner cases. * Do not lose track of fast pageflips across mode changes [regression from 2.20.8] * Fix listing of Visuals for Xv [regression from 2.21.8] https://bugs.freedesktop.org/show_bug.cgi?id=65479 * Improve coherency of concurrent CPU accesses to a pixmap https://bugs.freedesktop.org/show_bug.cgi?id=61628 * Set sampler swizzling for textured video on Haswell https://bugs.freedesktop.org/show_bug.cgi?id=65699 * Apply scanout stride limits https://bugs.freedesktop.org/show_bug.cgi?id=65099 * Undo the self-copy for cloned pixmaps for loimpress's animations [regression from 2.21.7] https://bugs.freedesktop.org/show_bug.cgi?id=65665 Release 2.21.9 (2013-06-06) =========================== Consolidating the copy-on-write support, hopefully cleaning up the last of the regressions. * Restore vsync on textured videos. [regression from 2.21.8] https://bugs.freedesktop.org/show_bug.cgi?id=65048 * Fix incorrect ordering of possible_clones with certain outputs, which can lead to attempting to incorrectly clone 2 outputs and failing to light them up. [regression from 2.20.10] * Fix performance regression from not promoting large fills to the GPU [regression from 2.21.7] * Undo the pixmap clone before performing a DRI2CopyRegion [regression from 2.21.7] https://bugs.freedesktop.org/show_bug.cgi?id=65250 Release 2.21.8 (2013-05-27) =========================== A quick release to cleanup a few regressions from the introduction of copy-on-write support, notably hitting wine applications and a memory leak for firefox. * Only mark a PolyFillRect operation as replacing if it is unclipped https://bugs.freedesktop.org/show_bug.cgi?id=64841 * Prevent potential NULL dereference of damage when checking COW support * Fix invalidation of clone after dirtying the pixmap via the CPU * Prevent discarding an operation before requiring it for a fallback * Fix memory leak from replacing the clone under certain circumstances https://bugs.freedesktop.org/show_bug.cgi?id=64978 Release 2.21.7 (2013-05-21) =========================== A couple of weeks turned into a month and a couple of weeks... Amidst the usual bug fixes, we have added the complete set of Haswell PCI IDs - hopefully future proofing ourselves against being surprised by new products. We can also now use the correct term for the top of the range Haswell variants, GT3. * Fix several assertion failures hit by Jiri Slaby. * Allow XvMC to also target overlay/sprite planes. * Throw in a paranoid MI_FLUSH between BLT and RENDER operations on Ironlake. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1168066 * Prevent reuse of old framebuffers after a resize. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1157678 * Fix compilation with --enable-valgrind and no --enable-debug * Improve partial migration of render sources. * Fix origin of trapezoids. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1178020 * Introduce copy-on-write support for cloning pixmaps. The ultimate goal here is to efficiently support the TearFree mode of operation, but this provides immediate benefits with firefox - most importantly because of the inefficient way it now implements scrolling. Release 2.21.6 (2013-04-06) =========================== A surprising highlight of this release is a little refresh to the KMS support for OpenBSD. OpenBSD now has its own KMS implementation which is mostly compatible with the interface in Linux, with one or two tweaks supplied by Mark Kettenis. This release continues to cleanup behaviour for Haswell. * Workaround a failure by the xserver to invalidate DRI buffers following a pixmap change for XComposite redirection. https://bugs.freedesktop.org/show_bug.cgi?id=62614 * Fix computation of clip extents for stippling https://bugs.freedesktop.org/show_bug.cgi?id=62618 * Support KMS on OpenBSD, by Mark Kettenis * Clean up sockets upon CloseScreen (making ourselves better behaved for muxed setups). * Fix the tests for AVX/AVX2 support in CPUID and remember to check for OS support as well. * Report a monotonic UST value for undisplayed drawables rather than 0 by Daniel Kurtz * Fix video playback on gen4 through a complex clip (more gen4 GPU woes) https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1162046 Release 2.21.5 (2013-03-21) =========================== Haswell reintroduces a command to load the scanline window from the command stream and so requires its own specialised wait-for-vsync routine - failure to do so was then causing hangs when trying to do tearfree video or use a compositor. * Prevent buffer leak if a non-fullscreen Window is closed with multiple pending swap events. * Fix offset transformation for fallback gradient paths. https://bugs.freedesktop.org/show_bug.cgi?id=62198 * Prevent Glamor from crashing if misconfigured. Thanks to Michel Dänzer. * Prevent UXA from crashing if torn down during PreInit. Thanks to Aaron Plattner. * Prevent miscompilation with different functional units having different compiler flags. Some functions were expected to be inlined and so recompiled with the current target. However, some compilers were choosing to emit subroutine calls instead without noticing that the ABI was different between the caller and callee - causing corruption. https://bugs.freedesktop.org/show_bug.cgi?id=62198 * Fix rendering of CompositeTriFan with recent Xorg. * Apply the video src-offset fix highlighted in the last release! A typo prevented the fix from working for gen4+. https://bugs.freedesktop.org/show_bug.cgi?id=62343 * Fix rendering of multiple glyphs to very large destination surfaces https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156387 * Fix scanline waits for Haswell https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1156679 Release 2.21.4 (2013-03-11) =========================== More bugs, more fixes, more releases. A minor new feature being introduced is the runtime detection of CPU instructions sets along with specialised paths to take advantage of the available CPU. * Honour LinearFramebuffer for clumsy PowerXpress integration * Disable read-read optimisations of mappings whilst the root cause of a corruption issue remains elusive. https://bugs.freedesktop.org/show_bug.cgi?id=61628 * Disable 8-bpp framebuffers in UXA as the regressions therein remain unfixed. * Restart vertex checks after lock contention https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1124576 * Handle Screen Pixmap recreation whilst exported via PRIME. * Correct application of scale factors to video source offsets. https://bugs.freedesktop.org/show_bug.cgi?id=61610 * Chain up CloseScreen so that resources are actually freed across regen https://bugs.freedesktop.org/show_bug.cgi?id=56608 * Fix Haswell CRW PCI-IDs * Handle batch submission failure during DRI copies https://bugs.freedesktop.org/show_bug.cgi?id=61708 * Probe for kernel support of requested Screen depth https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1135403 * Correct GPU limits for early gen2 and gen3 architectures and prevent an infinite recursion for particular image sizes. Release 2.21.3 (2013-02-20) =========================== A few minor bugfixes, another point release. * Fix tracking of DRI pixmaps and their backing bo across reparenting. If we tried to execute a SwapBuffers after a Window was reparented, but before the DRI client has updated its references, then we would end up manipulating an exported pixmap without a flush flag set. In the worst case, this would culminate in a segfault in the driver. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1127497 * Restore the gen4 workarounds for flickering rendering - a few cases still remain, as the root cause persists. https://bugs.freedesktop.org/show_bug.cgi?id=60402 * Double check that the device has KMS enabled before claiming. This allows X to gracefully fallback to VESA/fbdev rather than bailing out. https://bugs.freedesktop.org/show_bug.cgi?id=60987 * Fix the UXA render programs for projective transforms on Ivybridge. Release 2.21.2 (2013-02-10) =========================== Pass the brown paper bags, I need half a dozen or so. That seemingly innocuous build fix with xorg-1.13 happened to have the little side-effect of breaking glyph rendering with xorg-1.12 and older on 64-bit machines. Release 2.21.1 (2013-02-10) =========================== A fix for a potential GPU hang on 945gm (GMA950) and earlier chipsets, along with backporting SNA to the packages found in stable distributions like Debian 6.0 (Squeeze). * Cleanup compilation warnings from deblint, thanks to Paul Menzel * Minor build improvements by Damien Lespiau. * Disable generating span geometry for non-rectilinear spans on gen4 in order to work around and prevent one class of render corruption. * Prevent cache thrashing and severe performance degradation on LLC machines for streaming texture updates. However, note the effect was only observed on just one particular laptop. * Fix alignment of subsurface proxies for old chipsets. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1120108 * Repair build against Xserver-1.6 and contemporary packages. Release 2.21.0 (2013-02-01) =========================== A few new features: * Enable render acceleration for Haswell GT1/GT2. * Enable multi-threaded rasterisation of trapezoids and fallback composition * Utilise a new kernel interface (v3.9) for processing relocations along with a few older features from the 2.20.x series: * PRIME support for hotplug GPUs and hybrid systems * Support for IvyBridge GT1 machines, aka HD2500 graphics. * Stable 830gm/845g support, at last! As usual we have a large number of bug fixes since the last release: * Prevent a stray relocation being left after a buffer is removed from a batch, leading to GPU hangs. * Make the driver more robust against its own failures to submit batches by falling back to software rendering. * Fix emission of scanline waits for secondary pipes on gen6/7. Otherwise you may encounter GPU hangs in MI_WAIT_FOR_EVENT. * Fix a missing corner pixel when drawing rectangles with PolyLines https://bugs.freedesktop.org/show_bug.cgi?id=55484 * Don't try to use Y-tiling colour buffers with mesa/i915c as mesa doesn't support them and wil fallback to software rendering * Ensure that any cached mmaps are invalidated for a SwapBuffers https://bugs.freedesktop.org/show_bug.cgi?id=60042 * Correctly handle the composition of rotated displays too large for the 3D pipeline https://bugs.freedesktop.org/show_bug.cgi?id=60124 * Fix the computation of the planar video frame size https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1104180 Release 2.20.19 (2013-01-20) ============================ A quick release as the last broke USB DisplayLink slave outputs badly. The performance of those displays was unusable due to an inadvertent change that caused us to flush the entire scanout over the USB for every drawing operation. * Implement the GNOME Build API. A couple of minor changes to make integrators and distributors lives a little easier, or at least more consistent. * Correctly offset inplace trapezoids for subwindows, such as the GTK+ close button after it has a background image uploaded. * Explicitly prevent ring-switching for synchronized rendering to scanouts (for vsync). * Clip dirty region to slave pixmaps (otherwise UDL is nigh unusable) https://bugs.freedesktop.org/show_bug.cgi?id=59539 Release 2.20.18 (2013-01-16) ============================ A bunch of miscellaneous fixes for assertion failures and various performance regressions when mixing new methods for offloads, along with a couple of improvements for rendering with gen4. * Remove use of packed unnormalized texture coordinates on gen4/5 as these GPUs do not support unnormalized coordinates in the sampler. * Remove dependency upon x86 asm for cross-building to unsupported architectures. https://bugs.gentoo.org/show_bug.cgi?id=448570 * Apply damage around PRIME updates in the correct order. * Correctly read the initial backlight level for when the user overrides UXA's choice of backlight controller. * Throttle UXA and prevent it queuing work much faster than the GPU can complete it. This realised itself in impossible performance figures and the entire display freezing for several seconds whlist the GPU caught up. One side effect is that it also caused the DDX to consume more memory than was required as it could not recycle buffers quick enough, and in some cases this produces a marked improvement in performance. Also note on gen2/3 this requires a new libdrm [2.4.41] in order to prevent a bug causing the DDX to fallback to swrast. Release 2.20.17 (2012-12-26) ============================ A minor update to prepare for co-operating with the kernel over managing stability on 830gm/845g. On this pair of chipsets, the kernel will perform an extra copy of the batchbuffer into reserved memory, which prevents them from randomly dying. However, that extra copy does have a noticeable impact upon throughput, so we also have a mechanism for userspace to opt-out of the kernel workaround and take responsibility for ensuring its batches are coherent. * Build fixes against xorg-1.14 https://bugs.freedesktop.org/show_bug.cgi?id=58552 https://bugs.freedesktop.org/show_bug.cgi?id=58406 * Fixed the origin of cropped (textured) video windows (Xv and XvMC) https://bugs.freedesktop.org/show_bug.cgi?id=23033 * Fix potential corruption when using images larger than ~1GiB Release 2.20.16 (2012-12-15) ============================ Rejoice! We have found a trick to make 830gm/845g stable at long last. Ever since the switch to GEM and dynamic video memory, those early second generation chipsets have been plagued by instability. The lack of flushing cachelines from the CPU to GMCH was eventually solved by using an undocmented bit, but 830/845 were still hanging under memory pressure. These deaths were all due to garbage finding its way into the command streamer, and they go away if we take a leaf out of the original driver and never reuse those pages for anything else. So for the first time ever, I have been able to complete running the test suite on an 845g, even whilst thrashing the page and buffer caches! * Run the SF stage as single-threaded on gen4 to workaround a few issues https://bugs.freedesktop.org/show_bug.cgi?id=57410 * Keep the scanout SURFACE_STATE separate to avoid overriding its memory access control on gen6/7 (i.e. writes to the scanout need to be kept out of the render cache) * Tune batch flushing after an operation to an exported surface under a compositor. * Make sure the source is on the CPU for inplace composition of trapezoids using the CPU https://bugs.freedesktop.org/show_bug.cgi?id=56825 * Immediately flush in the block hander after a split batch to reduce latency between the two halves of an operation. https://bugs.freedesktop.org/show_bug.cgi?id=51718 * Install a fallback config if we fail to install the desired config at VT switch (i.e. booting, after resume with 3 incompatible pipes on Ivybridge) * Pin batches to avoid CS incoherence on 830/845 https://bugs.freedesktop.org/show_bug.cgi?id=26345 Release 2.20.15 (2012-12-03) ============================ And lo, enabling more of the common acceleration paths for gen4 revealed another lurking bug - something is wrong with how we prepare Y-tiling surfaces for rendering. For the time being, we can surreptitiously disable them for gen4 and avoid hitting GPU hangs. * Avoid clobbering the render state after failing to convert the operation to use the blitter. https://bugs.freedesktop.org/show_bug.cgi?id=57601 * Disable shadow tracking upon server regeneration, and so fix a crash if you restart the server whilst a RandR transform (e.g. rotation) is in effect. https://bugs.freedesktop.org/show_bug.cgi?id=52255 https://bugs.freedesktop.org/show_bug.cgi?id=56608 Release 2.20.14 (2012-11-26) ============================ The highlight of this release is gen4, from 965g to gm45. Quite an old bug surfaced in the shader assembly, sparking a chance to review a few design choices within that backend and experiment on fresh ways to workaround the remaining issues. * Avoid using inplace XOR'ed uploads for very large buffers https://bugs.freedesktop.org/show_bug.cgi?id=57031 * Fix the gen4/5 opacity shader https://bugs.freedesktop.org/show_bug.cgi?id=57054 * Queue a pending vblank request after flip completion https://bugs.freedesktop.org/show_bug.cgi?id=56423 * Avoid migrating an uninitialised pixmap for use as a render source https://bugs.freedesktop.org/show_bug.cgi?id=47597 * Improve handing of texture fallbacks for 830/845. https://bugs.freedesktop.org/show_bug.cgi?id=57392 Release 2.20.13 (2012-11-11) ============================ Nothing but bug fixes. Many thanks to everyone who took the time to report their issues, and for their help in improving the driver. * Sanity check the platform probe points to our expected i915 device https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/1069031 * Prevent 16-bit overflow for computing the sample area to upload of sources for render operations https://bugs.freedesktop.org/show_bug.cgi?id=56324 * Clamp the drawable box for migration to prevent 16-bit overflow https://bugs.freedesktop.org/show_bug.cgi?id=56591 * Disable RandR hotplug events if Xinerama is enabled and thereby prevent a crash upon hotplug https://bugs.freedesktop.org/show_bug.cgi?id=55260 * Call ValidatePicture before attempting to flatten the alphamaps https://bugs.freedesktop.org/show_bug.cgi?id=56367 * Clip the trapezoid correctly if it ends on the boundary pixel https://bugs.freedesktop.org/show_bug.cgi?id=56395 * Make sure the pipeline choice is propagated to the scanline wait across a batch flush https://bugs.freedesktop.org/show_bug.cgi?id=47597 * Set the valid drawable box when choosing placement of BLT composite ops https://bugs.freedesktop.org/show_bug.cgi?id=47597 * Prevent use-after-free when promoting a partial-GPU bo to a full-GPU bo https://bugs.freedesktop.org/show_bug.cgi?id=56591 * gen4 opacity spans require the per-rectangle workaround https://bugs.freedesktop.org/show_bug.cgi?id=55500 * Prevent use of invalid damage pointers when redirecting rendering https://bugs.freedesktop.org/show_bug.cgi?id=56785 Release 2.20.12 (2012-10-20) ============================ More bug reports, more bug fixes! Perhaps the headline feature is that with a secure batches, coming to a 3.8 kernel near you, we may finally have the ability to perform updates to the scanout synchronized to the refresh rate on later SandyBridge and IvyBridge chipsets. It comes at quite a power cost as we need to keep the GPU out of its power saving modes, but it should allow legacy vsync to function at last. But this should allow us to address a longstanding issue with tearing on SandyBridge+. * Fix component-alpha rendering on IvyBridge, for example subpixel antialiased glyphs. https://bugs.freedesktop.org/show_bug.cgi?id=56037 * Flush before some "pipelined" state changes on gen4. The evidence is that the same flushes as required on gen5+ are also required for gen4. https://bugs.freedesktop.org/show_bug.cgi?id=55627 * Prevent a potential crash when forcing a stall on a busy CPU bo https://bugs.freedesktop.org/show_bug.cgi?id=56180 [Release 2.20.11 contained a typo causing UXA to fail immediately.] Release 2.20.10 (2012-10-14) ============================ The last couple of weeks have been fairly retrospective, a dive into prehistory tidying up the earlier generations which lay languishing as the core progressed and lead to a number of annoying core bugs being fixed. * Release DRM master earlier during shutdown so switching between multiple X servers works automatically. https://bugs.freedesktop.org/show_bug.cgi?id=55446 * Suppress error propagation from DRI2GetMSC and behave as if the pipe was simply off to avoid unexpected errors in the clients https://bugs.freedesktop.org/show_bug.cgi?id=55395 * A few fixes to i8xx batch emission, ensuring that the GPU is always in a valid state. https://bugs.freedesktop.org/show_bug.cgi?id=55455 * Prevent a use-after-free during UXA shutdown due to inspecting the glamor flags after the glamor interface had been freed. * Prevent a crash combining TearFree and rotations. https://bugs.freedesktop.org/show_bug.cgi?id=55527 * Correct a missing damage upload along PutImage after using the CPU bo as a source for the GPU. https://bugs.freedesktop.org/show_bug.cgi?id=55508 * Fix compilation for older glibc without O_CLOEXEC https://bugs.freedesktop.org/show_bug.cgi?id=55577 * Fix out-of-tree builds failing to recompile the gen4 assemblies https://bugs.freedesktop.org/show_bug.cgi?id=55645 * Fix non-standard build host configuration handling for intel-gen4asm https://bugs.freedesktop.org/show_bug.cgi?id=55646 * Fix a potential batch buffer overflow when replacing the last BLT fill operation with a copy https://bugs.freedesktop.org/show_bug.cgi?id=55700 * Flush the render pipeline more frequently on Ironlake as not all pipelined state changes are. https://bugs.freedesktop.org/show_bug.cgi?id=51422 * Detect when we need to read the destination for the background raster op during fallbacks. https://bugs.freedesktop.org/show_bug.cgi?id=55810 * Avoid a potential deference of an invalid CPU mmap after doing an inplace tiled upload. https://bugs.freedesktop.org/show_bug.cgi?id=55812 * Prevent sign extension when packing the upload data for CopyPlane https://bugs.freedesktop.org/show_bug.cgi?id=55823 * Fix some render corruption with a UDL slave output and pageflipping Release 2.20.9 (2012-09-29) =========================== And so it came to pass that a critical bug was uncovered in UXA. The kernel does not like to pageflip when the pipe is off, yet due to the delayed nature of a pageflip and the relaxed checking performed by UXA, we could request a pageflip after turning off the display (DPMS). The kernel rejected that pageflip and the error handling path failed to restore sanity, and when the screen came back it was stuck on the image seen before it went to sleep. (Note that there are also some related kernel bugs, but this update should prevent the most conspicious of the freezes.) Many thanks to Timo Aaltonen for his efforts in tracking down the issue. In other news: * Prepare for xorg-1.14, the api is being tweaked again. * Handle early FreeScreen in UXA. https://bugs.freedesktop.org/show_bug.cgi?id=55346 * Reenable XvMC support * Do not replace the GPU bo when uploading into the shadow/CPU copy https://bugs.freedesktop.org/show_bug.cgi?id=54978 * Fix use of an uninitialised GC when drawing glyphs to a depth=1 pixmap Release 2.20.8 (2012-09-16) =========================== Another new small feature, another new release. And a few more bugs fixed as well! But what is this new feature, do I hear you ask? Why, it is nothing less than enabling the ValleyView SDV! The lucky person to have their hands on one will now be able to enjoy X in full TechniColor. For the rest of us, a few more bugs were fixed with interesting combinations of software and rendering patterns. * Add an extra layer of defence against trying to use a non-GEM device with UXA. This should already be taken care of with the new probe, but the extra sanity check already existed in the code but was doing nothing. https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-intel/+bug/962892 * Fix computation of valid CRTCs bitmask for ZaphodHead Some systems can only handle certain outputs on certain pipes (Screens), and this information was not being propagated through to X and randr correctly, breaking valid configurations and not detecting invalid configurations correctly. * Disable global glyph caching with ZaphodHeads. The glyph privates need to be Screen private, but at the moment are global leading to conflicts and invalid rendering with multiple heads. https://bugs.freedesktop.org/show_bug.cgi?id=54707 * Prevent direct read back of unmappable buffers https://bugs.freedesktop.org/show_bug.cgi?id=54808 * Tile large uploads whilst replacing the alpha channel https://bugs.freedesktop.org/show_bug.cgi?id=54808 * Correct the source offset when converting a RENDER composite operation into a BLT composite operation. https://bugs.freedesktop.org/show_bug.cgi?id=54868 * Correct a minor typo in flattening alphamaps which caused the replacement pixmap to often end up with a height of zero. https://bugs.gentoo.org/show_bug.cgi?id=434860 * Don't discard the CPU damage if only part of is being replaced. This is most evident when combining software renders like Opera with accelerated rendering. https://bugs.freedesktop.org/show_bug.cgi?id=54937 Release 2.20.7 (2012-09-08) =========================== Continuing the flurry of releases, this week saw the release of xorg-1.13 bringing with it the first steps towards hotpluggable gpu support and the ability to offload DRI rendering onto other GPUs. In light of that advance, this release includes the support code by Dave Airlie to integrate PRIME into xf86-video-intel and make those new features available. Aside from landing PRIME, a few other bugs were fixed since 2.20.6: * Fix framebuffer leak on server regeneration * Fix texture cache flushing on IvyBridge and Kwin with plastique https://bugs.freedesktop.org/show_bug.cgi?id=54488 * Redirect large solid fills on SandyBridge+. By large I mean greater than 8192 or 16384 pixels on SandyBridge and IvyBridge respectively. https://bugs.freedesktop.org/show_bug.cgi?id=54134 * Fix up backlight option handling in the manpage and uxa. https://bugs.freedesktop.org/show_bug.cgi?id=54397 * Unbreak ZaphodHeads. https://bugs.freedesktop.org/show_bug.cgi?id=52438 Release 2.20.6 (2012-09-02) =========================== A serious bug that caused a crash on SandyBridge and IvyBridge when mixing CPU and GPU operations on the same buffer, and an annoyance from bad scheduling of windowed swapbuffer updates causing low framerates and jitter. Plus the usual smattering of assertion fixes and a long standing issue with incoherent page access to a streaming buffer. * Low frame rates in Blobby Valley when "fullscreen" https://bugs.freedesktop.org/show_bug.cgi?id=54274 * Incoherent concurrent access with the CPU and GPU https://bugs.freedesktop.org/show_bug.cgi?id=51422 https://bugs.freedesktop.org/show_bug.cgi?id=52299 * Add Option "Backlight" to override automatic selection of the backlight interface. * Avoid overwriting the composite operation info when testing if we can transfer the operation to the BLT. Release 2.20.5 (2012-08-26) =========================== Another silly bug found, another small bugfix release. The goal was for the driver to bind to all Intel devices supported by the kernel. Unfortunately we were too successful and started claiming Pouslbo, Medfield and Cedarview devices which are still encumbered by proprietary IP and not supported by this driver. Bugs fixed since 2.20.4: * Only bind to Intel devices using the i915 kernel module * Regression in the bitmap-to-region code, e.g. icewm window buttons https://bugs.freedesktop.org/show_bug.cgi?id=53699 Release 2.20.4 (2012-08-18) =========================== Continuing the small bugfix releases, the only real feature is initial enabling for Haswell for the purpose of rendering verification and validation - by no means is it complete! Bugs fixed since 2.20.3: * Some potential errors along failure paths found by a static analyser with the help of Zdenek Kablac. * Eliminate zero-sized rectangles from PolyFillRectangles as the code assumes that they did not exist and so caused corruption. * Remove the UXA warning for failing to tile the front buffer if it is disallowed by hardware, and so expected. * Fix the validation of the XV pipe parameter. * Fix 8x8 tiled pattern fills https://bugs.freedesktop.org/show_bug.cgi?id=53353 * Fix compile failure when using --with-builderstring * Restore w/a flush for gen4 fill/copy/video, fortunately rare operations as at least for fill/copy we prefer to use the BLT. https://bugs.freedesktop.org/show_bug.cgi?id=53119 * Restore preferred use of the RENDER ring for SNB+ DRI copies. Release 2.20.3 (2012-08-04) =========================== Just a minor bugfix for gen4 chipsets (965gm, gm45 and friends) that crept into 2.20.2. As an added bonus, the pessimistic workaround for a GPU hang on gen4 has been relaxed and the shaders have been overhauled which should pave the way to eliminating the last of the uncommon CPU operations, along with immediately realising a small perforamnce improvement. Bugs fixed since 2.20.2: * Update DPMS bookkeeping after modeset https://bugs.freedesktop.org/show_bug.cgi?id=52142 * Avoid overlapping gpu/cpu damage after ignoring cpu damage in the consideration of placement for the operation. * Enable acceleration by default on 830gm/845g. The GMCH on this pair of chipsets is notoriously incoherent, so the GPU is almost certainly going to hang at some point, though unlikely to hang the system and should automatically disable acceleration (and thence behave identically as if the acceleration was disabled from the start). Option "NoAccel" can be used to disable all 2D acceleration and Option "DRI" can be used to disable all 3D acceleration. https://bugs.freedesktop.org/show_bug.cgi?id=52624 * Fix vertex bookkeeping for gen4 that was causing corruption in the command stream. Release 2.20.2 (2012-07-27) =========================== For the last 9 months, since 2.16.901, we have been shipping a driver that does not work on IvyBridge GT1 systems (HD2500 graphics); we were telling the GPU to use an invalid number of threads for the pixel shader and this in turned caused the GPU to hang. Also fixed since the last release just a few days ago: * Support for the gmux backlight controller on Apple laptops https://bugs.freedesktop.org/show_bug.cgi?id=52423 * Fix X -configure not to list this driver as matching any Intel device, just the VGA class devices will do! * A crash in SNA when repeatedly switching xrandr rotations * Corruption in SNA observed in kwin on IvyBridge https://bugs.freedesktop.org/show_bug.cgi?id=52473 Release 2.20.1 (2012-07-22) =========================== A week in, grab the brown paper bags, for it is time to reveal a couple of critical bugs that spoilt the 2.20.0 release. Firstly we have the restoration of DRI for i810. I am sure that the solitary user will be overjoyed in a couple of years when a new xserver is forced upon him. That enjoyment will be short-lived when as no actual acceleration remains, not even shadow, for the chipset. Perhaps a little more wildly felt, I hope!, will be that the SNA fallbacks were broken on 64-bit machines if they required clipping. One little misplaced cast of a pointer, and the screen is filled with corruption. Among the other tweaks this week: * A bug affecting gen4 handling of trapezoids was fixed, and CPU overhead reduced. https://bugs.freedesktop.org/show_bug.cgi?id=52158 * A fix for a bug causing corruption of a DRI2 unredirected client window that was resized whilst under a compositor. * Support for snoopable buffers on non-LLC architectures, coming to a future kernel. The aim to accelerate transfers between the CPU and the GPU, in particular to dramatically improve readback performance, and to further minimise clflushes. * Improvement to the composite performance on GT2 SandyBridge and IvyBridge devices, in particular the render copy is significantly improved. * Improved handling for when acceleration is disabled, including permitting DRI2 to remain supported even if the X server believes the GPU wedged. * Shadow support was dropped from UXA as it was neither complete nor correct, use SNA instead. Release 2.20.0 (2012-07-15) =========================== First the big news, a new acceleration method that aims to be faster and consume far less CPU than UXA is now available for selection at runtime. This snazzy new architecture can be selected through use of Option "AccelMethod" "sna" in your xorg.conf. Whilst it has been under development for some time, it has not yet had the same degree of widespread testing of UXA, so tread lightly. Try it and if you spot anything that can be improved, please do report a bug. Otherwise we have the usual smattering of bug fixes for UXA: * Use a white source whilst adding glyphs to the glyph mask (This fixes blank glyphs if using a font that mixes ARGB and A glyphs.) * Avoid fallbacks for glyph-to-dst in e.g. gnome-terminal https://bugs.freedesktop.org/show_bug.cgi?id=50508 * Force unused outputs off when VT switching https://bugs.freedesktop.org/show_bug.cgi?id=50772 * Copy the fbcon across to the Screen pixmap at startup. (This patch has been kicking around in the distributions for years.) * Many missed malloc failures checks and forgotten frees found by a static analyzer. Thanks Zdenek Kabelac! * Leak of the back buffer when terminating an application after pageflipping https://bugs.freedesktop.org/show_bug.cgi?id=50670 * Double check that the pipe is on before emitting a WAIT_ON_EVENT. In conjunction with an uptodate kernel, this should eliminate any hangs when changing resolutions or adding/removing displays. https://bugs.freedesktop.org/show_bug.cgi?id=50668 * Update to new Xorg APIs. Future proofing for the next generation of hotplug Xorg display servers. Many thanks to everyone who has reported a bug and otherwise helped to improve the driver. Release 2.19.0 (2012-04-29) =========================== More stability fixes for UXA and support for another variant of IvyBridge. Given the severity of the stability fixes, I strongly recommend everybody to upgrade to 2.19.0. * Prevent waiting on scanlines whilst not in control of the VT and therefore whilst referencing foreign CRTC configurations. * Pixmap (and bo leak) during fallback glyph composition * Remove broken acceleration for rendering glyphs directly upon the destination pixmap, exposed by cairo-1.12.0 (and coincidentally fix another Pixmap leak upon fallback handling). * Add support for Ivy Bridge GT2 Server chipset [PCI id 0x016a] * Remove broken damage flushing with CompositeRectangles https://bugs.freedesktop.org/show_bug.cgi?id=32547 * Fix crash upon server start with multiple monitors https://bugs.freedesktop.org/show_bug.cgi?id=47395 * Fix composition issues resulting from overly aggressive Pixmap reuse https://bugs.freedesktop.org/show_bug.cgi?id=47345 Release 2.18.0 (2012-02-24) =========================== Time passes, a few more bugs have crept out of the woodwork that are a compelling reason to update. Bugs fixed in this release (compared to 2.17.0) ----------------------------------------------- * Limit maximum object size so that all of the source, mask and destination can be mapped into the aperture simultaneously by basing the limit on the mappable aperture size rather than the size of the total GATT. * Incorrect clipping of polygons https://bugs.freedesktop.org/show_bug.cgi?id=43649 Regression from 2.15.901 * Limit number of VMA cached to avoid hitting the per-process VMA limit There still is a residual bug in that we seem to have so many objects floating around in the first place and that still leads to exhaustion of system limits. https://bugs.freedesktop.org/show_bug.cgi?id=43075 https://bugs.freedesktop.org/show_bug.cgi?id=40066 * Latency in processing user-input during continuous rendering Release 2.17.0 (2011-11-16) ============================== A few months have passed, and we have accumulated a surprising number of bug fixes. Oops! We would strongly encourage everyone to upgrade. Bugs fixed in this snapshot (compared to 2.16.902) -------------------------------------------------- * Video clobbering composite batch state http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=635953 Snapshot 2.16.902 (2011-11-13) ============================== This is the second release candidate in preparation for the upcoming 2.17.0 release. We will appreciate any feedback we can get from testing of this snapshot, and thanks to everyone who tested and reported upon issues in the last snapshot. A very old bug demonstrating that nobody has ever used alpha maps, and a couple of more recent mistakes were found. Bugs fixed in this snapshot (compared to 2.16.901) -------------------------------------------------- * Incorrect reuse of surface bindings within a batch for multiple formats https://bugs.freedesktop.org/show_bug.cgi?id=40926 * Nothing was rendered for text with procedural sources https://bugs.freedesktop.org/show_bug.cgi?id=31819 * Handle fallbacks involving alpha maps Snapshot 2.16.901 (2011-10-30) ============================== This is the first release candidate in preparation for the upcoming 2.17.0 release. We will appreciate any feedback we can get from testing of this snapshot. The basis of this release are to push out a couple of critical stability fixes for SandyBridge and IvyBridge. There is very little else to see here. Those 200+ other commits do not exist... Bugs fixed in this snapshot (compared to 2.16.0) -------------------------------------------------- * Workaround blitter hang on SandyBridge and IvyBridge https://bugzilla.kernel.org/show_bug.cgi?id=27892 https://bugs.freedesktop.org/show_bug.cgi * Workaround pipe control issues on SandyBridge * Use correct maximum PS thread count on IvyBridge * Protect against failed pixmap allocation for XV https://bugs.freedesktop.org/show_bug.cgi?id=40439 Release 2.16.0 (2011-08-09) ============================== A new quarter, a new release! The key feature of this release, looking past the bug fixes, is the enabling of IvyBridge acceleration. We have also fixed many bugs and graphical glitches and would encourage everyone to upgrade. Bugs fixed in this snapshot (compared to 2.15.901) -------------------------------------------------- * Build fix for xserver-1.7.7 Snapshot 2.15.901 (2011-07-30) ============================== This is the first release candidate in preparation for the upcoming 2.16.0 release. We will appreciate any feedback we can get from testing of this snapshot. The highlight of this snapshot is the full enabling of IvyBridge with acceleration for Render and Xv, along with handling of the shared render buffer allocations required for Mesa. Also of note is that deep-color support is enabled (for all chipsets), which allows you to drive your 30-bit monitor at its native colour depth. Bugs fixed in this snapshot (compared to 2.15.0) -------------------------------------------------- * Misuse of the Resource database causing crashes after DRI clients close https://bugs.freedesktop.org/show_bug.cgi?id=37700 * Crash on large strings https://bugs.freedesktop.org/show_bug.cgi?id=36860 * Incorrect rendering for some core drawing operations http://bugs.freedesktop.org/show_bug.cgi?id=28768 http://bugs.freedesktop.org/show_bug.cgi?id=28798 http://bugs.freedesktop.org/show_bug.cgi?id=28908 http://bugs.freedesktop.org/show_bug.cgi?id=29401 * Crash in Xv due to insufficient checks on batch space https://bugs.freedesktop.org/show_bug.cgi?id=36319 Release 2.15.0 (2011-04-14) ============================== We are pleased to announce this major release of the xf86-video-intel driver, roughly on schedule at 3 months since 2.14.0. With the many bug fixes in this release, we encourage everyone to upgrade to 2.15. The priority for this quarter has been simply to be unexciting and stabilise the driver further, seeking to capitalise upon the improvements elsewhere in the stack. Bugs fixed in this snapshot (compared to 2.14.903) -------------------------------------------------- * Turn off relaxed fencing by default for older chipsets This was continuing to destabilize those system, so for the release we disabled the feature. If you wish to help us debug this, you can re-enable the optimisation with Option "RelaxedFencing" "True". Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36147 * Build fix for xserver-1.7.7 * KDE glitches on SNB [Technically fixed in the previous snapshot, but I'm really pleased that this got fixed in time for the release!] https://bugs.freedesktop.org/show_bug.cgi?id=35808 Snapshot 2.14.903 (2011-04-11) ============================== This is the third release candidate in preparation for the upcoming 2.15.0 release. We will appreciate any feedback we can get from testing of this snapshot. There was a bit of churn since 2.14.902 as a potential fix for a performance regression was tried but had to reverted when it was found to cause glitches running Compiz on SandyBridge. Otherwise, there were just a couple of fixes for building against old xservers and running on an obscure chipset. Bugs fixed in this snapshot (compared to 2.14.902) -------------------------------------------------- * Prevent issuing an invalid scanline wait command https://bugs.freedesktop.org/show_bug.cgi?id=35576 * The 946GZ in not a 945, but a 965. https://bugs.freedesktop.org/show_bug.cgi?id=35854 * Fix tile sizes for gen2 (finally). * Allow building of recent dri2 changes against old xservers. Snapshot 2.14.902 (2011-03-29) ============================== This is the second release candidate in preparation for the upcoming 2.15.0 release. We will appreciate any feedback we can get from testing of this snapshot. As befits testing of release candidates, no major regression was found and a couple more bugs have been fixed. Bugs fixed in this snapshot (compared to 2.14.901) -------------------------------------------------- * Clients disappearing with pending swaps * Incorrect clipping of Xv output on i915 across extended desktops https://bugs.freedesktop.org/show_bug.cgi?id=35346 * Introduction of a LinearFramebuffer option. (Defaults to tiled for performance and power saving.) Snapshot 2.14.901 (2011-03-02) ============================== This is the first release candidate in preparation for the upcoming 2.15.0 release. We will appreciate any feedback we can get from testing of this snapshot. Still no further along my grandiose plans to improve Render performance, aside from the performance tuning lower in the stack, instead we have had a steady stream of bug fixes. Bugs fixed in this snapshot (compared to 2.14.0) ------------------------------------------------ * Green pixels within partially off-screen video playback https://bugs.freedesktop.org/show_bug.cgi?id=24767 * Defer creation of the glyph cache to generation startup https://bugs.freedesktop.org/show_bug.cgi?id=33412 * Incorrect maximum addresses for video decoder state https://bugs.freedesktop.org/show_bug.cgi?id=34017 * Failure to handle oversized temporary surfaces https://bugs.freedesktop.org/show_bug.cgi?id=34399 * Relaxed tiling corruption on gen2 * Crash when destroying a foreign DRI drawable https://bugs.freedesktop.org/show_bug.cgi?id=34787 Release 2.14.0 (2011-01-07) =========================== We are pleased to announce this major release of the xf86-video-intel driver, on schedule at 3 months since 2.13.0. With the many bug fixes in this release, we encourage everyone to upgrade to 2.14. The most notable feature of this release is the inclusion of acceleration support, both RENDER and XVIDEO, for Sandy Bridge; note that this requires a 2.6.37 kernel. In improving the acceleration code paths to support Sandy Bridge, we were also able to improve the performance of the general i965+ RENDER acceleration. For example on i3, glyph (aa10 and rgb10) performance is about 3x faster, as is performing small copies between windows, with the improvement becoming negligible once you hit around 100 pixels square. Snapshot 2.13.903 (2010-01-04) ============================== This is the second release candidate in preparation for the upcoming 2.14.0 release, and if no showstoppers turn up in wider testing will become the next release. Besides the usual bug fixes, we've included patches by Mario Kleiner to improve vblank handing which both improve the timing accuracy and remove a few potential races -- provided you also have the corresponding fixes in the kernel. Bug fixes --------- * Crash on hot-unpluging with an active fullscreen GL application, e.g. a compositing WM or video player https://bugs.freedesktop.org/show_bug.cgi?id=32770 * Freeze upon maximising client-side software renderers, e.g. flash. https://bugs.freedesktop.org/show_bug.cgi?id=31367 * Fix confusion over G35 generation https://bugs.freedesktop.org/show_bug.cgi?id=32478 Snapshot 2.13.902 (2010-12-10) ============================== This is the first release candidate in preparation for the upcoming 2.14.0 release. Sandybridge support should be now be ready for use, and we will appreciate any feedback we can get from this snapshot. Improving the code base for Sandybridge should also have had knock on effects for earlier chips as well, in particular Ironlake and to a lesser extent i965. New requirements compared to 2.13 --------------------------------- * Librdrm >= 2.4.23 Bug fixes --------- * Crash after failing to allocate memory https://bugs.freedesktop.org/show_bug.cgi?id=31487 * EFAULT during pwrite https://bugs.freedesktop.org/show_bug.cgi?id=29752 * Mark outputs as on and restore backlight after mode-set * A hang with i965+ with newer kernels. Snapshot 2.13.901 (2010-11-05) ============================== This is an intermediate snapshot of ongoing driver development. The primary purpose of this snapshot is to capture some recent improvements, (particularly in Sandybridge support), for further testing. Release 2.13.0 (2010-09-30) =========================== We are pleased to announce this major release of the xf86-video-intel driver, on schedule at 3 months since 2.12.0. With the many bug fixes in this release, we encourage everyone using 2.12 to upgrade to 2.13. [This release is functionally identical to the earlier 2.12.902 release candidate.] New requirements compared to 2.12 --------------------------------- * Librdrm >= 2.4.22 Bug fixes --------- * Attempt to fix infinite MI_WAIT_FOR_EVENT while watching video https://bugs.freedesktop.org/show_bug.cgi?id=28964 [Various new checks have been added to the video code here, but the bug fix hasn't yet been verified by the original reporter.] * Fix buffer-object leak https://bugs.freedesktop.org/show_bug.cgi?id=26946 * Fix memory leak on server reset * Fix crash due to unchecked pixmap allocation https://bugs.freedesktop.org/show_bug.cgi?id=29187 * Fix for video artifacts when using dualscreen https://bugs.freedesktop.org/show_bug.cgi?id=29213 * Fix for incorrect characters in gnome-terminal when using compiz https://bugs.freedesktop.org/show_bug.cgi?id=28438 * Fix for hanging, full-screen applications, (flash, compiz, etc.) https://bugs.freedesktop.org/show_bug.cgi?id=29584 * Fix selection of backlight device on multi-GPU systems https://bugs.freedesktop.org/show_bug.cgi?id=29273 * Fix to avoid crash with extremely large glyphs https://bugs.freedesktop.org/show_bug.cgi?id=29430 * Fix for eDP panels incorrectly being given only a single, valid mode https://bugs.freedesktop.org/show_bug.cgi?id=30069 * Fix GPU hang involving clipped SRC copies https://bugs.freedesktop.org/show_bug.cgi?id=30120 * Fix to compile for 1.6 series X server. * Fix to retry framebuffer allocation after an initial failure. * Fix to disable dri2 after fallbacks are forced on. Snapshot 2.12.902 (2010-09-28) ============================== This is the second release candidate in preparation for the upcoming 2.13.0 release. The comes exactly one week after 2.12.902 and includes only a handful of changes. One significant change is that the drive now requires libdrm 2.4.22 (or newer), as several people reported compilation failures of xf86-video-intel 2.12.901 with libdrm 2.4.21. Other changes include a fix to compile for the 1.6 series X server, a fix to retry framebuffer allocation after an initial failure, and a fix to disable dri2 after fallbacks are forced on. Snapshot 2.12.901 (2010-09-21) ============================== This is the first release candidate in preparation for the upcoming 2.13.0 release. We will appreciate any feedback we can get from testing of this snapshot. Bugs fixed in this snapshot (compared to 2.12.0) ------------------------------------------------ * Attempt to fix infinite MI_WAIT_FOR_EVENT while watching video https://bugs.freedesktop.org/show_bug.cgi?id=28964 [Various new checks have been added to the video code here, but the bug fix hasn't yet been verified by the original reporter.] * Fix buffer-object leak https://bugs.freedesktop.org/show_bug.cgi?id=26946 * Fix memory leak on server reset * Fix crash due to unchecked pixmap allocation https://bugs.freedesktop.org/show_bug.cgi?id=29187 * Fix for video artifacts when using dualscreen https://bugs.freedesktop.org/show_bug.cgi?id=29213 * Fix for incorrect characters in gnome-terminal when using compiz https://bugs.freedesktop.org/show_bug.cgi?id=28438 * Fix for hanging, full-screen applications, (flash, compiz, etc.) https://bugs.freedesktop.org/show_bug.cgi?id=29584 * Fix selection of backlight device on multi-GPU systems https://bugs.freedesktop.org/show_bug.cgi?id=29273 * Fix to avoid crash with extremely large glyphs https://bugs.freedesktop.org/show_bug.cgi?id=29430 * Fix for eDP panels incorrectly being given only a single, valid mode https://bugs.freedesktop.org/show_bug.cgi?id=30069 * Fix GPU hang involving clipped SRC copies https://bugs.freedesktop.org/show_bug.cgi?id=30120 Release 2.12.0 (2010-06-24) =========================== We are pleased to announce this major release of the xf86-video-intel 2D driver. It contains many correctness and performance improvements compared to the 2.11 releases. We encourage everyone using 2.11 to upgrade to 2.12. [This release contains several bug fixes since the earlier 2.11.901 release candidate---see below for details.] New requirements compared to 2.11 --------------------------------- * Libdrm >= 2.4.21 Major performance improvements ------------------------------ There have been many performance improvements targeting the 915G/945G/Pineview graphics chipsets (thank to Chris Wilson!). Areas improved include: * Major improvements to glyph rendering * Avoid software fallback when using extended desktops, (for example, video playback) * Better performance when using large windows, (for example with firefox scrolling) * Avoiding migration ping-pong with gigantic drawing The following speedups (measured with cairo-perf-trace/cairo-traces) capture some of the improvements. These were measured on a Pineview system with X server 1.8.1. This compares how this 2.12 release improves performance compared to 2.11.0: Trace Speedup ----- ------- ocitysmap 5.41x speedup firefox-talos-gfx 2.41x speedup gnome-terminal-vim 2.15x speedup poppler 1.86x speedup firefox-planet-gnome 1.43x speedup midori-zoomed 1.39x speedup swfdec-giant-steps 1.36x speedup xfce4-terminal-a1 1.17x speedup evolution 1.09x speedup swfdec-youtube 1.06x speedup Other improvements ------------------ Daniel Vetter improved Xvmc and overlay, adding GEM support. Bug fixes --------- There have been many conformance improvements targeting the 915G/945G/Pineview graphics chipsets. The rendercheck test suite passes once again and there has been a significant reduction in the number of errors detected by the cairo test suite (notably center sampling and EXTEND_NONE behaviors are fixed). Other notable bug fixes include: * Fix for bug 28446 Garbled fonts with Mathematica https://bugs.freedesktop.org/show_bug.cgi?id=28446 * Fixes for page-flipping and other DRI2-handling bugs, (Thanks Jesse Barnes, and Kristian Høgsberg) * Avoid corruption when using extended desktops, (for example, video playback) (The bug fixes below are new since the 2.11.901 release candidate) * Fix corrupted output when screen rotated https://bugs.freedesktop.org/show_bug.cgi?id=28461 * Fix corrupted rendering in KDE due to missing flush. * Fixes i830_uxa_put_image for the following issues: Bug 28569 - [i965] IGN's flash-based video player crashes X https://bugs.freedesktop.org/show_bug.cgi?id=28569 Bug 28573 - [i965] Fullscreen flash and windowed SDL games fail to update the screen https://bugs.freedesktop.org/show_bug.cgi?id=28573 * Fix visual corruption of scrollbar in Chromium * Fix tiling limits to resolve this issue: Bug 28497 - Graphics corruption after opening a specific website https://bugs.freedesktop.org/show_bug.cgi?id=28497 Snapshot 2.11.901 (2010-06-14) ============================== This is the first release candidate in preparation for the upcoming 2.12.0 release. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.12.0 release. New requirements compared to 2.10 --------------------------------- * Libdrm >= 2.4.19 Major performance improvements ------------------------------ There have been many performance improvements targeting the 915G/945G/Pineview graphics chipsets (thank to Chris Wilson!). Areas improved include: * Major improvements to glyph rendering * Avoid software fallback when using extended desktops, (for example, video playback) * Better performance when using large windows, (for example with firefox scrolling) * Avoiding migration ping-pong with gigantic drawing The following speedups (measured with cairo-perf-trace/cairo-traces) capture some of the improvements. These were measured on a Pineview system with a very recent X server, (from git just before 1.8.1). This compares how this 2.12 release candidate improves performance compared to 2.11.0: Trace Speedup ----- ------- ocitysmap 5.41x speedup firefox-talos-gfx 2.41x speedup gnome-terminal-vim 2.15x speedup poppler 1.86x speedup firefox-planet-gnome 1.43x speedup midori-zoomed 1.39x speedup swfdec-giant-steps 1.36x speedup xfce4-terminal-a1 1.17x speedup evolution 1.09x speedup swfdec-youtube 1.06x speedup Other improvements ------------------ Daniel Vetter improved Xvmc and overlay, adding GEM support. Bug fixes --------- There have been many conformance improvements targeting the 915G/945G/Pineview graphics chipsets. The rendercheck test suite passes once again and there has been a significant reduction in the number of errors detected by the cairo test suite (notably center sampling and EXTEND_NONE behaviors are fixed). Other notable bug fixes include: * Fix for bug 28446 Garbled fonts with Mathematica https://bugs.freedesktop.org/show_bug.cgi?id=28446 * Fixes for page-flipping and other DRI2-handling bugs, (Thanks Jesse Barnes, and Kristian Høgsberg) * Avoid corruption when using extended desktops, (for example, video playback) Release 2.11.0 (2010-03-29) =========================== New in 2.11: DRI2 and page flipping ----------------------------------- The most significant new feature of this release is support for new DRI2 APIs, allowing page flipping to occur for swaps that are full-screen and not rotated. Performance improvements in 2.11 compared to 2.10 ------------------------------------------------- Dramatically improved performance of large pixmaps on memory-constrained hardware, (such as 945), by using tiling. Note that this fix is new since the most recent release candidate for this release (2.10.903). https://bugs.freedesktop.org/show_bug.cgi?id=25375 Elimination of software fallback with alpha-only pixmap (a fix which eliminated a full second from the Moblin boot time): https://bugs.freedesktop.org/show_bug.cgi?id=26189 Notable bug fixes in 2.11 compared to 2.10 ------------------------------------------ Fix for undesired black borders on some images, (caued several problems with firefox): http://bugs.freedesktop.org/show_bug.cgi?id=17933 And other fixes to provide more conformance with existing software-rendering, (as measures by the cairo test suite), such as the sampling location for nearest-neighbor sampling. Other changes ------------- Eric Anholt and Daniel Vetter both removed large piles of old and useless code now that the driver requires kernel modesetting (KMS). This continues to reduce the mainteance burden of the driver, making it easier to isolate and fix bugs. Snapshot 2.10.903 (2010-03-22) ============================== Some notable bug fixes ---------------------- * Fix unpredictable results in page-flipping code due to access of an uninitialized variable. * Two fixes that address a number of long-outstanding failures in the cairo test suite: Remove coord-adjust for nearest centre-sampling. Fill alpha on xrgb images. Closes: Bug 17933 - x8r8g8b8 doesn't sample alpha=0 outside surface bounds http://bugs.freedesktop.org/show_bug.cgi?id=17933 * Fix a regression introduced in 2.10.902: Fatal server error: i915_emit_composite_setup: ADVANCE_BATCH: under-used allocation 100/104 Bug 21723 [i915 bisected] rendering makes X crash http://bugs.freedesktop.org/show_bug.cgi?id=27123 Other minor fixes (avoid trying to print an error message with a freed string, set a variable to NULL after freeing), and documentation updates are also included. Snapshot 2.10.902 (2010-03-15) ============================== Some significant bug fixes -------------------------- Fix video color problems due to YUV plane ordering issue. This fixed a regression that showed up recently (only in these release candidates). Fix recent regression leading to corruption under compiz: https://bugs.freedesktop.org/show_bug.cgi?id=26814 Further DRI2 improvements/fixes from Mario Kleiner and Jesse Barnes, (including support for SwapBuffers request with divisor != 0). Fix build against X server 1.6 branch. Avoid flooding logs after an error occurs. And dramatic code cleanups -------------------------- Eric Anholt removed several cases of old, useless code, (conditions that could not occur now that we require KMS, etc.). Daniel Vetter eliminated piles of code by modernizing the XvMC memory-management and completely removing the old i830_memory allocator (i830_allocate_memory, i830_free_memory), etc. Snapshot 2.10.901 (2010-02-26) ============================== The most significant new feature of this release is support for new DRI2 APIs, allowing page flipping to occur for swaps that are full-screen and not rotated. Some significant bug fixes -------------------------- * Avoid fallback due to failing to extract pixel value from an alpha-only solid, (this fix eliminated 1 second from Mobilin boot time). https://bugs.freedesktop.org/show_bug.cgi?id=26189 * Handle full-height blits without tearing in CopyRegion https://bugs.freedesktop.org/show_bug.cgi?id=22475 Several other fixes and cleanups are included as well, (including the removal of stale utility code that is now maintained in the separate intel-gpu-tools module). Release 2.10.0 (2010-01-04) =========================== New requirements of 2.10 compared to 2.9 ---------------------------------------- * Linux kernel with kernel-modesetting (KMS) All user-modesetting code has now been removed from the driver. We highly recommend kernel version 2.6.32 or later. * Libdrm >= 2.4.16 New features in 2.10 compared to 2.9 ------------------------------------ * New driver debugging options available in xorg.conf (DebugFlushBatches, DebugFlushCaches, DebugWait). See "man intel" for more details. * Video overlay support with KMS. This currently requires Linux 2.6.33, but a backport to 2.6.32 is available here: http://gitorious.org/daniel-s-linux-stuff/linux-kernel/commits/intel-kms-overlay-for-2.6.32 Notable fixes in 2.10 compared to 2.9 ----------------------------------- * Fix crash when XRenderComposite is called with a -1 value for width/height, (crash at login when using compiz). http://bugs.freedesktop.org/show_bug.cgi?id=24724 * Fix to support larger extended desktops, (such as a 2560x1600 plus a 1920x1200 monitor). * Fix glyph corruption due to insufficient cache flushing: https://bugs.freedesktop.org/show_bug.cgi?id=24315 Several other correctness and performance fixes are also included. Note: The driver code of the 2.10.0 release is identical to that of the 2.9.99.901 release candidate. The only changes in 2.10.0 compared to 2.9.99.902 are a minor change to the configure script, and some small updates to the documentation. Snapshot 2.9.99.902 (2009-12-10) ================================ This is the second release candidate in preparation for the upcoming 2.10.0 release. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.10.0 release. Compared to the previous snapshot, this snapshot now correctly verifies that libdrm 2.4.16 (or newer) is available. The previous snapshot also required libdrm 2.4.16 for correct functionality, but neglected to notify the user of this at configure, compile, or install time and would instead simply fail to run. Snapshot 2.9.99.901 (2009-11-30) ================================ This is the first release candidate in preparation for the upcoming 2.10.0 release. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.10.0 release. With this snapshot, the xf86-video-intel driver requires kernel modesetting (KMS) as all of the user modesetting (UMS) support has been removed from the driver. Release 2.9.0 (2009-09-28) ========================== We are pleased to announce the 2.9.0 release of the xf86-video-intel driver. (If you have been following along at home, this release is identical to the 2.8.99.902 release candidate other than the version number). New features in 2.9 compared to 2.8 ----------------------------------- * Support for the B43 chipset. Major fixes in 2.9.0 compared to 2.8.0 -------------------------------------- * Multiple fixes to make the driver stable for 8xx chipsets, (855GM, 865G, etc.). The 2.8 driver series was extremely unstable with many of these chipsets. https://bugs.freedesktop.org/show_bug.cgi?id=22904 (and many duplicates) https://bugs.freedesktop.org/show_bug.cgi?id=22947 * Add support for BACKLIGHT property when using kernel modesetting (KMS). This allows backlight adjustment with programs such as "xbacklight -set " or "xrandr --set BACKLIGHT ". https://bugs.freedesktop.org/show_bug.cgi?id=20963 * Fix so that "xrandr --scale" works when using KMS. https://bugs.freedesktop.org/show_bug.cgi?id=22893 * Fix segfaults of X server when logging out. https://bugs.freedesktop.org/show_bug.cgi?id=20516 * Avoid falling back to software for 1-bit alpha-only masks. https://bugs.freedesktop.org/show_bug.cgi?id=23184 * Fix pixel sampling position for 8xx chipsets, (fixes some cairo-test suite failures). Snapshot 2.8.99.901 (2009-09-09) ================================ This is the first release candidate in preparation for the upcoming 2.9.0 release. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.9.0 release. See the commit log for changes in this release, and developers, please provide me summaries for any major features in this release that you think should appear in NEWS and in the 2.9.0 release notes. Note: We are still investigating failures with 865G chipsets, (these failures existed in the 2.8 series as well). We are hoping to fix these failures before the 2.9.0 release. Release 2.8.0 (2009-07-20) ========================== We are pleased to present this major release of the xf86-video-intel driver. This release is very similar to the 2.7.99.902 release candidate but includes a couple of additional bug fixes, (for bugs #22760 and @22483). Compared to the 2.7 releases this driver contains several new features and many bug fixes. The driver now depends on X server 1.6 or later, and eliminates several obsolete code paths, (XAA and EXA removed in favor of UXA, DRI1 support eliminated). The driver certainly will work best with an i915 module from a recent kernel (2.6.31) and with kernel-modesetting (KMS, specified by loading i915 with the option "modeset=1"). New features in 2.8.0 compared to 2.7 ------------------------------------- * Remove XAA/EXA/DRI1 and NoAccel, and only support UXA/DRI2 now (requiring xserver 1.6). * VLD support added into XvMC for Mpeg2, which decreases CPU usage when playing video. Major fixes in 2.8.0 compared to 2.7 ------------------------------------ * Fix broken front-buffer rendering https://bugs.freedesktop.org/show_bug.cgi?id=19174 * Fix disabling of XvMC disabled https://bugs.freedesktop.org/show_bug.cgi?id=20790 * Fix broken VT switch on some machines https://bugs.freedesktop.org/show_bug.cgi?id=19578 * Improve performance of trapezoid rendering for UXA https://bugs.freedesktop.org/show_bug.cgi?id=21376 * Vblank sync'd GL buffer swap (fixing video tearing under composite) https://bugs.freedesktop.org/show_bug.cgi?id=20664 * Fix G41 DRM support https://bugs.freedesktop.org/show_bug.cgi?id=21095 * Fix crash on some 8xx https://bugs.freedesktop.org/show_bug.cgi?id=18974 Various fixes for GPU hangs, and more... Snapshot 2.7.99.902 (2009-07-13) -------------------------------- This is the first release candidate in preparation for the upcoming 2.8.0 release. Most major and critical bugs should be fixed, but some minor bugs may still be present. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.8.0 release. Snapshot 2.7.99.901 (2009-06-10) -------------------------------- This is the first release candidate in preparation for the upcoming 2.8.0 release. Most critical bugs should be fixed, but some major bugs may still be present. We will appreciate any feedback we can get from testing of this snapshot to improve the 2.8.0 release. Some of the major fixes in this snapshot include: * Several fixes for intermittent GPU hangs/crashes, (some of which already appeared in the 2.7.1 release) * Fix to avoid X crash when viewing large images in browser * Fix X server failure when running old (non-GEM) kernel * Fixes for SDVO LVDS mode detection * Fix major performance regression of trapezoid rendering compared to XAA/EXA * New support for tear-free video when using KMS * New support for tear-free DRI2 CopyRegion Snapshot 2.7.99.1 (2009-04-28) ------------------------------ This is a development snapshot very early in the process toward developing 2.8. There have been some big changes to the code, and we're anxious to get feedback on these changes as early as possible. Here is a summary of the biggest changes: * Driver now depends on X server 1.6 or later * Eliminate XAA and EXA support (in favor of UXA) * Eliminate DRI1 support * Fixes for running without DRI at all These code removals represent a deletion of a substantial amount of code, (and hopefully piles of bugs), as well as reduce the maintenance effort going forward as the number of combinatorial configurations for the driver are greatly reduced. This means that users are much more likely to be running code that has actually been tested, and it will be much easy for developers to replicate bugs that users experience. One of the things that would be most useful in testing this release is to revisit any outstanding bugs that you have previously reported. If the buggy behavior is gone, (or the bug is no longer relevant---such as a bug that's specific to XAA only), please feel free to indicate so in bugzilla or even just close the bug. If you confirm that the bug is still present, please indicate so in the bug report. (I was going to ask that you select a 1.7.99 version, but it looks like bugzilla only has versions for products not compoenents, while we use a "xorg" product and a "driver/intel" component.) We definitely want to make any such confirmed bugs a priority, so it would be nice to have a consistent mechanism to search for these bugs. Suggestions are welcome on the best approach. Thanks in advance for any testing or feedback on this snapshot. Release 2.7.0 (2009-04-15) -------------------------- Compared to the 2.6 series, 2.7.0 has a large number of bug fixes, but also a few significant features, such as: SDVO-TV support, available on ADD2 card (bug#9992) and D945GCLF2 board (bug#17776). Basic SDVO-LVDS support XV video display without tearing [Though this isn't working for all users yet, see https://bugs.freedesktop.org/show_bug.cgi?id=21076 ] Various fixes for UXA, DRI2, and Kernel modesetting. We encourage users to use kernel modesetting and UXA acceleration with this release, which should give the best performance and robustness. When KMS is available, UXA is the default acceleration used by the driver, (EXA is the default otherwise). Known issue: Some Linux kernel versions (such as 2.6.29) are known to have broken PAT code that causes recent versions of this driver to fail, (which can manifest as the X server simply not starting). This can be verified by adding the "nopat" option to the kernel command-line and seeing the failure go away. We hope that newer kernels in the 2.6.29.x as well as 2.6.30 and above will have working PAT code. Some of the most notable bugs fixed in 2.7.0 include: [GM45 965GM] bad htotal causes panel startup failure https://bugs.freedesktop.org/show_bug.cgi?id=17292 [xrandr TV] need TV output property control https://bugs.freedesktop.org/show_bug.cgi?id=12763 [TV] "xrandr --set TV_FORMAT" gets BadMatch error https://bugs.freedesktop.org/show_bug.cgi?id=16566 [945 tiling] Low performance due to no A17 workaround https://bugs.freedesktop.org/show_bug.cgi?id=16835 [TV]Flicker when launching applications in the 2.4-branch https://bugs.freedesktop.org/show_bug.cgi?id=17405 [945GM FBC] FBC causes underruns & flicker https://bugs.freedesktop.org/show_bug.cgi?id=18651 [xv] Textured video suffers from tearing https://bugs.freedesktop.org/show_bug.cgi?id=19635 [G45] Random hangs with UXA https://bugs.freedesktop.org/show_bug.cgi?id=19734 [945GM] Any 3D app is slow in resolution higher than 800x600 with UXA+DRI2, due to tiling https://bugs.freedesktop.org/show_bug.cgi?id=19738 [i915 UXA,EXA] rotation messes display with tiling on https://bugs.freedesktop.org/show_bug.cgi?id=20265 [G45] DRI2/UXA gives solid white instead of transparency https://bugs.freedesktop.org/show_bug.cgi?id=20321 LVDS output not detected https://bugs.freedesktop.org/show_bug.cgi?id=20517 xf86-video-intel-2.6.3: Xv crashes X server https://bugs.freedesktop.org/show_bug.cgi?id=20525 [G965 non-GEM] systray in KDE 4 completely broken https://bugs.freedesktop.org/show_bug.cgi?id=20527 [SDVO-TV]the desktop is teared in four sections on the screen https://bugs.freedesktop.org/show_bug.cgi?id=20550 Intel video driver 2.6.3 crashes with XVideo https://bugs.freedesktop.org/show_bug.cgi?id=20563 [855GM] Xv crash with non-KMS https://bugs.freedesktop.org/show_bug.cgi?id=20585 2.6.99.902 breaks native 1680x1050 mode on TMDS -- EDID miss https://bugs.freedesktop.org/show_bug.cgi?id=20594 [945GM TV] 2.6.99.902 sets a too high CONTRAST-value https://bugs.freedesktop.org/show_bug.cgi?id=20670 [915GM] fail to detect LVDS with new VBT code https://bugs.freedesktop.org/show_bug.cgi?id=20752 [regression i965]tiled output when start X https://bugs.freedesktop.org/show_bug.cgi?id=20803 2.6.99.902: LVDS wrongly detected as disconnected https://bugs.freedesktop.org/show_bug.cgi?id=20826 vt switching fails and crashes X https://bugs.freedesktop.org/show_bug.cgi?id=20863 [HDMI] The screen will flicker when some application runs on G45-64 https://bugs.freedesktop.org/show_bug.cgi?id=20875 TexturedVideo is offsetted wrongly on dualhead https://bugs.freedesktop.org/show_bug.cgi?id=20980 [EXA] xvideo hang X https://bugs.freedesktop.org/show_bug.cgi?id=21027 [EXA] x11perf performance regression https://bugs.freedesktop.org/show_bug.cgi?id=21029 And many others... xserver-xorg-video-intel-2.99.917+git20160325/README000066400000000000000000000032071267532330400211550ustar00rootroot00000000000000xf86-video-intel Open-source X.org graphics driver for Intel graphics https://01.org/linuxgraphics/ What is xf86-video-intel ------------------------ The xf86-video-intel module is an open-source 2D graphics driver for the X Window System as implemented by X.org. It supports a variety of Intel graphics chipsets including: i810/i810e/i810-dc100,i815, i830M,845G,852GM,855GM,865G, 915G/GM,945G/GM/GME,946GZ G/GM/GME/Q965, G/Q33,G/Q35,G41,G/Q43,G/GM/Q45 PineView-M (Atom N400 series) PineView-D (Atom D400/D500 series) Intel(R) HD Graphics: 2000-6000, Intel(R) Iris(TM) Graphics: 5100/6100, and Intel(R) Iris(TM) Pro Graphics: 5200/6200/P6300. Where to get more information about the driver ---------------------------------------------- The primary source of information about this and other open-source drivers for Intel graphics is: https://01.org/linuxgraphics/ Documentation specific to the xf86-video-intel driver including possible configuration options for the xorg.conf file can be found in the intel(4) manual page. After installing the driver this documentation can be read with the following command: man intel Mailing list for communication with users and developers of xf86-video-intel: intel-gfx@lists.freedesktop.org Note: Subscription is required before posting, but anyone is free to subscribe. See instructions (and archives) here: http://lists.freedesktop.org/mailman/listinfo/intel-gfx To report bugs encountered with the driver, see: https://01.org/linuxgraphics/documentation/how-report-bugs To see bugs that are targeted to be fixed in the next release: https://bugs.freedesktop.org/show_bug.cgi?id=intel-2d-release xserver-xorg-video-intel-2.99.917+git20160325/RELEASING000066400000000000000000000024361267532330400215340ustar00rootroot00000000000000The process for releasing a new tarball is as follows: 1. Make sure you have the latest build requirements installed: git://git.freedesktop.org/git/util/macros git://git.freedesktop.org/git/util/modular 2. Add relevant release notes to the NEWS files Skim the git log since the last release, and add notes in a similar style to previous releases. For major releases list added features and known limitations. For minor releases indicate which bugs were fixed and which are still present. 3. Update your module version (usually found in configure.ac) $ vi configure.ac # bump version $ git commit $ git push origin # make sure you're on the release branch 4. Verify your module builds $ make distcheck 5. Tag the release $ git tag -m "Intel release" 6. Run the release script (this should push the tag) $ /util/modular/release.sh driver 7. Edit and send the generated release message. At the very least, add the release notes from the NEWS file. The message is generated as xf86-video-intel-.announce For snapshots and release candidates, mail to: intel-gfx@lists.freedesktop.org For major releases also send to: xorg@lists.freedesktop.org xorg-announce@lists.freedesktop.org 8. Throw a release party, you're done! :) xserver-xorg-video-intel-2.99.917+git20160325/autogen.sh000077500000000000000000000003211267532330400222700ustar00rootroot00000000000000#! /bin/sh srcdir=`dirname $0` test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir autoreconf -v --install || exit 1 cd $ORIGDIR || exit $? if test -z "$NOCONFIGURE"; then $srcdir/configure "$@" fi xserver-xorg-video-intel-2.99.917+git20160325/benchmarks/000077500000000000000000000000001267532330400224105ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/benchmarks/.gitignore000066400000000000000000000000241267532330400243740ustar00rootroot00000000000000dri2-swap dri3-swap xserver-xorg-video-intel-2.99.917+git20160325/benchmarks/Makefile.am000066400000000000000000000004151267532330400244440ustar00rootroot00000000000000AM_CFLAGS = @CWARNFLAGS@ $(X11_CFLAGS) $(DRM_CFLAGS) LDADD = $(X11_LIBS) $(DRM_LIBS) $(CLOCK_GETTIME_LIBS) check_PROGRAMS = if DRI2 check_PROGRAMS += dri2-swap endif if DRI3 check_PROGRAMS += dri3-swap AM_CFLAGS += $(X11_DRI3_CFLAGS) LDADD += $(X11_DRI3_LIBS) endif xserver-xorg-video-intel-2.99.917+git20160325/benchmarks/dri2-swap.c000066400000000000000000000347071267532330400243770ustar00rootroot00000000000000/* * Copyright (c) 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static char dri2ExtensionName[] = DRI2_NAME; static XExtensionInfo *dri2Info; static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); static Status DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); static int DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_gc */ NULL, /* copy_gc */ NULL, /* flush_gc */ NULL, /* free_gc */ NULL, /* create_font */ NULL, /* free_font */ DRI2CloseDisplay, /* close_display */ DRI2WireToEvent, /* wire_to_event */ DRI2EventToWire, /* event_to_wire */ DRI2Error, /* error */ NULL, /* error_string */ }; static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, 0, NULL) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); XextCheckExtension(dpy, info, dri2ExtensionName, False); switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { #ifdef X_DRI2SwapBuffers case DRI2_BufferSwapComplete: return False; #endif #ifdef DRI2_InvalidateBuffers case DRI2_InvalidateBuffers: return False; #endif default: /* client doesn't support server event */ break; } return False; } /* We don't actually support this. It doesn't make sense for clients to * send each other DRI2 events. */ static Status DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); XextCheckExtension(dpy, info, dri2ExtensionName, False); switch (event->type) { default: /* client doesn't support server event */ break; } return Success; } static int DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) { if (err->majorCode == codes->major_opcode && err->errorCode == BadDrawable && err->minorCode == X_DRI2CopyRegion) return True; /* If the X drawable was destroyed before the GLX drawable, the * DRI2 drawble will be gone by the time we call * DRI2DestroyDrawable. So just ignore BadDrawable here. */ if (err->majorCode == codes->major_opcode && err->errorCode == BadDrawable && err->minorCode == X_DRI2DestroyDrawable) return True; /* If the server is non-local DRI2Connect will raise BadRequest. * Swallow this so that DRI2Connect can signal this in its return code */ if (err->majorCode == codes->major_opcode && err->minorCode == X_DRI2Connect && err->errorCode == BadRequest) { *ret_code = False; return True; } return False; } static Bool DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); if (XextHasExtension(info)) { *eventBase = info->codes->first_event; *errorBase = info->codes->first_error; return True; } return False; } static Bool DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2ConnectReply rep; xDRI2ConnectReq *req; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2Connect, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2Connect; req->window = window; req->driverType = DRI2DriverDRI; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { UnlockDisplay(dpy); SyncHandle(); return False; } *driverName = Xmalloc(rep.driverNameLength + 1); if (*driverName == NULL) { _XEatData(dpy, ((rep.driverNameLength + 3) & ~3) + ((rep.deviceNameLength + 3) & ~3)); UnlockDisplay(dpy); SyncHandle(); return False; } _XReadPad(dpy, *driverName, rep.driverNameLength); (*driverName)[rep.driverNameLength] = '\0'; *deviceName = Xmalloc(rep.deviceNameLength + 1); if (*deviceName == NULL) { Xfree(*driverName); _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); UnlockDisplay(dpy); SyncHandle(); return False; } _XReadPad(dpy, *deviceName, rep.deviceNameLength); (*deviceName)[rep.deviceNameLength] = '\0'; UnlockDisplay(dpy); SyncHandle(); return True; } static Bool DRI2Authenticate(Display * dpy, XID window, unsigned int magic) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2AuthenticateReq *req; xDRI2AuthenticateReply rep; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2Authenticate, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2Authenticate; req->window = window; req->magic = magic; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } UnlockDisplay(dpy); SyncHandle(); return rep.authenticated; } static void DRI2CreateDrawable(Display * dpy, XID drawable) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2CreateDrawableReq *req; XextSimpleCheckExtension(dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2CreateDrawable, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2CreateDrawable; req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); } static void DRI2SwapInterval(Display *dpy, XID drawable, int interval) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2SwapIntervalReq *req; XextSimpleCheckExtension (dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2SwapInterval, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2SwapInterval; req->drawable = drawable; req->interval = interval; UnlockDisplay(dpy); SyncHandle(); } static int _x_error_occurred; static int _check_error_handler(Display *display, XErrorEvent *event) { fprintf(stderr, "X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static double elapsed(const struct timespec *start, const struct timespec *end) { return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000; } static void run(Display *dpy, Window win) { xcb_connection_t *c = XGetXCBConnection(dpy); struct timespec start, end; int n, completed = 0; clock_gettime(CLOCK_MONOTONIC, &start); do { for (n = 0; n < 1000; n++) { unsigned int attachments[] = { DRI2BufferBackLeft }; unsigned int seq[2]; seq[0] = xcb_dri2_swap_buffers_unchecked(c, win, 0, 0, 0, 0, 0, 0).sequence; seq[1] = xcb_dri2_get_buffers_unchecked(c, win, 1, 1, attachments).sequence; xcb_flush(c); xcb_discard_reply(c, seq[0]); xcb_discard_reply(c, seq[1]); completed++; } clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec < start.tv_sec + 10); printf("%f\n", completed / (elapsed(&start, &end) / 1000000)); } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2QueryExtension(dpy, &fd, &fd)) return -1; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; } static void fullscreen(Display *dpy, Window win) { Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&atom, 1); } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XDamageQueryExtension (dpy, &event, &error)) return 0; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } int main(int argc, char **argv) { Display *dpy; Window root, win; XRRScreenResources *res; XRRCrtcInfo **original_crtc; XSetWindowAttributes attr; enum window { ROOT, FULLSCREEN, WINDOW } w = FULLSCREEN; enum visible {REDIRECTED, NORMAL } v = NORMAL; enum display { OFF, ON } d = OFF; int width, height; int i, fd; int c; while ((c = getopt(argc, argv, "d:v:w:")) != -1) { switch (c) { case 'd': if (strcmp(optarg, "off") == 0) d = OFF; else if (strcmp(optarg, "on") == 0) d = ON; else abort(); break; case 'v': if (strcmp(optarg, "redirected") == 0) v = REDIRECTED; else if (strcmp(optarg, "normal") == 0) v = NORMAL; else abort(); break; case 'w': if (strcmp(optarg, "fullscreen") == 0) w = FULLSCREEN; else if (strcmp(optarg, "window") == 0) w = WINDOW; else if (strcmp(optarg, "root") == 0) w = ROOT; else abort(); break; } } attr.override_redirect = 1; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; width = DisplayWidth(dpy, DefaultScreen(dpy)); height = DisplayHeight(dpy, DefaultScreen(dpy)); fd = dri2_open(dpy); if (fd < 0) return 77; if (DPMSQueryExtension(dpy, &i, &i)) DPMSDisable(dpy); root = DefaultRootWindow(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); res = NULL; if (XRRQueryVersion(dpy, &i, &i)) res = _XRRGetScreenResourcesCurrent(dpy, root); if (res == NULL) return 77; if (v == REDIRECTED && !has_composite(dpy)) return 77; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); DRI2CreateDrawable(dpy, root); DRI2SwapInterval(dpy, root, 0); if (d != OFF) { for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); if (mode == NULL) continue; XRRSetCrtcConfig(dpy, res, output->crtcs[0], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); width = mode->width; height = mode->height; break; } if (i == res->noutput) { _x_error_occurred = 77; goto restore; } } if (w == ROOT) { run(dpy, root); } else if (w == FULLSCREEN) { win = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); if (v == REDIRECTED) { XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XDamageCreate(dpy, win, XDamageReportRawRectangles); } else fullscreen(dpy, win); XMapWindow(dpy, win); run(dpy, win); } else if (w == WINDOW) { win = XCreateWindow(dpy, root, 0, 0, width/2, height/2, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); if (v == REDIRECTED) { XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XDamageCreate(dpy, win, XDamageReportRawRectangles); } XMapWindow(dpy, win); run(dpy, win); } restore: for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); if (DPMSQueryExtension(dpy, &i, &i)) DPMSEnable(dpy); XSync(dpy, True); return _x_error_occurred; } xserver-xorg-video-intel-2.99.917+git20160325/benchmarks/dri3-swap.c000066400000000000000000000327141267532330400243740ustar00rootroot00000000000000/* * Copyright (c) 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct dri3_fence { XID xid; void *addr; }; static int _x_error_occurred; static uint32_t stamp; struct list { struct list *next, *prev; }; static void list_init(struct list *list) { list->next = list->prev = list; } static inline void __list_add(struct list *entry, struct list *prev, struct list *next) { next->prev = entry; entry->next = next; entry->prev = prev; prev->next = entry; } static inline void list_add(struct list *entry, struct list *head) { __list_add(entry, head, head->next); } static inline void __list_del(struct list *prev, struct list *next) { next->prev = prev; prev->next = next; } static inline void _list_del(struct list *entry) { __list_del(entry->prev, entry->next); } static inline void list_move(struct list *list, struct list *head) { if (list->prev != head) { _list_del(list); list_add(list, head); } } #define __container_of(ptr, sample, member) \ (void *)((char *)(ptr) - ((char *)&(sample)->member - (char *)(sample))) #define list_for_each_entry(pos, head, member) \ for (pos = __container_of((head)->next, pos, member); \ &pos->member != (head); \ pos = __container_of(pos->member.next, pos, member)) static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static int dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); struct dri3_fence f; int fd; fd = xshmfence_alloc_shm(); if (fd < 0) return -1; f.addr = xshmfence_map_shm(fd); if (f.addr == NULL) { close(fd); return -1; } f.xid = xcb_generate_id(c); xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); *fence = f; return 0; } static double elapsed(const struct timespec *start, const struct timespec *end) { return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000; } struct buffer { struct list link; Pixmap pixmap; struct dri3_fence fence; int fd; int busy; }; static void run(Display *dpy, Window win) { xcb_connection_t *c = XGetXCBConnection(dpy); struct timespec start, end; #define N_BACK 8 struct buffer buffer[N_BACK]; struct list mru; Window root; unsigned int width, height; unsigned border, depth; unsigned present_flags = XCB_PRESENT_OPTION_ASYNC; xcb_xfixes_region_t update = 0; int completed = 0; int queued = 0; uint32_t eid; void *Q; int i, n; list_init(&mru); XGetGeometry(dpy, win, &root, &i, &n, &width, &height, &border, &depth); _x_error_occurred = 0; for (n = 0; n < N_BACK; n++) { xcb_dri3_buffer_from_pixmap_reply_t *reply; int *fds; buffer[n].pixmap = XCreatePixmap(dpy, win, width, height, depth); buffer[n].fence.xid = 0; buffer[n].fd = -1; if (dri3_create_fence(dpy, win, &buffer[n].fence)) return; reply = xcb_dri3_buffer_from_pixmap_reply (c, xcb_dri3_buffer_from_pixmap(c, buffer[n].pixmap), NULL); if (reply == NULL) return; fds = xcb_dri3_buffer_from_pixmap_reply_fds (c, reply); buffer[n].fd = fds[0]; free(reply); /* start idle */ xshmfence_trigger(buffer[n].fence.addr); buffer[n].busy = 0; list_add(&buffer[n].link, &mru); } eid = xcb_generate_id(c); xcb_present_select_input(c, eid, win, XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY | XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY); Q = xcb_register_for_special_xge(c, &xcb_present_id, eid, &stamp); clock_gettime(CLOCK_MONOTONIC, &start); do { for (n = 0; n < 1000; n++) { struct buffer *tmp, *b = NULL; list_for_each_entry(tmp, &mru, link) { if (!tmp->busy) { b = tmp; break; } } while (b == NULL) { xcb_present_generic_event_t *ev; ev = (xcb_present_generic_event_t *) xcb_wait_for_special_event(c, Q); if (ev == NULL) abort(); do { switch (ev->evtype) { case XCB_PRESENT_COMPLETE_NOTIFY: completed++; queued--; break; case XCB_PRESENT_EVENT_IDLE_NOTIFY: { xcb_present_idle_notify_event_t *ie = (xcb_present_idle_notify_event_t *)ev; assert(ie->serial < N_BACK); buffer[ie->serial].busy = 0; if (b == NULL) b = &buffer[ie->serial]; break; } } free(ev); } while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q))); } b->busy = 1; if (b->fence.xid) { xshmfence_await(b->fence.addr); xshmfence_reset(b->fence.addr); } xcb_present_pixmap(c, win, b->pixmap, b - buffer, 0, /* valid */ update, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ b->fence.xid, present_flags, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); list_move(&b->link, &mru); queued++; xcb_flush(c); } clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec < start.tv_sec + 10); while (queued) { xcb_present_generic_event_t *ev; ev = (xcb_present_generic_event_t *) xcb_wait_for_special_event(c, Q); if (ev == NULL) abort(); do { switch (ev->evtype) { case XCB_PRESENT_COMPLETE_NOTIFY: completed++; queued--; break; case XCB_PRESENT_EVENT_IDLE_NOTIFY: break; } free(ev); } while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q))); } clock_gettime(CLOCK_MONOTONIC, &end); printf("%f\n", completed / (elapsed(&start, &end) / 1000000)); } static int has_present(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_generic_error_t *error = NULL; void *reply; reply = xcb_present_query_version_reply(c, xcb_present_query_version(c, XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "Present not supported on %s\n", DisplayString(dpy)); return 0; } return 1; } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XDamageQueryExtension (dpy, &event, &error)) return 0; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static void fullscreen(Display *dpy, Window win) { Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&atom, 1); } static int dri3_query_version(Display *dpy, int *major, int *minor) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_query_version_reply_t *reply; xcb_generic_error_t *error; *major = *minor = -1; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(error); if (reply == NULL) return -1; *major = reply->major_version; *minor = reply->minor_version; free(reply); return 0; } static int has_dri3(Display *dpy) { const xcb_query_extension_reply_t *ext; int major, minor; ext = xcb_get_extension_data(XGetXCBConnection(dpy), &xcb_dri3_id); if (ext == NULL || !ext->present) return 0; if (dri3_query_version(dpy, &major, &minor) < 0) return 0; return major >= 0; } int main(int argc, char **argv) { Display *dpy; Window root, win; XRRScreenResources *res; XRRCrtcInfo **original_crtc; XSetWindowAttributes attr; enum window { ROOT, FULLSCREEN, WINDOW } w = FULLSCREEN; enum visible {REDIRECTED, NORMAL } v = NORMAL; enum display { OFF, ON } d = OFF; int width, height; int i; while ((i = getopt(argc, argv, "d:v:w:")) != -1) { switch (i) { case 'd': if (strcmp(optarg, "off") == 0) d = OFF; else if (strcmp(optarg, "on") == 0) d = ON; else abort(); break; case 'v': if (strcmp(optarg, "redirected") == 0) v = REDIRECTED; else if (strcmp(optarg, "normal") == 0) v = NORMAL; else abort(); break; case 'w': if (strcmp(optarg, "fullscreen") == 0) w = FULLSCREEN; else if (strcmp(optarg, "window") == 0) w = WINDOW; else if (strcmp(optarg, "root") == 0) w = ROOT; else abort(); break; } } attr.override_redirect = 1; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; width = DisplayWidth(dpy, DefaultScreen(dpy)); height = DisplayHeight(dpy, DefaultScreen(dpy)); if (!has_present(dpy)) return 77; if (!has_dri3(dpy)) return 77; if (DPMSQueryExtension(dpy, &i, &i)) DPMSDisable(dpy); root = DefaultRootWindow(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); res = NULL; if (XRRQueryVersion(dpy, &i, &i)) res = _XRRGetScreenResourcesCurrent(dpy, root); if (res == NULL) return 77; if (v == REDIRECTED && !has_composite(dpy)) return 77; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); if (d != OFF) { for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); if (mode == NULL) continue; XRRSetCrtcConfig(dpy, res, output->crtcs[0], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); width = mode->width; height = mode->height; break; } if (i == res->noutput) { _x_error_occurred = 77; goto restore; } } if (w == ROOT) { run(dpy, root); } else if (w == FULLSCREEN) { win = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (v == REDIRECTED) { XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XDamageCreate(dpy, win, XDamageReportRawRectangles); } else fullscreen(dpy, win); XMapWindow(dpy, win); run(dpy, win); } else if (w == WINDOW) { win = XCreateWindow(dpy, root, 0, 0, width/2, height/2, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (v == REDIRECTED) { XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XDamageCreate(dpy, win, XDamageReportRawRectangles); } XMapWindow(dpy, win); run(dpy, win); } restore: for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); if (DPMSQueryExtension(dpy, &i, &i)) DPMSEnable(dpy); XSync(dpy, True); return _x_error_occurred; } xserver-xorg-video-intel-2.99.917+git20160325/configure.ac000066400000000000000000000722301267532330400225650ustar00rootroot00000000000000# 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 # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-intel], [2.99.917], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-intel]) AC_CONFIG_SRCDIR([Makefile.am]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR(.) # Initialize Automake AM_INIT_AUTOMAKE([foreign dist-bzip2]) # Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS m4_ifndef([XORG_MACROS_VERSION], [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen. Hint: either install from source, git://anongit.freedesktop.org/xorg/util/macros or, depending on you distribution, try package 'xutils-dev' or 'xorg-x11-util-macros'])]) XORG_MACROS_VERSION(1.8) XORG_DEFAULT_OPTIONS # And disable a few very noisy warnings m4_ifdef([XORG_TESTSET_CFLAG], [ XORG_TESTSET_CFLAG([NOWARNFLAGS], [-Wno-cast-qual]) XORG_TESTSET_CFLAG([NOWARNFLAGS], [-Wno-redundant-decls]) XORG_TESTSET_CFLAG([NOWARNFLAGS], [-Wno-maybe-uninitialized]) ]) AC_SUBST(NOWARNFLAGS) # Require X.Org server macros (i.e. XORG_DRIVER_CHECK_EXT) to check for required modules m4_ifndef([XORG_DRIVER_CHECK_EXT], [m4_fatal([must install xorg-server macros before running autoconf/autogen. Hint: either install from source, git://anongit.freedesktop.org/xorg/xserver or, depending on your distribution, try package 'xserver-xorg-dev' or 'xorg-x11-server-devel'])]) # Initialize libtool AC_DISABLE_STATIC AC_PROG_LIBTOOL AC_SYS_LARGEFILE # Check for common libc routines redefined by os.h AC_CHECK_FUNCS([strlcpy strlcat strndup], [], []) # Platform specific settings case $host_os in *linux*) backlight_helper=yes ;; esac AC_ARG_ENABLE(backlight, AS_HELP_STRING([--disable-backlight], [Enable control over the backlight [default=yes]]), [backlight="$enableval"], [backlight="yes"]) if test "x$backlight" = "xyes"; then AC_DEFINE(USE_BACKLIGHT, 1, [Enable control of the backlight]) fi AC_ARG_ENABLE(backlight-helper, AS_HELP_STRING([--disable-backlight-helper], [Enable building the backlight helper executable for running X under a normal user [default=auto]]), [backlight_helper="$enableval"],) AM_CONDITIONAL(BUILD_BACKLIGHT_HELPER, [test "x$backlight" = "xyes" -a "x$backlight_helper" = "xyes"]) if test "x$backlight_helper" = "xyes"; then tools_msg="$tools_msg xf86-video-intel-backlight-helper" AC_DEFINE(USE_BACKLIGHT_HELPER, 1, [Enable use of the backlight helper interfaces]) fi # Are we in a git checkout? dot_git=no if test -e .git; then AC_DEFINE(HAVE_DOT_GIT, 1, [Are we in a git checkout?]) dot_git=yes fi AM_CONDITIONAL(HAVE_DOT_GIT, test "x$dot_git" = "xyes") # If so, we include the git description in our logs for sanity checking. # # However, for people not running their own drivers this is just noise. # So we copy the xserver's builderstring idiom to allow for this to be # overridden and perhaps replaced with something more useful. AC_ARG_WITH(builderstring, AS_HELP_STRING([--with-builderstring=BUILDERSTRING], [Additional builder string (default: use git describe)]), [BUILDERSTRING="$withval"], [BUILDERSTRING="x-magic-git-describe"]) if test "x$BUILDERSTRING" = "xx-magic-git-describe" -a "x$dot_git" = "xyes"; then AC_DEFINE(USE_GIT_DESCRIBE, 1, [Use automagic builder description]) else if test "x$BUILDERSTRING" != x -a "x$BUILDERSTRING" != "xno" -a "x$BUILDERSTRING" != xx-magic-git-describe; then AC_DEFINE_UNQUOTED(BUILDER_DESCRIPTION, ["$BUILDERSTRING"], [Builder description]) fi fi AC_ARG_ENABLE(gen4asm, AS_HELP_STRING([--enable-gen4asm], [Enable rebuilding the gen4 assembly files [default=no]]), [ASM="$enableval"], [ASM="no"]) gen4asm=no if test "x$ASM" != "xno"; then AC_ARG_WITH(gen4asm, AS_HELP_STRING([--with-gen4asm=PATH], [Path to intel-gen4asm binary]), [path="$withval"], [path=""]) if test -n "$path" ; then gen4asm=yes else PKG_CHECK_MODULES(GEN4ASM, [intel-gen4asm >= 1.2], [gen4asm=yes], [gen4asm=no]) if test "x$ASM" = "xyes" -a "x$gen4asm" != "xyes"; then AC_MSG_ERROR([intel-gen4asm support requested but not found]) fi fi if test "x$gen4asm" = "xyes"; then AC_MSG_CHECKING([path to use for intel-gen4asm]) if test -n "$path" ; then INTEL_GEN4ASM="$path" else INTEL_GEN4ASM="`pkg-config intel-gen4asm --variable=exec_prefix`/bin/intel-gen4asm" fi if ! test -e "$INTEL_GEN4ASM"; then AC_MSG_ERROR([intel-gen4asm enabled, but not found. Tried '$INTEL_GEN4ASM'.]) fi AC_MSG_RESULT([$INTEL_GEN4ASM]) AC_SUBST([INTEL_GEN4ASM]) fi fi AM_CONDITIONAL(HAVE_GEN4ASM, test "x$gen4asm" = "xyes") # Check for atomic intrinsics AC_CACHE_CHECK([for native atomic primitives], intel_cv_atomic_primitives, [ intel_cv_atomic_primitives="none" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); } int atomic_cmpxchg(int i, int j, int k) { return __sync_val_compare_and_swap (&i, j, k); } ]],[[]])], [intel_cv_atomic_primitives="Intel"],[]) if test "x$intel_cv_atomic_primitives" = "xnone"; then AC_CHECK_HEADER([atomic_ops.h], intel_cv_atomic_primitives="libatomic-ops") fi # atomic functions defined in & libc on Solaris if test "x$intel_cv_atomic_primitives" = "xnone"; then AC_CHECK_FUNC([atomic_cas_uint], intel_cv_atomic_primitives="Solaris") fi ]) if test "x$intel_cv_atomic_primitives" = "xIntel"; then AC_DEFINE(HAVE_ATOMIC_PRIMITIVES, 1, [Enable if your compiler supports the Intel __sync_* atomic primitives]) fi if test "x$intel_cv_atomic_primitives" = "xlibatomic-ops"; then AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, [Enable if you have libatomic-ops-dev installed]) fi if test "x$intel_cv_atomic_primitives" = "xnone"; then AC_MSG_ERROR([xf86-video-intel depends upon atomic operations, which were not found for your compiler/cpu. Try compiling with -march=native, or install the libatomics-op-dev package.]) fi AC_ARG_ENABLE(udev, AS_HELP_STRING([--disable-udev], [Disable udev-based monitor hotplug detection [default=auto]]), [UDEV="$enableval"], [UDEV=auto]) udev_msg=" disabled" if test "x$UDEV" != "xno"; then PKG_CHECK_MODULES(UDEV, [libudev], [udev="yes"], [udev="no"]) AC_CHECK_HEADERS([sys/stat.h], [], [udev="no"]) if test "x$UDEV" = "xyes" -a "x$udev" != "xyes"; then AC_MSG_ERROR([udev support requested but not found (libudev)]) fi if test "x$udev" = "xyes"; then AC_DEFINE(HAVE_UDEV,1,[Enable udev-based monitor hotplug detection]) udev_msg=" yes" else udev_msg=" no" fi fi PKG_CHECK_MODULES(X11, [x11 x11-xcb xcb-dri2 xcomposite xdamage xrender xrandr xext xfixes cairo cairo-xlib-xrender pixman-1 libpng], [x11="yes"], [x11="no"]) AM_CONDITIONAL(HAVE_X11, test "x$x11" = "xyes") echo X11_CLFAGS="$X11_CLFAGS" X11_LIBS="$X11_LIBS" cpuid="yes" AC_TRY_LINK([ #include #include ], [ int eax, ebx, ecx, edx; if (__get_cpuid_max(0, NULL) < 4) return 0; __cpuid_count(4, 0, eax, ebx, ecx, edx); ], [cpuid="yes"], [cpuid="no"] ) if test "x$cpuid" = "xyes"; then AC_DEFINE(HAVE_CPUID_H,1,[Found a useable cpuid.h]) fi shm=yes AC_CHECK_HEADERS([sys/ipc.h sys/ipc.h], [], [shm="no"]) AC_CHECK_HEADERS([X11/extensions/XShm.h], [], [shm="no"], [ #include #include ]) AC_CHECK_HEADERS([X11/extensions/shmproto.h X11/extensions/shmstr.h], [], [], [ #include #include ]) if test "x$ac_cv_header_X11_extensions_shmproto_h" != "xyes" -a "x$ac_cv_header_X11_extensions_shmstr_h" != "xyes"; then shm="no" fi if test "x$shm" = "xyes"; then AC_MSG_CHECKING(whether shmctl IPC_RMID allows subsequent attaches) AC_TRY_RUN([ #include #include #include int main() { char *shmaddr; int id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600); if (id == -1) return 2; shmaddr = shmat (id, 0, 0); shmctl (id, IPC_RMID, 0); if ((char*) shmat (id, 0, 0) == (char*) -1) { shmdt (shmaddr); return 1; } shmdt (shmaddr); shmdt (shmaddr); return 0; } ], AC_DEFINE(IPC_RMID_DEFERRED_RELEASE, 1, [Define to 1 if shared memory segments are released deferred.]) AC_MSG_RESULT(yes), AC_MSG_RESULT(no), AC_MSG_RESULT(assuming no)) AC_DEFINE([HAVE_MIT_SHM], 1, [Define to 1 if MIT-SHM is available]) fi PKG_CHECK_MODULES(X11_DRI3, [xcb-dri3 xcb-sync xcb-xfixes xcb-present x11-xcb xshmfence x11 xcomposite xdamage xrender xrandr xxf86vm xext libdrm], [x11_dri3="yes"], [x11_dri3="no"]) AM_CONDITIONAL(X11_DRI3, test "x$x11_dri3" = "xyes" -a "x$shm" = "xyes") AM_CONDITIONAL(X11_SHM, test "x$shm" = "xyes") AC_ARG_ENABLE(tools, AS_HELP_STRING([--disable-tools], [Enable building and installing the miscellaneous tools [default=auto]]), [tools="$enableval"], [tools="auto"]) if test "x$shm" != "xyes"; then if test "x$tools" = "xyes"; then AC_MSG_ERROR([Incomplete requirements for extra tools, X11 MIT-SHM extension required]) fi tools="no" fi if test "x$tools" != "xno"; then ivo_requires="xrandr xdamage xfixes xcursor xtst xrender xscrnsaver xext x11 pixman-1" extra_cflags="" ignore="xinerama" PKG_CHECK_MODULES(IVO_EXTRA, [$ignore], [AC_CHECK_HEADERS([X11/extensions/Xinerama.h], [ivo_requires="$ignore $ivo_requires"], [], [#include #include ])], [ignore=""]) ignore="xcb-dri3 xcb-sync x11-xcb xshmfence x11" PKG_CHECK_MODULES(IVO_EXTRA, [$ignore], [ivo_requires="$ivo_requires $ignore"; extra_cflags="-DDRI3"], [ignore=""]) PKG_CHECK_MODULES(IVO, [$ivo_requires], [ivo="yes"], [ivo="no"]) AC_CHECK_HEADER([sys/timerfd.h], [], [ivo="no"]) if test "x$ivo" = "xno"; then if test "x$tools" = "xyes"; then AC_MSG_ERROR([Incomplete requirements for intel-virtual-output, requires $ivo_requires]) fi tools="no" fi PKG_CHECK_MODULES(TOOL_CURSOR, [xfixes x11 libpng], [cursor="yes"], [ivo="no"]) IVO_CFLAGS="$IVO_CFLAGS $extra_cflags" fi if test "x$tools" != "xno"; then tools_msg="$tools_msg intel-virtual-output" fi AC_MSG_CHECKING([whether to build additional tools]) AC_MSG_RESULT([$tools]) AM_CONDITIONAL(BUILD_TOOLS, test "x$tools" != "xno") AM_CONDITIONAL(BUILD_TOOL_CURSOR, test "x$cursor" = "xyes") # Define a configure option for an alternate module directory AC_ARG_WITH(xorg-module-dir, AS_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, AS_HELP_STRING([--disable-dri], [Disable DRI support [[default=auto]]]), [DRI=$enableval], [DRI=auto]) AC_ARG_ENABLE(dri1, AS_HELP_STRING([--disable-dri1], [Disable DRI1 support [[default=yes]]]), [DRI1=$enableval], [DRI1=yes]) AC_ARG_ENABLE(dri2, AS_HELP_STRING([--disable-dri2], [Disable DRI2 support [[default=yes]]]), [DRI2=$enableval], [DRI2=yes]) AC_ARG_ENABLE(dri3, AS_HELP_STRING([--disable-dri3], [Disable DRI3 support [[default=yes]]]), [DRI3=$enableval], [DRI3=yes]) AC_ARG_WITH(default-dri, AS_HELP_STRING([--with-default-dri], [Select the default maximum DRI level [default 2]]), [DRI_DEFAULT=$withval], [DRI_DEFAULT=2]) if test "x$DRI_DEFAULT" = "x0"; then AC_DEFINE(DEFAULT_DRI_LEVEL, 0,[Default DRI level]) else AC_DEFINE(DEFAULT_DRI_LEVEL, ~0, [Default DRI level]) fi AC_ARG_ENABLE(xvmc, AS_HELP_STRING([--disable-xvmc], [Disable XvMC support [[default=yes]]]), [XVMC="$enableval"], [XVMC="yes"]) AC_ARG_ENABLE(kms, AS_HELP_STRING([--enable-kms], [Assume KMS support [[default=yes]]]), [KMS="$enableval"], [KMS="yes"]) AC_ARG_ENABLE(ums, AS_HELP_STRING([--enable-ums], [Assume UMS support [[default=auto]]]), [UMS="$enableval"], [UMS="auto"]) AC_ARG_ENABLE(kms-only, AS_HELP_STRING([--enable-kms-only], [Only assume KMS support (no UMS) [[default=no]]]), [ONLY_KMS="$enableval"], [ONLY_KMS="no"]) AC_ARG_ENABLE(ums-only, AS_HELP_STRING([--enable-ums-only], [Only assume UMS support (no KMS) [[default=no]]]), [ONLY_UMS="$enableval"], [ONLY_UMS="no"]) required_xorg_server_version=1.6 required_pixman_version=0.16 PKG_CHECK_EXISTS([pixman-1 >= 0.24.0], AC_DEFINE([HAS_PIXMAN_TRIANGLES], 1, [Enable pixman triangle rasterisation]) []) PKG_CHECK_EXISTS([pixman-1 >= 0.27.1], [AC_DEFINE([HAS_PIXMAN_GLYPHS], 1, [Enable pixman glyph cache])], []) # Store the list of server defined optional extensions in REQUIRED_MODULES XORG_DRIVER_CHECK_EXT(RANDR, randrproto) XORG_DRIVER_CHECK_EXT(RENDER, renderproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Obtain compiler/linker options for the driver dependencies PKG_CHECK_MODULES(DRM, [libdrm >= 2.4.20]) # libdrm_intel is checked separately PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10]) AC_ARG_ENABLE(sna, AS_HELP_STRING([--enable-sna], [Enable SandyBridge\'s New Acceleration (SNA) [default=auto]]), [SNA="$enableval"], [SNA=auto]) AC_CHECK_HEADERS([dev/wscons/wsconsio.h]) AC_FUNC_ALLOCA AC_HEADER_MAJOR if test "x$SNA" != "xno"; then AC_DEFINE(USE_SNA, 1, [Enable SNA support]) AC_CHECK_HEADERS([sys/sysinfo.h], AC_CHECK_MEMBERS([struct sysinfo.totalram], [], [], [[#include ]])) fi uxa_requires_libdrm=2.4.52 uxa_requires_pixman=0.24.0 AC_ARG_ENABLE(uxa, AS_HELP_STRING([--enable-uxa], [Enable Unified Acceleration Architecture (UXA) [default=auto]]), [UXA="$enableval"], [UXA=auto]) if test "x$UXA" = "xauto"; then PKG_CHECK_EXISTS([libdrm_intel >= $uxa_requires_libdrm pixman-1 >= $uxa_requires_pixman], [], [UXA=no]) fi if test "x$UXA" != "xno"; then AC_DEFINE(USE_UXA, 1, [Enable UXA support]) PKG_CHECK_MODULES(DRMINTEL, [libdrm_intel >= $uxa_requires_libdrm]) required_pixman_version=0.24 UXA=yes fi PKG_CHECK_MODULES(XORG, [xorg-server >= $required_xorg_server_version xproto fontsproto pixman-1 >= $required_pixman_version $REQUIRED_MODULES]) ABI_VERSION=`$PKG_CONFIG --variable=abi_videodrv xorg-server` XSERVER_VERSION=`$PKG_CONFIG --modversion xorg-server` PIXMAN_VERSION=`$PKG_CONFIG --modversion pixman-1` if test "x$ONLY_UMS" = "xyes"; then UMS="yes" KMS="no" fi if test "x$ONLY_KMS" = "xyes"; then UMS="no" KMS="yes" fi save_CPPFLAGS=$CPPFLAGS CPPFLAGS=$XORG_CFLAGS AC_CHECK_HEADERS([vgaHW.h], legacy="yes", legacy="no") CPPFLAGS=$save_CPPFLAGS if test "x$UMS" = "xauto"; then UMS="$legacy" fi if test "x$UMS" = "xyes" -a "x$legacy" = "xno"; then AC_MSG_ERROR([vgaHW support required for UMS (i810) driver]) fi if test "x$UMS" = "xyes"; then AC_ARG_ENABLE(xaa, AS_HELP_STRING([--enable-xaa], [Enable legacy X Acceleration Architecture (XAA) for i810 chipsets [default=auto]]), [XAA="$enableval"], [XAA="auto"]) if test "x$XAA" != "xno"; then save_CPPFLAGS=$CPPFLAGS CPPFLAGS=$XORG_CFLAGS AC_CHECK_HEADERS([xaa.h], XAA="yes", XAA="no") CPPFLAGS=$save_CPPFLAGS fi AC_MSG_CHECKING([whether to include XAA support]) AC_MSG_RESULT([$XAA]) AC_ARG_ENABLE(dga, AS_HELP_STRING([--enable-dga], [Enable legacy Direct Graphics Access (DGA) for i810 chipsets [default=auto]]), [DGA="$enableval"], [DGA="auto"]) if test "x$DGA" != "xno"; then save_CFLAGS=$CFLAGS CFLAGS=$XORG_CFLAGS AC_CHECK_HEADERS([dgaproc.h], DGA="yes", DGA="no", [#include ]) CFLAGS=$save_CFLAGS fi AC_MSG_CHECKING([whether to include DGA support]) AC_MSG_RESULT([$DGA]) fi AM_CONDITIONAL(DGA, test "x$DGA" = "xyes") AM_CONDITIONAL(XAA, test "x$XAA" = "xyes") AM_CONDITIONAL(KMS, test "x$KMS" = "xyes") if test "x$KMS" = "xyes"; then AC_DEFINE(KMS,1,[Assume KMS support]) fi AM_CONDITIONAL(UMS, test "x$UMS" = "xyes") if test "x$UMS" = "xyes"; then AC_DEFINE(UMS,1,[Assume UMS support]) fi have_dri1=no XORG_DRIVER_CHECK_EXT(XF86DRI, xf86driproto) if test "x$_EXT_CHECK" != "xno" -a "x$DRI" != "xno" -a "x$DRI1" != "xno" -a "x$UMS" = "xyes"; then PKG_CHECK_MODULES(DRI1, [xf86driproto], [have_dri1=$DRI], [have_dri1=no]) save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" CFLAGS="$CFLAGS $XORG_CFLAGS $DRI1_CFLAGS $DRM_CFLAGS" CPPFLAGS="$CPPFLAGS $XORG_CFLAGS $DRI1_CFLAGS $DRM_CFLAGS" AC_CHECK_HEADERS([dri.h sarea.h dristruct.h], [], [have_dri1=no], [/* for dri.h */ #include /* for dristruct.h */ #include #ifdef HAVE_DRI_H # include #endif #ifdef HAVE_SAREA_H # include #endif ]) CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" fi AC_MSG_CHECKING([whether to include DRI1 support]) AC_MSG_RESULT([$have_dri1]) AM_CONDITIONAL(DRI1, test "x$have_dri1" != "xno") if test "x$have_dri1" != "xno"; then AC_DEFINE(HAVE_DRI1,1,[Enable DRI1 driver support]) str="DRI1" if test "x$DRI_DEFAULT" = "x1"; then AC_DEFINE(DEFAULT_DRI_LEVEL,1,[Default DRI level]) str="*$str" fi dri_msg="$dri_msg $str" else DRI1_CFLAGS="" DRI1_LIBS="" if test "x$DRI" = "xyes" -a "x$UMS" = "xyes" -a "x$DRI1" != "xno"; then AC_MSG_ERROR([DRI1 requested but prerequisites not found]) fi fi have_dri2=no have_dri3=no if test "x$DRI" != "xno"; then if test "x$DRI2" != "xno"; then PKG_CHECK_MODULES(DRI2, [dri2proto >= 2.6], [have_dri2=$DRI], [have_dri2=no]) fi if test "x$have_dri2" != "xno"; then save_CFLAGS=$CFLAGS CFLAGS="$XORG_CFLAGS $DRM_CFLAGS $DRI1_CFLAGS $DRI2_CFLAGS" AC_CHECK_HEADERS([dri2.h], [], [have_dri2=no], [ #include #include ]) CFLAGS=$save_CFLAGS fi if test "x$have_dri2" != "xno"; then dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri` if test "x$dridriverdir" = "x"; then dridriverdir="$libdir/dri" fi AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default have_dri2 driver path]) fi if test "x$DRI3" != "xno"; then XORG_DRIVER_CHECK_EXT(DRI3, dri3proto) if test "x$_EXT_CHECK" != "xno"; then PKG_CHECK_MODULES(DRI3, [dri3proto], [have_dri3=$DRI], []) fi fi if test "x$have_dri3" != "xno"; then save_CFLAGS=$CFLAGS CFLAGS="$XORG_CFLAGS $DRI3_CFLAGS" AC_CHECK_DECL(DRI3, [], [have_dri3=no], [#include ]) AC_CHECK_HEADERS([misyncstr.h misyncshm.h], [], [have_dri3=no], [ #include #include #include ]) CFLAGS=$save_CFLAGS fi fi AC_MSG_CHECKING([whether to include DRI2 support]) AM_CONDITIONAL(DRI2, test "x$have_dri2" != "xno") AC_MSG_RESULT([$have_dri2]) if test "x$have_dri2" != "xno"; then AC_DEFINE(HAVE_DRI2,1,[Enable DRI2 driver support]) str="DRI2" if test "x$DRI_DEFAULT" = "x2"; then AC_DEFINE(DEFAULT_DRI_LEVEL,2,[Default DRI level]) str="*$str" fi dri_msg="$dri_msg $str" else if test "x$DRI" = "xyes" -a "x$DRI2" != "xno" -a "x$KMS" = "xyes"; then AC_MSG_ERROR([DRI2 requested but prerequisites not found]) fi # UXA doesn't build without DRI2 headers, too late to fix UXA=no fi AC_MSG_CHECKING([whether to include DRI3 support]) AM_CONDITIONAL(DRI3, test "x$have_dri3" != "xno") AC_MSG_RESULT([$have_dri3]) if test "x$have_dri3" != "xno"; then AC_DEFINE(HAVE_DRI3,1,[Enable DRI3 driver support]) str="DRI3" if test "x$DRI_DEFAULT" = "x3"; then AC_DEFINE(DEFAULT_DRI_LEVEL,3,[Default DRI level]) str="*$str" fi dri_msg="$dri_msg $str" else if test "x$DRI" = "xyes" -a "x$DRI3" != "xno" -a "x$KMS" = "xyes"; then AC_MSG_ERROR([DRI3 requested but prerequisites not found]) fi fi AC_MSG_CHECKING([default DRI support]) AC_MSG_RESULT([$DEFAULT_DRI_DEFAULT]) AC_CHECK_HEADERS([X11/extensions/dpmsconst.h]) PRESENT="no" XORG_DRIVER_CHECK_EXT(PRESENT, presentproto) if test "x$_EXT_CHECK" != "xno"; then PKG_CHECK_MODULES(PRESENT, [presentproto], [PRESENT="yes"], []) fi if test "x$PRESENT" != "xno"; then save_CFLAGS=$CFLAGS CFLAGS="$XORG_CFLAGS $PRESENT_CFLAGS" AC_CHECK_HEADERS([present.h], [], [PRESENT="no"], [ #include #include ]) CFLAGS=$save_CFLAGS fi AC_MSG_CHECKING([whether to include PRESENT support]) AM_CONDITIONAL(PRESENT, test "x$PRESENT" != "xno") AC_MSG_RESULT([$PRESENT]) if test "x$PRESENT" != "xno"; then AC_DEFINE(HAVE_PRESENT,1,[Enable PRESENT driver support]) dri_msg="$dri_msg Present" fi AC_MSG_CHECKING([whether to include UXA support]) AC_MSG_RESULT([$UXA]) AM_CONDITIONAL(UXA, test "x$UXA" != "xno") AC_MSG_CHECKING([whether to include SNA support]) AM_CONDITIONAL(SNA, test "x$SNA" != "xno") AC_MSG_RESULT([$SNA]) if test "$XVMC" = "yes"; then PKG_CHECK_MODULES(XVMCLIB, [xvmc dri2proto x11 x11-xcb xcb-dri2 xcb-aux libdrm_intel], [], [XVMC="no"]) fi AC_MSG_CHECKING([whether to include XvMC support]) AC_MSG_RESULT([$XVMC]) AM_CONDITIONAL(XVMC, test "x$XVMC" = "xyes") if test "x$XVMC" = "xyes"; then AC_DEFINE(ENABLE_XVMC,1,[Enable XvMC support]) xvmc_msg=" yes" else xvmc_msg=" no" fi AC_ARG_WITH(default-accel, AS_HELP_STRING([--with-default-accel], [Select the default acceleration method out of none, sna, or uxa [default is sna if enabled, otherwise uxa]]), [accel="$withval"], [accel="auto"]) if test "x$accel" = "xyes"; then AC_MSG_WARN([No default acceleration specified, choosing automatic selection]) accel="auto" fi AC_MSG_CHECKING([which acceleration method to use by default]) if test "x$accel" = "xauto"; then if test "x$SNA" != "xno"; then accel="sna" else if test "x$UXA" != "xno"; then accel="uxa" fi fi if test "x$accel" = "xauto" -a "x$KMS" = "xyes"; then AC_MSG_ERROR([No default acceleration option]) fi fi have_accel="none" if test "x$accel" = "xsna"; then if test "x$SNA" != "xno"; then AC_DEFINE(DEFAULT_ACCEL_METHOD, SNA, [Default acceleration method]) have_accel="yes" else AC_MSG_ERROR([SNA requested as default, but is not enabled]) fi fi if test "x$accel" = "xuxa"; then if test "x$UXA" != "xno"; then AC_DEFINE(DEFAULT_ACCEL_METHOD, UXA, [Default acceleration method]) have_accel="yes" else AC_MSG_ERROR([UXA requested as default, but is not enabled]) fi fi if test "x$have_accel" = "xnone"; then if test "x$KMS" = "xyes"; then if test "x$SNA" != "xno" -o "x$UXA" != "xno"; then AC_DEFINE(DEFAULT_ACCEL_METHOD, NOACCEL, [Default acceleration method]) else AC_MSG_ERROR([Invalid default acceleration option]) fi fi accel="none" fi AC_MSG_RESULT($accel) xp_msg="" AC_ARG_ENABLE(tear-free, AS_HELP_STRING([--enable-tear-free], [Enable use of TearFree by default [default=no]]), [TEARFREE="$enableval"], [TEARFREE="no"]) if test "x$TEARFREE" = "xyes"; then AC_DEFINE(TEARFREE,1,[Enable "TearFree" by default]) xp_msg="$xp_msg TearFree" fi AC_ARG_ENABLE(create2, AS_HELP_STRING([--enable-create2], [Enable use of create2 ioctl (experimental) [default=no]]), [CREATE2="$enableval"], [CREATE2="no"]) AM_CONDITIONAL(USE_CREATE2, test "x$CREATE2" = "xyes") if test "x$CREATE2" = "xyes"; then AC_DEFINE(USE_CREATE2,1,[Assume "create2" support]) xp_msg="$xp_msg create2" fi AC_ARG_ENABLE(async-swap, AS_HELP_STRING([--enable-async-swap], [Enable use of asynchronous swaps (experimental) [default=no]]), [ASYNC_SWAP="$enableval"], [ASYNC_SWAP="no"]) AM_CONDITIONAL(USE_ASYNC_SWAP, test "x$ASYNC_SWAP" = "xyes") if test "x$ASYNC_SWAP" = "xyes"; then AC_DEFINE(USE_ASYNC_SWAP,1,[Assume asynchronous swap support]) xp_msg="$xp_msg async-swap" fi AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enables internal debugging [default=no]]), [DEBUG="$enableval"], [DEBUG="no"]) AC_ARG_ENABLE(valgrind, AS_HELP_STRING([--enable-valgrind], [Enables valgrindified ioctls for debugging [default=no]]), [VG="$enableval"], [VG="no"]) LIBS="" AC_SEARCH_LIBS(clock_gettime, rt, [CLOCK_GETTIME_LIBS=$LIBS]) AC_SUBST(CLOCK_GETTIME_LIBS) sdkdir=`$PKG_CONFIG --variable=sdkdir xorg-server` AM_CONDITIONAL(DEBUG, test "x$DEBUG" != "xno") AM_CONDITIONAL(FULL_DEBUG, test "x$DEBUG" = "xfull") if test "x$DEBUG" = "xno"; then AC_DEFINE(NDEBUG,1,[Disable internal debugging]) else if test "x$VG" != "xyes"; then VG=auto fi fi debug_msg="" have_valgrind="no" if test "x$VG" != "xno"; then PKG_CHECK_MODULES(VALGRIND, [valgrind], have_valgrind="yes", have_valgrind="no") AC_MSG_CHECKING([whether to include valgrind support]) if test "x$have_valgrind" = "xyes"; then AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings]) else if test "x$VG" = "xyes"; then AC_MSG_ERROR([valgrind support requested, but valgrind-dev headers not found]) fi fi AC_MSG_RESULT([$have_valgrind ($VG)]) fi AM_CONDITIONAL(VALGRIND, test "x$have_valgrind" = "xyes") if test "x$have_valgrind" = "xyes"; then debug_msg="$debug_msg valgrind" fi if test "x$DEBUG" = "xsync"; then AC_DEFINE(DEBUG_SYNC,1,[Enable synchronous rendering for debugging]) debug_msg="$debug_msg sync" fi if test "x$DEBUG" = "xmemory"; then AC_DEFINE(DEBUG_MEMORY,1,[Enable memory debugging]) debug_msg="$debug_msg memory" fi if test "x$DEBUG" = "xpixmap"; then AC_DEFINE(DEBUG_PIXMAP,1,[Enable pixmap debugging]) debug_msg="$debug_msg pixmaps" fi if test "x$DEBUG" = "xfull"; then AC_DEFINE(DEBUG_MEMORY,1,[Enable memory debugging]) AC_DEFINE(DEBUG_PIXMAP,1,[Enable pixmap debugging]) AC_DEFINE(HAS_DEBUG_FULL,1,[Enable all debugging]) CFLAGS="$CFLAGS -O0 -ggdb3" debug_msg=" full" fi if test "x$debug_msg" = "x"; then debug_msg=" none" fi AC_CONFIG_LIBOBJ_DIR(libobj) AC_REPLACE_FUNCS(getline) DRIVER_NAME="intel" AC_SUBST([DRIVER_NAME]) AC_SUBST([moduledir]) AC_DEFINE_DIR([PREFIX_PATH], prefix, [installation prefix]) AC_DEFINE_DIR([LIBEXEC_PATH], libexecdir, [libexec directory]) AC_CONFIG_FILES([ Makefile man/Makefile libobj/Makefile src/Makefile src/legacy/Makefile src/legacy/i810/Makefile src/legacy/i810/xvmc/Makefile src/render_program/Makefile src/sna/Makefile src/sna/brw/Makefile src/sna/fb/Makefile src/uxa/Makefile xvmc/Makefile xvmc/shader/Makefile xvmc/shader/mc/Makefile xvmc/shader/vld/Makefile test/Makefile benchmarks/Makefile tools/Makefile tools/org.x.xf86-video-intel.backlight-helper.policy ]) AC_OUTPUT echo "" echo "" cat $srcdir/README accel_msg="" if test "x$SNA" != "xno"; then if test "$accel" = "none"; then accel_msg="$accel_msg *none" else accel_msg="$accel_msg none" fi if test "$accel" = "sna"; then accel_msg="$accel_msg *sna" else accel_msg="$accel_msg sna" fi fi if test "x$UXA" != "xno"; then if test "x$SNA" = "xno"; then if test "$accel" = "none"; then accel_msg="$accel_msg *none" else accel_msg="$accel_msg none" fi fi if test "$accel" = "uxa"; then accel_msg="$accel_msg *uxa" else accel_msg="$accel_msg uxa" fi fi if test "x$dri_msg" = "x"; then dri_msg=" none" fi if test "x$tools_msg" = "x"; then tools_msg=" none" fi echo "" echo "AC_PACKAGE_STRING will be compiled with:" echo " Xorg Video ABI version: $ABI_VERSION (xorg-server-$XSERVER_VERSION)" echo " pixman version: pixman-1-$PIXMAN_VERSION" echo " Acceleration backends:$accel_msg" echo " Additional debugging support?$debug_msg" echo " Support for Kernel Mode Setting? $KMS" echo " Support for legacy User Mode Setting (for i810)? $UMS" echo " Support for Direct Rendering Infrastructure:$dri_msg" echo " Support for Xv motion compensation (XvMC and libXvMC):$xvmc_msg" echo " Support for display hotplug notifications (udev):$udev_msg" echo " Build additional tools and utilities?$tools_msg" if test -n "$xp_msg"; then echo " Experimental support:$xp_msg" fi echo "" xserver-xorg-video-intel-2.99.917+git20160325/libobj/000077500000000000000000000000001267532330400215345ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/libobj/Makefile.am000066400000000000000000000002271267532330400235710ustar00rootroot00000000000000noinst_LTLIBRARIES = libcompat.la libcompat_la_SOURCES = ignore.c # for portability, always build something libcompat_la_LIBADD = $(LIBOBJS) $(ALLOCA) xserver-xorg-video-intel-2.99.917+git20160325/libobj/alloca.c000066400000000000000000000000521267532330400231300ustar00rootroot00000000000000void *alloca(size_t sz) { return NULL; } xserver-xorg-video-intel-2.99.917+git20160325/libobj/getline.c000066400000000000000000000014021267532330400233240ustar00rootroot00000000000000#include #include #include extern int getline(char **line, size_t *len, FILE *file); int getline(char **line, size_t *len, FILE *file) { char *ptr, *end; int c; if (*line == NULL) { errno = EINVAL; if (*len == 0) *line = malloc(4096); if (*line == NULL) return -1; *len = 4096; } ptr = *line; end = *line + *len; while ((c = fgetc(file)) != EOF) { if (ptr + 1 >= end) { char *newline; int offset; newline = realloc(*line, *len + 4096); if (newline == NULL) return -1; offset = ptr - *line; *line = newline; *len += 4096; ptr = *line + offset; end = *line + *len; } *ptr++ = c; if (c == '\n') { *ptr = '\0'; return ptr - *line; } } *ptr = '\0'; return -1; } xserver-xorg-video-intel-2.99.917+git20160325/libobj/ignore.c000066400000000000000000000001461267532330400231640ustar00rootroot00000000000000extern void ignore(void); void ignore(void) { /* libcompat.a cannot be empty therefore I exist */ } xserver-xorg-video-intel-2.99.917+git20160325/m4/000077500000000000000000000000001267532330400206135ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/m4/ac_define_dir.m4000066400000000000000000000031401267532330400236060ustar00rootroot00000000000000# =========================================================================== # http://autoconf-archive.cryp.to/ac_define_dir.html # =========================================================================== # # SYNOPSIS # # AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION]) # # DESCRIPTION # # This macro sets VARNAME to the expansion of the DIR variable, taking # care of fixing up ${prefix} and such. # # VARNAME is then offered as both an output variable and a C preprocessor # symbol. # # Example: # # AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.]) # # LAST MODIFICATION # # 2008-04-12 # # COPYLEFT # # Copyright (c) 2008 Stepan Kasal # Copyright (c) 2008 Andreas Schwab # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2008 Alexandre Oliva # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AC_DEFUN([AC_DEFINE_DIR], [ prefix_NONE= exec_prefix_NONE= test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn dnl refers to ${prefix}. Thus we have to use `eval' twice. eval ac_define_dir="\"[$]$2\"" eval ac_define_dir="\"$ac_define_dir\"" AC_SUBST($1, "$ac_define_dir") AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) test "$prefix_NONE" && prefix=NONE test "$exec_prefix_NONE" && exec_prefix=NONE ]) xserver-xorg-video-intel-2.99.917+git20160325/man/000077500000000000000000000000001267532330400210465ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/man/Makefile.am000066400000000000000000000027351267532330400231110ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, 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, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice (including the next # paragraph) shall be included in all copies or substantial portions of the # Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. # drivermandir = $(DRIVER_MAN_DIR) driverman_DATA = $(DRIVER_NAME).$(DRIVER_MAN_SUFFIX) EXTRA_DIST = $(DRIVER_NAME).man CLEANFILES = $(driverman_DATA) # String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man .man.$(DRIVER_MAN_SUFFIX): $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ xserver-xorg-video-intel-2.99.917+git20160325/man/intel.man000066400000000000000000000560311267532330400226630ustar00rootroot00000000000000.\" shorthand for double quote that works everywhere. .ds q \N'34' .TH intel __drivermansuffix__ __vendorversion__ .SH NAME intel \- Intel integrated graphics chipsets .SH SYNOPSIS .nf .B "Section \*qDevice\*q" .BI " Identifier \*q" devname \*q .B " Driver \*qintel\*q" \ \ ... .B EndSection .fi .SH DESCRIPTION .B intel is an __xservername__ driver for Intel integrated graphics chipsets. The driver supports depths 8, 15, 16 and 24. All visual types are supported in depth 8. For the i810/i815 other depths support the TrueColor and DirectColor visuals. For the i830M and later, only the TrueColor visual is supported for depths greater than 8. The driver supports hardware accelerated 3D via the Direct Rendering Infrastructure (DRI), but only in depth 16 for the i810/i815 and depths 16 and 24 for the 830M and later. .SH SUPPORTED HARDWARE .B intel supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM, 865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ, 965GM, 945GME, G33, Q33, Q35, G35, GM45, G45, Q45, G43, G41 chipsets, Pineview-M in Atom N400 series, Pineview-D in Atom D400/D500 series, Intel(R) HD Graphics: 2000-6000, Intel(R) Iris(TM) Graphics: 5100/6100, and Intel(R) Iris(TM) Pro Graphics: 5200/6200/P6300. .SH CONFIGURATION DETAILS Please refer to __xconfigfile__(__filemansuffix__) for general configuration details. This section only covers configuration details specific to this driver. .PP The Intel 8xx and 9xx families of integrated graphics chipsets have a unified memory architecture meaning that system memory is used as video RAM. For the i810 and i815 family of chipsets, operating system support for allocating system memory is required in order to use this driver. For the 830M and later, this is required in order for the driver to use more video RAM than has been pre-allocated at boot time by the BIOS. This is usually achieved with an "agpgart" or "agp" kernel driver. Linux, FreeBSD, OpenBSD, NetBSD, and Solaris have such kernel drivers available. .PP By default, the i810/i815 will use 8 MB of system memory for graphics if AGP allocable memory is < 128 MB, 16 MB if < 192 MB or 24 MB if higher. Use the .B VideoRam option to change the default value. .PP For the 830M and later, the driver will automatically size its memory allocation according to the features it will support. Therefore, the .B VideoRam option, which in the past had been necessary to allow more than some small amount of memory to be allocated, is now ignored. .PP The following driver .B Options are supported .TP .BI "Option \*qColorKey\*q \*q" integer \*q This sets the default pixel value for the YUV video overlay key. .IP Default: undefined. .TP .BI "Option \*qDRI\*q \*q" string \*q Disable or enable DRI support. A driver name to use can be provided instead of simple boolean value, which will be passed to the GL implementation for it to load the appropriate backend. Alternatively the maximum level of DRI to enable (e.g. "1", "2" or "3") can be specified. .IP Default: All levels of DRI are enabled for configurations where it is supported. .PP The following driver .B Options are supported for the i810 and i815 chipsets: .TP .BI "Option \*qCacheLines\*q \*q" integer \*q This allows the user to change the amount of graphics memory used for 2D acceleration and video when XAA acceleration is enabled. Decreasing this amount leaves more for 3D textures. Increasing it can improve 2D performance at the expense of 3D performance. .IP Default: depends on the resolution, depth, and available video memory. The driver attempts to allocate space for at 3 screenfuls of pixmaps plus an HD-sized XV video. The default used for a specific configuration can be found by examining the __xservername__ log file. .TP .BI "Option \*qDDC\*q \*q" boolean \*q Disable or enable DDC support. .IP Default: enabled. .TP .BI "Option \*qDac6Bit\*q \*q" boolean \*q Enable or disable 6-bits per RGB for 8-bit modes. .IP Default: 8-bits per RGB for 8-bit modes. .TP .BI "Option \*qXvMCSurfaces\*q \*q" integer \*q This option enables XvMC. The integer parameter specifies the number of surfaces to use. Valid values are 6 and 7. .IP Default: XvMC is disabled. .TP .BI "VideoRam " integer This option specifies the amount of system memory to use for graphics, in KB. .IP The default is 8192 if AGP allocable memory is < 128 MB, 16384 if < 192 MB, 24576 if higher. DRI require at least a value of 16384. Higher values may give better 3D performance, at expense of available system memory. .TP .BI "Option \*qAccel\*q \*q" boolean \*q Enable or disable acceleration. .IP Default: acceleration is enabled. .PP The following driver .B Options are supported for the 830M and later chipsets: .TP .BI "Option \*qAccel\*q \*q" boolean \*q Enable or disable acceleration. .IP Default: acceleration is enabled. .TP .BI "Option \*qPresent\*q \*q" boolean \*q Enable use of hardware counters and flow control for the Present extension. .IP Default: Enabled .TP .BI "Option \*qAccelMethod\*q \*q" string \*q Select acceleration method. There are a couple of backends available for accelerating the DDX. \*qUXA\*q (Unified Acceleration Architecture) is the mature backend that was introduced to support the GEM driver model. It is in the process of being superseded by \*qSNA\*q (Sandybridge's New Acceleration). Until that process is complete, the ability to choose which backend to use remains for backwards compatibility. In addition, there are a pair of sub-options to limit the acceleration for debugging use. Specify \*qoff\*q or \*qnone\*q to disable all acceleration, or \*qblt\*q to disable render acceleration and only use the BLT engine. .IP Default: use SNA (render acceleration) .TP .BI "Option \*qTearFree\*q \*q" boolean \*q Disable or enable TearFree updates. This option forces X to perform all rendering to a backbuffer prior to updating the actual display. It requires an extra memory allocation the same size as a framebuffer, the occasional extra copy, and requires Damage tracking. Thus enabling TearFree requires more memory and is slower (reduced throughput) and introduces a small amount of output latency, but it should not impact input latency. However, the update to the screen is then performed synchronously with the vertical refresh of the display so that the entire update is completed before the display starts its refresh. That is only one frame is ever visible, preventing an unsightly tear between two visible and differing frames. Note that this replicates what the compositing manager should be doing, however TearFree will redirect the compositor updates (and those of fullscreen games) directly on to the scanout thus incurring no additional overhead in the composited case. Also note that not all compositing managers prevent tearing, and if the outputs are rotated, there will still be tearing without TearFree enabled. .IP Default: TearFree is disabled. .TP .BI "Option \*qReprobeOutputs\*q \*q" boolean \*q Disable or enable rediscovery of connected displays during server startup. As the kernel driver loads it scans for connected displays and configures a console spanning those outputs. When the X server starts, we then take the list of connected displays and framebuffer layout and use that for the initial configuration. Sometimes, not all displays are correctly detected by the kernel and so it is useful in a few circumstances for X to force the kernel to reprobe all displays when it starts. To make the X server recheck the status of connected displays, set the \*qReprobeOutputs\*q option to true. Please do file a bug for any circumstances which require this workaround. .IP Default: reprobing is disabled for a faster startup. .TP .BI "Option \*qVideoKey\*q \*q" integer \*q This is the same as the .B \*qColorKey\*q option described above. It is provided for compatibility with most other drivers. .TP .BI "Option \*qXvPreferOverlay\*q \*q" boolean \*q Make hardware overlay be the first XV adaptor. The overlay behaves incorrectly in the presence of compositing, but some prefer it due to it syncing to vblank in the absence of compositing. While most XV-using applications have options to select which XV adaptor to use, this option can be used to place the overlay first for applications which don't have options for selecting adaptors. .IP Default: Textured video adaptor is preferred. .TP .BI "Option \*qBacklight\*q \*q" string \*q Override the probed backlight control interface. Sometimes the automatically selected backlight interface may not correspond to the correct, or simply most useful, interface available on the system. This allows you to override that choice by specifying the entry under /sys/class/backlight to use. .IP Default: Automatic selection. .TP .BI "Option \*qCustomEDID\*q \*q" string \*q Override the probed EDID on particular outputs. Sometimes the manufacturer supplied EDID is corrupt or lacking a few usable modes and supplying a corrected EDID may be easier than specifying every modeline. This option allows to pass the path to load an EDID from per output. The format is a comma separated string of output:path pairs, e.g. DP1:/path/to/dp1.edid,DP2:/path/to/dp2.edid .IP Default: No override, use manufacturer supplied EDIDs. .TP .BI "Option \*qFallbackDebug\*q \*q" boolean \*q Enable printing of debugging information on acceleration fallbacks to the server log. .IP Default: Disabled .TP .BI "Option \*qDebugFlushBatches\*q \*q" boolean \*q Flush the batch buffer after every single operation. .IP Default: Disabled .TP .BI "Option \*qDebugFlushCaches\*q \*q" boolean \*q Include an MI_FLUSH at the end of every batch buffer to force data to be flushed out of cache and into memory before the completion of the batch. .IP Default: Disabled .TP .BI "Option \*qDebugWait\*q \*q" boolean \*q Wait for the completion of every batch buffer before continuing, i.e. perform synchronous rendering. .IP Default: Disabled .TP .BI "Option \*qHWRotation\*q \*q" boolean \*q Override the use of native hardware rotation and force the use of software, but GPU accelerated where possible, rotation. On some platforms the hardware can scanout directly into a rotated output bypassing the intermediate rendering and extra allocations required for software implemented rotation (i.e. native rotation uses less resources, is quicker and uses less power). This allows you to disable the native rotation in case of errors. .IP Default: Enabled (use hardware rotation) .TP .BI "Option \*qVSync\*q \*q" boolean \*q This option controls the use of commands to synchronise rendering with the vertical refresh of the display. Some rendering commands have the option to be performed in a "tear-free" fashion by stalling the GPU to wait for the display to be outside of the region to be updated. This slows down all rendering, and historically has been the source of many GPU hangs. .IP Default: enabled. .TP .BI "Option \*qPageFlip\*q \*q" boolean \*q This option controls the use of commands to flip the scanout address on a VBlank. This is used by glXSwapBuffers to efficiently perform the back-to-front exchange at the end of a frame without incurring the penalty of a copy, or stalling the render pipeline (the flip is performed asynchronrously to the render command stream by the display engine). However, it has historically been the source of many GPU hangs. .IP Default: enabled. .TP .BI "Option \*qSwapbuffersWait\*q \*q" boolean \*q This option controls the behavior of glXSwapBuffers and glXCopySubBufferMESA calls by GL applications. If enabled, the calls will avoid tearing by making sure the display scanline is outside of the area to be copied before the copy occurs. If disabled, no scanline synchronization is performed, meaning tearing will likely occur. .IP Default: enabled. .TP .BI "Option \*qTripleBuffer\*q \*q" boolean \*q This option enables the use of a third buffer for page-flipping. The third buffer allows applications to run at vrefresh rates even if they occasionally fail to swapbuffers on time. The effect of such missed swaps is the output jitters between 60fps and 30fps, and in the worst case appears frame-locked to 30fps. The disadvantage of triple buffering is that there is an extra frame of latency, due to the pre-rendered frame sitting in the swap queue, between input and any display update. .IP Default: enabled. .TP .BI "Option \*qTiling\*q \*q" boolean \*q This option controls whether memory buffers for Pixmaps are allocated in tiled mode. In most cases (especially for complex rendering), tiling dramatically improves performance. .IP Default: enabled. .TP .BI "Option \*qLinearFramebuffer\*q \*q" boolean \*q This option controls whether the memory for the scanout (also known as the front or frame buffer) is allocated in linear memory. A tiled framebuffer is required for power conservation features, but for certain system configurations you may wish to override this and force a linear layout. .IP Default: disabled .TP .BI "Option \*qRelaxedFencing\*q \*q" boolean \*q This option controls whether we attempt to allocate the minimal amount of memory required for the buffers. The reduction in working set has a substantial improvement on system performance. However, this has been demonstrate to be buggy on older hardware (845-865 and 915-945, but ok on PineView and later) so on those chipsets defaults to off. .IP Default: Enabled for G33 (includes PineView), and later, class machines. .TP .BI "Option \*qXvMC\*q \*q" boolean \*q Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series. User should provide absolute path to libIntelXvMC.so in XvMCConfig file. .IP Default: Disabled. .TP .BI "Option \*qThrottle\*q \*q" boolean \*q This option controls whether the driver periodically waits for pending drawing operations to complete. Throttling ensures that the GPU does not lag too far behind the CPU and thus noticeable delays in user responsible at the cost of throughput performance. .IP Default: enabled. .TP .BI "Option \*qHotPlug\*q \*q" boolean \*q This option controls whether the driver automatically notifies applications when monitors are connected or disconnected. .IP Default: enabled. .TP .BI "Option \*qVirtualheads\*q \*q" integer \*q This option controls specifies the number of fake outputs to create in addition to the normal outputs detected on your hardware. These outputs cannot be assigned to the regular displays attached to the GPU, but do otherwise act as any other xrandr output and share a portion of the regular framebuffer. One use case for these extra heads is for extending your desktop onto a discrete GPU using the Bumblebee project. However, the recommendation here is to use PRIME instead to create a single Xserver that can addresses and coordinate between multiple GPUs. .IP Default: 0 .TP .BI "Option \*qZaphodHeads\*q \*q" string \*q .IP Specify the randr output(s) to use with zaphod mode for a particular driver instance. If you set this option you must use it with all instances of the driver. By default, each head is assigned only one CRTC (which limits using multiple outputs with that head to cloned mode). CRTC can be manually assigned to individual heads by preceding the output names with a comma delimited list of pipe numbers followed by a colon. Note that different pipes may be limited in their functionality and some outputs may only work with different pipes. .br For example: .RS .B Option \*qZaphodHeads\*q \*qLVDS1,VGA1\*q will assign xrandr outputs LVDS1 and VGA1 to this instance of the driver. .RE .RS .B Option \*qZaphodHeads\*q \*q0,2:HDMI1,DP2\*q will assign xrandr outputs HDMI1 and DP2 and CRTCs 0 and 2 to this instance of the driver. .RE .SH OUTPUT CONFIGURATION On 830M and better chipsets, the driver supports runtime configuration of detected outputs. You can use the .B xrandr tool to control outputs on the command line as follows: .RS .B xrandr \-\-output .I output .B \-\-set .I property value .RE Note that you may need to quote property and value arguments that contain spaces. Each output listed below may have one or more properties associated with it (like a binary EDID block if one is found). Some outputs have unique properties which are described below. See the "MULTIHEAD CONFIGURATIONS" section below for additional information. .SS "VGA" VGA output port (typically exposed via an HD15 connector). .SS "LVDS" Low Voltage Differential Signalling output (typically a laptop LCD panel). Available properties: .TP \fBBACKLIGHT\fB - current backlight level (adjustable) By adjusting the BACKLIGHT property, the brightness on the LVDS output can be adjusted. In some cases, this property may be unavailable (for example if your platform uses an external microcontroller to control the backlight). .TP \fBscaling mode\fP - control LCD panel scaling mode When the currently selected display mode differs from the native panel resolution, various scaling options are available. These include .RS .TP .B Center Simply center the image on-screen without scaling. This is the only scaling mode that guarantees a one-to-one correspondence between native and displayed pixels, but some portions of the panel may be unused (so-called "letterboxing"). .TP .B Full aspect Scale the image as much as possible while preserving aspect ratio. Pixels may not be displayed one-to-one (there may be some blurriness). Some portions of the panel may be unused if the aspect ratio of the selected mode does not match that of the panel. .TP .B Full Scale the image to the panel size without regard to aspect ratio. This is the only mode which guarantees that every pixel of the panel will be used. But the displayed image may be distorted by stretching either horizontally or vertically, and pixels may not be displayed one-to-one (there may be some blurriness). .RE The precise names of these options may differ depending on the kernel video driver, (but the functionality should be similar). See the output of .B xrandr \-\-prop for a list of currently available scaling modes. .SS "TV" Integrated TV output. Available properties include: .TP \fBBOTTOM, RIGHT, TOP, LEFT\fP - margins Adjusting these properties allows you to control the placement of your TV output buffer on the screen. The options with the same name can also be set in xorg.conf with integer value. .TP \fBBRIGHTNESS\fP - TV brightness, range 0-255 Adjust TV brightness, default value is 128. .TP \fBCONTRAST\fP - TV contrast, range 0-255 Adjust TV contrast, default value is 1.0 in chipset specific format. .TP \fBSATURATION\fP - TV saturation, range 0-255 Adjust TV saturation, default value is 1.0 in chipset specific format. .TP \fBHUE\fP - TV hue, range 0-255 Adjust TV hue, default value is 0. .TP \fBTV_FORMAT\fP - output standard This property allows you to control the output standard used on your TV output port. You can select between NTSC-M, NTSC-443, NTSC-J, PAL-M, PAL-N, and PAL. .TP \fBTV_Connector\fP - connector type This config option should be added to xorg.conf TV monitor's section, it allows you to force the TV output connector type, which bypass load detect and TV will always be taken as connected. You can select between S-Video, Composite and Component. .SS "TMDS-1" First DVI SDVO output .SS "TMDS-2" Second DVI SDVO output .SS "TMDS-1", "TMDS-2", "HDMI-1", "HDMI-2" DVI/HDMI outputs. Available common properties include: .TP \fBBROADCAST_RGB\fP - method used to set RGB color range Adjusting this property allows you to set RGB color range on each channel in order to match HDTV requirement(default 0 for full range). Setting 1 means RGB color range is 16-235, 0 means RGB color range is 0-255 on each channel. (Full range is 0-255, not 16-235) .PP SDVO and DVO TV outputs are not supported by the driver at this time. .PP See __xconfigfile__(__filemansuffix__) for information on associating Monitor sections with these outputs for configuration. Associating Monitor sections with each output can be helpful if you need to ignore a specific output, for example, or statically configure an extended desktop monitor layout. .SH MULTIHEAD CONFIGURATIONS The number of independent outputs is dictated by the number of CRTCs (in X parlance) a given chip supports. Most recent Intel chips have two CRTCs, meaning that two separate framebuffers can be displayed simultaneously, in an extended desktop configuration. If a chip supports more outputs than it has CRTCs (say local flat panel, VGA and TV in the case of many outputs), two of the outputs will have to be "cloned", meaning that they display the same framebuffer contents (or one displays a subset of another's framebuffer if the modes aren't equal). You can use the "xrandr" tool, or various desktop utilities, to change your output configuration at runtime. To statically configure your outputs, you can use the "Monitor-" options along with additional monitor sections in your xorg.conf to create your screen topology. The example below puts the VGA output to the right of the builtin laptop screen, both running at 1024x768. .nf .B "Section \*qMonitor\*q" .BI " Identifier \*qLaptop FooBar Internal Display\*q" .BI " Option \*qPosition\*q \*q0 0\*q" .B "EndSection" .B "Section \*qMonitor\*q" .BI " Identifier \*qSome Random CRT\*q" .BI " Option \*qPosition\*q \*q1024 0\*q" .BI " Option \*qRightOf\*q \*qLaptop FoodBar Internal Display\*q" .B "EndSection" .B "Section \*qDevice\*q" .BI " Driver \*qintel\*q" .BI " Option \*qmonitor-LVDS\*q \*qLaptop FooBar Internal Display\*q" .BI " Option \*qmonitor-VGA\*q \*qSome Random CRT\*q" .B "EndSection" .SH TEXTURED VIDEO ATTRIBUTES The driver supports the following X11 Xv attributes for Textured Video. You can use the "xvattr" tool to query/set those attributes at runtime. .SS "XV_SYNC_TO_VBLANK" XV_SYNC_TO_VBLANK is used to control whether textured adapter synchronizes the screen update to the vblank to eliminate tearing. It is a Boolean attribute with values of 0 (never sync) or 1 (always sync). An historic value of -1 (sync for large windows only) will now be interpreted as 1, (since the current approach for sync is not costly even with small video windows). .SS "XV_BRIGHTNESS" .SS "XV_CONTRAST" .SH REPORTING BUGS The xf86-video-intel driver is part of the X.Org and Freedesktop.org umbrella projects. Details on bug reporting can be found at https://01.org/linuxgraphics/documentation/how-report-bugs. Mailing lists are also commonly used to report experiences and ask questions about configuration and other topics. See lists.freedesktop.org for more information (the xorg@lists.freedesktop.org mailing list is the most appropriate place to ask X.Org and driver related questions). .SH "SEE ALSO" __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) .SH AUTHORS Authors include: Keith Whitwell, and also Jonathan Bian, Matthew J Sottek, Jeff Hartmann, Mark Vojkovich, Alan Hourihane, H. J. Lu. 830M and 845G support reworked for XFree86 4.3 by David Dawes and Keith Whitwell. 852GM, 855GM, and 865G support added by David Dawes and Keith Whitwell. 915G, 915GM, 945G, 945GM, 965G, 965Q and 946GZ support added by Alan Hourihane and Keith Whitwell. Lid status support added by Alan Hourihane. Textured video support for 915G and later chips, RandR 1.2 and hardware modesetting added by Eric Anholt and Keith Packard. EXA and Render acceleration added by Wang Zhenyu. TV out support added by Zou Nan Hai and Keith Packard. 965GM, G33, Q33, and Q35 support added by Wang Zhenyu. xserver-xorg-video-intel-2.99.917+git20160325/src/000077500000000000000000000000001267532330400210625ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/Makefile.am000066400000000000000000000043551267532330400231250ustar00rootroot00000000000000# 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. SUBDIRS = render_program legacy # 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. AM_CFLAGS = \ @CWARNFLAGS@ \ $(XORG_CFLAGS) \ $(DRM_CFLAGS) \ $(PCIACCESS_CFLAGS) \ @NOWARNFLAGS@ \ $(NULL) if VALGRIND AM_CFLAGS += $(VALGRIND_CFLAGS) endif intel_drv_la_LTLIBRARIES = intel_drv.la intel_drv_la_LDFLAGS = -module -avoid-version intel_drv_ladir = $(moduledir)/drivers intel_drv_la_LIBADD = legacy/liblegacy.la $(PCIACCESS_LIBS) $(XORG_LIBS) if SNA SUBDIRS += sna intel_drv_la_LIBADD += sna/libsna.la endif if UXA SUBDIRS += uxa intel_drv_la_LIBADD += uxa/libuxa.la endif NULL:=# intel_drv_la_SOURCES = \ backlight.c \ backlight.h \ fd.h \ fd.c \ i915_pciids.h \ intel_list.h \ intel_options.h \ intel_device.c \ intel_driver.h \ intel_options.c \ intel_module.c \ compat-api.h \ $(NULL) EXTRA_DIST = \ scripts/clock.5c \ scripts/clock-graph.5c \ scripts/fix.5c \ scripts/tv.5c \ $(NULL) xserver-xorg-video-intel-2.99.917+git20160325/src/backlight.c000066400000000000000000000262461267532330400231700ustar00rootroot00000000000000/*************************************************************************** Copyright 2014 Intel Corporation. All Rights Reserved. Copyright 2014 Red Hat, Inc. 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 INTEL, 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 #include #include #include #if MAJOR_IN_MKDEV #include #elif MAJOR_IN_SYSMACROS #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "backlight.h" #include "fd.h" #define BACKLIGHT_CLASS "/sys/class/backlight" /* Enough for 10 digits of backlight + '\n' + '\0' */ #define BACKLIGHT_VALUE_LEN 12 #ifndef ARRAY_SIZE #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0])) #endif /* * Unfortunately this is not as simple as I would like it to be. If selinux is * dropping dbus messages pkexec may block *forever*. * * Backgrounding pkexec by doing System("pkexec ...&") does not work because * that detaches pkexec from its parent at which point its security checks * fail and it refuses to execute the helper. * * So we're left with spawning a helper child which gets levels to set written * to it through a pipe. This turns the blocking forever problem from a hung * machine problem into a simple backlight control not working problem. * * If only things were as simple as on OpenBSD! :) */ void backlight_init(struct backlight *b) { b->type = BL_NONE; b->iface = NULL; b->fd = -1; b->pid = -1; b->max = -1; b->has_power = 0; } #ifdef HAVE_DEV_WSCONS_WSCONSIO_H #include #include int backlight_set(struct backlight *b, int level) { struct wsdisplay_param param; if (b->iface == NULL) return -1; if ((unsigned)level > b->max) level = b->max; memset(¶m, 0, sizeof(param)); param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; param.curval = level; return ioctl(xf86Info.consoleFd, WSDISPLAYIO_SETPARAM, ¶m); } int backlight_get(struct backlight *b) { struct wsdisplay_param param; if (b->iface == NULL) return -1; memset(¶m, 0, sizeof(param)); param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, ¶m)) return -1; return param.curval; } int backlight_open(struct backlight *b, char *iface) { struct wsdisplay_param param; if (iface != NULL) return -1; memset(¶m, 0, sizeof(param)); param.param = WSDISPLAYIO_PARAM_BRIGHTNESS; if (ioctl(xf86Info.consoleFd, WSDISPLAYIO_GETPARAM, ¶m) == -1) return -1; b->iface = strdup("wscons"); if (b->iface == NULL) return -1; b->max = param.max; b->fd = -1; b->type = BL_PLATFORM; return param.curval; } int backlight_exists(const char *iface) { return iface == NULL; } int backlight_on(struct backlight *b) { return 0; } int backlight_off(struct backlight *b) { return 0; } #else static int is_sysfs_fd(int fd) { struct stat st; return fstat(fd, &st) == 0 && major(st.st_dev) == 0; } static int __backlight_open(const char *iface, const char *file, int mode) { char buf[1024]; int fd; snprintf(buf, sizeof(buf), BACKLIGHT_CLASS "/%s/%s", iface, file); fd = open(buf, mode); if (fd == -1) return -1; if (!is_sysfs_fd(fd)) { close(fd); return -1; } return fd; } static int __backlight_read(const char *iface, const char *file) { char buf[BACKLIGHT_VALUE_LEN]; int fd, val; fd = __backlight_open(iface, file, O_RDONLY); if (fd < 0) return -1; val = read(fd, buf, BACKLIGHT_VALUE_LEN - 1); if (val > 0) { buf[val] = '\0'; val = atoi(buf); } else val = -1; close(fd); return val; } static int __backlight_write(const char *iface, const char *file, const char *value) { int fd, ret; fd = __backlight_open(iface, file, O_WRONLY); if (fd < 0) return -1; ret = write(fd, value, strlen(value)+1); close(fd); return ret; } /* List of available kernel interfaces in priority order */ static const char *known_interfaces[] = { "dell_backlight", "gmux_backlight", "asus-laptop", "asus-nb-wmi", "eeepc", "thinkpad_screen", "mbp_backlight", "fujitsu-laptop", "sony", "samsung", "acpi_video1", "acpi_video0", "intel_backlight", }; static int __backlight_type(const char *iface) { char buf[1024]; int fd, v, i; v = -1; fd = __backlight_open(iface, "type", O_RDONLY); if (fd >= 0) { v = read(fd, buf, sizeof(buf)-1); close(fd); } if (v > 0) { while (v > 0 && isspace(buf[v-1])) v--; buf[v] = '\0'; if (strcmp(buf, "raw") == 0) v = BL_RAW << 8; else if (strcmp(buf, "platform") == 0) v = BL_PLATFORM << 8; else if (strcmp(buf, "firmware") == 0) v = BL_FIRMWARE << 8; else v = BL_NAMED << 8; } else v = BL_NAMED << 8; for (i = 0; i < ARRAY_SIZE(known_interfaces); i++) { if (strcmp(iface, known_interfaces[i]) == 0) break; } v += i; return v; } static int __backlight_exists(const char *iface) { if (__backlight_read(iface, "brightness") < 0) return -1; if (__backlight_read(iface, "max_brightness") <= 0) return -1; return __backlight_type(iface); } int backlight_exists(const char *iface) { return __backlight_exists(iface) != -1; } static int __backlight_init(struct backlight *b, char *iface, int fd) { b->fd = fd_move_cloexec(fd_set_nonblock(fd)); b->iface = iface; return 1; } static int __backlight_direct_init(struct backlight *b, char *iface) { int fd; fd = __backlight_open(iface, "brightness", O_RDWR); if (fd < 0) return 0; if (__backlight_read(iface, "bl_power") != -1) b->has_power = 1; return __backlight_init(b, iface, fd); } static int __backlight_helper_init(struct backlight *b, char *iface) { #if USE_BACKLIGHT_HELPER struct stat st; char *env[] = { NULL }; int use_pkexec = 0; int fds[2]; /* * Some systems may prefer using PolicyKit's pkexec over * making the helper suid root, since the suid option will allow * anyone to control the backlight. However, as pkexec * is quite troublesome and not universally available, we * still try the old fashioned and simple method first. * Either way, we have to trust that it is our backlight-helper * that is run and that we have scrutinised it carefully. */ if (stat(LIBEXEC_PATH "/xf86-video-intel-backlight-helper", &st)) return 0; if ((st.st_mode & (S_IFREG | S_ISUID | S_IXUSR)) != (S_IFREG | S_ISUID | S_IXUSR)) { if (System("pkexec --version")) return 0; use_pkexec = 1; } if (pipe(fds)) return 0; switch ((b->pid = fork())) { case 0: if (setgid(getgid()) || setuid(getuid())) _exit(127); close(fds[1]); if (dup2(fds[0], 0)) _exit(127); close(fds[0]); if (use_pkexec) { execlp("pkexec", "pkexec", LIBEXEC_PATH "/xf86-video-intel-backlight-helper", iface, (char *)0); } else { execle(LIBEXEC_PATH "/xf86-video-intel-backlight-helper", "xf86-video-intel-backlight-helper", iface, (char *)0, env); } _exit(1); /* unreachable fallthrough */ case -1: close(fds[1]); close(fds[0]); return 0; default: close(fds[0]); return __backlight_init(b, iface, fds[1]); } #else return 0; #endif } static char * __backlight_find(void) { char *best_iface = NULL; unsigned best_type = INT_MAX; DIR *dir; struct dirent *de; dir = opendir(BACKLIGHT_CLASS); if (dir == NULL) return NULL; while ((de = readdir(dir))) { int v; if (*de->d_name == '.') continue; /* Fallback to priority list of known iface for old kernels */ v = __backlight_exists(de->d_name); if (v < 0) continue; if (v < best_type) { char *copy = strdup(de->d_name); if (copy) { free(best_iface); best_iface = copy; best_type = v; } } } closedir(dir); return best_iface; } int backlight_open(struct backlight *b, char *iface) { int level, type; if (iface == NULL) iface = __backlight_find(); if (iface == NULL) goto err; type = __backlight_type(iface); if (type < 0) goto err; b->type = type >> 8; b->max = __backlight_read(iface, "max_brightness"); if (b->max <= 0) goto err; level = __backlight_read(iface, "brightness"); if (level < 0) goto err; if (!__backlight_direct_init(b, iface) && !__backlight_helper_init(b, iface)) goto err; return level; err: backlight_init(b); return -1; } int backlight_set(struct backlight *b, int level) { char val[BACKLIGHT_VALUE_LEN]; int len, ret = 0; if (b->iface == NULL) return 0; if ((unsigned)level > b->max) level = b->max; len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); if (write(b->fd, val, len) != len) ret = -1; return ret; } int backlight_get(struct backlight *b) { int level; if (b->iface == NULL) return -1; level = __backlight_read(b->iface, "brightness"); if (level > b->max) level = b->max; else if (level < 0) level = -1; return level; } int backlight_off(struct backlight *b) { if (b->iface == NULL) return 0; if (!b->has_power) return 0; /* 4 -> FB_BLANK_POWERDOWN */ return __backlight_write(b->iface, "bl_power", "4"); } int backlight_on(struct backlight *b) { if (b->iface == NULL) return 0; if (!b->has_power) return 0; /* 0 -> FB_BLANK_UNBLANK */ return __backlight_write(b->iface, "bl_power", "0"); } #endif void backlight_disable(struct backlight *b) { if (b->iface == NULL) return; if (b->fd != -1) close(b->fd); free(b->iface); b->iface = NULL; } void backlight_close(struct backlight *b) { backlight_disable(b); if (b->pid > 0) waitpid(b->pid, NULL, 0); } char *backlight_find_for_device(struct pci_device *pci) { char path[200]; unsigned best_type = INT_MAX; char *best_iface = NULL; DIR *dir; struct dirent *de; snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%d/backlight", pci->domain, pci->bus, pci->dev, pci->func); dir = opendir(path); if (dir == NULL) return NULL; while ((de = readdir(dir))) { int v; if (*de->d_name == '.') continue; v = __backlight_exists(de->d_name); if (v < 0) continue; if (v < best_type) { char *copy = strdup(de->d_name); if (copy) { free(best_iface); best_iface = copy; best_type = v; } } } closedir(dir); return best_iface; } xserver-xorg-video-intel-2.99.917+git20160325/src/backlight.h000066400000000000000000000040201267532330400231570ustar00rootroot00000000000000/*************************************************************************** Copyright 2014 Intel Corporation. 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 INTEL, 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 BACKLIGHT_H #define BACKLIGHT_H enum backlight_type { BL_NONE = -1, BL_PLATFORM, BL_FIRMWARE, BL_RAW, BL_NAMED, }; struct backlight { char *iface; enum backlight_type type; int max; int has_power; int pid, fd; }; int backlight_exists(const char *iface); void backlight_init(struct backlight *backlight); int backlight_open(struct backlight *backlight, char *iface); int backlight_set(struct backlight *backlight, int level); int backlight_get(struct backlight *backlight); int backlight_on(struct backlight *b); int backlight_off(struct backlight *b); void backlight_disable(struct backlight *backlight); void backlight_close(struct backlight *backlight); struct pci_device; char *backlight_find_for_device(struct pci_device *pci); #endif /* BACKLIGHT_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/compat-api.h000066400000000000000000000217461267532330400232770ustar00rootroot00000000000000/* * Copyright 2012 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Author: Dave Airlie */ /* this file provides API compat between server post 1.13 and pre it, it should be reused inside as many drivers as possible */ #ifndef COMPAT_API_H #define COMPAT_API_H #include #include #include #ifndef GLYPH_HAS_GLYPH_PICTURE_ACCESSOR #define GetGlyphPicture(g, s) GlyphPicture((g))[(s)->myNum] #define SetGlyphPicture(g, s, p) GlyphPicture((g))[(s)->myNum] = p #endif #ifndef XF86_HAS_SCRN_CONV #define xf86ScreenToScrn(s) xf86Screens[(s)->myNum] #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,1,0,0,0) #define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex] #else #define xf86ScrnToScreen(s) ((s)->pScreen) #endif #else #define xf86ScrnToScreen(s) ((s)->pScreen) #endif #ifndef XF86_SCRN_INTERFACE #define SCRN_ARG_TYPE int #define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = xf86Screens[(arg1)] #define SCREEN_ARG_TYPE int #define SCREEN_PTR(arg1) ScreenPtr screen = screenInfo.screens[(arg1)] #define SCREEN_INIT_ARGS_DECL int scrnIndex, ScreenPtr screen, int argc, char **argv #define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer timeout, pointer read_mask #define BLOCKHANDLER_ARGS arg, blockData, timeout, read_mask #define WAKEUPHANDLER_ARGS_DECL int arg, pointer wakeupData, unsigned long result, pointer read_mask #define WAKEUPHANDLER_ARGS arg, wakeupData, result, read_mask #define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr screen #define CLOSE_SCREEN_ARGS scrnIndex, screen #define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags #define ADJUST_FRAME_ARGS(arg, x, y) (arg)->scrnIndex, x, y, 0 #define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags #define SWITCH_MODE_ARGS(arg, m) (arg)->scrnIndex, m, 0 #define FREE_SCREEN_ARGS_DECL int arg, int flags #define VT_FUNC_ARGS_DECL int arg, int flags #define VT_FUNC_ARGS(flags) scrn->scrnIndex, (flags) #define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex) #else #define SCRN_ARG_TYPE ScrnInfoPtr #define SCRN_INFO_PTR(arg1) ScrnInfoPtr scrn = (arg1) #define SCREEN_ARG_TYPE ScreenPtr #define SCREEN_PTR(arg1) ScreenPtr screen = (arg1) #define SCREEN_INIT_ARGS_DECL ScreenPtr screen, int argc, char **argv #define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer timeout, pointer read_mask #define BLOCKHANDLER_ARGS arg, timeout, read_mask #define WAKEUPHANDLER_ARGS_DECL ScreenPtr arg, unsigned long result, pointer read_mask #define WAKEUPHANDLER_ARGS arg, result, read_mask #define CLOSE_SCREEN_ARGS_DECL ScreenPtr screen #define CLOSE_SCREEN_ARGS screen #define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y #define ADJUST_FRAME_ARGS(arg, x, y) arg, x, y #define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode #define SWITCH_MODE_ARGS(arg, m) arg, m #define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg #define VT_FUNC_ARGS_DECL ScrnInfoPtr arg #define VT_FUNC_ARGS(flags) scrn #define XF86_ENABLEDISABLEFB_ARG(x) (x) #endif static inline int region_num_rects(const RegionRec *r) { return r->data ? r->data->numRects : 1; } static inline int region_nil(const RegionRec *r) { return region_num_rects(r) == 0; } static inline BoxPtr region_boxptr(const RegionRec *r) { return (BoxPtr)(r->data + 1); } static inline const BoxRec * region_rects(const RegionRec *r) { return r->data ? (const BoxRec *)(r->data + 1) : &r->extents; } inline static void region_get_boxes(const RegionRec *r, const BoxRec **s, const BoxRec **e) { int n; if (r->data) *s = region_boxptr(r), n = r->data->numRects; else *s = &r->extents, n = 1; *e = *s + n; } #ifndef INCLUDE_LEGACY_REGION_DEFINES #define RegionCreate(r, s) REGION_CREATE(NULL, r, s) #define RegionBreak(r) REGION_BREAK(NULL, r) #define RegionSizeof REGION_SZOF #define RegionBoxptr REGION_BOXPTR #define RegionEnd REGION_END #define RegionExtents(r) REGION_EXTENTS(NULL, r) #define RegionRects REGION_RECTS #define RegionNumRects REGION_NUM_RECTS #define RegionContainsRect(r, b) RECT_IN_REGION(NULL, r, b) #define RegionContainsPoint(r, x, y, b) POINT_IN_REGION(NULL, r, x, y, b) #define RegionCopy(res, r) REGION_COPY(NULL, res, r) #define RegionIntersect(res, r1, r2) REGION_INTERSECT(NULL, res, r1, r2) #define RegionUnion(res, r1, r2) REGION_UNION(NULL, res, r1, r2) #define RegionSubtract(res, r1, r2) REGION_SUBTRACT(NULL, res, r1, r2) #define RegionTranslate(r, x, y) REGION_TRANSLATE(NULL, r, x, y) #define RegionUninit(r) REGION_UNINIT(NULL, r) #define region_from_bitmap BITMAP_TO_REGION #define RegionNil REGION_NIL #define RegionNull(r) REGION_NULL(NULL, r) #define RegionNotEmpty(r) REGION_NOTEMPTY(NULL, r) #define RegionEmpty(r) REGION_EMPTY(NULL, r) #define RegionEqual(a, b) REGION_EQUAL(NULL, a, b) #define RegionDestroy(r) REGION_DESTROY(NULL, r) #else #define region_from_bitmap BitmapToRegion #endif #ifndef _X_UNUSED #define _X_UNUSED #endif #if HAS_DEVPRIVATEKEYREC #define __get_private(p, key) dixGetPrivateAddr(&(p)->devPrivates, &(key)) #else #define __get_private(p, key) dixLookupPrivate(&(p)->devPrivates, &(key)) typedef int DevPrivateKeyRec; static inline void FreePixmap(PixmapPtr pixmap) { dixFreePrivates(pixmap->devPrivates); free(pixmap); } #endif #if !HAS_DIXREGISTERPRIVATEKEY #define dixPrivateKeyRegistered(key__) (*(key__) != 0) #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,902,0) #define SourceValidate(d, x, y, w, h, mode) \ if ((d)->pScreen->SourceValidate) (d)->pScreen->SourceValidate(d, x, y, w, h, mode) #else #define SourceValidate(d, x, y, w, h, mode) \ if ((d)->pScreen->SourceValidate) (d)->pScreen->SourceValidate(d, x, y, w, h) #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0) #define DamageUnregister(d, dd) DamageUnregister(dd) #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,16,99,1,0) #define XORG_XV_VERSION 2 #define ddStopVideo_ARGS XvPortPtr port, DrawablePtr draw #define ddSetPortAttribute_ARGS XvPortPtr port, Atom attribute, INT32 value #define ddGetPortAttribute_ARGS XvPortPtr port, Atom attribute, INT32 *value #define ddQueryBestSize_ARGS XvPortPtr port, CARD8 motion, CARD16 vid_w, CARD16 vid_h, CARD16 drw_w, CARD16 drw_h, unsigned int *p_w, unsigned int *p_h #define ddPutImage_ARGS DrawablePtr draw, XvPortPtr port, GCPtr gc, INT16 src_x, INT16 src_y, CARD16 src_w, CARD16 src_h, INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h, XvImagePtr format, unsigned char *buf, Bool sync, CARD16 width, CARD16 height #define ddQueryImageAttributes_ARGS XvPortPtr port, XvImagePtr format, unsigned short *w, unsigned short *h, int *pitches, int *offsets #else #define XORG_XV_VERSION 1 #define ddStopVideo_ARGS ClientPtr client, XvPortPtr port, DrawablePtr draw #define ddSetPortAttribute_ARGS ClientPtr client, XvPortPtr port, Atom attribute, INT32 value #define ddGetPortAttribute_ARGS ClientPtr client, XvPortPtr port, Atom attribute, INT32 *value #define ddQueryBestSize_ARGS ClientPtr client, XvPortPtr port, CARD8 motion, CARD16 vid_w, CARD16 vid_h, CARD16 drw_w, CARD16 drw_h, unsigned int *p_w, unsigned int *p_h #define ddPutImage_ARGS ClientPtr client, DrawablePtr draw, XvPortPtr port, GCPtr gc, INT16 src_x, INT16 src_y, CARD16 src_w, CARD16 src_h, INT16 drw_x, INT16 drw_y, CARD16 drw_w, CARD16 drw_h, XvImagePtr format, unsigned char *buf, Bool sync, CARD16 width, CARD16 height #define ddQueryImageAttributes_ARGS ClientPtr client, XvPortPtr port, XvImagePtr format, unsigned short *w, unsigned short *h, int *pitches, int *offsets #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,16,99,1,0) #include #define miHandleExposures(pSrcDrawable, pDstDrawable, \ pGC, srcx, srcy, width, height, \ dstx, dsty, plane) \ miHandleExposures(pSrcDrawable, pDstDrawable, \ pGC, srcx, srcy, width, height, \ dstx, dsty) #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) #define isGPU(S) (S)->is_gpu #else #define isGPU(S) 0 #endif #endif #if HAS_DIRTYTRACKING_ROTATION #define PixmapSyncDirtyHelper(d, dd) PixmapSyncDirtyHelper(d) #endif xserver-xorg-video-intel-2.99.917+git20160325/src/fd.c000066400000000000000000000041061267532330400216200ustar00rootroot00000000000000/*************************************************************************** Copyright 2013 Intel Corporation. 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 INTEL, 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 #include #include /* MAXCLIENTS */ #include "fd.h" int fd_move_cloexec(int fd) { int newfd; newfd = fcntl(fd, #ifdef F_DUPFD_CLOEXEC F_DUPFD_CLOEXEC, #else F_DUPFD, #endif MAXCLIENTS); if (newfd < 0) return fd; #ifndef F_DUPFD_CLOEXEC newfd = fd_set_cloexec(newfd); #endif close(fd); return newfd; } int fd_set_cloexec(int fd) { int flags; if (fd == -1) return fd; #ifdef FD_CLOEXEC flags = fcntl(fd, F_GETFD); if (flags != -1) { flags |= FD_CLOEXEC; fcntl(fd, F_SETFD, flags); } #endif return fd; } int fd_set_nonblock(int fd) { int flags; if (fd == -1) return fd; flags = fcntl(fd, F_GETFL); if (flags != -1) { flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); } return fd; } xserver-xorg-video-intel-2.99.917+git20160325/src/fd.h000066400000000000000000000026071267532330400216310ustar00rootroot00000000000000/*************************************************************************** Copyright 2013 Intel Corporation. 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 INTEL, 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 FD_H #define FD_H int fd_move_cloexec(int fd); int fd_set_cloexec(int fd); int fd_set_nonblock(int fd); #endif /* FD_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/i915_pciids.h000066400000000000000000000311141267532330400232550ustar00rootroot00000000000000/* * Copyright 2013 Intel Corporation * 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 NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _I915_PCIIDS_H #define _I915_PCIIDS_H /* * A pci_device_id struct { * __u32 vendor, device; * __u32 subvendor, subdevice; * __u32 class, class_mask; * kernel_ulong_t driver_data; * }; * Don't use C99 here because "class" is reserved and we want to * give userspace flexibility. */ #define INTEL_VGA_DEVICE(id, info) { \ 0x8086, id, \ ~0, ~0, \ 0x030000, 0xff0000, \ (unsigned long) info } #define INTEL_QUANTA_VGA_DEVICE(info) { \ 0x8086, 0x16a, \ 0x152d, 0x8990, \ 0x030000, 0xff0000, \ (unsigned long) info } #define INTEL_I830_IDS(info) \ INTEL_VGA_DEVICE(0x3577, info) #define INTEL_I845G_IDS(info) \ INTEL_VGA_DEVICE(0x2562, info) #define INTEL_I85X_IDS(info) \ INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \ INTEL_VGA_DEVICE(0x358e, info) #define INTEL_I865G_IDS(info) \ INTEL_VGA_DEVICE(0x2572, info) /* I865_G */ #define INTEL_I915G_IDS(info) \ INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \ INTEL_VGA_DEVICE(0x258a, info) /* E7221_G */ #define INTEL_I915GM_IDS(info) \ INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */ #define INTEL_I945G_IDS(info) \ INTEL_VGA_DEVICE(0x2772, info) /* I945_G */ #define INTEL_I945GM_IDS(info) \ INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \ INTEL_VGA_DEVICE(0x27ae, info) /* I945_GME */ #define INTEL_I965G_IDS(info) \ INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */ \ INTEL_VGA_DEVICE(0x2982, info), /* G35_G */ \ INTEL_VGA_DEVICE(0x2992, info), /* I965_Q */ \ INTEL_VGA_DEVICE(0x29a2, info) /* I965_G */ #define INTEL_G33_IDS(info) \ INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \ INTEL_VGA_DEVICE(0x29c2, info), /* G33_G */ \ INTEL_VGA_DEVICE(0x29d2, info) /* Q33_G */ #define INTEL_I965GM_IDS(info) \ INTEL_VGA_DEVICE(0x2a02, info), /* I965_GM */ \ INTEL_VGA_DEVICE(0x2a12, info) /* I965_GME */ #define INTEL_GM45_IDS(info) \ INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */ #define INTEL_G45_IDS(info) \ INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \ INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \ INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \ INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \ INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \ INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */ #define INTEL_PINEVIEW_IDS(info) \ INTEL_VGA_DEVICE(0xa001, info), \ INTEL_VGA_DEVICE(0xa011, info) #define INTEL_IRONLAKE_D_IDS(info) \ INTEL_VGA_DEVICE(0x0042, info) #define INTEL_IRONLAKE_M_IDS(info) \ INTEL_VGA_DEVICE(0x0046, info) #define INTEL_SNB_D_IDS(info) \ INTEL_VGA_DEVICE(0x0102, info), \ INTEL_VGA_DEVICE(0x0112, info), \ INTEL_VGA_DEVICE(0x0122, info), \ INTEL_VGA_DEVICE(0x010A, info) #define INTEL_SNB_M_IDS(info) \ INTEL_VGA_DEVICE(0x0106, info), \ INTEL_VGA_DEVICE(0x0116, info), \ INTEL_VGA_DEVICE(0x0126, info) #define INTEL_IVB_M_IDS(info) \ INTEL_VGA_DEVICE(0x0156, info), /* GT1 mobile */ \ INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */ #define INTEL_IVB_D_IDS(info) \ INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \ INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \ INTEL_VGA_DEVICE(0x015a, info), /* GT1 server */ \ INTEL_VGA_DEVICE(0x016a, info) /* GT2 server */ #define INTEL_IVB_Q_IDS(info) \ INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */ #define INTEL_HSW_D_IDS(info) \ INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \ INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \ INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \ INTEL_VGA_DEVICE(0x040a, info), /* GT1 server */ \ INTEL_VGA_DEVICE(0x041a, info), /* GT2 server */ \ INTEL_VGA_DEVICE(0x042a, info), /* GT3 server */ \ INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \ INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \ INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \ INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \ INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \ INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \ INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \ INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \ INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \ INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \ INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \ INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \ INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \ INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \ INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \ INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \ INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \ INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \ INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \ INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \ INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \ INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \ INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \ INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \ INTEL_VGA_DEVICE(0x0A0B, info), /* ULT GT1 reserved */ \ INTEL_VGA_DEVICE(0x0A1B, info), /* ULT GT2 reserved */ \ INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \ INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \ INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \ INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \ INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \ INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \ INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \ INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \ INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \ INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \ INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */ \ #define INTEL_HSW_M_IDS(info) \ INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \ INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \ INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \ INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \ INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \ INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \ INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \ INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \ INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ INTEL_VGA_DEVICE(0x0D26, info) /* CRW GT3 mobile */ #define INTEL_VLV_M_IDS(info) \ INTEL_VGA_DEVICE(0x0f30, info), \ INTEL_VGA_DEVICE(0x0f31, info), \ INTEL_VGA_DEVICE(0x0f32, info), \ INTEL_VGA_DEVICE(0x0f33, info), \ INTEL_VGA_DEVICE(0x0157, info) #define INTEL_VLV_D_IDS(info) \ INTEL_VGA_DEVICE(0x0155, info) #define INTEL_BDW_GT12M_IDS(info) \ INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \ INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \ INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \ INTEL_VGA_DEVICE(0x160E, info), /* GT1 ULX */ \ INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \ INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \ INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \ INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */ #define INTEL_BDW_GT12D_IDS(info) \ INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \ INTEL_VGA_DEVICE(0x160D, info), /* GT1 Workstation */ \ INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \ INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */ #define INTEL_BDW_GT3M_IDS(info) \ INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \ INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \ INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \ INTEL_VGA_DEVICE(0x162E, info) /* ULX */ #define INTEL_BDW_GT3D_IDS(info) \ INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ #define INTEL_BDW_RSVDM_IDS(info) \ INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \ INTEL_VGA_DEVICE(0x163E, info) /* ULX */ #define INTEL_BDW_RSVDD_IDS(info) \ INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ #define INTEL_BDW_M_IDS(info) \ INTEL_BDW_GT12M_IDS(info), \ INTEL_BDW_GT3M_IDS(info), \ INTEL_BDW_RSVDM_IDS(info) #define INTEL_BDW_D_IDS(info) \ INTEL_BDW_GT12D_IDS(info), \ INTEL_BDW_GT3D_IDS(info), \ INTEL_BDW_RSVDD_IDS(info) #define INTEL_CHV_IDS(info) \ INTEL_VGA_DEVICE(0x22b0, info), \ INTEL_VGA_DEVICE(0x22b1, info), \ INTEL_VGA_DEVICE(0x22b2, info), \ INTEL_VGA_DEVICE(0x22b3, info) #define INTEL_SKL_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */ #define INTEL_SKL_GT2_IDS(info) \ INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \ INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \ INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \ INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \ INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \ INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ #define INTEL_SKL_GT3_IDS(info) \ INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \ INTEL_VGA_DEVICE(0x192A, info) /* SRV GT3 */ #define INTEL_SKL_GT4_IDS(info) \ INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \ INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \ INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \ INTEL_VGA_DEVICE(0x193A, info) /* SRV GT4 */ #define INTEL_SKL_IDS(info) \ INTEL_SKL_GT1_IDS(info), \ INTEL_SKL_GT2_IDS(info), \ INTEL_SKL_GT3_IDS(info), \ INTEL_SKL_GT4_IDS(info) #define INTEL_BXT_IDS(info) \ INTEL_VGA_DEVICE(0x0A84, info), \ INTEL_VGA_DEVICE(0x1A84, info), \ INTEL_VGA_DEVICE(0x1A85, info), \ INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \ INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */ #define INTEL_KBL_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \ INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \ INTEL_VGA_DEVICE(0x5917, info), /* DT GT1.5 */ \ INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \ INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \ INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \ INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \ INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */ #define INTEL_KBL_GT2_IDS(info) \ INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \ INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \ INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \ INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \ INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \ INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \ INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */ #define INTEL_KBL_GT3_IDS(info) \ INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x592B, info), /* Halo GT3 */ \ INTEL_VGA_DEVICE(0x592A, info) /* SRV GT3 */ #define INTEL_KBL_GT4_IDS(info) \ INTEL_VGA_DEVICE(0x5932, info), /* DT GT4 */ \ INTEL_VGA_DEVICE(0x593B, info), /* Halo GT4 */ \ INTEL_VGA_DEVICE(0x593A, info), /* SRV GT4 */ \ INTEL_VGA_DEVICE(0x593D, info) /* WKS GT4 */ #define INTEL_KBL_IDS(info) \ INTEL_KBL_GT1_IDS(info), \ INTEL_KBL_GT2_IDS(info), \ INTEL_KBL_GT3_IDS(info), \ INTEL_KBL_GT4_IDS(info) #endif /* _I915_PCIIDS_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/intel_device.c000066400000000000000000000377531267532330400236770ustar00rootroot00000000000000/*************************************************************************** Copyright 2013 Intel Corporation. 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 INTEL, 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 #include #include #include #include #include #include #include #include #if MAJOR_IN_MKDEV #include #elif MAJOR_IN_SYSMACROS #include #endif #include #include #include #include #include #include #include #ifdef XSERVER_PLATFORM_BUS #include #endif #ifdef HAVE_VALGRIND #include #include #define VG(x) x #else #define VG(x) #endif #define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) #include "intel_driver.h" #include "fd.h" struct intel_device { int idx; char *master_node; char *render_node; int fd; int device_id; int open_count; int master_count; }; static int intel_device_key = -1; static int dump_file(ScrnInfoPtr scrn, const char *path) { FILE *file; size_t len = 0; char *line = NULL; file = fopen(path, "r"); if (file == NULL) return 0; xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] Contents of '%s':\n", path); while (getline(&line, &len, file) != -1) xf86DrvMsg(scrn->scrnIndex, X_INFO, "[drm] %s", line); free(line); fclose(file); return 1; } static int __find_debugfs(void) { int i; for (i = 0; i < DRM_MAX_MINOR; i++) { char path[80]; sprintf(path, "/sys/kernel/debug/dri/%d/i915_wedged", i); if (access(path, R_OK) == 0) return i; sprintf(path, "/debug/dri/%d/i915_wedged", i); if (access(path, R_OK) == 0) return i; } return -1; } static int drm_get_minor(int fd) { struct stat st; if (fstat(fd, &st)) return __find_debugfs(); if (!S_ISCHR(st.st_mode)) return __find_debugfs(); return st.st_rdev & 0x63; } #if __linux__ #include static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name) { char path[80]; int minor; minor = drm_get_minor(fd); if (minor < 0) return; sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name); if (dump_file(scrn, path)) return; sprintf(path, "/debug/dri/%d/%s", minor, name); if (dump_file(scrn, path)) return; if (mount("X-debug", "/sys/kernel/debug", "debugfs", 0, 0) == 0) { sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name); dump_file(scrn, path); umount("X-debug"); return; } } #else static void dump_debugfs(ScrnInfoPtr scrn, int fd, const char *name) { } #endif static void dump_clients_info(ScrnInfoPtr scrn, int fd) { dump_debugfs(scrn, fd, "clients"); } static int __intel_get_device_id(int fd) { struct drm_i915_getparam gp; int devid = 0; VG_CLEAR(gp); gp.param = I915_PARAM_CHIPSET_ID; gp.value = &devid; if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) return 0; return devid; } int intel_entity_get_devid(int idx) { struct intel_device *dev; dev = xf86GetEntityPrivate(idx, intel_device_key)->ptr; if (dev == NULL) return 0; return dev->device_id; } static inline struct intel_device *intel_device(ScrnInfoPtr scrn) { if (scrn->entityList == NULL) return NULL; return xf86GetEntityPrivate(scrn->entityList[0], intel_device_key)->ptr; } static const char *kernel_module_names[] ={ "i915", NULL, }; static int is_i915_device(int fd) { drm_version_t version; const char **kn; char name[5] = ""; memset(&version, 0, sizeof(version)); version.name_len = 4; version.name = name; if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) return 0; for (kn = kernel_module_names; *kn; kn++) if (strcmp(*kn, name) == 0) return 1; return 0; } static int load_i915_kernel_module(void) { const char **kn; for (kn = kernel_module_names; *kn; kn++) if (xf86LoadKernelModule(*kn) == 0) return 0; return -1; } static int is_i915_gem(int fd) { int ret = is_i915_device(fd); if (ret) { struct drm_i915_getparam gp; VG_CLEAR(gp); gp.param = I915_PARAM_HAS_GEM; gp.value = &ret; if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) ret = 0; } return ret; } static int __intel_check_device(int fd) { int ret; /* Confirm that this is a i915.ko device with GEM/KMS enabled */ ret = is_i915_gem(fd); if (ret && !hosted()) { struct drm_mode_card_res res; memset(&res, 0, sizeof(res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) ret = 0; } return ret; } static int open_cloexec(const char *path) { struct stat st; int loop = 1000; int fd; /* No file? Assume the driver is loading slowly */ while (stat(path, &st) == -1 && errno == ENOENT && --loop) usleep(50000); if (loop != 1000) ErrorF("intel: waited %d ms for '%s' to appear\n", (1000 - loop) * 50, path); fd = -1; #ifdef O_CLOEXEC fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC); #endif if (fd == -1) fd = fd_set_cloexec(open(path, O_RDWR | O_NONBLOCK)); return fd; } #ifdef __linux__ static int __intel_open_device__major_minor(int _major, int _minor) { char path[256]; DIR *dir; struct dirent *de; int base, fd = -1; base = sprintf(path, "/dev/dri/"); dir = opendir(path); if (dir == NULL) return -1; while ((de = readdir(dir)) != NULL) { struct stat st; if (*de->d_name == '.') continue; sprintf(path + base, "%s", de->d_name); if (stat(path, &st) == 0 && major(st.st_rdev) == _major && minor(st.st_rdev) == _minor) { fd = open_cloexec(path); break; } } closedir(dir); return fd; } static int __intel_open_device__pci(const struct pci_device *pci) { struct stat st; char path[256]; DIR *dir; struct dirent *de; int base; int fd; /* Look up the major:minor for the drm device through sysfs. * First we need to check that sysfs is available, then * check that we have loaded our driver. When we are happy * that our KMS module is loaded, we can then search for our * device node. We make the assumption that it uses the same * name, but after that we read the major:minor assigned to us * and search for a matching entry in /dev. */ base = sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/", pci->domain, pci->bus, pci->dev, pci->func); if (stat(path, &st)) return -1; sprintf(path + base, "drm"); dir = opendir(path); if (dir == NULL) { int loop = 0; sprintf(path + base, "driver"); if (stat(path, &st)) { if (load_i915_kernel_module()) return -1; (void)xf86LoadKernelModule("fbcon"); } sprintf(path + base, "drm"); while ((dir = opendir(path)) == NULL && loop++ < 100) usleep(20000); ErrorF("intel: waited %d ms for i915.ko driver to load\n", loop * 20000 / 1000); if (dir == NULL) return -1; } fd = -1; while ((de = readdir(dir)) != NULL) { if (*de->d_name == '.') continue; if (strncmp(de->d_name, "card", 4) == 0) { sprintf(path + base + 4, "/dev/dri/%s", de->d_name); fd = open_cloexec(path + base + 4); if (fd != -1) break; sprintf(path + base + 3, "/%s/dev", de->d_name); fd = open(path, O_RDONLY); if (fd == -1) break; base = read(fd, path, sizeof(path) - 1); close(fd); fd = -1; if (base > 0) { int major, minor; path[base] = '\0'; if (sscanf(path, "%d:%d", &major, &minor) == 2) fd = __intel_open_device__major_minor(major, minor); } break; } } closedir(dir); return fd; } #else static int __intel_open_device__pci(const struct pci_device *pci) { return -1; } #endif static int __intel_open_device__legacy(const struct pci_device *pci) { char id[20]; int ret; snprintf(id, sizeof(id), "pci:%04x:%02x:%02x.%d", pci->domain, pci->bus, pci->dev, pci->func); ret = drmCheckModesettingSupported(id); if (ret) { if (load_i915_kernel_module() == 0) ret = drmCheckModesettingSupported(id); if (ret) return -1; /* Be nice to the user and load fbcon too */ (void)xf86LoadKernelModule("fbcon"); } return fd_set_nonblock(drmOpen(NULL, id)); } static int __intel_open_device(const struct pci_device *pci, const char *path) { int fd; if (path == NULL) { if (pci == NULL) return -1; fd = __intel_open_device__pci(pci); if (fd == -1) fd = __intel_open_device__legacy(pci); } else fd = open_cloexec(path); return fd; } static char *find_master_node(int fd) { struct stat st, master; char buf[128]; if (fstat(fd, &st)) return NULL; if (!S_ISCHR(st.st_mode)) return NULL; sprintf(buf, "/dev/dri/card%d", (int)(st.st_rdev & 0x7f)); if (stat(buf, &master) == 0 && st.st_mode == master.st_mode && (st.st_rdev & 0x7f) == master.st_rdev) return strdup(buf); /* Fallback to iterating over the usual suspects */ return drmGetDeviceNameFromFd(fd); } static int is_render_node(int fd, struct stat *st) { if (fstat(fd, st)) return 0; if (!S_ISCHR(st->st_mode)) return 0; return st->st_rdev & 0x80; } static char *find_render_node(int fd) { struct stat master, render; char buf[128]; int i; /* Are we a render-node ourselves? */ if (is_render_node(fd, &master)) return NULL; sprintf(buf, "/dev/dri/renderD%d", (int)((master.st_rdev | 0x80) & 0xbf)); if (stat(buf, &render) == 0 && master.st_mode == render.st_mode && render.st_rdev == (master.st_rdev | 0x80)) return strdup(buf); /* Misaligned card <-> renderD, do a full search */ for (i = 0; i < 16; i++) { sprintf(buf, "/dev/dri/renderD%d", i + 128); if (stat(buf, &render) == 0 && master.st_mode == render.st_mode && render.st_rdev == (master.st_rdev | 0x80)) return strdup(buf); } return NULL; } #if defined(ODEV_ATTRIB_PATH) static char *get_path(struct xf86_platform_device *dev) { const char *path; if (dev == NULL) return NULL; path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH); if (path == NULL) return NULL; return strdup(path); } #else static char *get_path(struct xf86_platform_device *dev) { return NULL; } #endif #if defined(ODEV_ATTRIB_FD) static int get_fd(struct xf86_platform_device *dev) { if (dev == NULL) return -1; return xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1); } #else static int get_fd(struct xf86_platform_device *dev) { return -1; } #endif static int is_master(int fd) { drmSetVersion sv; sv.drm_di_major = 1; sv.drm_di_minor = 1; sv.drm_dd_major = -1; sv.drm_dd_minor = -1; return drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv) == 0; } int intel_open_device(int entity_num, const struct pci_device *pci, struct xf86_platform_device *platform) { struct intel_device *dev; char *path; int fd, master_count; if (intel_device_key == -1) intel_device_key = xf86AllocateEntityPrivateIndex(); if (intel_device_key == -1) return -1; dev = xf86GetEntityPrivate(entity_num, intel_device_key)->ptr; if (dev) return dev->fd; path = get_path(platform); master_count = 1; /* DRM_MASTER is managed by Xserver */ fd = get_fd(platform); if (fd == -1) { fd = __intel_open_device(pci, path); if (fd == -1) goto err_path; master_count = 0; } if (path == NULL) { path = find_master_node(fd); if (path == NULL) goto err_close; } if (!__intel_check_device(fd)) goto err_close; dev = malloc(sizeof(*dev)); if (dev == NULL) goto err_close; /* If hosted under a system compositor, just pretend to be master */ if (hosted()) master_count++; /* Non-root user holding MASTER, don't let go */ if (geteuid() && is_master(fd)) master_count++; if (pci) dev->device_id = pci->device_id; else dev->device_id = __intel_get_device_id(fd); dev->idx = entity_num; dev->fd = fd; dev->open_count = master_count; dev->master_count = master_count; dev->master_node = path; dev->render_node = find_render_node(fd); if (dev->render_node == NULL) dev->render_node = dev->master_node; xf86GetEntityPrivate(entity_num, intel_device_key)->ptr = dev; return fd; err_close: if (master_count == 0) /* Don't close server-fds */ close(fd); err_path: free(path); return -1; } int __intel_peek_fd(ScrnInfoPtr scrn) { struct intel_device *dev; dev = intel_device(scrn); assert(dev && dev->fd != -1); return dev->fd; } int intel_has_render_node(struct intel_device *dev) { struct stat st; assert(dev && dev->fd != -1); return is_render_node(dev->fd, &st); } struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd) { struct intel_device *dev; int ret; dev = intel_device(scrn); if (dev == NULL) return NULL; assert(dev->fd != -1); if (dev->open_count++ == 0) { drmSetVersion sv; int retry = 2000; assert(!hosted()); /* Check that what we opened was a master or a * master-capable FD, by setting the version of the * interface we'll use to talk to it. */ do { sv.drm_di_major = 1; sv.drm_di_minor = 1; sv.drm_dd_major = -1; sv.drm_dd_minor = -1; ret = drmIoctl(dev->fd, DRM_IOCTL_SET_VERSION, &sv); if (ret == 0) break; usleep(1000); } while (--retry); if (ret != 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "[drm] failed to set drm interface version: %s [%d].\n", strerror(errno), errno); dump_clients_info(scrn, dev->fd); dev->open_count--; return NULL; } } *fd = dev->fd; return dev; } const char *intel_get_master_name(struct intel_device *dev) { assert(dev && dev->master_node); return dev->master_node; } const char *intel_get_client_name(struct intel_device *dev) { assert(dev && dev->render_node); return dev->render_node; } static int authorise(struct intel_device *dev, int fd) { struct stat st; drm_magic_t magic; if (is_render_node(fd, &st)) /* restricted authority, do not elevate */ return 1; return drmGetMagic(fd, &magic) == 0 && drmAuthMagic(dev->fd, magic) == 0; } int intel_get_client_fd(struct intel_device *dev) { int fd = -1; assert(dev && dev->fd != -1); assert(dev->render_node); #ifdef O_CLOEXEC fd = open(dev->render_node, O_RDWR | O_CLOEXEC); #endif if (fd < 0) fd = fd_set_cloexec(open(dev->render_node, O_RDWR)); if (fd < 0) return -BadAlloc; if (!authorise(dev, fd)) { close(fd); return -BadMatch; } assert(is_i915_gem(fd)); return fd; } int intel_get_device_id(struct intel_device *dev) { assert(dev && dev->fd != -1); return dev->device_id; } int intel_get_master(struct intel_device *dev) { int ret; assert(dev && dev->fd != -1); ret = 0; if (dev->master_count++ == 0) { int retry = 2000; assert(!hosted()); do { ret = drmSetMaster(dev->fd); if (ret == 0) break; usleep(1000); } while (--retry); } return ret; } int intel_put_master(struct intel_device *dev) { int ret; assert(dev && dev->fd != -1); ret = 0; assert(dev->master_count); if (--dev->master_count == 0) { assert(!hosted()); assert(drmSetMaster(dev->fd) == 0); ret = drmDropMaster(dev->fd); } return ret; } void intel_put_device(struct intel_device *dev) { assert(dev && dev->fd != -1); assert(dev->open_count); if (--dev->open_count) return; assert(!hosted()); xf86GetEntityPrivate(dev->idx, intel_device_key)->ptr = NULL; drmClose(dev->fd); if (dev->render_node != dev->master_node) free(dev->render_node); free(dev->master_node); free(dev); } xserver-xorg-video-intel-2.99.917+git20160325/src/intel_driver.h000066400000000000000000000114261267532330400237250ustar00rootroot00000000000000#ifndef INTEL_DRIVER_H #define INTEL_DRIVER_H struct xf86_platform_device; #define INTEL_VERSION 4000 #define INTEL_NAME "intel" #define INTEL_DRIVER_NAME "intel" #define INTEL_VERSION_MAJOR PACKAGE_VERSION_MAJOR #define INTEL_VERSION_MINOR PACKAGE_VERSION_MINOR #define INTEL_VERSION_PATCH PACKAGE_VERSION_PATCHLEVEL #define PCI_CHIP_I810 0x7121 #define PCI_CHIP_I810_DC100 0x7123 #define PCI_CHIP_I810_E 0x7125 #define PCI_CHIP_I815 0x1132 #define PCI_CHIP_I830_M 0x3577 #define PCI_CHIP_845_G 0x2562 #define PCI_CHIP_I854 0x358E #define PCI_CHIP_I855_GM 0x3582 #define PCI_CHIP_I865_G 0x2572 #define PCI_CHIP_I915_G 0x2582 #define PCI_CHIP_I915_GM 0x2592 #define PCI_CHIP_E7221_G 0x258A #define PCI_CHIP_I945_G 0x2772 #define PCI_CHIP_I945_GM 0x27A2 #define PCI_CHIP_I945_GME 0x27AE #define PCI_CHIP_PINEVIEW_M 0xA011 #define PCI_CHIP_PINEVIEW_G 0xA001 #define PCI_CHIP_Q35_G 0x29B2 #define PCI_CHIP_G33_G 0x29C2 #define PCI_CHIP_Q33_G 0x29D2 #define PCI_CHIP_G35_G 0x2982 #define PCI_CHIP_I965_Q 0x2992 #define PCI_CHIP_I965_G 0x29A2 #define PCI_CHIP_I946_GZ 0x2972 #define PCI_CHIP_I965_GM 0x2A02 #define PCI_CHIP_I965_GME 0x2A12 #define PCI_CHIP_GM45_GM 0x2A42 #define PCI_CHIP_G45_E_G 0x2E02 #define PCI_CHIP_G45_G 0x2E22 #define PCI_CHIP_Q45_G 0x2E12 #define PCI_CHIP_G41_G 0x2E32 #define PCI_CHIP_B43_G 0x2E42 #define PCI_CHIP_B43_G1 0x2E92 #define PCI_CHIP_IRONLAKE_D_G 0x0042 #define PCI_CHIP_IRONLAKE_M_G 0x0046 #define PCI_CHIP_SANDYBRIDGE_GT1 0x0102 #define PCI_CHIP_SANDYBRIDGE_GT2 0x0112 #define PCI_CHIP_SANDYBRIDGE_GT2_PLUS 0x0122 #define PCI_CHIP_SANDYBRIDGE_M_GT1 0x0106 #define PCI_CHIP_SANDYBRIDGE_M_GT2 0x0116 #define PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS 0x0126 #define PCI_CHIP_SANDYBRIDGE_S_GT 0x010A #define PCI_CHIP_IVYBRIDGE_M_GT1 0x0156 #define PCI_CHIP_IVYBRIDGE_M_GT2 0x0166 #define PCI_CHIP_IVYBRIDGE_D_GT1 0x0152 #define PCI_CHIP_IVYBRIDGE_D_GT2 0x0162 #define PCI_CHIP_IVYBRIDGE_S_GT1 0x015a #define PCI_CHIP_IVYBRIDGE_S_GT2 0x016a #define PCI_CHIP_HASWELL_D_GT1 0x0402 #define PCI_CHIP_HASWELL_D_GT2 0x0412 #define PCI_CHIP_HASWELL_D_GT3 0x0422 #define PCI_CHIP_HASWELL_M_GT1 0x0406 #define PCI_CHIP_HASWELL_M_GT2 0x0416 #define PCI_CHIP_HASWELL_M_GT3 0x0426 #define PCI_CHIP_HASWELL_S_GT1 0x040A #define PCI_CHIP_HASWELL_S_GT2 0x041A #define PCI_CHIP_HASWELL_S_GT3 0x042A #define PCI_CHIP_HASWELL_B_GT1 0x040B #define PCI_CHIP_HASWELL_B_GT2 0x041B #define PCI_CHIP_HASWELL_B_GT3 0x042B #define PCI_CHIP_HASWELL_E_GT1 0x040E #define PCI_CHIP_HASWELL_E_GT2 0x041E #define PCI_CHIP_HASWELL_E_GT3 0x042E #define PCI_CHIP_HASWELL_ULT_D_GT1 0x0A02 #define PCI_CHIP_HASWELL_ULT_D_GT2 0x0A12 #define PCI_CHIP_HASWELL_ULT_D_GT3 0x0A22 #define PCI_CHIP_HASWELL_ULT_M_GT1 0x0A06 #define PCI_CHIP_HASWELL_ULT_M_GT2 0x0A16 #define PCI_CHIP_HASWELL_ULT_M_GT3 0x0A26 #define PCI_CHIP_HASWELL_ULT_S_GT1 0x0A0A #define PCI_CHIP_HASWELL_ULT_S_GT2 0x0A1A #define PCI_CHIP_HASWELL_ULT_S_GT3 0x0A2A #define PCI_CHIP_HASWELL_ULT_B_GT1 0x0A0B #define PCI_CHIP_HASWELL_ULT_B_GT2 0x0A1B #define PCI_CHIP_HASWELL_ULT_B_GT3 0x0A2B #define PCI_CHIP_HASWELL_ULT_E_GT1 0x0A0E #define PCI_CHIP_HASWELL_ULT_E_GT2 0x0A1E #define PCI_CHIP_HASWELL_ULT_E_GT3 0x0A2E #define PCI_CHIP_HASWELL_CRW_D_GT1 0x0D02 #define PCI_CHIP_HASWELL_CRW_D_GT2 0x0D12 #define PCI_CHIP_HASWELL_CRW_D_GT3 0x0D22 #define PCI_CHIP_HASWELL_CRW_M_GT1 0x0D06 #define PCI_CHIP_HASWELL_CRW_M_GT2 0x0D16 #define PCI_CHIP_HASWELL_CRW_M_GT3 0x0D26 #define PCI_CHIP_HASWELL_CRW_S_GT1 0x0D0A #define PCI_CHIP_HASWELL_CRW_S_GT2 0x0D1A #define PCI_CHIP_HASWELL_CRW_S_GT3 0x0D2A #define PCI_CHIP_HASWELL_CRW_B_GT1 0x0D0B #define PCI_CHIP_HASWELL_CRW_B_GT2 0x0D1B #define PCI_CHIP_HASWELL_CRW_B_GT3 0x0D2B #define PCI_CHIP_HASWELL_CRW_E_GT1 0x0D0E #define PCI_CHIP_HASWELL_CRW_E_GT2 0x0D1E #define PCI_CHIP_HASWELL_CRW_E_GT3 0x0D2E struct intel_device_info { int gen; }; struct intel_device; int intel_entity_get_devid(int index); int intel_open_device(int entity_num, const struct pci_device *pci, struct xf86_platform_device *dev); int __intel_peek_fd(ScrnInfoPtr scrn); struct intel_device *intel_get_device(ScrnInfoPtr scrn, int *fd); int intel_has_render_node(struct intel_device *dev); const char *intel_get_master_name(struct intel_device *dev); const char *intel_get_client_name(struct intel_device *dev); int intel_get_client_fd(struct intel_device *dev); int intel_get_device_id(struct intel_device *dev); int intel_get_master(struct intel_device *dev); int intel_put_master(struct intel_device *dev); void intel_put_device(struct intel_device *dev); void intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev); #define IS_DEFAULT_ACCEL_METHOD(x) ({ \ enum { NOACCEL, SNA, UXA } default_accel_method__ = DEFAULT_ACCEL_METHOD; \ default_accel_method__ == x; \ }) #define hosted() (0) #endif /* INTEL_DRIVER_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/intel_list.h000066400000000000000000000271631267532330400234120ustar00rootroot00000000000000/* * Copyright © 2010-2012 Intel Corporation * Copyright © 2010 Francisco Jerez * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ #ifndef _INTEL_LIST_H_ #define _INTEL_LIST_H_ #include #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,0,0,0) || XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,11,99,903,0) #include /** * @file Classic doubly-link circular list implementation. * For real usage examples of the linked list, see the file test/list.c * * Example: * We need to keep a list of struct foo in the parent struct bar, i.e. what * we want is something like this. * * struct bar { * ... * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{} * ... * } * * We need one list head in bar and a list element in all list_of_foos (both are of * data type 'struct list'). * * struct bar { * ... * struct list list_of_foos; * ... * } * * struct foo { * ... * struct list entry; * ... * } * * Now we initialize the list head: * * struct bar bar; * ... * list_init(&bar.list_of_foos); * * Then we create the first element and add it to this list: * * struct foo *foo = malloc(...); * .... * list_add(&foo->entry, &bar.list_of_foos); * * Repeat the above for each element you want to add to the list. Deleting * works with the element itself. * list_del(&foo->entry); * free(foo); * * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty * list again. * * Looping through the list requires a 'struct foo' as iterator and the * name of the field the subnodes use. * * struct foo *iterator; * list_for_each_entry(iterator, &bar.list_of_foos, entry) { * if (iterator->something == ...) * ... * } * * Note: You must not call list_del() on the iterator if you continue the * loop. You need to run the safe for-each loop instead: * * struct foo *iterator, *next; * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) { * if (...) * list_del(&iterator->entry); * } * */ /** * The linkage struct for list nodes. This struct must be part of your * to-be-linked struct. struct list is required for both the head of the * list and for each list node. * * Position and name of the struct list field is irrelevant. * There are no requirements that elements of a list are of the same type. * There are no requirements for a list head, any struct list can be a list * head. */ struct list { struct list *next, *prev; }; /** * Initialize the list as an empty list. * * Example: * list_init(&bar->list_of_foos); * * @param The list to initialized. */ static void list_init(struct list *list) { list->next = list->prev = list; } static inline void __list_add(struct list *entry, struct list *prev, struct list *next) { next->prev = entry; entry->next = next; entry->prev = prev; prev->next = entry; } /** * Insert a new element after the given list head. The new element does not * need to be initialised as empty list. * The list changes from: * head → some element → ... * to * head → new element → older element → ... * * Example: * struct foo *newfoo = malloc(...); * list_add(&newfoo->entry, &bar->list_of_foos); * * @param entry The new element to prepend to the list. * @param head The existing list. */ static inline void list_add(struct list *entry, struct list *head) { __list_add(entry, head, head->next); } static inline void list_add_tail(struct list *entry, struct list *head) { __list_add(entry, head->prev, head); } static inline void list_replace(struct list *old, struct list *new) { new->next = old->next; new->next->prev = new; new->prev = old->prev; new->prev->next = new; } #define list_last_entry(ptr, type, member) \ list_entry((ptr)->prev, type, member) #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next) /** * Append a new element to the end of the list given with this list head. * * The list changes from: * head → some element → ... → lastelement * to * head → some element → ... → lastelement → new element * * Example: * struct foo *newfoo = malloc(...); * list_append(&newfoo->entry, &bar->list_of_foos); * * @param entry The new element to prepend to the list. * @param head The existing list. */ static inline void list_append(struct list *entry, struct list *head) { __list_add(entry, head->prev, head); } static inline void __list_del(struct list *prev, struct list *next) { assert(next->prev == prev->next); next->prev = prev; prev->next = next; } static inline void _list_del(struct list *entry) { assert(entry->prev->next == entry); assert(entry->next->prev == entry); __list_del(entry->prev, entry->next); } /** * Remove the element from the list it is in. Using this function will reset * the pointers to/from this element so it is removed from the list. It does * NOT free the element itself or manipulate it otherwise. * * Using list_del on a pure list head (like in the example at the top of * this file) will NOT remove the first element from * the list but rather reset the list as empty list. * * Example: * list_del(&foo->entry); * * @param entry The element to remove. */ static inline void list_del(struct list *entry) { _list_del(entry); list_init(entry); } static inline void list_move(struct list *list, struct list *head) { if (list->prev != head) { _list_del(list); list_add(list, head); } } static inline void list_move_tail(struct list *list, struct list *head) { _list_del(list); list_add_tail(list, head); } /** * Check if the list is empty. * * Example: * list_is_empty(&bar->list_of_foos); * * @return True if the list contains one or more elements or False otherwise. */ static inline bool list_is_empty(const struct list *head) { return head->next == head; } /** * Alias of container_of */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) /** * Retrieve the first list entry for the given list pointer. * * Example: * struct foo *first; * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos); * * @param ptr The list head * @param type Data type of the list element to retrieve * @param member Member name of the struct list field in the list element. * @return A pointer to the first list element. */ #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) /** * Retrieve the last list entry for the given listpointer. * * Example: * struct foo *first; * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos); * * @param ptr The list head * @param type Data type of the list element to retrieve * @param member Member name of the struct list field in the list element. * @return A pointer to the last list element. */ #define list_last_entry(ptr, type, member) \ list_entry((ptr)->prev, type, member) #define __container_of(ptr, sample, member) \ (void *)((char *)(ptr) - ((char *)&(sample)->member - (char *)(sample))) /** * Loop through the list given by head and set pos to struct in the list. * * Example: * struct foo *iterator; * list_for_each_entry(iterator, &bar->list_of_foos, entry) { * [modify iterator] * } * * This macro is not safe for node deletion. Use list_for_each_entry_safe * instead. * * @param pos Iterator variable of the type of the list elements. * @param head List head * @param member Member name of the struct list in the list elements. * */ #define list_for_each_entry(pos, head, member) \ for (pos = __container_of((head)->next, pos, member); \ &pos->member != (head); \ pos = __container_of(pos->member.next, pos, member)) #define list_for_each_entry_reverse(pos, head, member) \ for (pos = __container_of((head)->prev, pos, member); \ &pos->member != (head); \ pos = __container_of(pos->member.prev, pos, member)) /** * Loop through the list, keeping a backup pointer to the element. This * macro allows for the deletion of a list element while looping through the * list. * * See list_for_each_entry for more details. */ #define list_for_each_entry_safe(pos, tmp, head, member) \ for (pos = __container_of((head)->next, pos, member), \ tmp = __container_of(pos->member.next, pos, member); \ &pos->member != (head); \ pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) #else #include static inline void list_add_tail(struct list *entry, struct list *head) { __list_add(entry, head->prev, head); } static inline void _list_del(struct list *entry) { assert(entry->prev->next == entry); assert(entry->next->prev == entry); __list_del(entry->prev, entry->next); } static inline void list_replace(struct list *old, struct list *new) { new->next = old->next; new->next->prev = new; new->prev = old->prev; new->prev->next = new; } static inline void list_move(struct list *list, struct list *head) { if (list->prev != head) { _list_del(list); list_add(list, head); } } static inline void list_move_tail(struct list *list, struct list *head) { _list_del(list); list_add_tail(list, head); } #define list_last_entry(ptr, type, member) \ list_entry((ptr)->prev, type, member) #define list_for_each_entry_reverse(pos, head, member) \ for (pos = __container_of((head)->prev, pos, member); \ &pos->member != (head); \ pos = __container_of(pos->member.prev, pos, member)) #endif #define list_for_each_entry_safe_from(pos, tmp, head, member) \ for (tmp = __container_of(pos->member.next, pos, member); \ &pos->member != (head); \ pos = tmp, tmp = __container_of(tmp->member.next, tmp, member)) #undef container_of #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (char *) &((type *)0)->member)) static inline void __list_splice(const struct list *list, struct list *prev, struct list *next) { struct list *first = list->next; struct list *last = list->prev; first->prev = prev; prev->next = first; last->next = next; next->prev = last; } static inline void list_splice(const struct list *list, struct list *head) { if (!list_is_empty(list)) __list_splice(list, head, head->next); } static inline void list_splice_tail(const struct list *list, struct list *head) { if (!list_is_empty(list)) __list_splice(list, head->prev, head); } static inline int list_is_singular(const struct list *list) { return list->next == list->prev; } #endif /* _INTEL_LIST_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/intel_module.c000066400000000000000000000452571267532330400237230ustar00rootroot00000000000000/* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,0,0) #include #endif #include "intel_driver.h" #include "intel_options.h" #include "legacy/legacy.h" #include "sna/sna_module.h" #include "uxa/uxa_module.h" #include "i915_pciids.h" /* copied from (kernel) include/drm/i915_pciids.h */ #ifdef XSERVER_PLATFORM_BUS #include #endif #ifndef XF86_ALLOCATE_GPU_SCREEN #define XF86_ALLOCATE_GPU_SCREEN 0 #endif static const struct intel_device_info intel_generic_info = { .gen = -1, }; static const struct intel_device_info intel_i81x_info = { .gen = 010, }; static const struct intel_device_info intel_i830_info = { .gen = 020, }; static const struct intel_device_info intel_i845_info = { .gen = 020, }; static const struct intel_device_info intel_i855_info = { .gen = 021, }; static const struct intel_device_info intel_i865_info = { .gen = 022, }; static const struct intel_device_info intel_i915_info = { .gen = 030, }; static const struct intel_device_info intel_i945_info = { .gen = 031, }; static const struct intel_device_info intel_g33_info = { .gen = 033, }; static const struct intel_device_info intel_i965_info = { .gen = 040, }; static const struct intel_device_info intel_g4x_info = { .gen = 045, }; static const struct intel_device_info intel_ironlake_info = { .gen = 050, }; static const struct intel_device_info intel_sandybridge_info = { .gen = 060, }; static const struct intel_device_info intel_ivybridge_info = { .gen = 070, }; static const struct intel_device_info intel_valleyview_info = { .gen = 071, }; static const struct intel_device_info intel_haswell_info = { .gen = 075, }; static const struct intel_device_info intel_broadwell_info = { .gen = 0100, }; static const struct intel_device_info intel_cherryview_info = { .gen = 0101, }; static const struct intel_device_info intel_skylake_info = { .gen = 0110, }; static const struct intel_device_info intel_broxton_info = { .gen = 0111, }; static const struct intel_device_info intel_kabylake_info = { .gen = 0112, }; static const SymTabRec intel_chipsets[] = { {PCI_CHIP_I810, "i810"}, {PCI_CHIP_I810_DC100, "i810-dc100"}, {PCI_CHIP_I810_E, "i810e"}, {PCI_CHIP_I815, "i815"}, {PCI_CHIP_I830_M, "i830M"}, {PCI_CHIP_845_G, "845G"}, {PCI_CHIP_I854, "854"}, {PCI_CHIP_I855_GM, "852GM/855GM"}, {PCI_CHIP_I865_G, "865G"}, {PCI_CHIP_I915_G, "915G"}, {PCI_CHIP_E7221_G, "E7221 (i915)"}, {PCI_CHIP_I915_GM, "915GM"}, {PCI_CHIP_I945_G, "945G"}, {PCI_CHIP_I945_GM, "945GM"}, {PCI_CHIP_I945_GME, "945GME"}, {PCI_CHIP_PINEVIEW_M, "Pineview GM"}, {PCI_CHIP_PINEVIEW_G, "Pineview G"}, {PCI_CHIP_I965_G, "965G"}, {PCI_CHIP_G35_G, "G35"}, {PCI_CHIP_I965_Q, "965Q"}, {PCI_CHIP_I946_GZ, "946GZ"}, {PCI_CHIP_I965_GM, "965GM"}, {PCI_CHIP_I965_GME, "965GME/GLE"}, {PCI_CHIP_G33_G, "G33"}, {PCI_CHIP_Q35_G, "Q35"}, {PCI_CHIP_Q33_G, "Q33"}, {PCI_CHIP_GM45_GM, "GM45"}, {PCI_CHIP_G45_E_G, "4 Series"}, {PCI_CHIP_G45_G, "G45/G43"}, {PCI_CHIP_Q45_G, "Q45/Q43"}, {PCI_CHIP_G41_G, "G41"}, {PCI_CHIP_B43_G, "B43"}, {PCI_CHIP_B43_G1, "B43"}, {0, ""}, {PCI_CHIP_IRONLAKE_D_G, "HD Graphics"}, {PCI_CHIP_IRONLAKE_M_G, "HD Graphics"}, {PCI_CHIP_SANDYBRIDGE_GT1, "HD Graphics 2000" }, {PCI_CHIP_SANDYBRIDGE_GT2, "HD Graphics 3000" }, {PCI_CHIP_SANDYBRIDGE_GT2_PLUS, "HD Graphics 3000" }, {PCI_CHIP_SANDYBRIDGE_M_GT1, "HD Graphics 2000" }, {PCI_CHIP_SANDYBRIDGE_M_GT2, "HD Graphics 3000" }, {PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS, "HD Graphics 3000" }, {PCI_CHIP_SANDYBRIDGE_S_GT, "HD Graphics" }, {PCI_CHIP_IVYBRIDGE_M_GT1, "HD Graphics 2500" }, {PCI_CHIP_IVYBRIDGE_M_GT2, "HD Graphics 4000" }, {PCI_CHIP_IVYBRIDGE_D_GT1, "HD Graphics 2500" }, {PCI_CHIP_IVYBRIDGE_D_GT2, "HD Graphics 4000" }, {PCI_CHIP_IVYBRIDGE_S_GT1, "HD Graphics" }, {PCI_CHIP_IVYBRIDGE_S_GT2, "HD Graphics P4000" }, {PCI_CHIP_HASWELL_D_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_D_GT2, "HD Graphics 4600" }, {PCI_CHIP_HASWELL_D_GT3, "HD Graphics 5000" }, /* ??? */ {PCI_CHIP_HASWELL_M_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_M_GT2, "HD Graphics 4600" }, {PCI_CHIP_HASWELL_M_GT3, "HD Graphics 5000" }, /* ??? */ {PCI_CHIP_HASWELL_S_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_S_GT2, "HD Graphics P4600/P4700" }, {PCI_CHIP_HASWELL_S_GT3, "HD Graphics 5000" }, /* ??? */ {PCI_CHIP_HASWELL_B_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_B_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_B_GT3, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_E_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_E_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_E_GT3, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_D_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_D_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_D_GT3, "Iris(TM) Graphics 5100" }, {PCI_CHIP_HASWELL_ULT_M_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_ULT_M_GT2, "HD Graphics 4400" }, {PCI_CHIP_HASWELL_ULT_M_GT3, "HD Graphics 5000" }, {PCI_CHIP_HASWELL_ULT_S_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_S_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_S_GT3, "Iris(TM) Graphics 5100" }, {PCI_CHIP_HASWELL_ULT_B_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_B_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_ULT_B_GT3, "Iris(TM) Graphics 5100" }, {PCI_CHIP_HASWELL_ULT_E_GT1, "HD Graphics" }, {PCI_CHIP_HASWELL_ULT_E_GT2, "HD Graphics 4200" }, {PCI_CHIP_HASWELL_ULT_E_GT3, "Iris(TM) Graphics 5100" }, {PCI_CHIP_HASWELL_CRW_D_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_D_GT2, "HD Graphics 4600" }, {PCI_CHIP_HASWELL_CRW_D_GT3, "Iris(TM) Pro Graphics 5200" }, {PCI_CHIP_HASWELL_CRW_M_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_M_GT2, "HD Graphics 4600" }, {PCI_CHIP_HASWELL_CRW_M_GT3, "Iris(TM) Pro Graphics 5200" }, {PCI_CHIP_HASWELL_CRW_S_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_S_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_S_GT3, "Iris(TM) Pro Graphics 5200" }, {PCI_CHIP_HASWELL_CRW_B_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_B_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_B_GT3, "Iris(TM) Pro Graphics 5200" }, {PCI_CHIP_HASWELL_CRW_E_GT1, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_E_GT2, "HD Graphics" }, /* ??? */ {PCI_CHIP_HASWELL_CRW_E_GT3, "Iris(TM) Pro Graphics 5200" }, /* Valleyview (Baytail) */ {0x0f30, "HD Graphics"}, {0x0f31, "HD Graphics"}, {0x0f32, "HD Graphics"}, {0x0f33, "HD Graphics"}, {0x0155, "HD Graphics"}, {0x0157, "HD Graphics"}, /* Broadwell Marketing names */ {0x1602, "HD Graphics"}, {0x1606, "HD Graphics"}, {0x160B, "HD Graphics"}, {0x160A, "HD Graphics"}, {0x160D, "HD Graphics"}, {0x160E, "HD Graphics"}, {0x1612, "HD Graphics 5600"}, {0x1616, "HD Graphics 5500"}, {0x161B, "HD Graphics"}, {0x161A, "HD Graphics"}, {0x161D, "HD Graphics"}, {0x161E, "HD Graphics 5300"}, {0x1622, "Iris Pro Graphics 6200"}, {0x1626, "HD Graphics 6000"}, {0x162B, "Iris Graphics 6100"}, {0x162A, "Iris Pro Graphics P6300"}, {0x162D, "HD Graphics"}, {0x162E, "HD Graphics"}, {0x1632, "HD Graphics"}, {0x1636, "HD Graphics"}, {0x163B, "HD Graphics"}, {0x163A, "HD Graphics"}, {0x163D, "HD Graphics"}, {0x163E, "HD Graphics"}, /* Cherryview (Cherrytrail/Braswell) */ {0x22b0, "HD Graphics"}, {0x22b1, "HD Graphics"}, {0x22b2, "HD Graphics"}, {0x22b3, "HD Graphics"}, /* When adding new identifiers, also update: * 1. intel_identify() * 2. man/intel.man * 3. README */ {-1, NULL} /* Sentinel */ }; static const struct pci_id_match intel_device_match[] = { #if UMS INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info), INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info), INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info), INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info), #endif #if KMS INTEL_I830_IDS(&intel_i830_info), INTEL_I845G_IDS(&intel_i845_info), INTEL_I85X_IDS(&intel_i855_info), INTEL_I865G_IDS(&intel_i865_info), INTEL_I915G_IDS(&intel_i915_info), INTEL_I915GM_IDS(&intel_i915_info), INTEL_I945G_IDS(&intel_i945_info), INTEL_I945GM_IDS(&intel_i945_info), INTEL_G33_IDS(&intel_g33_info), INTEL_PINEVIEW_IDS(&intel_g33_info), INTEL_I965G_IDS(&intel_i965_info), INTEL_I965GM_IDS(&intel_i965_info), INTEL_G45_IDS(&intel_g4x_info), INTEL_GM45_IDS(&intel_g4x_info), INTEL_IRONLAKE_D_IDS(&intel_ironlake_info), INTEL_IRONLAKE_M_IDS(&intel_ironlake_info), INTEL_SNB_D_IDS(&intel_sandybridge_info), INTEL_SNB_M_IDS(&intel_sandybridge_info), INTEL_IVB_D_IDS(&intel_ivybridge_info), INTEL_IVB_M_IDS(&intel_ivybridge_info), INTEL_HSW_D_IDS(&intel_haswell_info), INTEL_HSW_M_IDS(&intel_haswell_info), INTEL_VLV_D_IDS(&intel_valleyview_info), INTEL_VLV_M_IDS(&intel_valleyview_info), INTEL_BDW_D_IDS(&intel_broadwell_info), INTEL_BDW_M_IDS(&intel_broadwell_info), INTEL_CHV_IDS(&intel_cherryview_info), INTEL_SKL_IDS(&intel_skylake_info), INTEL_BXT_IDS(&intel_broxton_info), INTEL_KBL_IDS(&intel_kabylake_info), INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info), #endif { 0, 0, 0 }, }; void intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev) { int devid; const char *name = NULL; int i; if (dev == NULL) { EntityInfoPtr ent; struct pci_device *pci; ent = xf86GetEntityInfo(scrn->entityList[0]); if (ent->device->chipID >= 0) { xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", ent->device->chipID); devid = ent->device->chipID; } else { pci = xf86GetPciInfoForEntity(ent->index); if (pci) devid = pci->device_id; else devid = ~0; } } else devid = intel_get_device_id(dev); for (i = 0; intel_chipsets[i].name != NULL; i++) { if (devid == intel_chipsets[i].token) { name = intel_chipsets[i].name; break; } } if (name == NULL) { int gen = 0; for (i = 0; intel_device_match[i].device_id != 0; i++) { if (devid == intel_device_match[i].device_id) { const struct intel_device_info *info = (void *)intel_device_match[i].match_data; gen = info->gen >> 3; break; } } if (gen) { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "gen%d engineering sample\n", gen); } else { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Unknown chipset\n"); } name = "unknown"; } else { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Integrated Graphics Chipset: Intel(R) %s\n", name); } scrn->chipset = (char *)name; } /* * intel_identify -- * * Returns the string name for the driver based on the chipset. * */ static void intel_identify(int flags) { const SymTabRec *chipset; const char *stack[64], **unique; int i, j, size, len; unique = stack; size = sizeof(stack)/sizeof(stack[0]); i = 0; xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t"); len = 8; for (chipset = intel_chipsets; chipset->token; chipset++) { for (j = i; --j >= 0;) if (strcmp(unique[j], chipset->name) == 0) break; if (j < 0) { int name_len = strlen(chipset->name); if (i != 0) { xf86ErrorF(","); len++; if (len + 2 + name_len < 78) { xf86ErrorF(" "); len++; } else { xf86ErrorF("\n\t"); len = 8; } } xf86ErrorF("%s", chipset->name); len += name_len; if (i == size) { const char **new_unique; if (unique == stack) new_unique = malloc(2*sizeof(*unique)*size); else new_unique = realloc(unique, 2*sizeof(*unique)*size); if (new_unique != NULL) { if (unique == stack) memcpy(new_unique, stack, sizeof(stack)); unique = new_unique; size *= 2; } } if (i < size) unique[i++] = chipset->name; } } xf86ErrorF("\n"); if (unique != stack) free(unique); xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics: 2000-6000\n"); xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics: 5100, 6100\n"); xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300\n"); } static Bool intel_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) { xorgHWFlags *flag; switch (op) { case GET_REQUIRED_HW_INTERFACES: flag = (CARD32*)ptr; (*flag) = 0; #if UMS (*flag) = HW_IO | HW_MMIO; #endif #ifdef HW_SKIP_CONSOLE if (hosted()) (*flag) = HW_SKIP_CONSOLE; #endif return TRUE; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0) case SUPPORTS_SERVER_FDS: return TRUE; #endif default: /* Unknown or deprecated function */ return FALSE; } } #if KMS extern XF86ConfigPtr xf86configptr; static XF86ConfDevicePtr _xf86findDriver(const char *ident, XF86ConfDevicePtr p) { while (p) { if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0) return p; p = p->list.next; } return NULL; } static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void) { enum accel_method accel_method = DEFAULT_ACCEL_METHOD; XF86ConfDevicePtr dev; if (hosted()) return SNA; if (xf86configptr == NULL) /* X -configure */ return SNA; dev = _xf86findDriver("intel", xf86configptr->conf_device_lst); if (dev && dev->dev_option_lst) { const char *s; s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod"); if (s ) { if (strcasecmp(s, "none") == 0) accel_method = NOACCEL; else if (strcasecmp(s, "sna") == 0) accel_method = SNA; else if (strcasecmp(s, "uxa") == 0) accel_method = UXA; } } return accel_method; } #endif static Bool intel_scrn_create(DriverPtr driver, int entity_num, intptr_t match_data, unsigned flags) { ScrnInfoPtr scrn; if (match_data == 0) { int devid = intel_entity_get_devid(entity_num), i; if (devid == 0) return FALSE; for (i = 0; intel_device_match[i].device_id != 0; i++) { if (devid == intel_device_match[i].device_id) { match_data = (intptr_t)&intel_device_match[i]; break; } } if (match_data == 0) return FALSE; } scrn = xf86AllocateScreen(driver, flags); if (scrn == NULL) return FALSE; scrn->driverVersion = INTEL_VERSION; scrn->driverName = (char *)INTEL_DRIVER_NAME; scrn->name = (char *)INTEL_NAME; scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2); scrn->Probe = NULL; if (xf86IsEntitySharable(entity_num)) xf86SetEntityShared(entity_num); xf86AddEntityToScreen(scrn, entity_num); #if UMS if ((unsigned)((struct intel_device_info *)match_data)->gen < 020) return lg_i810_init(scrn); #endif #if KMS switch (get_accel_method()) { #if USE_SNA case NOACCEL: case SNA: return sna_init_scrn(scrn, entity_num); #endif #if USE_UXA #if !USE_SNA case NOACCEL: #endif case UXA: return intel_init_scrn(scrn); #endif default: #if USE_SNA return sna_init_scrn(scrn, entity_num); #elif USE_UXA return intel_init_scrn(scrn); #else break; #endif } #endif return FALSE; } /* * intel_pci_probe -- * * Look through the PCI bus to find cards that are intel boards. * Setup the dispatch table for the rest of the driver functions. * */ static Bool intel_pci_probe(DriverPtr driver, int entity_num, struct pci_device *pci, intptr_t match_data) { if (intel_open_device(entity_num, pci, NULL) == -1) { #if UMS switch (pci->device_id) { case PCI_CHIP_I810: case PCI_CHIP_I810_DC100: case PCI_CHIP_I810_E: case PCI_CHIP_I815: if (!hosted()) break; default: return FALSE; } #else return FALSE; #endif } return intel_scrn_create(driver, entity_num, match_data, 0); } #ifdef XSERVER_PLATFORM_BUS static Bool intel_platform_probe(DriverPtr driver, int entity_num, int flags, struct xf86_platform_device *dev, intptr_t match_data) { unsigned scrn_flags = 0; if (intel_open_device(entity_num, dev->pdev, dev) == -1) return FALSE; /* Allow ourselves to act as a slaved output if not primary */ if (flags & PLATFORM_PROBE_GPU_SCREEN) { flags &= ~PLATFORM_PROBE_GPU_SCREEN; scrn_flags |= XF86_ALLOCATE_GPU_SCREEN; } /* if we get any flags we don't understand fail to probe for now */ if (flags) return FALSE; return intel_scrn_create(driver, entity_num, match_data, scrn_flags); } #endif #ifdef XFree86LOADER static MODULESETUPPROTO(intel_setup); static XF86ModuleVersionInfo intel_version = { "intel", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XORG_VERSION_CURRENT, INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH, ABI_CLASS_VIDEODRV, ABI_VIDEODRV_VERSION, MOD_CLASS_VIDEODRV, {0, 0, 0, 0} }; static const OptionInfoRec * intel_available_options(int chipid, int busid) { switch (chipid) { #if UMS case PCI_CHIP_I810: case PCI_CHIP_I810_DC100: case PCI_CHIP_I810_E: case PCI_CHIP_I815: return lg_i810_available_options(chipid, busid); #endif default: return intel_options; } } static DriverRec intel = { INTEL_VERSION, (char *)INTEL_DRIVER_NAME, intel_identify, NULL, intel_available_options, NULL, 0, intel_driver_func, intel_device_match, intel_pci_probe, #ifdef XSERVER_PLATFORM_BUS intel_platform_probe #endif }; static pointer intel_setup(pointer module, pointer opts, int *errmaj, int *errmin) { static Bool setupDone = 0; /* This module should be loaded only once, but check to be sure. */ if (!setupDone) { setupDone = 1; xf86AddDriver(&intel, module, HaveDriverFuncs); /* * The return value must be non-NULL on success even though there * is no TearDownProc. */ return (pointer) 1; } else { if (errmaj) *errmaj = LDR_ONCEONLY; return NULL; } } _X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL }; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/intel_options.c000066400000000000000000000072671267532330400241300ustar00rootroot00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "intel_options.h" const OptionInfoRec intel_options[] = { {OPTION_ACCEL_ENABLE, "Accel", OPTV_BOOLEAN, {0}, 0}, {OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, 0}, {OPTION_BACKLIGHT, "Backlight", OPTV_STRING, {0}, 0}, {OPTION_EDID, "CustomEDID", OPTV_STRING, {0}, 0}, {OPTION_DRI, "DRI", OPTV_STRING, {0}, 0}, {OPTION_PRESENT, "Present", OPTV_BOOLEAN, {0}, 1}, {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, 0}, {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, 0}, {OPTION_TILING_2D, "Tiling", OPTV_BOOLEAN, {0}, 1}, {OPTION_TILING_FB, "LinearFramebuffer", OPTV_BOOLEAN, {0}, 0}, {OPTION_ROTATION, "HWRotation", OPTV_BOOLEAN, {0}, 1}, {OPTION_VSYNC, "VSync", OPTV_BOOLEAN, {0}, 1}, {OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, 1}, {OPTION_SWAPBUFFERS_WAIT, "SwapbuffersWait", OPTV_BOOLEAN, {0}, 1}, {OPTION_TRIPLE_BUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, 1}, {OPTION_PREFER_OVERLAY, "XvPreferOverlay", OPTV_BOOLEAN, {0}, 0}, {OPTION_HOTPLUG, "HotPlug", OPTV_BOOLEAN, {0}, 1}, {OPTION_REPROBE, "ReprobeOutputs", OPTV_BOOLEAN, {0}, 0}, #ifdef INTEL_XVMC {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, 1}, #endif #ifdef USE_SNA {OPTION_ZAPHOD, "ZaphodHeads", OPTV_STRING, {0}, 0}, {OPTION_VIRTUAL, "VirtualHeads", OPTV_INTEGER, {0}, 0}, {OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, 0}, {OPTION_CRTC_PIXMAPS, "PerCrtcPixmaps", OPTV_BOOLEAN, {0}, 0}, #endif #ifdef USE_UXA {OPTION_FALLBACKDEBUG, "FallbackDebug",OPTV_BOOLEAN, {0}, 0}, {OPTION_DEBUG_FLUSH_BATCHES, "DebugFlushBatches", OPTV_BOOLEAN, {0}, 0}, {OPTION_DEBUG_FLUSH_CACHES, "DebugFlushCaches", OPTV_BOOLEAN, {0}, 0}, {OPTION_DEBUG_WAIT, "DebugWait", OPTV_BOOLEAN, {0}, 0}, {OPTION_BUFFER_CACHE, "BufferCache", OPTV_BOOLEAN, {0}, 1}, #endif {-1, NULL, OPTV_NONE, {0}, 0} }; OptionInfoPtr intel_options_get(ScrnInfoPtr scrn) { OptionInfoPtr options; xf86CollectOptions(scrn, NULL); if (!(options = malloc(sizeof(intel_options)))) return NULL; memcpy(options, intel_options, sizeof(intel_options)); xf86ProcessOptions(scrn->scrnIndex, scrn->options, options); return options; } Bool intel_option_cast_to_bool(OptionInfoPtr options, int id, Bool val) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) xf86getBoolValue(&val, xf86GetOptValString(options, id)); #endif return val; } static int namecmp(const char *s1, const char *s2) { char c1, c2; if (!s1 || *s1 == 0) { if (!s2 || *s2 == 0) return 0; else return 1; } while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; while (c1 == c2) { if (c1 == '\0') return 0; s1++; while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; s2++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; } return c1 - c2; } unsigned intel_option_cast_to_unsigned(OptionInfoPtr options, int id, unsigned val) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) const char *str = xf86GetOptValString(options, id); #else const char *str = NULL; #endif unsigned v; if (str == NULL || *str == '\0') return val; if (namecmp(str, "on") == 0) return val; if (namecmp(str, "true") == 0) return val; if (namecmp(str, "yes") == 0) return val; if (namecmp(str, "0") == 0) return 0; if (namecmp(str, "off") == 0) return 0; if (namecmp(str, "false") == 0) return 0; if (namecmp(str, "no") == 0) return 0; v = atoi(str); if (v) return v; return val; } xserver-xorg-video-intel-2.99.917+git20160325/src/intel_options.h000066400000000000000000000024511267532330400241230ustar00rootroot00000000000000#ifndef INTEL_OPTIONS_H #define INTEL_OPTIONS_H #include #include #include /* * Note: "ColorKey" is provided for compatibility with the i810 driver. * However, the correct option name is "VideoKey". "ColorKey" usually * refers to the tranparency key for 8+24 overlays, not for video overlays. */ enum intel_options { OPTION_ACCEL_ENABLE, OPTION_ACCEL_METHOD, OPTION_BACKLIGHT, OPTION_EDID, OPTION_DRI, OPTION_PRESENT, OPTION_VIDEO_KEY, OPTION_COLOR_KEY, OPTION_TILING_2D, OPTION_TILING_FB, OPTION_ROTATION, OPTION_VSYNC, OPTION_PAGEFLIP, OPTION_SWAPBUFFERS_WAIT, OPTION_TRIPLE_BUFFER, OPTION_PREFER_OVERLAY, OPTION_HOTPLUG, OPTION_REPROBE, #if defined(XvMCExtension) && defined(ENABLE_XVMC) OPTION_XVMC, #define INTEL_XVMC 1 #endif #ifdef USE_SNA OPTION_ZAPHOD, OPTION_VIRTUAL, OPTION_TEAR_FREE, OPTION_CRTC_PIXMAPS, #endif #ifdef USE_UXA OPTION_FALLBACKDEBUG, OPTION_DEBUG_FLUSH_BATCHES, OPTION_DEBUG_FLUSH_CACHES, OPTION_DEBUG_WAIT, OPTION_BUFFER_CACHE, #endif NUM_OPTIONS, }; extern const OptionInfoRec intel_options[]; OptionInfoPtr intel_options_get(ScrnInfoPtr scrn); unsigned intel_option_cast_to_unsigned(OptionInfoPtr, int id, unsigned val); Bool intel_option_cast_to_bool(OptionInfoPtr, int id, Bool val); #endif /* INTEL_OPTIONS_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/000077500000000000000000000000001267532330400223265ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/Makefile.am000066400000000000000000000004031267532330400243570ustar00rootroot00000000000000SUBDIRS = noinst_LTLIBRARIES = liblegacy.la NULL:=# liblegacy_la_SOURCES = legacy.h liblegacy_la_LIBADD = if UMS SUBDIRS += i810 liblegacy_la_SOURCES += liblegacy_la_LIBADD += \ i810/liblegacy-i810.la \ $(NULL) endif EXTRA_DIST = README xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/README000066400000000000000000000004711267532330400232100ustar00rootroot00000000000000Welcome to the attic! The code contained herein is no longer under active development and is not the target for new features or other improvements. Instead, we have placed it here to mature gracefully and still provide hardware compatibility for those antiquated devices that turn up when you least expect them. xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/000077500000000000000000000000001267532330400230075ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/Makefile.am000066400000000000000000000014361267532330400250470ustar00rootroot00000000000000SUBDIRS = xvmc noinst_LTLIBRARIES = liblegacy-i810.la AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/legacy \ $(NULL) liblegacy_i810_la_SOURCES = \ i810_accel.c \ i810_common.h \ i810_cursor.c \ i810_driver.c \ i810.h \ i810_memory.c \ i810_reg.h \ i810_ring.h \ i810_video.c \ i810_wmark.c if XAA liblegacy_i810_la_SOURCES += \ i810_xaa.c endif if DGA liblegacy_i810_la_SOURCES += \ i810_dga.c endif if DRI1 liblegacy_i810_la_SOURCES +=\ i810_dri.c \ i810_dri.h \ $(NULL) AM_CFLAGS += $(DRI1_CFLAGS) if XVMC liblegacy_i810_la_SOURCES += \ i810_hwmc.c \ $(NULL) endif endif xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810.h000066400000000000000000000211511267532330400236410ustar00rootroot00000000000000 /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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: * Keith Whitwell * David Dawes * */ #ifndef _I810_H_ #define _I810_H_ #include #include "compiler.h" #include "xf86Pci.h" #include "i810_reg.h" #ifdef HAVE_XAA_H #include "xaa.h" #endif #include "xf86Cursor.h" #include "xf86xv.h" #include "vbe.h" #include "vgaHW.h" #include "xorg-server.h" #include #include "compat-api.h" #ifdef HAVE_DRI1 #include "xf86drm.h" #include "sarea.h" #define _XF86DRI_SERVER_ #include "dri.h" #include "i810_dri.h" #endif #include "i810_common.h" #include "i810_ring.h" #include "intel_driver.h" /* HWMC Surfaces */ #define I810_MAX_SURFACES 7 #define I810_MAX_SUBPICTURES 2 #define I810_TOTAL_SURFACES 9 /* Globals */ typedef struct _I810Rec *I810Ptr; extern void I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned start, unsigned pitch, unsigned size); typedef struct { unsigned long Start; unsigned long End; unsigned long Size; } I810MemRange; typedef struct { int tail_mask; I810MemRange mem; unsigned char *virtual_start; int head; int tail; int space; } I810RingBuffer; typedef struct { unsigned char DisplayControl; unsigned char PixelPipeCfg0; unsigned char PixelPipeCfg1; unsigned char PixelPipeCfg2; unsigned short VideoClk2_M; unsigned short VideoClk2_N; unsigned char VideoClk2_DivisorSel; unsigned char AddressMapping; unsigned char IOControl; unsigned char BitBLTControl; unsigned char ExtVertTotal; unsigned char ExtVertDispEnd; unsigned char ExtVertSyncStart; unsigned char ExtVertBlankStart; unsigned char ExtHorizTotal; unsigned char ExtHorizBlank; unsigned char ExtOffset; unsigned char InterlaceControl; unsigned int LMI_FIFO_Watermark; unsigned int LprbTail; unsigned int LprbHead; unsigned int LprbStart; unsigned int LprbLen; unsigned int Fence[8]; unsigned short OverlayActiveStart; unsigned short OverlayActiveEnd; } I810RegRec, *I810RegPtr; typedef struct _I810Rec { unsigned char *MMIOBase; unsigned char *FbBase; long FbMapSize; long DepthOffset; long BackOffset; int cpp; int MaxClock; unsigned int bufferOffset; /* for I810SelectBuffer */ Bool DoneFrontAlloc; BoxRec FbMemBox; I810MemRange FrontBuffer; I810MemRange BackBuffer; I810MemRange DepthBuffer; I810MemRange TexMem; I810MemRange Scratch; I810MemRange BufferMem; I810MemRange ContextMem; I810MemRange MC; int auxPitch; int auxPitchBits; Bool CursorIsARGB; int CursorOffset; unsigned long CursorPhysical; unsigned long CursorStart; int CursorARGBOffset; unsigned long CursorARGBPhysical; unsigned long CursorARGBStart; unsigned long OverlayPhysical; unsigned long OverlayStart; int colorKey; unsigned int surfaceAllocation[I810_TOTAL_SURFACES]; int numSurfaces; DGAModePtr DGAModes; int numDGAModes; Bool DGAactive; int DGAViewportStatus; int Chipset; unsigned long LinearAddr; unsigned long MMIOAddr; EntityInfoPtr pEnt; struct pci_device *PciInfo; I810RingBuffer *LpRing; unsigned int BR[20]; int LmFreqSel; int VramKey; unsigned long VramOffset; int DcacheKey; unsigned long DcacheOffset; int HwcursKey; unsigned long HwcursOffset; int ARGBHwcursKey; unsigned long ARGBHwcursOffset; int GttBound; I810MemRange DcacheMem; I810MemRange SysMem; I810MemRange SavedDcacheMem; I810MemRange SavedSysMem; unsigned char **ScanlineColorExpandBuffers; int NumScanlineColorExpandBuffers; int nextColorExpandBuf; I810RegRec SavedReg; I810RegRec ModeReg; #ifdef HAVE_XAA_H XAAInfoRecPtr AccelInfoRec; #endif xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; ScreenBlockHandlerProcPtr BlockHandler; Bool directRenderingDisabled; /* DRI disabled in PreInit */ Bool directRenderingEnabled; /* false if XF86DRI not defined. */ #ifdef HAVE_DRI1 int LockHeld; DRIInfoPtr pDRIInfo; int drmSubFD; int numVisualConfigs; unsigned long dcacheHandle; unsigned long backHandle; unsigned long zHandle; unsigned long cursorHandle; unsigned long cursorARGBHandle; unsigned long xvmcHandle; unsigned long sysmemHandle; Bool agpAcquired; drm_handle_t buffer_map; drm_handle_t ring_map; drm_handle_t overlay_map; drm_handle_t mc_map; drm_handle_t xvmcContext; #endif Bool agpAcquired2d; XF86VideoAdaptorPtr adaptor; OptionInfoPtr Options; int configured_device; Bool showCache; Bool noAccel; Bool allowPageFlip; Bool have3DWindows; int drmMinor; } I810Rec; #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) #define I810_SELECT_FRONT 0 #define I810_SELECT_BACK 1 #define I810_SELECT_DEPTH 2 #ifdef HAVE_DRI1 extern Bool I810DRIScreenInit(ScreenPtr pScreen); extern void I810DRICloseScreen(ScreenPtr pScreen); extern Bool I810DRIFinishScreenInit(ScreenPtr pScreen); extern Bool I810DRILeave(ScrnInfoPtr pScrn); extern Bool I810DRIEnter(ScrnInfoPtr pScrn); #endif extern Bool I810InitDma(ScrnInfoPtr pScrn); extern Bool I810CleanupDma(ScrnInfoPtr pScrn); #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) #define I810REGPTR(p) (&(I810PTR(p)->ModeReg)) extern Bool I810CursorInit(ScreenPtr pScreen); #ifdef HAVE_XAA_H extern Bool I810AccelInit(ScreenPtr pScreen); #else static inline Bool I810AccelInit(ScreenPtr pScreen) { return TRUE; } #endif extern void I810SetPIOAccess(I810Ptr pI810); extern void I810SetMMIOAccess(I810Ptr pI810); extern unsigned int I810CalcWatermark(ScrnInfoPtr pScrn, double freq, Bool dcache); extern void I810PrintErrorState(ScrnInfoPtr pScrn); extern int I810WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis); extern void I810Sync(ScrnInfoPtr pScrn); extern unsigned long I810LocalToPhysical(ScrnInfoPtr pScrn, unsigned long local); extern int I810AllocLow(I810MemRange * result, I810MemRange * pool, int size); extern int I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size); extern Bool I810AllocateFront(ScrnInfoPtr pScrn); extern int I810AllocateGARTMemory(ScrnInfoPtr pScrn); extern void I810FreeGARTMemory(ScrnInfoPtr pScrn); extern Bool I810BindGARTMemory(ScrnInfoPtr pScrn); extern Bool I810UnbindGARTMemory(ScrnInfoPtr pScrn); extern int I810CheckAvailableMemory(ScrnInfoPtr pScrn); extern Bool I810SwitchMode(SWITCH_MODE_ARGS_DECL); extern void I810AdjustFrame(ADJUST_FRAME_ARGS_DECL); extern void I810SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int trans_color); extern void I810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY, int dstX, int dstY, int w, int h); extern void I810SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); extern void I810SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); extern void I810SelectBuffer(ScrnInfoPtr pScrn, int buffer); extern void I810RefreshRing(ScrnInfoPtr pScrn); extern void I810EmitFlush(ScrnInfoPtr pScrn); extern Bool I810DGAInit(ScreenPtr pScreen); extern void I810InitVideo(ScreenPtr pScreen); extern void I810InitMC(ScreenPtr pScreen); extern const OptionInfoRec *I810AvailableOptions(int chipid, int busid); extern const int I810CopyROP[16]; const int I810PatternROP[16]; #endif /* _I810_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_accel.c000066400000000000000000000220411267532330400247620ustar00rootroot00000000000000 /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * Authors: * Keith Whitwell * */ #include "xorg-server.h" #include "xf86.h" #include "xaarop.h" #include "i810.h" const int I810CopyROP[16] = { ROP_0, /* GXclear */ ROP_DSa, /* GXand */ ROP_SDna, /* GXandReverse */ ROP_S, /* GXcopy */ ROP_DSna, /* GXandInverted */ ROP_D, /* GXnoop */ ROP_DSx, /* GXxor */ ROP_DSo, /* GXor */ ROP_DSon, /* GXnor */ ROP_DSxn, /* GXequiv */ ROP_Dn, /* GXinvert */ ROP_SDno, /* GXorReverse */ ROP_Sn, /* GXcopyInverted */ ROP_DSno, /* GXorInverted */ ROP_DSan, /* GXnand */ ROP_1 /* GXset */ }; const int I810PatternROP[16] = { ROP_0, ROP_DPa, ROP_PDna, ROP_P, ROP_DPna, ROP_D, ROP_DPx, ROP_DPo, ROP_DPon, ROP_PDxn, ROP_Dn, ROP_PDno, ROP_Pn, ROP_DPno, ROP_DPan, ROP_1 }; int I810WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) { I810Ptr pI810 = I810PTR(pScrn); I810RingBuffer *ring = pI810->LpRing; int iters = 0; int start = 0; int now = 0; int last_head = 0; int first = 0; /* If your system hasn't moved the head pointer in 2 seconds, I'm going to * call it crashed. */ if (timeout_millis == 0) timeout_millis = 2000; if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { ErrorF("I810WaitLpRing %d\n", n); first = GetTimeInMillis(); } while (ring->space < n) { ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->mem.Size; iters++; now = GetTimeInMillis(); if (start == 0 || now < start || ring->head != last_head) { if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) if (now > start) ErrorF("space: %d wanted %d\n", ring->space, n); start = now; last_head = ring->head; } else if (now - start > timeout_millis) { ErrorF("Error in I810WaitLpRing(), now is %d, start is %d\n", now, start); I810PrintErrorState(pScrn); ErrorF("space: %d wanted %d\n", ring->space, n); #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { DRIUnlock(xf86ScrnToScreen(pScrn)); DRICloseScreen(xf86ScrnToScreen(pScrn)); } #endif #if HAVE_XAA_H pI810->AccelInfoRec = NULL; /* Stops recursive behavior */ #endif FatalError("lockup\n"); } DELAY(10000); } if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { now = GetTimeInMillis(); if (now - first) { ErrorF("Elapsed %d ms\n", now - first); ErrorF("space: %d wanted %d\n", ring->space, n); } } return iters; } void I810Sync(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC)) ErrorF("I810Sync\n"); #ifdef HAVE_DRI1 /* VT switching tries to do this. */ if (!pI810->LockHeld && pI810->directRenderingEnabled) { return; } #endif /* Send a flush instruction and then wait till the ring is empty. * This is stronger than waiting for the blitter to finish as it also * flushes the internal graphics caches. */ { BEGIN_LP_RING(2); OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); OUT_RING(0); /* pad to quadword */ ADVANCE_LP_RING(); } I810WaitLpRing(pScrn, pI810->LpRing->mem.Size - 8, 0); pI810->LpRing->space = pI810->LpRing->mem.Size - 8; pI810->nextColorExpandBuf = 0; } void I810SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SetupForFillRectSolid color: %x rop: %x mask: %x\n", color, rop, planemask); /* Color blit, p166 */ pI810->BR[13] = (BR13_SOLID_PATTERN | (I810PatternROP[rop] << 16) | (pScrn->displayWidth * pI810->cpp)); pI810->BR[16] = color; } void I810SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h); { BEGIN_LP_RING(6); OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); OUT_RING(pI810->BR[13]); OUT_RING((h << 16) | (w * pI810->cpp)); OUT_RING(pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp); OUT_RING(pI810->BR[16]); OUT_RING(0); /* pad to quadword */ ADVANCE_LP_RING(); } } void I810SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SetupForScreenToScreenCopy %d %d %x %x %d\n", xdir, ydir, rop, planemask, transparency_color); pI810->BR[13] = (pScrn->displayWidth * pI810->cpp); if (ydir == -1) pI810->BR[13] = (-pI810->BR[13]) & 0xFFFF; if (xdir == -1) pI810->BR[13] |= BR13_RIGHT_TO_LEFT; pI810->BR[13] |= I810CopyROP[rop] << 16; pI810->BR[18] = 0; } void I810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { I810Ptr pI810 = I810PTR(pScrn); int src, dst; int w_back = w; if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF( "I810SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n", x1,y1,x2,y2,w,h); /* * This works around a bug in the i810 drawing engine. * This was developed empirically so it may not catch all * cases. */ #define I810_MWIDTH 8 if ( !(pI810->BR[13] & BR13_RIGHT_TO_LEFT) && (y2 - y1) < 3 && (y2 - y1) >= 0 && (x2 - x1) <= (w + I810_MWIDTH) && (w > I810_MWIDTH)) w = I810_MWIDTH; do { if (pI810->BR[13] & BR13_PITCH_SIGN_BIT) { src = (y1 + h - 1) * pScrn->displayWidth * pI810->cpp; dst = (y2 + h - 1) * pScrn->displayWidth * pI810->cpp; } else { src = y1 * pScrn->displayWidth * pI810->cpp; dst = y2 * pScrn->displayWidth * pI810->cpp; } if (pI810->BR[13] & BR13_RIGHT_TO_LEFT) { src += (x1 + w - 1) * pI810->cpp + pI810->cpp - 1; dst += (x2 + w - 1) * pI810->cpp + pI810->cpp - 1; } else { src += x1 * pI810->cpp; dst += x2 * pI810->cpp; } /* SRC_COPY_BLT, p169 */ { BEGIN_LP_RING(6); OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); OUT_RING( pI810->BR[13]); OUT_RING( (h << 16) | (w * pI810->cpp)); OUT_RING( pI810->bufferOffset + dst); OUT_RING( pI810->BR[13] & 0xFFFF); OUT_RING( pI810->bufferOffset + src); ADVANCE_LP_RING(); } w_back -= w; if (w_back <= 0) break; x2 += w; x1 += w; if (w_back > I810_MWIDTH) w = I810_MWIDTH; else w = w_back; } while (1); } void I810EmitFlush(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); BEGIN_LP_RING(2); OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); OUT_RING(0); ADVANCE_LP_RING(); } void I810SelectBuffer(ScrnInfoPtr pScrn, int buffer) { I810Ptr pI810 = I810PTR(pScrn); switch (buffer) { case I810_SELECT_BACK: pI810->bufferOffset = pI810->BackBuffer.Start; break; case I810_SELECT_DEPTH: pI810->bufferOffset = pI810->DepthBuffer.Start; break; default: case I810_SELECT_FRONT: pI810->bufferOffset = pI810->FrontBuffer.Start; break; } if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SelectBuffer %d --> offset %x\n", buffer, pI810->bufferOffset); } void I810RefreshRing(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); pI810->LpRing->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR; pI810->LpRing->tail = INREG(LP_RING + RING_TAIL); pI810->LpRing->space = pI810->LpRing->head - (pI810->LpRing->tail + 8); if (pI810->LpRing->space < 0) pI810->LpRing->space += pI810->LpRing->mem.Size; #if HAVE_XAA_H if (pI810->AccelInfoRec) pI810->AccelInfoRec->NeedToSync = TRUE; #endif } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_common.h000066400000000000000000000237251267532330400252220ustar00rootroot00000000000000/* i810_common.h -- common header definitions for I810 2D/3D/DRM suite * * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 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. * * Converted to common header format: * Jens Owen * * */ /* WARNING: If you change any of these defines, make sure to change * the kernel include file as well (i810_drm.h) */ #ifndef _I810_COMMON_H_ #define _I810_COMMON_H_ /* Provide substitutes for gcc's __FUNCTION__ on other compilers */ #if !defined(__GNUC__) && !defined(__FUNCTION__) # if defined(__STDC__) && (__STDC_VERSION__>=199901L) /* C99 */ # define __FUNCTION__ __func__ # else # define __FUNCTION__ "" # endif #endif #define PFX __FILE__,__LINE__,__FUNCTION__ #define FUNCTION_NAME __FUNCTION__ #define KB(x) ((x) * 1024) #define MB(x) ((x) * KB(1024)) #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) /* Using usleep() makes things noticeably slow. */ #if 0 #define DELAY(x) usleep(x) #else #define DELAY(x) do {;} while (0) #endif #define PrintErrorState I810PrintErrorState #define WaitRingFunc I810WaitLpRing #define RecPtr pI810 static inline void memset_volatile(volatile void *b, int c, size_t len) { unsigned i; for (i = 0; i < len; i++) ((volatile char *)b)[i] = c; } static inline void memcpy_volatile(volatile void *dst, const void *src, size_t len) { unsigned i; for (i = 0; i < len; i++) ((volatile char *)dst)[i] = ((const volatile char *)src)[i]; } /* Memory mapped register access macros */ #define INREG8(addr) *(volatile uint8_t *)(RecPtr->MMIOBase + (addr)) #define INREG16(addr) *(volatile uint16_t *)(RecPtr->MMIOBase + (addr)) #define INREG(addr) *(volatile uint32_t *)(RecPtr->MMIOBase + (addr)) #define INGTT(addr) *(volatile uint32_t *)(RecPtr->GTTBase + (addr)) #define POSTING_READ(addr) (void)INREG(addr) #define OUTREG8(addr, val) do { \ *(volatile uint8_t *)(RecPtr->MMIOBase + (addr)) = (val); \ if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \ ErrorF("OUTREG8(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \ (unsigned long)(val), FUNCTION_NAME); \ } \ } while (0) #define OUTREG16(addr, val) do { \ *(volatile uint16_t *)(RecPtr->MMIOBase + (addr)) = (val); \ if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \ ErrorF("OUTREG16(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \ (unsigned long)(val), FUNCTION_NAME); \ } \ } while (0) #define OUTREG(addr, val) do { \ *(volatile uint32_t *)(RecPtr->MMIOBase + (addr)) = (val); \ if (I810_DEBUG&DEBUG_VERBOSE_OUTREG) { \ ErrorF("OUTREG(0x%lx, 0x%lx) in %s\n", (unsigned long)(addr), \ (unsigned long)(val), FUNCTION_NAME); \ } \ } while (0) /* To remove all debugging, make sure I810_DEBUG is defined as a * preprocessor symbol, and equal to zero. */ #if 1 #define I810_DEBUG 0 #endif #ifndef I810_DEBUG #warning "Debugging enabled - expect reduced performance" extern int I810_DEBUG; #endif #define DEBUG_VERBOSE_ACCEL 0x1 #define DEBUG_VERBOSE_SYNC 0x2 #define DEBUG_VERBOSE_VGA 0x4 #define DEBUG_VERBOSE_RING 0x8 #define DEBUG_VERBOSE_OUTREG 0x10 #define DEBUG_VERBOSE_MEMORY 0x20 #define DEBUG_VERBOSE_CURSOR 0x40 #define DEBUG_ALWAYS_SYNC 0x80 #define DEBUG_VERBOSE_DRI 0x100 #define DEBUG_VERBOSE_BIOS 0x200 /* Size of the mmio region. */ #define I810_REG_SIZE 0x80000 #define GTT_PAGE_SIZE KB(4) #define PRIMARY_RINGBUFFER_SIZE KB(128) #define MIN_SCRATCH_BUFFER_SIZE KB(16) #define MAX_SCRATCH_BUFFER_SIZE KB(64) #define HWCURSOR_SIZE GTT_PAGE_SIZE #define HWCURSOR_SIZE_ARGB GTT_PAGE_SIZE * 4 /* Use a 64x64 HW cursor */ #define I810_CURSOR_X 64 #define I810_CURSOR_Y I810_CURSOR_X #define PIPE_NAME(n) ('A' + (n)) extern struct pci_device * intel_host_bridge (void); /** * Hints to CreatePixmap to tell the driver how the pixmap is going to be * used. * * Compare to CREATE_PIXMAP_USAGE_* in the server. */ enum { INTEL_CREATE_PIXMAP_TILING_X = 0x10000000, INTEL_CREATE_PIXMAP_TILING_Y, INTEL_CREATE_PIXMAP_TILING_NONE, }; #ifndef _I810_DEFINES_ #define _I810_DEFINES_ #define I810_USE_BATCH 1 #define I810_DMA_BUF_ORDER 12 #define I810_DMA_BUF_SZ (1< * * Add ARGB HW cursor support: * Alan Hourihane * */ #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86fbman.h" #include "i810.h" static Bool I810UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); static void I810LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); static void I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); static void I810ShowCursor(ScrnInfoPtr pScrn); static void I810HideCursor(ScrnInfoPtr pScrn); static void I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); static void I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); static Bool I810UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); Bool I810CursorInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn; I810Ptr pI810; xf86CursorInfoPtr infoPtr; pScrn = xf86ScreenToScrn(pScreen); pI810 = I810PTR(pScrn); pI810->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); if (!infoPtr) return FALSE; infoPtr->MaxWidth = 64; infoPtr->MaxHeight = 64; infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_INVERT_MASK | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 0); infoPtr->SetCursorColors = I810SetCursorColors; infoPtr->SetCursorPosition = I810SetCursorPosition; infoPtr->LoadCursorImage = I810LoadCursorImage; infoPtr->HideCursor = I810HideCursor; infoPtr->ShowCursor = I810ShowCursor; infoPtr->UseHWCursor = I810UseHWCursor; #ifdef ARGB_CURSOR pI810->CursorIsARGB = FALSE; if (!pI810->CursorARGBPhysical) { infoPtr->UseHWCursorARGB = I810UseHWCursorARGB; infoPtr->LoadCursorARGB = I810LoadCursorARGB; } #endif return xf86InitCursor(pScreen, infoPtr); } #ifdef ARGB_CURSOR #include "cursorstr.h" static Bool I810UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); if (!pI810->CursorARGBPhysical) return FALSE; if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64) return TRUE; return FALSE; } static void I810LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) { I810Ptr pI810 = I810PTR(pScrn); uint32_t *pcurs = (uint32_t *) (pI810->FbBase + pI810->CursorStart); uint32_t *image = (uint32_t *) pCurs->bits->argb; int x, y, w, h; #ifdef ARGB_CURSOR pI810->CursorIsARGB = TRUE; #endif w = pCurs->bits->width; h = pCurs->bits->height; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) *pcurs++ = *image++; for (; x < 64; x++) *pcurs++ = 0; } for (; y < 64; y++) for (x = 0; x < 64; x++) *pcurs++ = 0; } #endif static Bool I810UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); if (!pI810->CursorPhysical) return FALSE; else return TRUE; } static void I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { I810Ptr pI810 = I810PTR(pScrn); uint8_t *pcurs = (uint8_t *) (pI810->FbBase + pI810->CursorStart); int x, y; #ifdef ARGB_CURSOR pI810->CursorIsARGB = FALSE; #endif for (y = 0; y < 64; y++) { for (x = 0; x < 64 / 4; x++) { *pcurs++ = *src++; } } } static void I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { I810Ptr pI810 = I810PTR(pScrn); int flag; x += pI810->CursorOffset; if (x >= 0) flag = CURSOR_X_POS; else { flag = CURSOR_X_NEG; x = -x; } OUTREG8(CURSOR_X_LO, x & 0xFF); OUTREG8(CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); if (y >= 0) flag = CURSOR_Y_POS; else { flag = CURSOR_Y_NEG; y = -y; } OUTREG8(CURSOR_Y_LO, y & 0xFF); OUTREG8(CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); if (pI810->CursorIsARGB) OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical); else OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical); } static void I810ShowCursor(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); unsigned char tmp; if (pI810->CursorIsARGB) { OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical); OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_ARGB_AX); } else { OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical); OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); } tmp = INREG8(PIXPIPE_CONFIG_0); tmp |= HW_CURSOR_ENABLE; OUTREG8(PIXPIPE_CONFIG_0, tmp); } static void I810HideCursor(ScrnInfoPtr pScrn) { unsigned char tmp; I810Ptr pI810 = I810PTR(pScrn); tmp = INREG8(PIXPIPE_CONFIG_0); tmp &= ~HW_CURSOR_ENABLE; OUTREG8(PIXPIPE_CONFIG_0, tmp); } static void I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { int tmp; I810Ptr pI810 = I810PTR(pScrn); vgaHWPtr hwp; #ifdef ARGB_CURSOR if (pI810->CursorIsARGB) return; #endif hwp = VGAHWPTR(pScrn); tmp = INREG8(PIXPIPE_CONFIG_0); tmp |= EXTENDED_PALETTE; OUTREG8(PIXPIPE_CONFIG_0, tmp); hwp->writeDacMask(hwp, 0xFF); hwp->writeDacWriteAddr(hwp, 0x04); hwp->writeDacData(hwp, (bg & 0x00FF0000) >> 16); hwp->writeDacData(hwp, (bg & 0x0000FF00) >> 8); hwp->writeDacData(hwp, (bg & 0x000000FF)); hwp->writeDacData(hwp, (fg & 0x00FF0000) >> 16); hwp->writeDacData(hwp, (fg & 0x0000FF00) >> 8); hwp->writeDacData(hwp, (fg & 0x000000FF)); tmp = INREG8(PIXPIPE_CONFIG_0); tmp &= ~EXTENDED_PALETTE; OUTREG8(PIXPIPE_CONFIG_0, tmp); } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_dga.c000066400000000000000000000165351267532330400244610ustar00rootroot00000000000000/* * Copyright 2000 by Alan Hourihane, Sychdyn, North Wales, UK. * * 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, and that the name of Alan Hourihane not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Alan Hourihane makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "i810.h" #include "i810_reg.h" #include "dgaproc.h" #include "vgaHW.h" static Bool I810_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, int *, int *, int *); static Bool I810_SetMode(ScrnInfoPtr, DGAModePtr); static int I810_GetViewport(ScrnInfoPtr); static void I810_SetViewport(ScrnInfoPtr, int, int, int); #ifdef HAVE_XAA_H static void I810_Sync(ScrnInfoPtr); static void I810_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); static void I810_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); #endif #if 0 static void I810_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, unsigned long); #endif static DGAFunctionRec I810DGAFuncs = { I810_OpenFramebuffer, NULL, I810_SetMode, I810_SetViewport, I810_GetViewport, #ifdef HAVE_XAA_H I810_Sync, I810_FillRect, I810_BlitRect, #else NULL, NULL, NULL, #endif #if 0 I810_BlitTransRect #else NULL #endif }; Bool I810DGAInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); DGAModePtr modes = NULL, newmodes = NULL, currentMode; DisplayModePtr pMode, firstMode; int Bpp = pScrn->bitsPerPixel >> 3; int num = 0; pMode = firstMode = pScrn->modes; while (pMode) { newmodes = realloc(modes, (num + 1) * sizeof(DGAModeRec)); if (!newmodes) { free(modes); return FALSE; } modes = newmodes; currentMode = modes + num; num++; currentMode->mode = pMode; currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; if (!pI810->noAccel) currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; if (pMode->Flags & V_DBLSCAN) currentMode->flags |= DGA_DOUBLESCAN; if (pMode->Flags & V_INTERLACE) currentMode->flags |= DGA_INTERLACED; currentMode->byteOrder = pScrn->imageByteOrder; currentMode->depth = pScrn->depth; currentMode->bitsPerPixel = pScrn->bitsPerPixel; currentMode->red_mask = pScrn->mask.red; currentMode->green_mask = pScrn->mask.green; currentMode->blue_mask = pScrn->mask.blue; currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor; currentMode->viewportWidth = pMode->HDisplay; currentMode->viewportHeight = pMode->VDisplay; currentMode->xViewportStep = (Bpp == 3) ? 2 : 1; currentMode->yViewportStep = 1; currentMode->viewportFlags = DGA_FLIP_RETRACE; currentMode->offset = 0; currentMode->address = pI810->FbBase; currentMode->bytesPerScanline = ((pScrn->displayWidth * Bpp) + 3) & ~3L; currentMode->imageWidth = pI810->FbMemBox.x2; currentMode->imageHeight = pI810->FbMemBox.y2; currentMode->pixmapWidth = currentMode->imageWidth; currentMode->pixmapHeight = currentMode->imageHeight; currentMode->maxViewportX = currentMode->imageWidth - currentMode->viewportWidth; /* this might need to get clamped to some maximum */ currentMode->maxViewportY = currentMode->imageHeight - currentMode->viewportHeight; pMode = pMode->next; if (pMode == firstMode) break; } pI810->numDGAModes = num; pI810->DGAModes = modes; return DGAInit(pScreen, &I810DGAFuncs, modes, num); } static DisplayModePtr I810SavedDGAModes[MAXSCREENS]; static Bool I810_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) { int index = pScrn->pScreen->myNum; I810Ptr pI810 = I810PTR(pScrn); if (!pMode) { /* restore the original mode */ if (pI810->DGAactive) { pScrn->currentMode = I810SavedDGAModes[index]; pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pScrn->currentMode)); pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); pI810->DGAactive = FALSE; } } else { if (!pI810->DGAactive) { I810SavedDGAModes[index] = pScrn->currentMode; pI810->DGAactive = TRUE; } pScrn->SwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode)); } return TRUE; } static int I810_GetViewport(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); return pI810->DGAViewportStatus; } static void I810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) { I810Ptr pI810 = I810PTR(pScrn); vgaHWPtr hwp = VGAHWPTR(pScrn); pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y)); /* wait for retrace */ while ((hwp->readST01(hwp) & 0x08)) ; while (!(hwp->readST01(hwp) & 0x08)) ; pI810->DGAViewportStatus = 0; } #ifdef HAVE_XAA_H static void I810_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) { I810Ptr pI810 = I810PTR(pScrn); if (pI810->AccelInfoRec) { (*pI810->AccelInfoRec->SetupForSolidFill) (pScrn, color, GXcopy, ~0); (*pI810->AccelInfoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); SET_SYNC_FLAG(pI810->AccelInfoRec); } } static void I810_Sync(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (pI810->AccelInfoRec) { (*pI810->AccelInfoRec->Sync) (pScrn); } } static void I810_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, int dstx, int dsty) { I810Ptr pI810 = I810PTR(pScrn); if (pI810->AccelInfoRec) { int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; int ydir = (srcy < dsty) ? -1 : 1; (*pI810->AccelInfoRec->SetupForScreenToScreenCopy) (pScrn, xdir, ydir, GXcopy, ~0, -1); (*pI810->AccelInfoRec->SubsequentScreenToScreenCopy) (pScrn, srcx, srcy, dstx, dsty, w, h); SET_SYNC_FLAG(pI810->AccelInfoRec); } } #endif #if 0 static void I810_BlitTransRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long color) { /* this one should be separate since the XAA function would * prohibit usage of ~0 as the key */ } #endif static Bool I810_OpenFramebuffer(ScrnInfoPtr pScrn, char **name, unsigned char **mem, int *size, int *offset, int *flags) { I810Ptr pI810 = I810PTR(pScrn); *name = NULL; /* no special device */ *mem = (unsigned char *)pI810->LinearAddr; *size = pI810->FbMapSize; *offset = 0; *flags = DGA_NEED_ROOT; return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_dri.c000066400000000000000000001260421267532330400244770ustar00rootroot00000000000000#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "windowstr.h" #include "shadow.h" #include "shadowfb.h" #include "i810.h" #include "i810_dri.h" static char I810KernelDriverName[] = "i810"; static char I810ClientDriverName[] = "i810"; static Bool I810CreateContext(ScreenPtr pScreen, VisualPtr visual, drm_context_t hwContext, void *pVisualConfigPriv, DRIContextType contextStore); static void I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, DRIContextType contextStore); static void I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType readContextType, void *readContextStore, DRIContextType writeContextType, void *writeContextStore); static void I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); static void I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index); static void I810EnablePageFlip(ScreenPtr pScreen); static void I810DisablePageFlip(ScreenPtr pScreen); static void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen); static void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I810DRITransitionTo3d(ScreenPtr pScreen); static void I810DRITransitionTo2d(ScreenPtr pScreen); static void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); static int i810_pitches[] = { 512, 1024, 2048, 4096, 0 }; static int i810_pitch_flags[] = { 0x0, 0x1, 0x2, 0x3, 0 }; static unsigned int i810_drm_version = 0; Bool I810CleanupDma(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); drmI810Init info; memset(&info, 0, sizeof(drmI810Init)); info.func = I810_CLEANUP_DMA; if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, &info, sizeof(drmI810Init))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] I810 Dma Cleanup Failed\n"); return FALSE; } return TRUE; } Bool I810InitDma(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); I810RingBuffer *ring = pI810->LpRing; I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; drmI810Init info; memset(&info, 0, sizeof(drmI810Init)); info.ring_start = ring->mem.Start; info.ring_end = ring->mem.End; info.ring_size = ring->mem.Size; info.mmio_offset = (unsigned int)pI810DRI->regs; info.buffers_offset = (unsigned int)pI810->buffer_map; info.sarea_priv_offset = sizeof(XF86DRISAREARec); info.front_offset = 0; info.back_offset = pI810->BackBuffer.Start; info.depth_offset = pI810->DepthBuffer.Start; info.overlay_offset = pI810->OverlayStart; info.overlay_physical = pI810->OverlayPhysical; info.w = pScrn->virtualX; info.h = pScrn->virtualY; info.pitch = pI810->auxPitch; info.pitch_bits = pI810->auxPitchBits; /* We require DRM v1.2 or greater. Since DRM v1.2 broke compatibility * we created a new v1.4 that supports a new init function. Eventually the * old init function will go away. If you change the drm interface, make a * new init type too so that we can detect the new client. */ switch(i810_drm_version) { case ((1<<16) | 0): case ((1<<16) | 1): case ((1<<16) | 2): case ((1<<16) | 3): /* Use OLD drm < 1.4 init */ info.func = I810_INIT_DMA; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init PRE v1.4 interface.\n"); break; default: case ((1<<16) | 4): /* DRM version 1.3 or greater init */ info.func = I810_INIT_DMA_1_4; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Init v1.4 interface.\n"); break; } if (drmCommandWrite(pI810->drmSubFD, DRM_I810_INIT, &info, sizeof(drmI810Init))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] I810 Dma Initialization failed.\n"); return FALSE; } return TRUE; } static unsigned int mylog2(unsigned int n) { unsigned int log2 = 1; while (n > 1) n >>= 1, log2++; return log2; } Bool I810DRIScreenInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); DRIInfoPtr pDRIInfo; I810DRIPtr pI810DRI; unsigned long tom; drm_handle_t agpHandle; drm_handle_t dcacheHandle; int sysmem_size = 0; int back_size = 0; unsigned int pitch_idx = 0; int bufs; int width = pScrn->displayWidth * pI810->cpp; int i; /* Hardware 3D rendering only implemented for 16bpp */ /* And it only works for 5:6:5 (Mark) */ if (pScrn->depth != 16) return FALSE; /* Check that the DRI, and DRM modules have been loaded by testing * for known symbols in each module. */ if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed (libdri.a too old)\n"); return FALSE; } /* adjust width first */ #define Elements(x) sizeof(x)/sizeof(*x) for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++) if (width <= i810_pitches[pitch_idx]) break; if (pitch_idx == Elements(i810_pitches)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Couldn't find depth/back buffer pitch"); DRICloseScreen(pScreen); return FALSE; } else { /* for tiled memory to work, the buffer needs to have the * number of lines as a multiple of 16 (the tile size), * - airlied */ int lines = (pScrn->virtualY + 15) / 16 * 16; back_size = i810_pitches[pitch_idx] * lines; back_size = ((back_size + 4096 - 1) / 4096) * 4096; } pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp; /* Check the DRI version */ { int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", major, minor, patch, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION); return FALSE; } } pDRIInfo = DRICreateInfoRec(); if (!pDRIInfo) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRICreateInfoRec failed. Disabling DRI.\n"); return FALSE; } /* pDRIInfo->wrap.ValidateTree = 0; */ /* pDRIInfo->wrap.PostValidateTree = 0; */ pI810->pDRIInfo = pDRIInfo; pI810->LockHeld = 0; pDRIInfo->drmDriverName = I810KernelDriverName; pDRIInfo->clientDriverName = I810ClientDriverName; if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo); } else { pDRIInfo->busIdString = malloc(64); if (pDRIInfo->busIdString) sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d", ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), pI810->PciInfo->dev, pI810->PciInfo->func ); } if (!pDRIInfo->busIdString) { DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION; pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION; pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL; pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr; pDRIInfo->frameBufferSize = (((pScrn->displayWidth * pScrn->virtualY * pI810->cpp) + 4096 - 1) / 4096) * 4096; pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp; pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES; if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES) pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; else pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES; /* For now the mapping works by using a fixed size defined * in the SAREA header */ if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] Data does not fit in SAREA\n"); return FALSE; } pDRIInfo->SAREASize = SAREA_MAX; if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) { DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } pDRIInfo->devPrivate = pI810DRI; pDRIInfo->devPrivateSize = sizeof(I810DRIRec); pDRIInfo->contextSize = sizeof(I810DRIContextRec); pDRIInfo->CreateContext = I810CreateContext; pDRIInfo->DestroyContext = I810DestroyContext; pDRIInfo->SwapContext = I810DRISwapContext; pDRIInfo->InitBuffers = I810DRIInitBuffers; pDRIInfo->MoveBuffers = I810DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; pDRIInfo->TransitionTo2d = I810DRITransitionTo2d; pDRIInfo->TransitionTo3d = I810DRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d; pDRIInfo->createDummyCtx = TRUE; pDRIInfo->createDummyCtxPriv = FALSE; /* This adds the framebuffer as a drm map *before* we have asked agp * to allocate it. Scary stuff, hold on... */ if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] DRIScreenInit failed. Disabling DRI.\n"); free(pDRIInfo->devPrivate); pDRIInfo->devPrivate = NULL; DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; return FALSE; } /* Check the i810 DRM versioning */ { drmVersionPtr version; /* Check the DRM lib version. * drmGetLibVersion was not supported in version 1.0, so check for * symbol first to avoid possible crash or hang. */ if (xf86LoaderCheckSymbol("drmGetLibVersion")) { version = drmGetLibVersion(pI810->drmSubFD); } else { /* drmlib version 1.0.0 didn't have the drmGetLibVersion * entry point. Fake it by allocating a version record * via drmGetVersion and changing it to version 1.0.0 */ version = drmGetVersion(pI810->drmSubFD); version->version_major = 1; version->version_minor = 0; version->version_patchlevel = 0; } #define REQ_MAJ 1 #define REQ_MIN 1 if (version) { if (version->version_major != REQ_MAJ || version->version_minor < REQ_MIN) { /* incompatible drm library version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel, REQ_MAJ, REQ_MIN); drmFreeVersion(version); I810DRICloseScreen(pScreen); return FALSE; } drmFreeVersion(version); } /* Check the i810 DRM version */ version = drmGetVersion(pI810->drmSubFD); if (version) { i810_drm_version = (version->version_major<<16) | version->version_minor; if (version->version_major != 1 || version->version_minor < 2) { /* incompatible drm version */ xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] I810DRIScreenInit failed because of a version mismatch.\n" "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); I810DRICloseScreen(pScreen); drmFreeVersion(version); return FALSE; } pI810->drmMinor = version->version_minor; drmFreeVersion(version); } } pI810DRI->regsSize = I810_REG_SIZE; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr, pI810DRI->regsSize, DRM_REGISTERS, 0, (drmAddress) &pI810DRI->regs) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n"); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n", (int)pI810DRI->regs); pI810->backHandle = DRM_AGP_NO_HANDLE; pI810->zHandle = DRM_AGP_NO_HANDLE; pI810->cursorHandle = DRM_AGP_NO_HANDLE; pI810->xvmcHandle = DRM_AGP_NO_HANDLE; pI810->sysmemHandle = DRM_AGP_NO_HANDLE; pI810->agpAcquired = FALSE; pI810->dcacheHandle = DRM_AGP_NO_HANDLE; /* Agp Support - Need this just to get the framebuffer. */ if (drmAgpAcquire(pI810->drmSubFD) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n"); DRICloseScreen(pScreen); return FALSE; } pI810->agpAcquired = TRUE; if (drmAgpEnable(pI810->drmSubFD, 0) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n"); DRICloseScreen(pScreen); return FALSE; } memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); memset(&pI810->BackBuffer, 0, sizeof(I810MemRange)); memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange)); pI810->CursorPhysical = 0; pI810->CursorARGBPhysical = 0; /* Dcache - half the speed of normal ram, but has use as a Z buffer * under the DRI. */ drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL, (drmAddress) &dcacheHandle); pI810->dcacheHandle = dcacheHandle; xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n", (int)dcacheHandle); sysmem_size = pScrn->videoRam * 1024; if (dcacheHandle != DRM_AGP_NO_HANDLE) { if (back_size > 4 * 1024 * 1024) { xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Backsize is larger then 4 meg\n"); sysmem_size = sysmem_size - 2 * back_size; drmAgpFree(pI810->drmSubFD, dcacheHandle); pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; } else { sysmem_size = sysmem_size - back_size; } } else { sysmem_size = sysmem_size - 2 * back_size; } /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */ if (pI810->numSurfaces && (pI810->numSurfaces == 6)) { if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) { sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User requested more memory then fits in the agp aperture\n" "Truncating to %d bytes of memory\n", sysmem_size); } } if (pI810->numSurfaces && (pI810->numSurfaces == 7)) { if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) { sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "User requested more memory then fits in the agp aperture\n" "Truncating to %d bytes of memory\n", sysmem_size); } } if (sysmem_size > pI810->FbMapSize) { sysmem_size = pI810->FbMapSize; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] User requested more memory then fits in the agp" " aperture\n\tTruncating to %d bytes of memory\n", sysmem_size); } sysmem_size -= 4096; /* remove 4k for the hw cursor */ sysmem_size -= 16384; /* remove 16k for the ARGB hw cursor */ pI810->SysMem.Start = 0; pI810->SysMem.Size = sysmem_size; pI810->SysMem.End = sysmem_size; tom = sysmem_size; pI810->SavedSysMem = pI810->SysMem; if (dcacheHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) { memset(&pI810->DcacheMem, 0, sizeof(I810MemRange)); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Found 4096K Z buffer memory\n"); pI810->DcacheMem.Start = pI810->DepthOffset; pI810->DcacheMem.Size = 1024 * 4096; pI810->DcacheMem.End = pI810->DcacheMem.Start + pI810->DcacheMem.Size; if (!I810AllocLow (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Depth buffer allocation failed\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: dcache bind failed\n"); drmAgpFree(pI810->drmSubFD, dcacheHandle); pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: no dcache memory found\n"); } drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, (drmAddress) &agpHandle); pI810->backHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound backbuffer memory\n"); pI810->BackBuffer.Start = pI810->BackOffset; pI810->BackBuffer.Size = back_size; pI810->BackBuffer.End = (pI810->BackBuffer.Start + pI810->BackBuffer.Size); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to bind backbuffer. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (dcacheHandle == DRM_AGP_NO_HANDLE) { drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL, (drmAddress) &agpHandle); pI810->zHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound depthbuffer memory\n"); pI810->DepthBuffer.Start = pI810->DepthOffset; pI810->DepthBuffer.Size = back_size; pI810->DepthBuffer.End = (pI810->DepthBuffer.Start + pI810->DepthBuffer.Size); } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to bind depthbuffer. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } /* Now allocate and bind the agp space. This memory will include the * regular framebuffer as well as texture memory. */ drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL, (drmAddress)&agpHandle); pI810->sysmemHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Bound System Texture Memory\n"); } else { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } else { xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled regions and required surface pitches. (Numbers are adjusted if the AGP region is only 32MB For numSurfaces == 6 44 - 48MB = 4MB Fence, 8 Tiles wide 43 - 44MB = 1MB Fence, 8 Tiles wide 42 - 43MB = 1MB Fence, 4 Tiles wide 41 - 42MB = 1MB Fence, 4 Tiles wide For numSurfaces == 7 44 - 48MB = 4MB Fence, 8 Tiles wide 43 - 44MB = 1MB Fence, 8 Tiles wide 42.5 - 43MB = 0.5MB Fence, 8 Tiles wide 42 - 42.5MB = 0.5MB Fence, 4 Tiles wide 40 - 42MB = 2MB Fence, 4 Tiles wide */ if (pI810->numSurfaces) { if (pI810->numSurfaces == 6) { pI810->MC.Size = 7 * 1024 * 1024; pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024; } if (pI810->numSurfaces == 7) { pI810->MC.Size = 8 * 1024 * 1024; pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024; } drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL, (drmAddress) &agpHandle); pI810->xvmcHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: Allocated 7MB for HWMC\n"); pI810->MC.End = pI810->MC.Start + pI810->MC.Size; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n"); pI810->MC.Start = 0; pI810->MC.Size = 0; pI810->MC.End = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n"); pI810->MC.Start = 0; pI810->MC.Size = 0; pI810->MC.End = 0; } pI810->xvmcContext = 0; } drmAgpAlloc(pI810->drmSubFD, 4096, 2, (unsigned long *)&pI810->CursorPhysical, (drmAddress) &agpHandle); pI810->cursorHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { tom = sysmem_size; if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Allocated 4K for mouse cursor image\n"); pI810->CursorStart = tom; tom += 4096; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: cursor bind failed\n"); pI810->CursorPhysical = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: cursor alloc failed\n"); pI810->CursorPhysical = 0; } drmAgpAlloc(pI810->drmSubFD, 16384, 2, (unsigned long *)&pI810->CursorARGBPhysical, (drmAddress) &agpHandle); pI810->cursorARGBHandle = agpHandle; if (agpHandle != DRM_AGP_NO_HANDLE) { if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: Allocated 16K for ARGB mouse cursor image\n"); pI810->CursorARGBStart = tom; tom += 16384; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: ARGB cursor bind failed\n"); pI810->CursorARGBPhysical = 0; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] GART: ARGB cursor alloc failed\n"); pI810->CursorARGBPhysical = 0; } /* Steal some of the excess cursor space for the overlay regs. */ pI810->OverlayPhysical = pI810->CursorPhysical + 1024; pI810->OverlayStart = pI810->CursorStart + 1024; I810SetTiledMemory(pScrn, 1, pI810->DepthBuffer.Start, i810_pitches[pitch_idx], 8 * 1024 * 1024); I810SetTiledMemory(pScrn, 2, pI810->BackBuffer.Start, i810_pitches[pitch_idx], 8 * 1024 * 1024); /* These are for HWMC surfaces */ if (pI810->numSurfaces == 6) { I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024); I810SetTiledMemory(pScrn, 4, pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024); I810SetTiledMemory(pScrn, 5, pI810->MC.Start + 1024 * 1024 * 2, 1024, 1024 * 1024); I810SetTiledMemory(pScrn, 6, pI810->MC.Start + 1024 * 1024 * 3, 1024, 4 * 1024 * 1024); } if (pI810->numSurfaces == 7) { I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024); I810SetTiledMemory(pScrn, 4, pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024); I810SetTiledMemory(pScrn, 5, pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024, 1024, 512 * 1024); I810SetTiledMemory(pScrn, 6, pI810->MC.Start + 3 * 1024 * 1024, 1024, 1 * 1024 * 1024); I810SetTiledMemory(pScrn, 7, pI810->MC.Start + 4 * 1024 * 1024, 1024, 4 * 1024 * 1024); } pI810->auxPitch = i810_pitches[pitch_idx]; pI810->auxPitchBits = i810_pitch_flags[pitch_idx]; pI810->SavedDcacheMem = pI810->DcacheMem; pI810DRI->backbufferSize = pI810->BackBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start, pI810->BackBuffer.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->backbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n"); DRICloseScreen(pScreen); return FALSE; } pI810DRI->depthbufferSize = pI810->DepthBuffer.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start, pI810->DepthBuffer.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->depthbuffer) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Allocate FrontBuffer etc. */ if (!I810AllocateFront(pScrn)) { DRICloseScreen(pScreen); return FALSE; } /* Allocate buffer memory */ I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem), I810_DMA_BUF_NR * I810_DMA_BUF_SZ); xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n", pI810->BufferMem.Start); if (pI810->BufferMem.Start == 0 || pI810->BufferMem.End - pI810->BufferMem.Start > I810_DMA_BUF_NR * I810_DMA_BUF_SZ) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] Not enough memory for dma buffers. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start, pI810->BufferMem.Size, DRM_AGP, 0, (drmAddress) &pI810->buffer_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } pI810DRI->agp_buffers = pI810->buffer_map; pI810DRI->agp_buf_size = pI810->BufferMem.Size; if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start, pI810->LpRing->mem.Size, DRM_AGP, 0, (drmAddress) &pI810->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } /* Use the rest of memory for textures. */ pI810DRI->textureSize = pI810->SysMem.Size; i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS); if (i < I810_LOG_MIN_TEX_REGION_SIZE) i = I810_LOG_MIN_TEX_REGION_SIZE; pI810DRI->logTextureGranularity = i; pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i; /* truncate */ if (pI810DRI->textureSize < 512 * 1024) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Less then 512k memory left for textures. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[agp] Texure memory allocation failed\n"); DRICloseScreen(pScreen); return FALSE; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start, pI810->TexMem.Size, DRM_AGP, 0, (drmAddress) &pI810DRI->textures) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(textures) failed. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } if ((bufs = drmAddBufs(pI810->drmSubFD, I810_DMA_BUF_NR, I810_DMA_BUF_SZ, DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding %d %d byte DMA buffers. Disabling DRI.\n", I810_DMA_BUF_NR, I810_DMA_BUF_SZ); DRICloseScreen(pScreen); return FALSE; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ); I810InitDma(pScrn); /* Okay now initialize the dma engine */ if (!pI810DRI->irq) { pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD, ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus), pI810->PciInfo->dev, pI810->PciInfo->func ); if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] failure adding irq handler, there is a device " "already using that irq\n Consider rearranging your " "PCI cards. Disabling DRI.\n"); DRICloseScreen(pScreen); return FALSE; } } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq); pI810DRI->deviceID = pI810->PciInfo->device_id; pI810DRI->width = pScrn->virtualX; pI810DRI->height = pScrn->virtualY; pI810DRI->mem = pScrn->videoRam * 1024; pI810DRI->cpp = pI810->cpp; pI810DRI->fbOffset = pI810->FrontBuffer.Start; pI810DRI->fbStride = pI810->auxPitch; pI810DRI->bitsPerPixel = pScrn->bitsPerPixel; pI810DRI->textureOffset = pI810->TexMem.Start; pI810DRI->backOffset = pI810->BackBuffer.Start; pI810DRI->depthOffset = pI810->DepthBuffer.Start; pI810DRI->ringOffset = pI810->LpRing->mem.Start; pI810DRI->ringSize = pI810->LpRing->mem.Size; pI810DRI->auxPitch = pI810->auxPitch; pI810DRI->auxPitchBits = pI810->auxPitchBits; pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized.\n"); pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; return TRUE; } void I810DRICloseScreen(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); if (pI810->pDRIInfo) { I810DRIPtr pI810DRI = (I810DRIPtr) pI810->pDRIInfo->devPrivate; if (pI810DRI) { if (pI810DRI->irq) { drmCtlUninstHandler(pI810->drmSubFD); pI810DRI->irq = 0; } free(pI810->pDRIInfo->devPrivate); pI810->pDRIInfo->devPrivate = NULL; } I810CleanupDma(pScrn); DRICloseScreen(pScreen); DRIDestroyInfoRec(pI810->pDRIInfo); pI810->pDRIInfo = NULL; } if (pI810->dcacheHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->dcacheHandle); if (pI810->backHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->backHandle); if (pI810->zHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->zHandle); if (pI810->cursorHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->cursorHandle); if (pI810->xvmcHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->xvmcHandle); if (pI810->sysmemHandle!=DRM_AGP_NO_HANDLE) drmAgpFree(pI810->drmSubFD, pI810->sysmemHandle); if (pI810->agpAcquired == TRUE) drmAgpRelease(pI810->drmSubFD); pI810->backHandle = DRM_AGP_NO_HANDLE; pI810->zHandle = DRM_AGP_NO_HANDLE; pI810->cursorHandle = DRM_AGP_NO_HANDLE; pI810->xvmcHandle = DRM_AGP_NO_HANDLE; pI810->sysmemHandle = DRM_AGP_NO_HANDLE; pI810->agpAcquired = FALSE; pI810->dcacheHandle = DRM_AGP_NO_HANDLE; } static Bool I810CreateContext(ScreenPtr pScreen, VisualPtr visual, drm_context_t hwContext, void *pVisualConfigPriv, DRIContextType contextStore) { return TRUE; } static void I810DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, DRIContextType contextStore) { } Bool I810DRIFinishScreenInit(ScreenPtr pScreen) { I810SAREARec *sPriv = (I810SAREARec *) DRIGetSAREAPrivate(pScreen); ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr info = I810PTR(pScrn); memset(sPriv, 0, sizeof(*sPriv)); /* Have shadow run only while there is 3d active. */ if (info->allowPageFlip && info->drmMinor >= 3) { ShadowFBInit( pScreen, I810DRIRefreshArea ); } else info->allowPageFlip = 0; return DRIFinishScreenInit(pScreen); } void I810DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType oldContextType, void *oldContext, DRIContextType newContextType, void *newContext) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); if (syncType == DRI_3D_SYNC && oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) { if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("I810DRISwapContext (in)\n"); if (!pScrn->vtSema) return; pI810->LockHeld = 1; I810RefreshRing(pScrn); } else if (syncType == DRI_2D_SYNC && oldContextType == DRI_NO_CONTEXT && newContextType == DRI_2D_CONTEXT) { pI810->LockHeld = 0; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("I810DRISwapContext (out)\n"); } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("I810DRISwapContext (other)\n"); } static void I810DRISetNeedSync(ScrnInfoPtr pScrn) { #ifdef HAVE_XAA_H I810Ptr pI810 = I810PTR(pScrn); if (pI810->AccelInfoRec) pI810->AccelInfoRec->NeedToSync = TRUE; #endif } static void I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) { ScreenPtr pScreen = pWin->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); BoxPtr pbox = REGION_RECTS(prgn); int nbox = REGION_NUM_RECTS(prgn); if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("I810DRIInitBuffers\n"); I810SetupForSolidFill(pScrn, 0, GXcopy, -1); while (nbox--) { I810SelectBuffer(pScrn, I810_SELECT_BACK); I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } /* Clear the depth buffer - uses 0xffff rather than 0. */ pbox = REGION_RECTS(prgn); nbox = REGION_NUM_RECTS(prgn); I810SelectBuffer(pScrn, I810_SELECT_DEPTH); I810SetupForSolidFill(pScrn, 0xffff, GXcopy, -1); while (nbox--) { I810SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } I810SelectBuffer(pScrn, I810_SELECT_FRONT); I810DRISetNeedSync(pScrn); } /* This routine is a modified form of XAADoBitBlt with the calls to * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source * instead of destination. My origin is upside down so the ydir cases * are reversed. * * KW: can you believe that this is called even when a 2d window moves? */ static void I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index) { ScreenPtr pScreen = pParent->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); BoxPtr pboxTmp, pboxNext, pboxBase; DDXPointPtr pptTmp, pptNew2 = NULL; int xdir, ydir; int screenwidth = pScrn->virtualX; int screenheight = pScrn->virtualY; BoxPtr pbox = REGION_RECTS(prgnSrc); int nbox = REGION_NUM_RECTS(prgnSrc); BoxPtr pboxNew1 = NULL; BoxPtr pboxNew2 = NULL; DDXPointPtr pptNew1 = NULL; DDXPointPtr pptSrc = &ptOldOrg; int dx = pParent->drawable.x - ptOldOrg.x; int dy = pParent->drawable.y - ptOldOrg.y; /* If the copy will overlap in Y, reverse the order */ if (dy > 0) { ydir = -1; if (nbox > 1) { /* Keep ordering in each band, reverse order of bands */ pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); if (!pboxNew1) return; pptNew1 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); if (!pptNew1) { free(pboxNew1); return; } pboxBase = pboxNext = pbox + nbox - 1; while (pboxBase >= pbox) { while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) pboxNext--; pboxTmp = pboxNext + 1; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp <= pboxBase) { *pboxNew1++ = *pboxTmp++; *pptNew1++ = *pptTmp++; } pboxBase = pboxNext; } pboxNew1 -= nbox; pbox = pboxNew1; pptNew1 -= nbox; pptSrc = pptNew1; } } else { /* No changes required */ ydir = 1; } /* If the regions will overlap in X, reverse the order */ if (dx > 0) { xdir = -1; if (nbox > 1) { /*reverse orderof rects in each band */ pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); pptNew2 = (DDXPointPtr) malloc(sizeof(DDXPointRec) * nbox); if (!pboxNew2 || !pptNew2) { if (pptNew2) free(pptNew2); if (pboxNew2) free(pboxNew2); if (pboxNew1) { free(pptNew1); free(pboxNew1); } return; } pboxBase = pboxNext = pbox; while (pboxBase < pbox + nbox) { while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1)) pboxNext++; pboxTmp = pboxNext; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp != pboxBase) { *pboxNew2++ = *--pboxTmp; *pptNew2++ = *--pptTmp; } pboxBase = pboxNext; } pboxNew2 -= nbox; pbox = pboxNew2; pptNew2 -= nbox; pptSrc = pptNew2; } } else { /* No changes are needed */ xdir = 1; } /* SelectBuffer isn't really a good concept for the i810. */ I810EmitFlush(pScrn); I810SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); for (; nbox--; pbox++) { int x1 = pbox->x1; int y1 = pbox->y1; int destx = x1 + dx; int desty = y1 + dy; int w = pbox->x2 - x1 + 1; int h = pbox->y2 - y1 + 1; if (destx < 0) x1 -= destx, w += destx, destx = 0; if (desty < 0) y1 -= desty, h += desty, desty = 0; if (destx + w > screenwidth) w = screenwidth - destx; if (desty + h > screenheight) h = screenheight - desty; if (w <= 0) continue; if (h <= 0) continue; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n", x1, y1, w, h, dx, dy); I810SelectBuffer(pScrn, I810_SELECT_BACK); I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); I810SelectBuffer(pScrn, I810_SELECT_DEPTH); I810SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); } I810SelectBuffer(pScrn, I810_SELECT_FRONT); I810EmitFlush(pScrn); if (pboxNew2) { free(pptNew2); free(pboxNew2); } if (pboxNew1) { free(pptNew1); free(pboxNew1); } I810DRISetNeedSync(pScrn); } /* Use the miext/shadow module to maintain a list of dirty rectangles. * These are blitted to the back buffer to keep both buffers clean * during page-flipping when the 3d application isn't fullscreen. * * Unlike most use of the shadow code, both buffers are in video memory. * * An alternative to this would be to organize for all on-screen drawing * operations to be duplicated for the two buffers. That might be * faster, but seems like a lot more work... */ /* This should be done *before* XAA syncs or fires its buffer. * Otherwise will have to fire it again??? */ static void I810DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) { I810Ptr pI810 = I810PTR(pScrn); int i; I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); unsigned int br13; int cpp=2; /* Don't want to do this when no 3d is active and pages are * right-way-round */ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) return; br13 = (pI810->auxPitch) | (0xcc << 16); for (i = 0 ; i < num ; i++, pbox++) { unsigned int w = min(pbox->y2, pScrn->virtualY-1) - max(pbox->y1, 0) + 1; unsigned int h = min(pbox->x2, pScrn->virtualX-1) - max(pbox->x1, 0) + 1; unsigned int dst = max(pbox->x1, 0)*cpp + (max(pbox->y1, 0)*pI810->auxPitch); BEGIN_LP_RING(6); OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); OUT_RING(br13); OUT_RING( (h<<16) | (w*cpp) ); OUT_RING(pI810->BackBuffer.Start + dst); OUT_RING(br13 & 0xffff); OUT_RING(dst); ADVANCE_LP_RING(); } } static void I810EnablePageFlip(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); int cpp=2; pSAREAPriv->pf_enabled = pI810->allowPageFlip; pSAREAPriv->pf_active = 0; if (pI810->allowPageFlip) { unsigned int br13 = pI810->auxPitch | (0xcc << 16); BEGIN_LP_RING(6); OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); OUT_RING(br13); OUT_RING((pScrn->virtualY << 16) | (pScrn->virtualX*cpp)); OUT_RING(pI810->BackBuffer.Start); OUT_RING(br13 & 0xFFFF); OUT_RING(0); ADVANCE_LP_RING(); pSAREAPriv->pf_active = 1; } } static void I810DisablePageFlip(ScreenPtr pScreen) { I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_active=0; } static void I810DRITransitionSingleToMulti3d(ScreenPtr pScreen) { /* Tell the clients not to pageflip. How? * -- Field in sarea, plus bumping the window counters. * -- DRM needs to cope with Front-to-Back swapbuffers. */ I810DisablePageFlip(pScreen); } static void I810DRITransitionMultiToSingle3d(ScreenPtr pScreen) { /* Let the remaining 3d app start page flipping again */ I810EnablePageFlip(pScreen); } static void I810DRITransitionTo3d(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); I810EnablePageFlip(pScreen); pI810->have3DWindows = 1; } static void I810DRITransitionTo2d(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); I810SAREAPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); /* Try flipping back to the front page if necessary */ if (pSAREAPriv->pf_current_page == 1) drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP); /* Shut down shadowing if we've made it back to the front page */ if (pSAREAPriv->pf_current_page == 0) { I810DisablePageFlip(pScreen); } pI810->have3DWindows = 0; } Bool I810DRILeave(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (pI810->directRenderingEnabled) { if (pI810->dcacheHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->backHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->zHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->sysmemHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->xvmcHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->cursorHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->cursorARGBHandle != 0) if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorARGBHandle) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); return FALSE; } if (pI810->agpAcquired == TRUE) drmAgpRelease(pI810->drmSubFD); pI810->agpAcquired = FALSE; } return TRUE; } Bool I810DRIEnter(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (pI810->directRenderingEnabled) { if (pI810->agpAcquired == FALSE) drmAgpAcquire(pI810->drmSubFD); pI810->agpAcquired = TRUE; if (pI810->dcacheHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle, pI810->DepthOffset) != 0) return FALSE; if (pI810->backHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->backHandle, pI810->BackOffset) != 0) return FALSE; if (pI810->zHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->zHandle, pI810->DepthOffset) != 0) return FALSE; if (pI810->sysmemHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, 0) != 0) return FALSE; if (pI810->xvmcHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle, pI810->MC.Start) != 0) return FALSE; if (pI810->cursorHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle, pI810->CursorStart) != 0) return FALSE; if (pI810->cursorARGBHandle != 0) if (drmAgpBind(pI810->drmSubFD, pI810->cursorARGBHandle, pI810->CursorARGBStart) != 0) return FALSE; } I810SelectBuffer(pScrn, I810_SELECT_FRONT); return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_dri.h000066400000000000000000000066111267532330400245030ustar00rootroot00000000000000 #ifndef _I810_DRI_ #define _I810_DRI_ #include "xf86drm.h" #include "i810_common.h" #define I810_MAX_DRAWABLES 256 #define I810_MAJOR_VERSION 1 #define I810_MINOR_VERSION 7 #define I810_PATCHLEVEL 4 typedef struct { drm_handle_t regs; drmSize regsSize; drmSize backbufferSize; drm_handle_t backbuffer; drmSize depthbufferSize; drm_handle_t depthbuffer; drm_handle_t textures; int textureSize; drm_handle_t agp_buffers; drmSize agp_buf_size; int deviceID; int width; int height; int mem; int cpp; int bitsPerPixel; int fbOffset; int fbStride; int backOffset; int depthOffset; int auxPitch; int auxPitchBits; int logTextureGranularity; int textureOffset; /* For non-dma direct rendering. */ int ringOffset; int ringSize; drmBufMapPtr drmBufs; int irq; unsigned int sarea_priv_offset; } I810DRIRec, *I810DRIPtr; /* WARNING: Do not change the SAREA structure without changing the kernel * as well */ #define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */ #define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */ #define I810_UPLOAD_CTX 0x4 #define I810_UPLOAD_BUFFERS 0x8 #define I810_UPLOAD_TEX0 0x10 #define I810_UPLOAD_TEX1 0x20 #define I810_UPLOAD_CLIPRECTS 0x40 typedef struct { unsigned char next, prev; /* indices to form a circular LRU */ unsigned char in_use; /* owned by a client, or free? */ int age; /* tracked by clients to update local LRU's */ } I810TexRegionRec, *I810TexRegionPtr; typedef struct { unsigned int ContextState[I810_CTX_SETUP_SIZE]; unsigned int BufferState[I810_DEST_SETUP_SIZE]; unsigned int TexState[2][I810_TEX_SETUP_SIZE]; unsigned int dirty; unsigned int nbox; drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; /* Maintain an LRU of contiguous regions of texture space. If * you think you own a region of texture memory, and it has an * age different to the one you set, then you are mistaken and * it has been stolen by another client. If global texAge * hasn't changed, there is no need to walk the list. * * These regions can be used as a proxy for the fine-grained * texture information of other clients - by maintaining them * in the same lru which is used to age their own textures, * clients have an approximate lru for the whole of global * texture space, and can make informed decisions as to which * areas to kick out. There is no need to choose whether to * kick out your own texture or someone else's - simply eject * them all in LRU order. */ drmTextureRegion texList[I810_NR_TEX_REGIONS + 1]; /* Last elt is sentinal */ int texAge; /* last time texture was uploaded */ int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ int last_quiescent; /* */ int ctxOwner; /* last context to upload state */ int vertex_prim; int pf_enabled; /* is pageflipping allowed? */ int pf_active; /* is pageflipping active right now? */ int pf_current_page; /* which buffer is being displayed? */ } I810SAREARec, *I810SAREAPtr; typedef struct { /* Nothing here yet */ int dummy; } I810ConfigPrivRec, *I810ConfigPrivPtr; typedef struct { /* Nothing here yet */ int dummy; } I810DRIContextRec, *I810DRIContextPtr; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_driver.c000066400000000000000000001574601267532330400252240ustar00rootroot00000000000000 /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * Authors: * Keith Whitwell * * Add ARGB HW cursor support: * Alan Hourihane * */ /* * This server does not support these XFree86 4.0 features yet * shadowFb (if requested or acceleration is off) * Overlay planes * DGA */ #include #include #include /* * These are X and server generic header files. */ #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86cmap.h" #include "compiler.h" #include "vgaHW.h" #include "mipointer.h" #include "micmap.h" #include "fb.h" #include "miscstruct.h" #include "xf86xv.h" #include #include "vbe.h" #include "xf86fbman.h" #include "i810.h" #ifdef HAVE_DRI1 #include "dri.h" #endif #include "../legacy.h" static Bool I810PreInit(ScrnInfoPtr pScrn, int flags); static Bool I810ScreenInit(SCREEN_INIT_ARGS_DECL); static Bool I810EnterVT(VT_FUNC_ARGS_DECL); static void I810LeaveVT(VT_FUNC_ARGS_DECL); static Bool I810CloseScreen(CLOSE_SCREEN_ARGS_DECL); static Bool I810SaveScreen(ScreenPtr pScreen, Bool unblank); static void I810FreeScreen(FREE_SCREEN_ARGS_DECL); static void I810DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagermentMode, int flags); static ModeStatus I810ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags); typedef enum { OPTION_NOACCEL, OPTION_SW_CURSOR, OPTION_COLOR_KEY, OPTION_CACHE_LINES, OPTION_DAC_6BIT, OPTION_DRI, OPTION_NO_DDC, OPTION_SHOW_CACHE, OPTION_XVMC_SURFACES, OPTION_PAGEFLIP } I810Opts; static const OptionInfoRec I810Options[] = { {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {OPTION_CACHE_LINES, "CacheLines", OPTV_INTEGER, {0}, FALSE}, {OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SHOW_CACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_XVMC_SURFACES, "XvMCSurfaces", OPTV_INTEGER, {0}, FALSE}, {OPTION_PAGEFLIP, "PageFlip", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ #ifndef I810_DEBUG int I810_DEBUG = (0 /* | DEBUG_ALWAYS_SYNC */ /* | DEBUG_VERBOSE_ACCEL */ /* | DEBUG_VERBOSE_SYNC */ /* | DEBUG_VERBOSE_VGA */ /* | DEBUG_VERBOSE_RING */ /* | DEBUG_VERBOSE_OUTREG */ /* | DEBUG_VERBOSE_MEMORY */ /* | DEBUG_VERBOSE_CURSOR */ ); #endif #ifdef HAVE_DRI1 static int i810_pitches[] = { 512, 1024, 2048, 4096, 0 }; #endif /* * I810GetRec and I810FreeRec -- * * Private data for the driver is stored in the screen structure. * These two functions create and destroy that private data. * */ static Bool I810GetRec(ScrnInfoPtr scrn) { if (((uintptr_t)scrn->driverPrivate & 3) == 0) return TRUE; scrn->driverPrivate = xnfcalloc(sizeof(I810Rec), 1); return TRUE; } static void I810FreeRec(ScrnInfoPtr scrn) { if (!scrn) return; if (!scrn->driverPrivate) return; free(scrn->driverPrivate); scrn->driverPrivate = NULL; } struct pci_device * intel_host_bridge (void) { static const struct pci_slot_match bridge_match = { 0, 0, 0, PCI_MATCH_ANY, 0 }; struct pci_device_iterator *slot_iterator; struct pci_device *bridge; slot_iterator = pci_slot_match_iterator_create (&bridge_match); bridge = pci_device_next (slot_iterator); pci_iterator_destroy (slot_iterator); return bridge; } static void I810ProbeDDC(ScrnInfoPtr scrn, int index) { vbeInfoPtr pVbe; if (xf86LoadSubModule(scrn, "vbe")) { pVbe = VBEInit(NULL, index); ConfiguredMonitor = vbeDoEDID(pVbe, NULL); vbeFree(pVbe); } } static xf86MonPtr I810DoDDC(ScrnInfoPtr scrn, int index) { vbeInfoPtr pVbe; xf86MonPtr MonInfo = NULL; I810Ptr pI810 = I810PTR(scrn); /* Honour Option "noDDC" */ if (xf86ReturnOptValBool(pI810->Options, OPTION_NO_DDC, FALSE)) { return MonInfo; } if (xf86LoadSubModule(scrn, "vbe") && (pVbe = VBEInit(NULL, index))) { MonInfo = vbeDoEDID(pVbe, NULL); xf86PrintEDID(MonInfo); xf86SetDDCproperties(scrn, MonInfo); vbeFree(pVbe); } else { xf86DrvMsg(scrn->scrnIndex, X_INFO, "this driver cannot do DDC without VBE\n"); } return MonInfo; } /* * I810PreInit -- * * Do initial setup of the board before we know what resolution we will * be running at. * */ static Bool I810PreInit(ScrnInfoPtr scrn, int flags) { I810Ptr pI810; ClockRangePtr clockRanges; int i; MessageType from; int flags24; rgb defaultWeight = { 0, 0, 0 }; int mem; Bool enable; if (scrn->numEntities != 1) return FALSE; /* Allocate driverPrivate */ if (!I810GetRec(scrn)) return FALSE; pI810 = I810PTR(scrn); pI810->pEnt = xf86GetEntityInfo(scrn->entityList[0]); if (pI810->pEnt == NULL || pI810->pEnt->location.type != BUS_PCI) return FALSE; if (flags & PROBE_DETECT) { I810ProbeDDC(scrn, pI810->pEnt->index); return TRUE; } /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(scrn, "vgahw")) return FALSE; /* Allocate a vgaHWRec */ if (!vgaHWGetHWRec(scrn)) return FALSE; pI810->PciInfo = xf86GetPciInfoForEntity(pI810->pEnt->index); /* Set scrn->monitor */ scrn->monitor = scrn->confScreen->monitor; flags24 = Support24bppFb | PreferConvert32to24 | SupportConvert32to24; if (!xf86SetDepthBpp(scrn, 16, 0, 16, flags24)) { return FALSE; } else { switch (scrn->depth) { case 8: case 15: case 16: case 24: break; default: xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by i810 driver\n", scrn->depth); return FALSE; } } xf86PrintDepthBpp(scrn); switch (scrn->bitsPerPixel) { case 8: case 16: case 24: break; default: xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Given bpp (%d) is not supported by i810 driver\n", scrn->bitsPerPixel); return FALSE; } if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) return FALSE; if (!xf86SetDefaultVisual(scrn, -1)) return FALSE; /* We use a programmable clock */ scrn->progClock = TRUE; pI810->cpp = scrn->bitsPerPixel / 8; /* Process the options */ xf86CollectOptions(scrn, NULL); if (!(pI810->Options = malloc(sizeof(I810Options)))) return FALSE; memcpy(pI810->Options, I810Options, sizeof(I810Options)); xf86ProcessOptions(scrn->scrnIndex, scrn->options, pI810->Options); scrn->rgbBits = 8; if (xf86ReturnOptValBool(pI810->Options, OPTION_DAC_6BIT, FALSE)) scrn->rgbBits = 6; if (xf86ReturnOptValBool(pI810->Options, OPTION_SHOW_CACHE, FALSE)) pI810->showCache = TRUE; else pI810->showCache = FALSE; /* 6-BIT dac isn't reasonable for modes with > 8bpp */ if (xf86ReturnOptValBool(pI810->Options, OPTION_DAC_6BIT, FALSE) && scrn->bitsPerPixel > 8) { OptionInfoPtr ptr; ptr = xf86TokenToOptinfo(pI810->Options, OPTION_DAC_6BIT); ptr->found = FALSE; } if (xf86ReturnOptValBool(pI810->Options, OPTION_NOACCEL, FALSE)) pI810->noAccel = TRUE; if (!pI810->noAccel && !xf86LoadSubModule(scrn, "xaa")) pI810->noAccel = TRUE; #ifdef HAVE_DRI1 pI810->directRenderingDisabled = !xf86ReturnOptValBool(pI810->Options, OPTION_DRI, TRUE); if (!pI810->directRenderingDisabled) { if (scrn->depth!=16) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "DRI is disabled because it " "runs only at 16-bit depth.\n"); pI810->directRenderingDisabled=TRUE; } } #endif /* Get DDC info from monitor */ /* after xf86ProcessOptions, * because it is controlled by options [no]vbe and [no]ddc */ I810DoDDC(scrn, pI810->pEnt->index); intel_detect_chipset(scrn, NULL); pI810->LinearAddr = pI810->PciInfo->regions[0].base_addr; xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n", (unsigned long)pI810->LinearAddr); pI810->MMIOAddr = pI810->PciInfo->regions[1].base_addr; xf86DrvMsg(scrn->scrnIndex, X_PROBED, "IO registers at addr 0x%lX\n", (unsigned long)pI810->MMIOAddr); /* AGP GART support is required. Don't proceed any further if it isn't * present. */ if (!xf86AgpGARTSupported()) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "AGP GART support is not available. Make sure your kernel has\n" "\tagpgart support or that the agpgart kernel module is loaded.\n"); return FALSE; } /* Find out memory bus frequency. */ { uint32_t whtcfg_pamr_drp; pci_device_cfg_read_u32(pI810->PciInfo, & whtcfg_pamr_drp, WHTCFG_PAMR_DRP); /* Need this for choosing watermarks. */ if ((whtcfg_pamr_drp & LM_FREQ_MASK) == LM_FREQ_133) pI810->LmFreqSel = 133; else pI810->LmFreqSel = 100; } /* Default to 4MB framebuffer, which is sufficient for all * supported 2d resolutions. If the user has specified a different * size in the XF86Config, use that amount instead. * * Changed to 8 Meg so we can have acceleration by default (Mark). */ mem = I810CheckAvailableMemory(scrn); if (pI810->directRenderingDisabled || mem < 131072) /* < 128 MB */ scrn->videoRam = 8192; else if (mem < 196608) scrn->videoRam = 16384; /* < 192 MB */ else scrn->videoRam = 24576; from = X_DEFAULT; if (pI810->pEnt->device->videoRam) { scrn->videoRam = pI810->pEnt->device->videoRam; from = X_CONFIG; } if (mem > 0 && mem < scrn->videoRam) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%dk of memory was requested," " but the\n\t maximum AGP memory available is %dk.\n", scrn->videoRam, mem); from = X_PROBED; if (mem > (6 * 1024)) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Reducing video memory to 4MB\n"); scrn->videoRam = 4096; } else { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Less than 6MB of AGP memory" " is available. Cannot proceed.\n"); I810FreeRec(scrn); return FALSE; } } xf86DrvMsg(scrn->scrnIndex, from, "Will alloc AGP framebuffer: %d kByte\n", scrn->videoRam); /* Calculate Fixed Offsets depending on graphics aperture size */ { struct pci_device *bridge = intel_host_bridge (); uint32_t smram_miscc; pci_device_cfg_read_u32 (bridge, & smram_miscc, SMRAM_MISCC); if ((smram_miscc & GFX_MEM_WIN_SIZE) == GFX_MEM_WIN_32M) { pI810->FbMapSize = 0x1000000; pI810->DepthOffset = 0x1000000; pI810->BackOffset = 0x1800000; } else { pI810->FbMapSize = 0x3000000; pI810->DepthOffset = 0x3000000; pI810->BackOffset = 0x3800000; } } /* * If the driver can do gamma correction, it should call xf86SetGamma() * here. */ { Gamma zeros = { 0.0, 0.0, 0.0 }; if (!xf86SetGamma(scrn, zeros)) { return FALSE; } } pI810->MaxClock = 0; if (pI810->pEnt->device->dacSpeeds[0]) { switch (scrn->bitsPerPixel) { case 8: pI810->MaxClock = pI810->pEnt->device->dacSpeeds[DAC_BPP8]; break; case 16: pI810->MaxClock = pI810->pEnt->device->dacSpeeds[DAC_BPP16]; break; case 24: pI810->MaxClock = pI810->pEnt->device->dacSpeeds[DAC_BPP24]; break; case 32: /* not supported */ pI810->MaxClock = pI810->pEnt->device->dacSpeeds[DAC_BPP32]; break; } if (!pI810->MaxClock) pI810->MaxClock = pI810->pEnt->device->dacSpeeds[0]; } else { switch (scrn->bitsPerPixel) { case 8: pI810->MaxClock = 203000; break; case 16: pI810->MaxClock = 163000; break; case 24: pI810->MaxClock = 136000; break; case 32: /* not supported */ pI810->MaxClock = 86000; } } clockRanges = xnfcalloc(sizeof(ClockRange), 1); clockRanges->next = NULL; /* 9.4MHz appears to be the smallest that works. */ clockRanges->minClock = 9500; clockRanges->maxClock = pI810->MaxClock; clockRanges->clockIndex = -1; clockRanges->interlaceAllowed = TRUE; clockRanges->doubleScanAllowed = FALSE; i = xf86ValidateModes(scrn, scrn->monitor->Modes, scrn->display->modes, clockRanges, #ifndef HAVE_DRI1 0, 320, 1600, 64 * scrn->bitsPerPixel, #else i810_pitches, 0, 0, 64 * scrn->bitsPerPixel, #endif 200, 1200, scrn->display->virtualX, scrn->display->virtualY, scrn->videoRam * 1024, LOOKUP_BEST_REFRESH); if (i == -1) { I810FreeRec(scrn); return FALSE; } xf86PruneDriverModes(scrn); if (!i || !scrn->modes) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "No valid modes found\n"); I810FreeRec(scrn); return FALSE; } xf86SetCrtcForModes(scrn, INTERLACE_HALVE_V); scrn->currentMode = scrn->modes; xf86PrintModes(scrn); xf86SetDpi(scrn, 0, 0); if (!xf86LoadSubModule(scrn, "fb")) { I810FreeRec(scrn); return FALSE; } if (!xf86ReturnOptValBool(pI810->Options, OPTION_SW_CURSOR, FALSE)) { if (!xf86LoadSubModule(scrn, "ramdac")) { I810FreeRec(scrn); return FALSE; } } if (xf86GetOptValInteger (pI810->Options, OPTION_COLOR_KEY, &(pI810->colorKey))) { xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "video overlay key set to 0x%x\n", pI810->colorKey); } else { pI810->colorKey = (1 << scrn->offset.red) | (1 << scrn->offset.green) | (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); } pI810->allowPageFlip=FALSE; enable = xf86ReturnOptValBool(pI810->Options, OPTION_PAGEFLIP, FALSE); #ifdef HAVE_DRI1 if (!pI810->directRenderingDisabled) { pI810->allowPageFlip = enable; if (pI810->allowPageFlip == TRUE) { if (!xf86LoadSubModule(scrn, "shadowfb")) { pI810->allowPageFlip = 0; xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't load shadowfb module:\n"); } } xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "page flipping %s\n", enable ? "enabled" : "disabled"); } #endif if (xf86GetOptValInteger(pI810->Options, OPTION_XVMC_SURFACES, &(pI810->numSurfaces))) { xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "%d XvMC Surfaces Requested.\n", pI810->numSurfaces); if (pI810->numSurfaces > 7) { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Using 7 XvMC Surfaces (Maximum Allowed).\n"); pI810->numSurfaces = 7; } if (pI810->numSurfaces < 6) { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Using 6 XvMC Surfaces (Minimum Allowed).\n"); pI810->numSurfaces = 6; } } else { xf86DrvMsg(scrn->scrnIndex, X_INFO, "XvMC is Disabled: use XvMCSurfaces config option to enable.\n"); pI810->numSurfaces = 0; } #ifdef HAVE_DRI1 /* Load the dri module if requested. */ if (xf86ReturnOptValBool(pI810->Options, OPTION_DRI, FALSE)) { xf86LoadSubModule(scrn, "dri"); } #endif return TRUE; } static Bool I810MapMMIO(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); struct pci_device *const device = pI810->PciInfo; int err; err = pci_device_map_range (device, pI810->MMIOAddr, I810_REG_SIZE, PCI_DEV_MAP_FLAG_WRITABLE, (void **) &pI810->MMIOBase); if (err) { xf86DrvMsg (scrn->scrnIndex, X_ERROR, "Unable to map mmio BAR. %s (%d)\n", strerror (err), err); return FALSE; } return TRUE; } static Bool I810MapMem(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); struct pci_device *const device = pI810->PciInfo; int err; if (!I810MapMMIO(scrn)) return FALSE; err = pci_device_map_range (device, pI810->LinearAddr, pI810->FbMapSize, PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE, (void **) &pI810->FbBase); if (err) { xf86DrvMsg (scrn->scrnIndex, X_ERROR, "Unable to map frame buffer BAR. %s (%d)\n", strerror (err), err); return FALSE; } pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start; return TRUE; } static void I810UnmapMMIO(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); pci_device_unmap_range (pI810->PciInfo, pI810->MMIOBase, I810_REG_SIZE); pI810->MMIOBase = NULL; } static Bool I810UnmapMem(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); pci_device_unmap_range (pI810->PciInfo, pI810->FbBase, pI810->FbMapSize); pI810->FbBase = NULL; I810UnmapMMIO(scrn); return TRUE; } /* Famous last words */ void I810PrintErrorState(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n", (unsigned long) INREG(PGETBL_CTL), (unsigned long) INREG(PGE_ERR)); ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long) INREG(IPEIR), (unsigned long) INREG(IPEHR)); ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n", (unsigned long) INREG(LP_RING + RING_TAIL), (unsigned long) INREG(LP_RING + RING_HEAD) & HEAD_ADDR, (unsigned long) INREG(LP_RING + RING_LEN), (unsigned long) INREG(LP_RING + RING_START)); ErrorF("eir: %x esr: %x emr: %x\n", INREG16(EIR), INREG16(ESR), INREG16(EMR)); ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM)); ErrorF("memmode: %lx instps: %lx\n", (unsigned long) INREG(MEMMODE), (unsigned long) INREG(INST_PS)); ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n", INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR)); } /* * I810Save -- * * This function saves the video state. It reads all of the SVGA registers * into the vgaI810Rec data structure. There is in general no need to * mask out bits here - just read the registers. */ static void DoSave(ScrnInfoPtr scrn, vgaRegPtr vgaReg, I810RegPtr i810Reg, Bool saveFonts) { I810Ptr pI810; vgaHWPtr hwp; int i; pI810 = I810PTR(scrn); hwp = VGAHWPTR(scrn); /* * This function will handle creating the data structure and filling * in the generic VGA portion. */ if (saveFonts) vgaHWSave(scrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS | VGA_SR_CMAP); else vgaHWSave(scrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); /* * The port I/O code necessary to read in the extended registers * into the fields of the vgaI810Rec structure goes here. */ i810Reg->IOControl = hwp->readCrtc(hwp, IO_CTNL); i810Reg->AddressMapping = hwp->readGr(hwp, ADDRESS_MAPPING); i810Reg->BitBLTControl = INREG8(BITBLT_CNTL); i810Reg->VideoClk2_M = INREG16(VCLK2_VCO_M); i810Reg->VideoClk2_N = INREG16(VCLK2_VCO_N); i810Reg->VideoClk2_DivisorSel = INREG8(VCLK2_VCO_DIV_SEL); i810Reg->ExtVertTotal = hwp->readCrtc(hwp, EXT_VERT_TOTAL); i810Reg->ExtVertDispEnd = hwp->readCrtc(hwp, EXT_VERT_DISPLAY); i810Reg->ExtVertSyncStart = hwp->readCrtc(hwp, EXT_VERT_SYNC_START); i810Reg->ExtVertBlankStart = hwp->readCrtc(hwp, EXT_VERT_BLANK_START); i810Reg->ExtHorizTotal = hwp->readCrtc(hwp, EXT_HORIZ_TOTAL); i810Reg->ExtHorizBlank = hwp->readCrtc(hwp, EXT_HORIZ_BLANK); i810Reg->ExtOffset = hwp->readCrtc(hwp, EXT_OFFSET); i810Reg->InterlaceControl = hwp->readCrtc(hwp, INTERLACE_CNTL); i810Reg->PixelPipeCfg0 = INREG8(PIXPIPE_CONFIG_0); i810Reg->PixelPipeCfg1 = INREG8(PIXPIPE_CONFIG_1); i810Reg->PixelPipeCfg2 = INREG8(PIXPIPE_CONFIG_2); i810Reg->DisplayControl = INREG8(DISPLAY_CNTL); i810Reg->LMI_FIFO_Watermark = INREG(FWATER_BLC); for (i = 0; i < 8; i++) i810Reg->Fence[i] = INREG(FENCE + i * 4); i810Reg->LprbTail = INREG(LP_RING + RING_TAIL); i810Reg->LprbHead = INREG(LP_RING + RING_HEAD); i810Reg->LprbStart = INREG(LP_RING + RING_START); i810Reg->LprbLen = INREG(LP_RING + RING_LEN); if ((i810Reg->LprbTail & TAIL_ADDR) != (i810Reg->LprbHead & HEAD_ADDR) && i810Reg->LprbLen & RING_VALID) { I810PrintErrorState(scrn); FatalError("Active ring not flushed\n"); } } static void I810Save(ScrnInfoPtr scrn) { vgaHWPtr hwp; I810Ptr pI810; uint32_t temp; hwp = VGAHWPTR(scrn); pI810 = I810PTR(scrn); DoSave(scrn, &hwp->SavedReg, &pI810->SavedReg, TRUE); temp = INREG(MEMMODE); temp |= 4; OUTREG(MEMMODE, temp); } static void i810PrintMode(vgaRegPtr vgaReg, I810RegPtr mode) { int i; ErrorF(" MiscOut: %x\n", vgaReg->MiscOutReg); ErrorF("SEQ: "); for (i = 0; i < vgaReg->numSequencer; i++) { if ((i & 7) == 0) ErrorF("\n"); ErrorF(" %d: %x", i, vgaReg->Sequencer[i]); } ErrorF("\n"); ErrorF("CRTC: "); for (i = 0; i < vgaReg->numCRTC; i++) { if ((i & 3) == 0) ErrorF("\n"); ErrorF(" %d: %x", i, vgaReg->CRTC[i]); } ErrorF("\n"); ErrorF("GFX: "); for (i = 0; i < vgaReg->numGraphics; i++) { if ((i & 7) == 0) ErrorF("\n"); ErrorF(" %d: %x", i, vgaReg->Graphics[i]); } ErrorF("\n"); ErrorF("ATTR: "); for (i = 0; i < vgaReg->numAttribute; i++) { if ((i & 7) == 0) ErrorF("\n"); ErrorF(" %d: %x", i, vgaReg->Attribute[i]); } ErrorF("\n"); ErrorF(" DisplayControl: %x\n", mode->DisplayControl); ErrorF(" PixelPipeCfg0: %x\n", mode->PixelPipeCfg0); ErrorF(" PixelPipeCfg1: %x\n", mode->PixelPipeCfg1); ErrorF(" PixelPipeCfg2: %x\n", mode->PixelPipeCfg2); ErrorF(" VideoClk2_M: %x\n", mode->VideoClk2_M); ErrorF(" VideoClk2_N: %x\n", mode->VideoClk2_N); ErrorF(" VideoClk2_DivisorSel: %x\n", mode->VideoClk2_DivisorSel); ErrorF(" AddressMapping: %x\n", mode->AddressMapping); ErrorF(" IOControl: %x\n", mode->IOControl); ErrorF(" BitBLTControl: %x\n", mode->BitBLTControl); ErrorF(" ExtVertTotal: %x\n", mode->ExtVertTotal); ErrorF(" ExtVertDispEnd: %x\n", mode->ExtVertDispEnd); ErrorF(" ExtVertSyncStart: %x\n", mode->ExtVertSyncStart); ErrorF(" ExtVertBlankStart: %x\n", mode->ExtVertBlankStart); ErrorF(" ExtHorizTotal: %x\n", mode->ExtHorizTotal); ErrorF(" ExtHorizBlank: %x\n", mode->ExtHorizBlank); ErrorF(" ExtOffset: %x\n", mode->ExtOffset); ErrorF(" InterlaceControl: %x\n", mode->InterlaceControl); ErrorF(" LMI_FIFO_Watermark: %x\n", mode->LMI_FIFO_Watermark); ErrorF(" LprbTail: %x\n", mode->LprbTail); ErrorF(" LprbHead: %x\n", mode->LprbHead); ErrorF(" LprbStart: %x\n", mode->LprbStart); ErrorF(" LprbLen: %x\n", mode->LprbLen); } static void DoRestore(ScrnInfoPtr scrn, vgaRegPtr vgaReg, I810RegPtr i810Reg, Bool restoreFonts) { I810Ptr pI810; vgaHWPtr hwp; unsigned char temp; unsigned int itemp; int i; pI810 = I810PTR(scrn); hwp = VGAHWPTR(scrn); if (I810_DEBUG & DEBUG_VERBOSE_VGA) { ErrorF("Setting mode in I810Restore:\n"); i810PrintMode(vgaReg, i810Reg); } vgaHWProtect(scrn, TRUE); usleep(50000); /* Turn off DRAM Refresh */ temp = INREG8(DRAM_ROW_CNTL_HI); temp &= ~DRAM_REFRESH_RATE; temp |= DRAM_REFRESH_DISABLE; OUTREG8(DRAM_ROW_CNTL_HI, temp); usleep(1000); /* Wait 1 ms */ /* Write the M, N and P values */ OUTREG16(VCLK2_VCO_M, i810Reg->VideoClk2_M); OUTREG16(VCLK2_VCO_N, i810Reg->VideoClk2_N); OUTREG8(VCLK2_VCO_DIV_SEL, i810Reg->VideoClk2_DivisorSel); /* * Turn on 8 bit dac mode, if requested. This is needed to make * sure that vgaHWRestore writes the values into the DAC properly. * The problem occurs if 8 bit dac mode is requested and the HW is * in 6 bit dac mode. If this happens, all the values are * automatically shifted left twice by the HW and incorrect colors * will be displayed on the screen. The only time this can happen * is at server startup time and when switching back from a VT. */ temp = INREG8(PIXPIPE_CONFIG_0); temp &= 0x7F; /* Save all but the 8 bit dac mode bit */ temp |= (i810Reg->PixelPipeCfg0 & DAC_8_BIT); OUTREG8(PIXPIPE_CONFIG_0, temp); /* * Code to restore any SVGA registers that have been saved/modified * goes here. Note that it is allowable, and often correct, to * only modify certain bits in a register by a read/modify/write cycle. * * A special case - when using an external clock-setting program, * this function must not change bits associated with the clock * selection. This condition can be checked by the condition: * * if (i810Reg->std.NoClock >= 0) * restore clock-select bits. */ if (restoreFonts) vgaHWRestore(scrn, vgaReg, VGA_SR_FONTS | VGA_SR_MODE | VGA_SR_CMAP); else vgaHWRestore(scrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); hwp->writeCrtc(hwp, EXT_VERT_TOTAL, i810Reg->ExtVertTotal); hwp->writeCrtc(hwp, EXT_VERT_DISPLAY, i810Reg->ExtVertDispEnd); hwp->writeCrtc(hwp, EXT_VERT_SYNC_START, i810Reg->ExtVertSyncStart); hwp->writeCrtc(hwp, EXT_VERT_BLANK_START, i810Reg->ExtVertBlankStart); hwp->writeCrtc(hwp, EXT_HORIZ_TOTAL, i810Reg->ExtHorizTotal); hwp->writeCrtc(hwp, EXT_HORIZ_BLANK, i810Reg->ExtHorizBlank); hwp->writeCrtc(hwp, EXT_OFFSET, i810Reg->ExtOffset); temp = hwp->readCrtc(hwp, INTERLACE_CNTL); temp &= ~INTERLACE_ENABLE; temp |= i810Reg->InterlaceControl; hwp->writeCrtc(hwp, INTERLACE_CNTL, temp); temp = hwp->readGr(hwp, ADDRESS_MAPPING); temp &= 0xE0; /* Save reserved bits 7:5 */ temp |= i810Reg->AddressMapping; hwp->writeGr(hwp, ADDRESS_MAPPING, temp); /* Setting the OVRACT Register for video overlay */ { uint32_t LCD_TV_Control = INREG(LCD_TV_C); uint32_t TV_HTotal = INREG(LCD_TV_HTOTAL); uint32_t ActiveStart, ActiveEnd; if((LCD_TV_Control & LCD_TV_ENABLE) && !(LCD_TV_Control & LCD_TV_VGAMOD) && TV_HTotal) { ActiveStart = ((TV_HTotal >> 16) & 0xfff) - 31; ActiveEnd = (TV_HTotal & 0x3ff) - 31; } else { ActiveStart = i810Reg->OverlayActiveStart; ActiveEnd = i810Reg->OverlayActiveEnd; } OUTREG(LCD_TV_OVRACT, (ActiveEnd << 16) | ActiveStart); } /* Turn on DRAM Refresh */ temp = INREG8(DRAM_ROW_CNTL_HI); temp &= ~DRAM_REFRESH_RATE; temp |= DRAM_REFRESH_60HZ; OUTREG8(DRAM_ROW_CNTL_HI, temp); temp = INREG8(BITBLT_CNTL); temp &= ~COLEXP_MODE; temp |= i810Reg->BitBLTControl; OUTREG8(BITBLT_CNTL, temp); temp = INREG8(DISPLAY_CNTL); temp &= ~(VGA_WRAP_MODE | GUI_MODE); temp |= i810Reg->DisplayControl; OUTREG8(DISPLAY_CNTL, temp); temp = INREG8(PIXPIPE_CONFIG_0); temp &= 0x64; /* Save reserved bits 6:5,2 */ temp |= i810Reg->PixelPipeCfg0; OUTREG8(PIXPIPE_CONFIG_0, temp); temp = INREG8(PIXPIPE_CONFIG_2); temp &= 0xF3; /* Save reserved bits 7:4,1:0 */ temp |= i810Reg->PixelPipeCfg2; OUTREG8(PIXPIPE_CONFIG_2, temp); temp = INREG8(PIXPIPE_CONFIG_1); temp &= ~DISPLAY_COLOR_MODE; temp &= 0xEF; /* Restore the CRT control bit */ temp |= i810Reg->PixelPipeCfg1; OUTREG8(PIXPIPE_CONFIG_1, temp); OUTREG16(EIR, 0); itemp = INREG(FWATER_BLC); itemp &= ~(LM_BURST_LENGTH | LM_FIFO_WATERMARK | MM_BURST_LENGTH | MM_FIFO_WATERMARK); itemp |= i810Reg->LMI_FIFO_Watermark; OUTREG(FWATER_BLC, itemp); for (i = 0; i < 8; i++) { OUTREG(FENCE + i * 4, i810Reg->Fence[i]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) ErrorF("Fence Register : %x\n", i810Reg->Fence[i]); } /* First disable the ring buffer (Need to wait for empty first?, if so * should probably do it before entering this section) */ itemp = INREG(LP_RING + RING_LEN); itemp &= ~RING_VALID_MASK; OUTREG(LP_RING + RING_LEN, itemp); /* Set up the low priority ring buffer. */ OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_HEAD, 0); pI810->LpRing->head = 0; pI810->LpRing->tail = 0; itemp = INREG(LP_RING + RING_START); itemp &= ~(START_ADDR); itemp |= i810Reg->LprbStart; OUTREG(LP_RING + RING_START, itemp); itemp = INREG(LP_RING + RING_LEN); itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK); itemp |= i810Reg->LprbLen; OUTREG(LP_RING + RING_LEN, itemp); if (!(vgaReg->Attribute[0x10] & 0x1)) { usleep(50000); if (restoreFonts) vgaHWRestore(scrn, vgaReg, VGA_SR_FONTS | VGA_SR_MODE | VGA_SR_CMAP); else vgaHWRestore(scrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); } vgaHWProtect(scrn, FALSE); temp = hwp->readCrtc(hwp, IO_CTNL); temp &= ~(EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL); temp |= i810Reg->IOControl; hwp->writeCrtc(hwp, IO_CTNL, temp); } static void I810SetRingRegs(ScrnInfoPtr scrn) { unsigned int itemp; I810Ptr pI810 = I810PTR(scrn); OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_HEAD, 0); itemp = INREG(LP_RING + RING_START); itemp &= ~(START_ADDR); itemp |= pI810->LpRing->mem.Start; OUTREG(LP_RING + RING_START, itemp); itemp = INREG(LP_RING + RING_LEN); itemp &= ~(RING_NR_PAGES | RING_REPORT_MASK | RING_VALID_MASK); itemp |= ((pI810->LpRing->mem.Size - 4096) | RING_NO_REPORT | RING_VALID); OUTREG(LP_RING + RING_LEN, itemp); } static void I810Restore(ScrnInfoPtr scrn) { vgaHWPtr hwp; I810Ptr pI810; hwp = VGAHWPTR(scrn); pI810 = I810PTR(scrn); DoRestore(scrn, &hwp->SavedReg, &pI810->SavedReg, TRUE); } /* * I810CalcVCLK -- * * Determine the closest clock frequency to the one requested. */ #define MAX_VCO_FREQ 600.0 #define TARGET_MAX_N 30 #define REF_FREQ 24.0 #define CALC_VCLK(m,n,p) \ (double)m / ((double)n * (1 << p)) * 4 * REF_FREQ static void I810CalcVCLK(ScrnInfoPtr scrn, double freq) { I810Ptr pI810 = I810PTR(scrn); I810RegPtr i810Reg = &pI810->ModeReg; int m, n, p; double f_out; double f_err; double f_vco; int m_best = 0, n_best = 0, p_best = 0; double f_target = freq; double err_max = 0.005; double err_target = 0.001; double err_best = 999999.0; p_best = p = log(MAX_VCO_FREQ / f_target) / log((double)2); /* Make sure p is within range. */ if (p_best > 5) { p_best = p = 5; } f_vco = f_target * (1 << p); n = 2; do { n++; m = f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5; if (m < 3) m = 3; f_out = CALC_VCLK(m, n, p); f_err = 1.0 - (f_target / f_out); if (fabs(f_err) < err_max) { m_best = m; n_best = n; err_best = f_err; } } while ((fabs(f_err) >= err_target) && ((n <= TARGET_MAX_N) || (fabs(err_best) > err_max))); if (fabs(f_err) < err_target) { m_best = m; n_best = n; } i810Reg->VideoClk2_M = (m_best - 2) & 0x3FF; i810Reg->VideoClk2_N = (n_best - 2) & 0x3FF; i810Reg->VideoClk2_DivisorSel = (p_best << 4); xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, 3, "Setting dot clock to %.1f MHz " "[ 0x%x 0x%x 0x%x ] " "[ %d %d %d ]\n", CALC_VCLK(m_best, n_best, p_best), i810Reg->VideoClk2_M, i810Reg->VideoClk2_N, i810Reg->VideoClk2_DivisorSel, m_best, n_best, p_best); } static Bool I810SetMode(ScrnInfoPtr scrn, DisplayModePtr mode) { I810Ptr pI810 = I810PTR(scrn); I810RegPtr i810Reg = &pI810->ModeReg; vgaRegPtr pVga = &VGAHWPTR(scrn)->ModeReg; double dclk = mode->Clock / 1000.0; switch (scrn->bitsPerPixel) { case 8: pVga->CRTC[0x13] = scrn->displayWidth >> 3; i810Reg->ExtOffset = scrn->displayWidth >> 11; i810Reg->PixelPipeCfg1 = DISPLAY_8BPP_MODE; i810Reg->BitBLTControl = COLEXP_8BPP; break; case 16: if (scrn->weight.green == 5) { i810Reg->PixelPipeCfg1 = DISPLAY_15BPP_MODE; } else { i810Reg->PixelPipeCfg1 = DISPLAY_16BPP_MODE; } pVga->CRTC[0x13] = scrn->displayWidth >> 2; i810Reg->ExtOffset = scrn->displayWidth >> 10; i810Reg->BitBLTControl = COLEXP_16BPP; /* Enable Palette Programming for Direct Color visuals. -jens */ i810Reg->PixelPipeCfg2 = DISPLAY_GAMMA_ENABLE; break; case 24: pVga->CRTC[0x13] = (scrn->displayWidth * 3) >> 3; i810Reg->ExtOffset = (scrn->displayWidth * 3) >> 11; i810Reg->PixelPipeCfg1 = DISPLAY_24BPP_MODE; i810Reg->BitBLTControl = COLEXP_24BPP; /* Enable Palette Programming for Direct Color visuals. -jens */ i810Reg->PixelPipeCfg2 = DISPLAY_GAMMA_ENABLE; break; default: break; } /* Turn on 8 bit dac if requested */ if (xf86ReturnOptValBool(pI810->Options, OPTION_DAC_6BIT, FALSE)) i810Reg->PixelPipeCfg0 = DAC_6_BIT; else i810Reg->PixelPipeCfg0 = DAC_8_BIT; /* Do not delay CRT Blank: needed for video overlay */ i810Reg->PixelPipeCfg1 |= 0x10; /* Turn on Extended VGA Interpretation */ i810Reg->IOControl = EXTENDED_CRTC_CNTL; /* Turn on linear and page mapping */ i810Reg->AddressMapping = (LINEAR_MODE_ENABLE | GTT_MEM_MAP_ENABLE); /* Turn on GUI mode */ i810Reg->DisplayControl = HIRES_MODE; /* Calculate the extended CRTC regs */ i810Reg->ExtVertTotal = (mode->CrtcVTotal - 2) >> 8; i810Reg->ExtVertDispEnd = (mode->CrtcVDisplay - 1) >> 8; i810Reg->ExtVertSyncStart = mode->CrtcVSyncStart >> 8; i810Reg->ExtVertBlankStart = mode->CrtcVBlankStart >> 8; i810Reg->ExtHorizTotal = ((mode->CrtcHTotal >> 3) - 5) >> 8; i810Reg->ExtHorizBlank = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 6; /* * the KGA fix in vgaHW.c results in the first * scanline and the first character clock (8 pixels) * of each scanline thereafter on display with an i810 * to be blank. Restoring CRTC 3, 5, & 22 to their * "theoretical" values corrects the problem. KAO. */ pVga->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80; pVga->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2) | (((mode->CrtcHSyncEnd >> 3)) & 0x1F); pVga->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; i810Reg->ExtHorizBlank = vgaHWHBlankKGA(mode, pVga, 7, 0); vgaHWVBlankKGA(mode, pVga, 8, 0); /* * The following workarounds are needed to get video overlay working * at 1024x768 and 1280x1024 display resolutions. */ if ((mode->CrtcVDisplay == 768) && (i810Reg->ExtVertBlankStart == 3)) { i810Reg->ExtVertBlankStart = 2; } if ((mode->CrtcVDisplay == 1024) && (i810Reg->ExtVertBlankStart == 4)) { i810Reg->ExtVertBlankStart = 3; } /* OVRACT Register */ i810Reg->OverlayActiveStart = mode->CrtcHTotal - 32; i810Reg->OverlayActiveEnd = mode->CrtcHDisplay - 32; /* Turn on interlaced mode if necessary */ if (mode->Flags & V_INTERLACE) { i810Reg->InterlaceControl = INTERLACE_ENABLE; i810Reg->ExtVertDispEnd *= 2; } else i810Reg->InterlaceControl = INTERLACE_DISABLE; /* * Set the overscan color to 0. * NOTE: This only affects >8bpp mode. */ pVga->Attribute[0x11] = 0; /* * Calculate the VCLK that most closely matches the requested dot * clock. */ I810CalcVCLK(scrn, dclk); /* Since we program the clocks ourselves, always use VCLK2. */ pVga->MiscOutReg |= 0x0C; /* Calculate the FIFO Watermark and Burst Length. */ i810Reg->LMI_FIFO_Watermark = I810CalcWatermark(scrn, dclk, FALSE); /* Setup the ring buffer */ i810Reg->LprbTail = 0; i810Reg->LprbHead = 0; i810Reg->LprbStart = pI810->LpRing->mem.Start; if (i810Reg->LprbStart) i810Reg->LprbLen = ((pI810->LpRing->mem.Size - 4096) | RING_NO_REPORT | RING_VALID); else i810Reg->LprbLen = RING_INVALID; return TRUE; } static Bool I810ModeInit(ScrnInfoPtr scrn, DisplayModePtr mode) { vgaHWPtr hwp; I810Ptr pI810; hwp = VGAHWPTR(scrn); pI810 = I810PTR(scrn); vgaHWUnlock(hwp); if (!vgaHWInit(scrn, mode)) return FALSE; scrn->vtSema = TRUE; if (!I810SetMode(scrn, mode)) return FALSE; #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { DRILock(xf86ScrnToScreen(scrn), 0); pI810->LockHeld = 1; } #endif DoRestore(scrn, &hwp->ModeReg, &pI810->ModeReg, FALSE); #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { DRIUnlock(xf86ScrnToScreen(scrn)); pI810->LockHeld = 0; } #endif return TRUE; } static void I810LoadPalette15(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) { vgaHWPtr hwp; int i, j, index; unsigned char r, g, b; hwp = VGAHWPTR(scrn); for (i = 0; i < numColors; i++) { index = indices[i]; r = colors[index].red; g = colors[index].green; b = colors[index].blue; for (j = 0; j < 8; j++) { hwp->writeDacWriteAddr(hwp, (index << 3) + j); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); } } } static void I810LoadPalette16(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) { vgaHWPtr hwp; int i, index; unsigned char r, g, b; hwp = VGAHWPTR(scrn); /* Load all four entries in each of the 64 color ranges. -jens */ for (i = 0; i < numColors; i++) { index = indices[i / 2]; r = colors[index].red; b = colors[index].blue; index = indices[i]; g = colors[index].green; hwp->writeDacWriteAddr(hwp, index << 2); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 1); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 2); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 3); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); i++; index = indices[i]; g = colors[index].green; hwp->writeDacWriteAddr(hwp, index << 2); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 1); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 2); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); hwp->writeDacWriteAddr(hwp, (index << 2) + 3); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); } } static void I810LoadPalette24(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) { vgaHWPtr hwp; int i, index; unsigned char r, g, b; hwp = VGAHWPTR(scrn); for (i = 0; i < numColors; i++) { index = indices[i]; r = colors[index].red; g = colors[index].green; b = colors[index].blue; hwp->writeDacWriteAddr(hwp, index); hwp->writeDacData(hwp, r); hwp->writeDacData(hwp, g); hwp->writeDacData(hwp, b); } } Bool I810AllocateFront(ScrnInfoPtr scrn) { I810Ptr pI810 = I810PTR(scrn); int cache_lines = -1; if (pI810->DoneFrontAlloc) return TRUE; memset(&(pI810->FbMemBox), 0, sizeof(BoxRec)); /* Alloc FrontBuffer/Ring/Accel memory */ pI810->FbMemBox.x1 = 0; pI810->FbMemBox.x2 = scrn->displayWidth; pI810->FbMemBox.y1 = 0; pI810->FbMemBox.y2 = scrn->virtualY; xf86GetOptValInteger(pI810->Options, OPTION_CACHE_LINES, &cache_lines); if (cache_lines < 0) { /* make sure there is enough for two DVD sized YUV buffers */ cache_lines = (scrn->depth == 24) ? 256 : 384; if (scrn->displayWidth <= 1024) cache_lines *= 2; } /* Make sure there's enough space for cache_lines. * * Had a bug here where maxCacheLines was computed to be less than 0. * Not sure why 256 was initially subtracted from videoRam in the * maxCacheLines calculation, but that was causing a problem * for configurations that have exactly enough Ram for the framebuffer. * Common code should catch the case where there isn't enough space for * framebuffer, we'll just check for no space for cache_lines. -jens * */ { int maxCacheLines; maxCacheLines = (scrn->videoRam * 1024 / (scrn->bitsPerPixel / 8) / scrn->displayWidth) - scrn->virtualY; if (maxCacheLines < 0) maxCacheLines = 0; if (cache_lines > maxCacheLines) cache_lines = maxCacheLines; } pI810->FbMemBox.y2 += cache_lines; xf86DrvMsg(scrn->scrnIndex, X_INFO, "Adding %i scanlines for pixmap caching\n", cache_lines); /* Reserve room for the framebuffer and pixcache. Put at the top * of memory so we can have nice alignment for the tiled regions at * the start of memory. */ if (!I810AllocLow(&(pI810->FrontBuffer), &(pI810->SysMem), ALIGN((pI810->FbMemBox.x2 * pI810->FbMemBox.y2 * pI810->cpp), 4096))) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Framebuffer allocation failed\n"); return FALSE; } memset(pI810->LpRing, 0, sizeof(I810RingBuffer)); if (I810AllocLow(&(pI810->LpRing->mem), &(pI810->SysMem), 16 * 4096)) { pI810->LpRing->tail_mask = pI810->LpRing->mem.Size - 1; pI810->LpRing->virtual_start = pI810->FbBase + pI810->LpRing->mem.Start; pI810->LpRing->head = 0; pI810->LpRing->tail = 0; pI810->LpRing->space = 0; } else { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Ring buffer allocation failed\n"); return (FALSE); } if (I810AllocLow(&pI810->Scratch, &(pI810->SysMem), 64 * 1024) || I810AllocLow(&pI810->Scratch, &(pI810->SysMem), 16 * 1024)) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocated Scratch Memory\n"); } else { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Scratch memory allocation failed\n"); return (FALSE); } pI810->DoneFrontAlloc = TRUE; return TRUE; } static Bool I810ScreenInit(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr scrn; vgaHWPtr hwp; I810Ptr pI810; VisualPtr visual; scrn = xf86ScreenToScrn(screen); pI810 = I810PTR(scrn); hwp = VGAHWPTR(scrn); pI810->LpRing = calloc(sizeof(I810RingBuffer),1); if (!pI810->LpRing) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Could not allocate lpring data structure.\n"); return FALSE; } miClearVisualTypes(); /* Re-implemented Direct Color support, -jens */ if (!miSetVisualTypes(scrn->depth, miGetDefaultVisualMask(scrn->depth), scrn->rgbBits, scrn->defaultVisual)) return FALSE; if (!miSetPixmapDepths()) return FALSE; { I810RegPtr i810Reg = &pI810->ModeReg; int i; for (i = 0; i < 8; i++) i810Reg->Fence[i] = 0; } /* Have to init the DRM earlier than in other drivers to get agp * memory. Wonder if this is going to be a problem... */ #ifdef HAVE_DRI1 /* * Setup DRI after visuals have been established, but before fbScreenInit * is called. fbScreenInit will eventually call into the drivers * InitGLXVisuals call back. */ /* * pI810->directRenderingDisabled is set once in PreInit. Reinitialise * pI810->directRenderingEnabled based on it each generation. */ pI810->directRenderingEnabled = !pI810->directRenderingDisabled; if (pI810->directRenderingEnabled==TRUE) pI810->directRenderingEnabled = I810DRIScreenInit(screen); #else pI810->directRenderingEnabled = FALSE; if (!I810AllocateGARTMemory(scrn)) return FALSE; if (!I810AllocateFront(scrn)) return FALSE; #endif if (!I810MapMem(scrn)) return FALSE; scrn->memPhysBase = (unsigned long)pI810->LinearAddr; scrn->fbOffset = 0; vgaHWSetMmioFuncs(hwp, pI810->MMIOBase, 0); vgaHWGetIOBase(hwp); if (!vgaHWMapMem(scrn)) return FALSE; I810Save(scrn); if (!I810ModeInit(scrn, scrn->currentMode)) return FALSE; I810SaveScreen(screen, FALSE); I810AdjustFrame(ADJUST_FRAME_ARGS(scrn, scrn->frameX0, scrn->frameY0)); if (!fbScreenInit(screen, pI810->FbBase + scrn->fbOffset, scrn->virtualX, scrn->virtualY, scrn->xDpi, scrn->yDpi, scrn->displayWidth, scrn->bitsPerPixel)) return FALSE; if (scrn->bitsPerPixel > 8) { /* Fixup RGB ordering */ visual = screen->visuals + screen->numVisuals; while (--visual >= screen->visuals) { if ((visual->class | DynamicClass) == DirectColor) { visual->offsetRed = scrn->offset.red; visual->offsetGreen = scrn->offset.green; visual->offsetBlue = scrn->offset.blue; visual->redMask = scrn->mask.red; visual->greenMask = scrn->mask.green; visual->blueMask = scrn->mask.blue; } } } fbPictureInit(screen, NULL, 0); xf86SetBlackWhitePixels(screen); #ifdef HAVE_DRI1 if (pI810->LpRing->mem.Start == 0 && pI810->directRenderingEnabled) { pI810->directRenderingEnabled = FALSE; I810DRICloseScreen(screen); } if (!pI810->directRenderingEnabled) { pI810->DoneFrontAlloc = FALSE; if (!I810AllocateGARTMemory(scrn)) return FALSE; if (!I810AllocateFront(scrn)) return FALSE; } #endif #ifdef HAVE_DGAPROC_H I810DGAInit(screen); #endif if (!xf86InitFBManager(screen, &(pI810->FbMemBox))) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to init memory manager\n"); return FALSE; } if (pI810->LpRing->mem.Size != 0) { I810SetRingRegs(scrn); if (!pI810->noAccel && !I810AccelInit(screen)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Hardware acceleration initialization failed\n"); } I810EmitFlush(scrn); } xf86SetBackingStore(screen); xf86SetSilkenMouse(screen); miDCInitialize(screen, xf86GetPointerScreenFuncs()); if (!xf86ReturnOptValBool(pI810->Options, OPTION_SW_CURSOR, FALSE)) { if (!I810CursorInit(screen)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); } } if (!miCreateDefColormap(screen)) return FALSE; /* Use driver specific palette load routines for Direct Color support. -jens */ if (scrn->bitsPerPixel == 16) { if (scrn->depth == 15) { if (!xf86HandleColormaps(screen, 256, 8, I810LoadPalette15, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } else { if (!xf86HandleColormaps(screen, 256, 8, I810LoadPalette16, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } } else { if (!xf86HandleColormaps(screen, 256, 8, I810LoadPalette24, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } xf86DPMSInit(screen, I810DisplayPowerManagementSet, 0); I810InitVideo(screen); #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { /* Now that mi, fb, drm and others have done their thing, * complete the DRI setup. */ pI810->directRenderingEnabled = I810DRIFinishScreenInit(screen); } #ifdef XvMCExtension if ((pI810->directRenderingEnabled) && (pI810->numSurfaces)) { /* Initialize the hardware motion compensation code */ I810InitMC(screen); } #endif #endif if (pI810->directRenderingEnabled) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); } else { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); } screen->SaveScreen = I810SaveScreen; pI810->CloseScreen = screen->CloseScreen; screen->CloseScreen = I810CloseScreen; if (serverGeneration == 1) xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); return TRUE; } Bool I810SwitchMode(SWITCH_MODE_ARGS_DECL) { SCRN_INFO_PTR(arg); #if 0 I810Ptr pI810 = I810PTR(scrn); #endif if (I810_DEBUG & DEBUG_VERBOSE_CURSOR) ErrorF("I810SwitchMode %p\n", (void *)mode); #if 0 /* * This has been added to prevent lockups on mode switch by modeling * it after I810Leave()/I810Enter() but the call to I810DRILeave() * was missing so it caused the opposite. * The version below works but it is doubtful it does any good. * If lockups on mode switch are still seen revisit this code. (EE) */ # ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("calling dri lock\n"); DRILock(screenInfo.screens[scrnIndex], 0); pI810->LockHeld = 1; } # endif if (pI810->AccelInfoRec != NULL) { I810RefreshRing(scrn); I810Sync(scrn); pI810->AccelInfoRec->NeedToSync = FALSE; } I810Restore(scrn); # ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { if (!I810DRILeave(scrn)) return FALSE; if (!I810DRIEnter(scrn)) return FALSE; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("calling dri unlock\n"); DRIUnlock(screenInfo.screens[scrnIndex]); pI810->LockHeld = 0; } # endif #endif return I810ModeInit(scrn, mode); } void I810AdjustFrame(ADJUST_FRAME_ARGS_DECL) { SCRN_INFO_PTR(arg); I810Ptr pI810 = I810PTR(scrn); vgaHWPtr hwp = VGAHWPTR(scrn); int Base; #if 1 if (pI810->showCache) { int lastline = pI810->FbMapSize / ((scrn->displayWidth * scrn->bitsPerPixel) / 8); lastline -= scrn->currentMode->VDisplay; if (y > 0) y += scrn->currentMode->VDisplay; if (y > lastline) y = lastline; } #endif Base = (y * scrn->displayWidth + x) >> 2; if (I810_DEBUG & DEBUG_VERBOSE_CURSOR) ErrorF("I810AdjustFrame %d,%d\n", x, y); switch (scrn->bitsPerPixel) { case 8: break; case 16: Base *= 2; break; case 24: /* KW: Need to do 16-pixel alignment for i810, otherwise you * get bad watermark problems. Need to fixup the mouse * pointer positioning to take this into account. */ pI810->CursorOffset = (Base & 0x3) * 4; Base &= ~0x3; Base *= 3; break; case 32: Base *= 4; break; } hwp->writeCrtc(hwp, START_ADDR_LO, Base & 0xFF); hwp->writeCrtc(hwp, START_ADDR_HI, (Base & 0xFF00) >> 8); hwp->writeCrtc(hwp, EXT_START_ADDR_HI, (Base & 0x3FC00000) >> 22); hwp->writeCrtc(hwp, EXT_START_ADDR, ((Base & 0x00eF0000) >> 16 | EXT_START_ADDR_ENABLE)); } /* These functions are usually called with the lock **not held**. */ static Bool I810EnterVT(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); #ifdef HAVE_DRI1 I810Ptr pI810 = I810PTR(scrn); #endif if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("\n\nENTER VT\n"); if (!I810BindGARTMemory(scrn)) { return FALSE; } #ifdef HAVE_DRI1 if (!I810DRIEnter(scrn)) { return FALSE; } if (pI810->directRenderingEnabled) { if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("calling dri unlock\n"); DRIUnlock(xf86ScrnToScreen(scrn)); pI810->LockHeld = 0; } #endif if (!I810ModeInit(scrn, scrn->currentMode)) return FALSE; I810AdjustFrame(ADJUST_FRAME_ARGS(scrn, scrn->frameX0, scrn->frameY0)); return TRUE; } static void I810LeaveVT(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); vgaHWPtr hwp = VGAHWPTR(scrn); I810Ptr pI810 = I810PTR(scrn); if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("\n\n\nLeave VT\n"); #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("calling dri lock\n"); DRILock(xf86ScrnToScreen(scrn), 0); pI810->LockHeld = 1; } #endif #ifdef HAVE_XAA_H if (pI810->AccelInfoRec != NULL) { I810RefreshRing(scrn); I810Sync(scrn); pI810->AccelInfoRec->NeedToSync = FALSE; } #endif I810Restore(scrn); if (!I810UnbindGARTMemory(scrn)) return; #ifdef HAVE_DRI1 if (!I810DRILeave(scrn)) return; #endif vgaHWLock(hwp); } static Bool I810CloseScreen(CLOSE_SCREEN_ARGS_DECL) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); vgaHWPtr hwp = VGAHWPTR(scrn); I810Ptr pI810 = I810PTR(scrn); #ifdef HAVE_XAA_H XAAInfoRecPtr infoPtr = pI810->AccelInfoRec; #endif if (scrn->vtSema == TRUE) { #ifdef HAVE_XAA_H if (pI810->AccelInfoRec != NULL) { I810RefreshRing(scrn); I810Sync(scrn); pI810->AccelInfoRec->NeedToSync = FALSE; } #endif I810Restore(scrn); vgaHWLock(hwp); } #ifdef HAVE_DRI1 if (pI810->directRenderingEnabled) { I810DRICloseScreen(screen); pI810->directRenderingEnabled = FALSE; } #endif if (scrn->vtSema == TRUE) { I810UnbindGARTMemory(scrn); I810Restore(scrn); vgaHWLock(hwp); } I810UnmapMem(scrn); vgaHWUnmapMem(scrn); if (pI810->ScanlineColorExpandBuffers) { free(pI810->ScanlineColorExpandBuffers); pI810->ScanlineColorExpandBuffers = NULL; } #ifdef HAVE_XAA_H if (infoPtr) { if (infoPtr->ScanlineColorExpandBuffers) free(infoPtr->ScanlineColorExpandBuffers); XAADestroyInfoRec(infoPtr); pI810->AccelInfoRec = NULL; } #endif if (pI810->CursorInfoRec) { xf86DestroyCursorInfoRec(pI810->CursorInfoRec); pI810->CursorInfoRec = NULL; } /* Free all allocated video ram. */ pI810->SysMem = pI810->SavedSysMem; pI810->DcacheMem = pI810->SavedDcacheMem; pI810->DoneFrontAlloc = FALSE; /* Need to actually close the gart fd, or the unbound memory will just sit * around. Will prevent the Xserver from recycling. */ xf86GARTCloseScreen(scrn->scrnIndex); free(pI810->LpRing); pI810->LpRing = NULL; scrn->vtSema = FALSE; screen->CloseScreen = pI810->CloseScreen; return (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); } static void I810FreeScreen(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); I810FreeRec(scrn); if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(scrn); } static ModeStatus I810ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { SCRN_INFO_PTR(arg); if (mode->Flags & V_INTERLACE) { if (verbose) { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Removing interlaced mode \"%s\"\n", mode->name); } return MODE_BAD; } return MODE_OK; } static Bool I810SaveScreen(ScreenPtr screen, Bool unblack) { return vgaHWSaveScreen(screen, unblack); } static void I810DisplayPowerManagementSet(ScrnInfoPtr scrn, int PowerManagementMode, int flags) { I810Ptr pI810; unsigned char SEQ01 = 0; int DPMSSyncSelect = 0; vgaHWPtr hwp; pI810 = I810PTR(scrn); switch (PowerManagementMode) { case DPMSModeOn: /* Screen: On; HSync: On, VSync: On */ SEQ01 = 0x00; DPMSSyncSelect = HSYNC_ON | VSYNC_ON; break; case DPMSModeStandby: /* Screen: Off; HSync: Off, VSync: On */ SEQ01 = 0x20; DPMSSyncSelect = HSYNC_OFF | VSYNC_ON; break; case DPMSModeSuspend: /* Screen: Off; HSync: On, VSync: Off */ SEQ01 = 0x20; DPMSSyncSelect = HSYNC_ON | VSYNC_OFF; break; case DPMSModeOff: /* Screen: Off; HSync: Off, VSync: Off */ SEQ01 = 0x20; DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF; break; } hwp = VGAHWPTR(scrn); /* Turn the screen on/off */ SEQ01 |= hwp->readSeq(hwp, 0x01) & ~0x20; hwp->writeSeq(hwp, 0x01, SEQ01); /* Set the DPMS mode */ OUTREG8(DPMS_SYNC_SELECT, DPMSSyncSelect); } const OptionInfoRec * lg_i810_available_options(int chipid, int busid) { return I810Options; } Bool lg_i810_init(ScrnInfoPtr scrn) { scrn->PreInit = I810PreInit; scrn->ScreenInit = I810ScreenInit; scrn->SwitchMode = I810SwitchMode; scrn->AdjustFrame = I810AdjustFrame; scrn->EnterVT = I810EnterVT; scrn->LeaveVT = I810LeaveVT; scrn->FreeScreen = I810FreeScreen; scrn->ValidMode = I810ValidMode; return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_hwmc.c000066400000000000000000000267531267532330400246670ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i810_hwmc.c: i810 HWMC Driver * * Authors: * Matt Sottek * * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" #include "i810.h" #include "i810_dri.h" #include "xf86xv.h" #include "xf86xvmc.h" #include #include #include "dixstruct.h" #include "fourcc.h" int I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, int *num_priv, long **priv ); void I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext); int I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, int *num_priv, long **priv ); void I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf); int I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf, int *num_priv, long **priv ); void I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSurf); typedef struct { drm_context_t drmcontext; unsigned int fbBase; unsigned int OverlayOffset; unsigned int OverlaySize; unsigned int SurfacesOffset; unsigned int SurfacesSize; char busIdString[10]; char pad[2]; } I810XvMCCreateContextRec; static int yv12_subpicture_index_list[2] = { FOURCC_IA44, FOURCC_AI44 }; static XF86MCImageIDList yv12_subpicture_list = { 2, yv12_subpicture_index_list }; static XF86MCSurfaceInfoRec i810_YV12_mpg2_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_2, XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | XVMC_INTRA_UNSIGNED, &yv12_subpicture_list }; static XF86MCSurfaceInfoRec i810_YV12_mpg1_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_1, XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | XVMC_INTRA_UNSIGNED, &yv12_subpicture_list }; static XF86MCSurfaceInfoPtr ppSI[2] = { (XF86MCSurfaceInfoPtr)&i810_YV12_mpg2_surface, (XF86MCSurfaceInfoPtr)&i810_YV12_mpg1_surface }; /* List of subpicture types that we support */ static XF86ImageRec ia44_subpicture = XVIMAGE_IA44; static XF86ImageRec ai44_subpicture = XVIMAGE_AI44; static XF86ImagePtr i810_subpicture_list[2] = { (XF86ImagePtr)&ia44_subpicture, (XF86ImagePtr)&ai44_subpicture }; /* Fill in the device dependent adaptor record. * This is named "I810 Video Overlay" because this code falls under the * XV extenstion, the name must match or it won't be used. * * Surface and Subpicture - see above * Function pointers to functions below */ static XF86MCAdaptorRec pAdapt = { "I810 Video Overlay", /* name */ 2, /* num_surfaces */ ppSI, /* surfaces */ 2, /* num_subpictures */ i810_subpicture_list, /* subpictures */ (xf86XvMCCreateContextProcPtr)I810XvMCCreateContext, (xf86XvMCDestroyContextProcPtr)I810XvMCDestroyContext, (xf86XvMCCreateSurfaceProcPtr)I810XvMCCreateSurface, (xf86XvMCDestroySurfaceProcPtr)I810XvMCDestroySurface, (xf86XvMCCreateSubpictureProcPtr)I810XvMCCreateSubpicture, (xf86XvMCDestroySubpictureProcPtr)I810XvMCDestroySubpicture }; static XF86MCAdaptorPtr ppAdapt[1] = { (XF86MCAdaptorPtr)&pAdapt }; /************************************************************************** * * I810InitMC * * Initialize the hardware motion compensation extension for this * hardware. The initialization routines want the address of the pointers * to the structures, not the address of the structures. This means we * allocate (or create static?) the pointer memory and pass that * address. This seems a little convoluted. * * We need to allocate memory for the device depended adaptor record. * This is what holds the pointers to all our device functions. * * We need to map the overlay registers into the drm. * * We need to map the surfaces into the drm. * * Inputs: * Screen pointer * * Outputs: * None, this calls the device independent screen initialization * function. * * Revisions: * **************************************************************************/ void I810InitMC(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); int i; /* Clear the Surface Allocation */ for(i=0; isurfaceAllocation[i] = 0; } /* Cursor is at a page boundary, Overlay regs are not, don't forget */ if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->CursorStart, 4096, DRM_AGP, 0, (drmAddress) &pI810->overlay_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(overlay) failed\n"); return; } if (drmAddMap(pI810->drmSubFD, (drm_handle_t)pI810->MC.Start, pI810->MC.Size, DRM_AGP, 0, (drmAddress) &pI810->mc_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap(MC) failed\n"); return; } xf86XvMCScreenInit(pScreen, 1, ppAdapt); } /************************************************************************** * * I810XvMCCreateContext * * Some info about the private data: * * Set *num_priv to the number of 32bit words that make up the size of * of the data that priv will point to. * * *priv = (long *) calloc (elements, sizeof(element)) * *num_priv = (elements * sizeof(element)) >> 2; * **************************************************************************/ int I810XvMCCreateContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext, int *num_priv, long **priv ) { I810Ptr pI810 = I810PTR(pScrn); DRIInfoPtr pDRIInfo = pI810->pDRIInfo; I810XvMCCreateContextRec *contextRec; if(!pI810->directRenderingEnabled) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateContext: Cannot use XvMC without DRI!\n"); return BadAlloc; } /* Context Already in use! */ if(pI810->xvmcContext) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "I810XvMCCreateContext: 2 XvMC Contexts Attempted, not supported.\n"); return BadAlloc; } *priv = calloc(1,sizeof(I810XvMCCreateContextRec)); contextRec = (I810XvMCCreateContextRec *)*priv; if(!*priv) { *num_priv = 0; return BadAlloc; } *num_priv = sizeof(I810XvMCCreateContextRec) >> 2; if(drmCreateContext(pI810->drmSubFD, &(contextRec->drmcontext) ) < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateContext: Unable to create DRMContext!\n"); free(*priv); return BadAlloc; } drmAuthMagic(pI810->drmSubFD, pContext->flags); pI810->xvmcContext = contextRec->drmcontext; contextRec->fbBase = pScrn->memPhysBase; /* Overlay Regs are at 1024 offset into the Cursor Space */ contextRec->OverlayOffset = pI810->CursorStart; contextRec->OverlaySize = 4096; contextRec->SurfacesOffset = pI810->MC.Start; contextRec->SurfacesSize = pI810->MC.Size; strncpy (contextRec->busIdString, pDRIInfo->busIdString, 9); return Success; } int I810XvMCCreateSurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf, int *num_priv, long **priv ) { I810Ptr pI810 = I810PTR(pScrn); int i; *priv = (long *)calloc(2,sizeof(long)); if(!*priv) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateSurface: Unable to allocate memory!\n"); *num_priv = 0; return BadAlloc; } *num_priv = 2; /* Surface Arrangement is different based on 6 or 7 Surfaces */ if(pI810->numSurfaces == 6) { for(i=0; inumSurfaces; i++) { if(!pI810->surfaceAllocation[i]) { pI810->surfaceAllocation[i] = pSurf->surface_id; /* Y data starts at 2MB offset, each surface is 576k */ (*priv)[0] = (2*1024*1024 + 576*1024 * i); /* UV data starts at 0 offset, each set is 288k */ (*priv)[1] = (576*512 * i); return Success; } } } if(pI810->numSurfaces == 7) { for(i=0; inumSurfaces; i++) { if(!pI810->surfaceAllocation[i]) { pI810->surfaceAllocation[i] = pSurf->surface_id; /* Y data starts at 2.5MB offset, each surface is 576k */ (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i); /* UV data starts at 0 offset, each set is 288k */ (*priv)[1] = (576*512 * i); return Success; } } } (*priv)[0] = 0; (*priv)[1] = 0; return BadAlloc; } int I810XvMCCreateSubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp, int *num_priv, long **priv ) { I810Ptr pI810 = I810PTR(pScrn); int i; *priv = (long *)calloc(1,sizeof(long)); if(!*priv) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I810XvMCCreateSubpicture: Unable to allocate memory!\n"); *num_priv = 0; return BadAlloc; } *num_priv = 1; if(pI810->numSurfaces == 6) { for(i=6; i<8; i++) { if(!pI810->surfaceAllocation[i]) { pI810->surfaceAllocation[i] = pSubp->subpicture_id; /* Subpictures are after the Y surfaces in memory */ (*priv)[0] = (2*1024*1024 + 576*1024 * i); return Success; } } } if(pI810->numSurfaces == 7) { for(i=7; i<9; i++) { if(!pI810->surfaceAllocation[i]) { pI810->surfaceAllocation[i] = pSubp->subpicture_id; /* Subpictures are after the Y surfaces in memory */ (*priv)[0] = (2*1024*1024 + 512*1024 + 576*1024 * i); return Success; } } } (*priv)[0] = 0; return BadAlloc; } void I810XvMCDestroyContext (ScrnInfoPtr pScrn, XvMCContextPtr pContext) { I810Ptr pI810 = I810PTR(pScrn); drmDestroyContext(pI810->drmSubFD,pI810->xvmcContext); pI810->xvmcContext = 0; } void I810XvMCDestroySurface (ScrnInfoPtr pScrn, XvMCSurfacePtr pSurf) { I810Ptr pI810 = I810PTR(pScrn); int i; for(i=0; isurfaceAllocation[i] == pSurf->surface_id) { pI810->surfaceAllocation[i] = 0; return; } } return; } void I810XvMCDestroySubpicture (ScrnInfoPtr pScrn, XvMCSubpicturePtr pSubp) { I810Ptr pI810 = I810PTR(pScrn); int i; for(i=pI810->numSurfaces; isurfaceAllocation[i] == pSubp->subpicture_id) { pI810->surfaceAllocation[i] = 0; return; } } return; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_memory.c000066400000000000000000000256751267532330400252430ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * Authors: * Keith Whitwell * */ #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "i810.h" #include "i810_reg.h" int I810AllocLow(I810MemRange * result, I810MemRange * pool, int size) { if (size > (long)pool->Size) return 0; pool->Size -= size; result->Size = size; result->Start = pool->Start; result->End = pool->Start += size; return 1; } int I810AllocHigh(I810MemRange * result, I810MemRange * pool, int size) { if (size > (long)pool->Size) return 0; pool->Size -= size; result->Size = size; result->End = pool->End; result->Start = pool->End -= size; return 1; } int I810AllocateGARTMemory(ScrnInfoPtr pScrn) { unsigned long size = pScrn->videoRam * 1024UL; I810Ptr pI810 = I810PTR(pScrn); int key; unsigned long tom = 0; unsigned long physical; if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "AGP GART support is either not available or cannot be used.\n" "\tMake sure your kernel has agpgart support or has the\n" "\tagpgart module loaded.\n"); return FALSE; } /* This allows the 2d only Xserver to regen */ pI810->agpAcquired2d = TRUE; /* * I810/I815 * * Treat the gart like video memory - we assume we own all that is * there, so ignore EBUSY errors. Don't try to remove it on * failure, either, as other X server may be using it. */ if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL)) == -1) return FALSE; pI810->VramOffset = 0; pI810->VramKey = key; if (!xf86BindGARTMemory(pScrn->scrnIndex, key, 0)) return FALSE; pI810->SysMem.Start = 0; pI810->SysMem.Size = size; pI810->SysMem.End = size; pI810->SavedSysMem = pI810->SysMem; tom = pI810->SysMem.End; pI810->DcacheMem.Start = 0; pI810->DcacheMem.End = 0; pI810->DcacheMem.Size = 0; pI810->CursorPhysical = 0; pI810->CursorARGBPhysical = 0; /* * Dcache - half the speed of normal ram, so not really useful for * a 2d server. Don't bother reporting its presence. This is * mapped in addition to the requested amount of system ram. */ size = 1024 * 4096; /* * Keep it 512K aligned for the sake of tiled regions. */ tom += 0x7ffffUL; tom &= ~0x7ffffUL; if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 1, NULL)) != -1) { pI810->DcacheOffset = tom; pI810->DcacheKey = key; if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocation of %ld bytes for DCACHE failed\n", size); pI810->DcacheKey = -1; } else { pI810->DcacheMem.Start = tom; pI810->DcacheMem.Size = size; pI810->DcacheMem.End = pI810->DcacheMem.Start + pI810->DcacheMem.Size; tom = pI810->DcacheMem.End; } } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No physical memory available for %ld bytes of DCACHE\n", size); pI810->DcacheKey = -1; } /* * Mouse cursor -- The i810 (crazy) needs a physical address in * system memory from which to upload the cursor. We get this from * the agpgart module using a special memory type. */ /* * 4k for the cursor is excessive, I'm going to steal 3k for * overlay registers later */ size = 4096; if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, &physical)) == -1) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No physical memory available for HW cursor\n"); pI810->HwcursKey = -1; pI810->CursorStart = 0; } else { pI810->HwcursOffset = tom; pI810->HwcursKey = key; if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocation of %ld bytes for HW cursor failed\n", size); pI810->HwcursKey = -1; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocated of %ld bytes for HW cursor\n", size); pI810->CursorPhysical = physical; pI810->CursorStart = tom; tom += size; } } /* * 16k for the ARGB cursor */ size = 16384; if ((key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, &physical)) == -1) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No physical memory available for ARGB HW cursor\n"); pI810->ARGBHwcursKey = -1; pI810->CursorARGBStart = 0; } else { pI810->ARGBHwcursOffset = tom; pI810->ARGBHwcursKey = key; if (!xf86BindGARTMemory(pScrn->scrnIndex, key, tom)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocation of %ld bytes for ARGB HW cursor failed\n", size); pI810->ARGBHwcursKey = -1; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Allocated of %ld bytes for ARGB HW cursor\n", size); pI810->CursorARGBPhysical = physical; pI810->CursorARGBStart = tom; tom += size; } } /* * Overlay register buffer -- Just like the cursor, the i810 needs a * physical address in system memory from which to upload the overlay * registers. */ if (pI810->CursorStart != 0) { pI810->OverlayPhysical = pI810->CursorPhysical + 1024; pI810->OverlayStart = pI810->CursorStart + 1024; } pI810->GttBound = 1; return TRUE; } /* Tiled memory is good... really, really good... * * Need to make it less likely that we miss out on this - probably * need to move the frontbuffer away from the 'guarenteed' alignment * of the first memory segment, or perhaps allocate a discontigous * framebuffer to get more alignment 'sweet spots'. */ void I810SetTiledMemory(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, unsigned int size) { I810Ptr pI810 = I810PTR(pScrn); I810RegPtr i810Reg = &pI810->ModeReg; uint32_t val; uint32_t fence_mask = 0; if (nr < 0 || nr > 7) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s - fence %d out of range\n", "I810SetTiledMemory", nr); return; } i810Reg->Fence[nr] = 0; fence_mask = ~FENCE_START_MASK; if (start & fence_mask) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: start (%x) is not 512k aligned\n", "I810SetTiledMemory", nr, start); return; } if (start % size) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: start (%x) is not size (%x) aligned\n", "I810SetTiledMemory", nr, start, size); return; } if (pitch & 127) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: pitch (%x) not a multiple of 128 bytes\n", "I810SetTiledMemory", nr, pitch); return; } val = (start | FENCE_X_MAJOR | FENCE_VALID); switch (size) { case KB(512): val |= FENCE_SIZE_512K; break; case MB(1): val |= FENCE_SIZE_1M; break; case MB(2): val |= FENCE_SIZE_2M; break; case MB(4): val |= FENCE_SIZE_4M; break; case MB(8): val |= FENCE_SIZE_8M; break; case MB(16): val |= FENCE_SIZE_16M; break; case MB(32): val |= FENCE_SIZE_32M; break; default: xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr, size); return; } switch (pitch / 128) { case 1: val |= FENCE_PITCH_1; break; case 2: val |= FENCE_PITCH_2; break; case 4: val |= FENCE_PITCH_4; break; case 8: val |= FENCE_PITCH_8; break; case 16: val |= FENCE_PITCH_16; break; case 32: val |= FENCE_PITCH_32; break; default: xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s %d: illegal size (0x%x)\n", "I810SetTiledMemory", nr, size); return; } i810Reg->Fence[nr] = val; } Bool I810BindGARTMemory(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (xf86AgpGARTSupported() && !pI810->directRenderingEnabled && !pI810->GttBound) { if (!xf86AcquireGART(pScrn->scrnIndex)) return FALSE; if (pI810->VramKey != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->VramKey, pI810->VramOffset)) return FALSE; if (pI810->DcacheKey != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->DcacheKey, pI810->DcacheOffset)) return FALSE; if (pI810->HwcursKey != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->HwcursKey, pI810->HwcursOffset)) return FALSE; if (pI810->ARGBHwcursKey != -1 && !xf86BindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey, pI810->ARGBHwcursOffset)) return FALSE; pI810->GttBound = 1; } return TRUE; } Bool I810UnbindGARTMemory(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); if (xf86AgpGARTSupported() && !pI810->directRenderingEnabled && pI810->GttBound) { if (pI810->VramKey != -1 && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->VramKey)) return FALSE; if (pI810->DcacheKey != -1 && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->DcacheKey)) return FALSE; if (pI810->HwcursKey != -1 && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->HwcursKey)) return FALSE; if (pI810->ARGBHwcursKey != -1 && !xf86UnbindGARTMemory(pScrn->scrnIndex, pI810->ARGBHwcursKey)) return FALSE; if (!xf86ReleaseGART(pScrn->scrnIndex)) return FALSE; pI810->GttBound = 0; } return TRUE; } int I810CheckAvailableMemory(ScrnInfoPtr pScrn) { AgpInfoPtr agpinf; int maxPages; if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex) || (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || !xf86ReleaseGART(pScrn->scrnIndex)) return -1; maxPages = agpinf->totalPages - agpinf->usedPages; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %dk available\n", "I810CheckAvailableMemory", maxPages * 4); return maxPages * 4; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_reg.h000066400000000000000000003104221267532330400245000ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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 * Register names and fields for Intel graphics. */ /* * Authors: * Keith Whitwell * Eric Anholt * * based on the i740 driver by * Kevin E. Martin * * */ #ifndef _I810_REG_H #define _I810_REG_H /* I/O register offsets */ #define SRX 0x3C4 /* p208 */ #define GRX 0x3CE /* p213 */ #define ARX 0x3C0 /* p224 */ /* VGA Color Palette Registers */ #define DACMASK 0x3C6 /* p232 */ #define DACSTATE 0x3C7 /* p232 */ #define DACRX 0x3C7 /* p233 */ #define DACWX 0x3C8 /* p233 */ #define DACDATA 0x3C9 /* p233 */ /* CRT Controller Registers (CRX) */ #define START_ADDR_HI 0x0C /* p246 */ #define START_ADDR_LO 0x0D /* p247 */ #define VERT_SYNC_END 0x11 /* p249 */ #define EXT_VERT_TOTAL 0x30 /* p257 */ #define EXT_VERT_DISPLAY 0x31 /* p258 */ #define EXT_VERT_SYNC_START 0x32 /* p259 */ #define EXT_VERT_BLANK_START 0x33 /* p260 */ #define EXT_HORIZ_TOTAL 0x35 /* p261 */ #define EXT_HORIZ_BLANK 0x39 /* p261 */ #define EXT_START_ADDR 0x40 /* p262 */ #define EXT_START_ADDR_ENABLE 0x80 #define EXT_OFFSET 0x41 /* p263 */ #define EXT_START_ADDR_HI 0x42 /* p263 */ #define INTERLACE_CNTL 0x70 /* p264 */ #define INTERLACE_ENABLE 0x80 #define INTERLACE_DISABLE 0x00 /* Miscellaneous Output Register */ #define MSR_R 0x3CC /* p207 */ #define MSR_W 0x3C2 /* p207 */ #define IO_ADDR_SELECT 0x01 #define MDA_BASE 0x3B0 /* p207 */ #define CGA_BASE 0x3D0 /* p207 */ /* CR80 - IO Control, p264 */ #define IO_CTNL 0x80 #define EXTENDED_ATTR_CNTL 0x02 #define EXTENDED_CRTC_CNTL 0x01 /* GR10 - Address mapping, p221 */ #define ADDRESS_MAPPING 0x10 #define PAGE_TO_LOCAL_MEM_ENABLE 0x10 #define GTT_MEM_MAP_ENABLE 0x08 #define PACKED_MODE_ENABLE 0x04 #define LINEAR_MODE_ENABLE 0x02 #define PAGE_MAPPING_ENABLE 0x01 #define HOTKEY_VBIOS_SWITCH_BLOCK 0x80 #define HOTKEY_SWITCH 0x20 #define HOTKEY_TOGGLE 0x10 /* Blitter control, p378 */ #define BITBLT_CNTL 0x7000c #define COLEXP_MODE 0x30 #define COLEXP_8BPP 0x00 #define COLEXP_16BPP 0x10 #define COLEXP_24BPP 0x20 #define COLEXP_RESERVED 0x30 #define BITBLT_STATUS 0x01 #define CHDECMISC 0x10111 #define DCC 0x10200 #define C0DRB0 0x10200 #define C0DRB1 0x10202 #define C0DRB2 0x10204 #define C0DRB3 0x10206 #define C0DRA01 0x10208 #define C0DRA23 0x1020a #define C1DRB0 0x10600 #define C1DRB1 0x10602 #define C1DRB2 0x10604 #define C1DRB3 0x10606 #define C1DRA01 0x10608 #define C1DRA23 0x1060a /* p375. */ #define DISPLAY_CNTL 0x70008 #define VGA_WRAP_MODE 0x02 #define VGA_WRAP_AT_256KB 0x00 #define VGA_NO_WRAP 0x02 #define GUI_MODE 0x01 #define STANDARD_VGA_MODE 0x00 #define HIRES_MODE 0x01 /* p375 */ #define PIXPIPE_CONFIG_0 0x70009 #define DAC_8_BIT 0x80 #define DAC_6_BIT 0x00 #define HW_CURSOR_ENABLE 0x10 #define EXTENDED_PALETTE 0x01 /* p375 */ #define PIXPIPE_CONFIG_1 0x7000a #define DISPLAY_COLOR_MODE 0x0F #define DISPLAY_VGA_MODE 0x00 #define DISPLAY_8BPP_MODE 0x02 #define DISPLAY_15BPP_MODE 0x04 #define DISPLAY_16BPP_MODE 0x05 #define DISPLAY_24BPP_MODE 0x06 #define DISPLAY_32BPP_MODE 0x07 /* p375 */ #define PIXPIPE_CONFIG_2 0x7000b #define DISPLAY_GAMMA_ENABLE 0x08 #define DISPLAY_GAMMA_DISABLE 0x00 #define OVERLAY_GAMMA_ENABLE 0x04 #define OVERLAY_GAMMA_DISABLE 0x00 /* p380 */ #define DISPLAY_BASE 0x70020 #define DISPLAY_BASE_MASK 0x03fffffc /* Cursor control registers, pp383-384 */ /* Desktop (845G, 865G) */ #define CURSOR_CONTROL 0x70080 #define CURSOR_ENABLE 0x80000000 #define CURSOR_GAMMA_ENABLE 0x40000000 #define CURSOR_STRIDE_MASK 0x30000000 #define CURSOR_FORMAT_SHIFT 24 #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT) #define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT) /* Mobile and i810 */ #define CURSOR_A_CONTROL CURSOR_CONTROL #define CURSOR_ORIGIN_SCREEN 0x00 /* i810 only */ #define CURSOR_ORIGIN_DISPLAY 0x1 /* i810 only */ #define CURSOR_MODE 0x27 #define CURSOR_MODE_DISABLE 0x00 #define CURSOR_MODE_32_4C_AX 0x01 /* i810 only */ #define CURSOR_MODE_64_3C 0x04 #define CURSOR_MODE_64_4C_AX 0x05 #define CURSOR_MODE_64_4C 0x06 #define CURSOR_MODE_64_32B_AX 0x07 #define CURSOR_MODE_64_ARGB_AX (0x20 | CURSOR_MODE_64_32B_AX) #define MCURSOR_PIPE_SELECT (1 << 28) #define MCURSOR_PIPE_A 0x00 #define MCURSOR_PIPE_B (1 << 28) #define MCURSOR_GAMMA_ENABLE (1 << 26) #define MCURSOR_MEM_TYPE_LOCAL (1 << 25) #define CURSOR_BASEADDR 0x70084 #define CURSOR_A_BASE CURSOR_BASEADDR #define CURSOR_BASEADDR_MASK 0x1FFFFF00 #define CURSOR_A_POSITION 0x70088 #define CURSOR_POS_SIGN 0x8000 #define CURSOR_POS_MASK 0x007FF #define CURSOR_X_SHIFT 0 #define CURSOR_Y_SHIFT 16 #define CURSOR_X_LO 0x70088 #define CURSOR_X_HI 0x70089 #define CURSOR_X_POS 0x00 #define CURSOR_X_NEG 0x80 #define CURSOR_Y_LO 0x7008A #define CURSOR_Y_HI 0x7008B #define CURSOR_Y_POS 0x00 #define CURSOR_Y_NEG 0x80 #define CURSOR_A_PALETTE0 0x70090 #define CURSOR_A_PALETTE1 0x70094 #define CURSOR_A_PALETTE2 0x70098 #define CURSOR_A_PALETTE3 0x7009C #define CURSOR_SIZE 0x700A0 #define CURSOR_SIZE_MASK 0x3FF #define CURSOR_SIZE_HSHIFT 0 #define CURSOR_SIZE_VSHIFT 12 #define CURSOR_B_CONTROL 0x700C0 #define CURSOR_B_BASE 0x700C4 #define CURSOR_B_POSITION 0x700C8 #define CURSOR_B_PALETTE0 0x700D0 #define CURSOR_B_PALETTE1 0x700D4 #define CURSOR_B_PALETTE2 0x700D8 #define CURSOR_B_PALETTE3 0x700DC /* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm * not sure they refer to local (graphics) memory. * * These details are for the local memory control registers, * (pp301-310). The test machines are not equipped with local memory, * so nothing is tested. Only a single row seems to be supported. */ #define DRAM_ROW_TYPE 0x3000 #define DRAM_ROW_0 0x01 #define DRAM_ROW_0_SDRAM 0x01 #define DRAM_ROW_0_EMPTY 0x00 #define DRAM_ROW_CNTL_LO 0x3001 #define DRAM_PAGE_MODE_CTRL 0x10 #define DRAM_RAS_TO_CAS_OVRIDE 0x08 #define DRAM_CAS_LATENCY 0x04 #define DRAM_RAS_TIMING 0x02 #define DRAM_RAS_PRECHARGE 0x01 #define DRAM_ROW_CNTL_HI 0x3002 #define DRAM_REFRESH_RATE 0x18 #define DRAM_REFRESH_DISABLE 0x00 #define DRAM_REFRESH_60HZ 0x08 #define DRAM_REFRESH_FAST_TEST 0x10 #define DRAM_REFRESH_RESERVED 0x18 #define DRAM_SMS 0x07 #define DRAM_SMS_NORMAL 0x00 #define DRAM_SMS_NOP_ENABLE 0x01 #define DRAM_SMS_ABPCE 0x02 #define DRAM_SMS_MRCE 0x03 #define DRAM_SMS_CBRCE 0x04 /* p307 */ #define DPMS_SYNC_SELECT 0x5002 #define VSYNC_CNTL 0x08 #define VSYNC_ON 0x00 #define VSYNC_OFF 0x08 #define HSYNC_CNTL 0x02 #define HSYNC_ON 0x00 #define HSYNC_OFF 0x02 #define GPIOA 0x5010 #define GPIOB 0x5014 #define GPIOC 0x5018 #define GPIOD 0x501c #define GPIOE 0x5020 #define GPIOF 0x5024 #define GPIOG 0x5028 #define GPIOH 0x502c # define GPIO_CLOCK_DIR_MASK (1 << 0) # define GPIO_CLOCK_DIR_IN (0 << 1) # define GPIO_CLOCK_DIR_OUT (1 << 1) # define GPIO_CLOCK_VAL_MASK (1 << 2) # define GPIO_CLOCK_VAL_OUT (1 << 3) # define GPIO_CLOCK_VAL_IN (1 << 4) # define GPIO_CLOCK_PULLUP_DISABLE (1 << 5) # define GPIO_DATA_DIR_MASK (1 << 8) # define GPIO_DATA_DIR_IN (0 << 9) # define GPIO_DATA_DIR_OUT (1 << 9) # define GPIO_DATA_VAL_MASK (1 << 10) # define GPIO_DATA_VAL_OUT (1 << 11) # define GPIO_DATA_VAL_IN (1 << 12) # define GPIO_DATA_PULLUP_DISABLE (1 << 13) /* GMBus registers for hardware-assisted (non-bitbanging) I2C access */ #define GMBUS0 0x5100 #define GMBUS1 0x5104 #define GMBUS2 0x5108 #define GMBUS3 0x510c #define GMBUS4 0x5110 #define GMBUS5 0x5120 /* p317, 319 */ #define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ #define VCLK2_VCO_N 0x600a #define VCLK2_VCO_DIV_SEL 0x6012 #define VCLK_DIVISOR_VGA0 0x6000 #define VCLK_DIVISOR_VGA1 0x6004 #define VCLK_POST_DIV 0x6010 /** Selects a post divisor of 4 instead of 2. */ # define VGA1_PD_P2_DIV_4 (1 << 15) /** Overrides the p2 post divisor field */ # define VGA1_PD_P1_DIV_2 (1 << 13) # define VGA1_PD_P1_SHIFT 8 /** P1 value is 2 greater than this field */ # define VGA1_PD_P1_MASK (0x1f << 8) /** Selects a post divisor of 4 instead of 2. */ # define VGA0_PD_P2_DIV_4 (1 << 7) /** Overrides the p2 post divisor field */ # define VGA0_PD_P1_DIV_2 (1 << 5) # define VGA0_PD_P1_SHIFT 0 /** P1 value is 2 greater than this field */ # define VGA0_PD_P1_MASK (0x1f << 0) #define POST_DIV_SELECT 0x70 #define POST_DIV_1 0x00 #define POST_DIV_2 0x10 #define POST_DIV_4 0x20 #define POST_DIV_8 0x30 #define POST_DIV_16 0x40 #define POST_DIV_32 0x50 #define VCO_LOOP_DIV_BY_4M 0x00 #define VCO_LOOP_DIV_BY_16M 0x04 /* Instruction Parser Mode Register * - p281 * - 2 new bits. */ #define INST_PM 0x20c0 #define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */ #define SYNC_PACKET_FLUSH_ENABLE 0x10 #define TWO_D_INST_DISABLE 0x08 #define THREE_D_INST_DISABLE 0x04 #define STATE_VAR_UPDATE_DISABLE 0x02 #define PAL_STIP_DISABLE 0x01 #define MEMMODE 0x20dc /* Instruction parser error register. p279 */ #define IPEIR 0x2088 #define IPEHR 0x208C #define INST_DONE 0x2090 # define IDCT_DONE (1 << 30) # define IQ_DONE (1 << 29) # define PR_DONE (1 << 28) # define VLD_DONE (1 << 27) # define IP_DONE (1 << 26) # define FBC_DONE (1 << 25) # define BINNER_DONE (1 << 24) # define SF_DONE (1 << 23) # define SE_DONE (1 << 22) # define WM_DONE (1 << 21) # define IZ_DONE (1 << 20) # define PERSPECTIVE_INTERP_DONE (1 << 19) # define DISPATCHER_DONE (1 << 18) # define PROJECTION_DONE (1 << 17) # define DEPENDENT_ADDRESS_DONE (1 << 16) # define QUAD_CACHE_DONE (1 << 15) # define TEXTURE_FETCH_DONE (1 << 14) # define TEXTURE_DECOMPRESS_DONE (1 << 13) # define SAMPLER_CACHE_DONE (1 << 12) # define FILTER_DONE (1 << 11) # define BYPASS_FIFO_DONE (1 << 10) # define PS_DONE (1 << 9) # define CC_DONE (1 << 8) # define MAP_FILTER_DONE (1 << 7) # define MAP_L2_IDLE (1 << 6) # define RING_2_ENABLE (1 << 2) # define RING_1_ENABLE (1 << 1) # define RING_0_ENABLE (1 << 0) #define SCPD0 0x209c /* debug */ #define INST_PS 0x20c4 #define IPEIR_I965 0x2064 /* i965 */ #define IPEHR_I965 0x2068 /* i965 */ #define INST_DONE_I965 0x206c # define I965_SF_DONE (1 << 23) # define I965_SE_DONE (1 << 22) # define I965_WM_DONE (1 << 21) # define I965_TEXTURE_FETCH_DONE (1 << 14) # define I965_SAMPLER_CACHE_DONE (1 << 12) # define I965_FILTER_DONE (1 << 11) # define I965_PS_DONE (1 << 9) # define I965_CC_DONE (1 << 8) # define I965_MAP_FILTER_DONE (1 << 7) # define I965_MAP_L2_IDLE (1 << 6) # define I965_CP_DONE (1 << 1) # define I965_RING_0_ENABLE (1 << 0) #define INST_PS_I965 0x2070 /* Current active ring head address: */ #define ACTHD_I965 0x2074 #define ACTHD 0x20C8 /* Current primary/secondary DMA fetch addresses: */ #define DMA_FADD_P 0x2078 #define DMA_FADD_S 0x20d4 #define INST_DONE_1 0x207c #define CACHE_MODE_0 0x2120 #define CACHE_MODE_1 0x2124 #define MI_MODE 0x209c #define MI_DISPLAY_POWER_DOWN 0x20e0 #define MI_ARB_STATE 0x20e4 #define MI_RDRET_STATE 0x20fc /* Start addresses for each of the primary rings: */ #define PR0_STR 0x20f0 #define PR1_STR 0x20f4 #define PR2_STR 0x20f8 #define WIZ_CTL 0x7c00 #define WIZ_CTL_SINGLE_SUBSPAN (1<<6) #define WIZ_CTL_IGNORE_STALLS (1<<5) #define SVG_WORK_CTL 0x7408 #define TS_CTL 0x7e00 #define TS_MUX_ERR_CODE (0<<8) #define TS_MUX_URB_0 (1<<8) #define TS_MUX_DISPATCH_ID_0 (10<<8) #define TS_MUX_ERR_CODE_VALID (15<<8) #define TS_MUX_TID_0 (16<<8) #define TS_MUX_EUID_0 (18<<8) #define TS_MUX_FFID_0 (22<<8) #define TS_MUX_EOT (26<<8) #define TS_MUX_SIDEBAND_0 (27<<8) #define TS_SNAP_ALL_CHILD (1<<2) #define TS_SNAP_ALL_ROOT (1<<1) #define TS_SNAP_ENABLE (1<<0) #define TS_DEBUG_DATA 0x7e0c #define TD_CTL 0x8000 #define TD_CTL2 0x8004 #define ECOSKPD 0x21d0 #define EXCC 0x2028 /* I965 debug regs: */ #define IA_VERTICES_COUNT_QW 0x2310 #define IA_PRIMITIVES_COUNT_QW 0x2318 #define VS_INVOCATION_COUNT_QW 0x2320 #define GS_INVOCATION_COUNT_QW 0x2328 #define GS_PRIMITIVES_COUNT_QW 0x2330 #define CL_INVOCATION_COUNT_QW 0x2338 #define CL_PRIMITIVES_COUNT_QW 0x2340 #define PS_INVOCATION_COUNT_QW 0x2348 #define PS_DEPTH_COUNT_QW 0x2350 #define TIMESTAMP_QW 0x2358 #define CLKCMP_QW 0x2360 /* General error reporting regs, p296 */ #define EIR 0x20B0 #define EMR 0x20B4 #define ESR 0x20B8 # define ERR_VERTEX_MAX (1 << 5) /* lpt/cst */ # define ERR_PGTBL_ERROR (1 << 4) # define ERR_DISPLAY_OVERLAY_UNDERRUN (1 << 3) # define ERR_MAIN_MEMORY_REFRESH (1 << 1) # define ERR_INSTRUCTION_ERROR (1 << 0) /* Interrupt Control Registers * - new bits for i810 * - new register hwstam (mask) */ #define HWS_PGA 0x2080 #define PWRCTXA 0x2088 /* 965GM+ only */ #define PWRCTX_EN (1<<0) #define HWSTAM 0x2098 /* p290 */ #define IER 0x20a0 /* p291 */ #define IIR 0x20a4 /* p292 */ #define IMR 0x20a8 /* p293 */ #define ISR 0x20ac /* p294 */ #define HW_ERROR 0x8000 #define SYNC_STATUS_TOGGLE 0x1000 #define DPY_0_FLIP_PENDING 0x0800 #define DPY_1_FLIP_PENDING 0x0400 /* not implemented on i810 */ #define OVL_0_FLIP_PENDING 0x0200 #define OVL_1_FLIP_PENDING 0x0100 /* not implemented on i810 */ #define DPY_0_VBLANK 0x0080 #define DPY_0_EVENT 0x0040 #define DPY_1_VBLANK 0x0020 /* not implemented on i810 */ #define DPY_1_EVENT 0x0010 /* not implemented on i810 */ #define HOST_PORT_EVENT 0x0008 /* */ #define CAPTURE_EVENT 0x0004 /* */ #define USER_DEFINED 0x0002 #define BREAKPOINT 0x0001 #define INTR_RESERVED (0x6000 | \ DPY_1_FLIP_PENDING | \ OVL_1_FLIP_PENDING | \ DPY_1_VBLANK | \ DPY_1_EVENT | \ HOST_PORT_EVENT | \ CAPTURE_EVENT ) /* FIFO Watermark and Burst Length Control Register * * - different offset and contents on i810 (p299) (fewer bits per field) * - some overlay fields added * - what does it all mean? */ #define FWATER_BLC 0x20d8 #define FWATER_BLC2 0x20dc #define MM_BURST_LENGTH 0x00700000 #define MM_FIFO_WATERMARK 0x0001F000 #define LM_BURST_LENGTH 0x00000700 #define LM_FIFO_WATERMARK 0x0000001F /* Fence/Tiling ranges [0..7] */ #define FENCE 0x2000 #define FENCE_NR 8 #define FENCE_NEW 0x3000 #define FENCE_NEW_NR 16 #define FENCE_LINEAR 0 #define FENCE_XMAJOR 1 #define FENCE_YMAJOR 2 #define I915G_FENCE_START_MASK 0x0ff00000 #define I830_FENCE_START_MASK 0x07f80000 #define FENCE_START_MASK 0x03F80000 #define FENCE_X_MAJOR 0x00000000 #define FENCE_Y_MAJOR 0x00001000 #define FENCE_SIZE_MASK 0x00000700 #define FENCE_SIZE_512K 0x00000000 #define FENCE_SIZE_1M 0x00000100 #define FENCE_SIZE_2M 0x00000200 #define FENCE_SIZE_4M 0x00000300 #define FENCE_SIZE_8M 0x00000400 #define FENCE_SIZE_16M 0x00000500 #define FENCE_SIZE_32M 0x00000600 #define FENCE_SIZE_64M 0x00000700 #define I915G_FENCE_SIZE_1M 0x00000000 #define I915G_FENCE_SIZE_2M 0x00000100 #define I915G_FENCE_SIZE_4M 0x00000200 #define I915G_FENCE_SIZE_8M 0x00000300 #define I915G_FENCE_SIZE_16M 0x00000400 #define I915G_FENCE_SIZE_32M 0x00000500 #define I915G_FENCE_SIZE_64M 0x00000600 #define I915G_FENCE_SIZE_128M 0x00000700 #define I965_FENCE_X_MAJOR 0x00000000 #define I965_FENCE_Y_MAJOR 0x00000002 #define FENCE_PITCH_1 0x00000000 #define FENCE_PITCH_2 0x00000010 #define FENCE_PITCH_4 0x00000020 #define FENCE_PITCH_8 0x00000030 #define FENCE_PITCH_16 0x00000040 #define FENCE_PITCH_32 0x00000050 #define FENCE_PITCH_64 0x00000060 #define FENCE_VALID 0x00000001 /* Registers to control page table, p274 */ #define PGETBL_CTL 0x2020 #define PGETBL_ADDR_MASK 0xFFFFF000 #define PGETBL_ENABLE_MASK 0x00000001 #define PGETBL_ENABLED 0x00000001 /** Added in 965G, this field has the actual size of the global GTT */ #define PGETBL_SIZE_MASK 0x0000000e #define PGETBL_SIZE_512KB (0 << 1) #define PGETBL_SIZE_256KB (1 << 1) #define PGETBL_SIZE_128KB (2 << 1) #define PGETBL_SIZE_1MB (3 << 1) #define PGETBL_SIZE_2MB (4 << 1) #define PGETBL_SIZE_1_5MB (5 << 1) #define G33_PGETBL_SIZE_MASK (3 << 8) #define G33_PGETBL_SIZE_1M (1 << 8) #define G33_PGETBL_SIZE_2M (2 << 8) #define I830_PTE_BASE 0x10000 #define PTE_ADDRESS_MASK 0xfffff000 #define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ #define PTE_MAPPING_TYPE_UNCACHED (0 << 1) #define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */ #define PTE_MAPPING_TYPE_CACHED (3 << 1) #define PTE_MAPPING_TYPE_MASK (3 << 1) #define PTE_VALID (1 << 0) /** @defgroup PGE_ERR * @{ */ /** Page table debug register for i845 */ #define PGE_ERR 0x2024 #define PGE_ERR_ADDR_MASK 0xFFFFF000 #define PGE_ERR_ID_MASK 0x00000038 #define PGE_ERR_CAPTURE 0x00000000 #define PGE_ERR_OVERLAY 0x00000008 #define PGE_ERR_DISPLAY 0x00000010 #define PGE_ERR_HOST 0x00000018 #define PGE_ERR_RENDER 0x00000020 #define PGE_ERR_BLITTER 0x00000028 #define PGE_ERR_MAPPING 0x00000030 #define PGE_ERR_CMD_PARSER 0x00000038 #define PGE_ERR_TYPE_MASK 0x00000007 #define PGE_ERR_INV_TABLE 0x00000000 #define PGE_ERR_INV_PTE 0x00000001 #define PGE_ERR_MIXED_TYPES 0x00000002 #define PGE_ERR_PAGE_MISS 0x00000003 #define PGE_ERR_ILLEGAL_TRX 0x00000004 #define PGE_ERR_LOCAL_MEM 0x00000005 #define PGE_ERR_TILED 0x00000006 /** @} */ /** @defgroup PGTBL_ER * @{ */ /** Page table debug register for i945 */ # define PGTBL_ER 0x2024 # define PGTBL_ERR_MT_TILING (1 << 27) # define PGTBL_ERR_MT_GTT_PTE (1 << 26) # define PGTBL_ERR_LC_TILING (1 << 25) # define PGTBL_ERR_LC_GTT_PTE (1 << 24) # define PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE (1 << 23) # define PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE (1 << 22) # define PGTBL_ERR_CS_VERTEXDATA_GTT_PTE (1 << 21) # define PGTBL_ERR_CS_INSTRUCTION_GTT_PTE (1 << 20) # define PGTBL_ERR_CS_GTT (1 << 19) # define PGTBL_ERR_OVERLAY_TILING (1 << 18) # define PGTBL_ERR_OVERLAY_GTT_PTE (1 << 16) # define PGTBL_ERR_DISPC_TILING (1 << 14) # define PGTBL_ERR_DISPC_GTT_PTE (1 << 12) # define PGTBL_ERR_DISPB_TILING (1 << 10) # define PGTBL_ERR_DISPB_GTT_PTE (1 << 8) # define PGTBL_ERR_DISPA_TILING (1 << 6) # define PGTBL_ERR_DISPA_GTT_PTE (1 << 4) # define PGTBL_ERR_HOST_PTE_DATA (1 << 1) # define PGTBL_ERR_HOST_GTT_PTE (1 << 0) /** @} */ /* Ring buffer registers, p277, overview p19 */ #define LP_RING 0x2030 #define HP_RING 0x2040 #define RING_TAIL 0x00 #define TAIL_ADDR 0x000FFFF8 #define I830_TAIL_MASK 0x001FFFF8 #define RING_HEAD 0x04 #define HEAD_WRAP_COUNT 0xFFE00000 #define HEAD_WRAP_ONE 0x00200000 #define HEAD_ADDR 0x001FFFFC #define I830_HEAD_MASK 0x001FFFFC #define RING_START 0x08 #define START_ADDR 0x03FFFFF8 #define I830_RING_START_MASK 0xFFFFF000 #define RING_LEN 0x0C #define RING_NR_PAGES 0x001FF000 #define I830_RING_NR_PAGES 0x001FF000 #define RING_REPORT_MASK 0x00000006 #define RING_REPORT_64K 0x00000002 #define RING_REPORT_128K 0x00000004 #define RING_NO_REPORT 0x00000000 #define RING_VALID_MASK 0x00000001 #define RING_VALID 0x00000001 #define RING_INVALID 0x00000000 /* BitBlt Instructions * * There are many more masks & ranges yet to add. */ #define BR00_BITBLT_CLIENT 0x40000000 #define BR00_OP_COLOR_BLT 0x10000000 #define BR00_OP_SRC_COPY_BLT 0x10C00000 #define BR00_OP_FULL_BLT 0x11400000 #define BR00_OP_MONO_SRC_BLT 0x11800000 #define BR00_OP_MONO_SRC_COPY_BLT 0x11000000 #define BR00_OP_MONO_PAT_BLT 0x11C00000 #define BR00_OP_MONO_SRC_COPY_IMMEDIATE_BLT (0x61 << 22) #define BR00_OP_TEXT_IMMEDIATE_BLT 0xc000000 #define BR00_TPCY_DISABLE 0x00000000 #define BR00_TPCY_ENABLE 0x00000010 #define BR00_TPCY_ROP 0x00000000 #define BR00_TPCY_NO_ROP 0x00000020 #define BR00_TPCY_EQ 0x00000000 #define BR00_TPCY_NOT_EQ 0x00000040 #define BR00_PAT_MSB_FIRST 0x00000000 /* ? */ #define BR00_PAT_VERT_ALIGN 0x000000e0 #define BR00_LENGTH 0x0000000F #define BR09_DEST_ADDR 0x03FFFFFF #define BR11_SOURCE_PITCH 0x00003FFF #define BR12_SOURCE_ADDR 0x03FFFFFF #define BR13_SOLID_PATTERN 0x80000000 #define BR13_RIGHT_TO_LEFT 0x40000000 #define BR13_LEFT_TO_RIGHT 0x00000000 #define BR13_MONO_TRANSPCY 0x20000000 #define BR13_MONO_PATN_TRANS 0x10000000 #define BR13_USE_DYN_DEPTH 0x04000000 #define BR13_DYN_8BPP 0x00000000 #define BR13_DYN_16BPP 0x01000000 #define BR13_DYN_24BPP 0x02000000 #define BR13_ROP_MASK 0x00FF0000 #define BR13_DEST_PITCH 0x0000FFFF #define BR13_PITCH_SIGN_BIT 0x00008000 #define BR14_DEST_HEIGHT 0xFFFF0000 #define BR14_DEST_WIDTH 0x0000FFFF #define BR15_PATTERN_ADDR 0x03FFFFFF #define BR16_SOLID_PAT_COLOR 0x00FFFFFF #define BR16_BACKGND_PAT_CLR 0x00FFFFFF #define BR17_FGND_PAT_CLR 0x00FFFFFF #define BR18_SRC_BGND_CLR 0x00FFFFFF #define BR19_SRC_FGND_CLR 0x00FFFFFF /* Instruction parser instructions */ #define INST_PARSER_CLIENT 0x00000000 #define INST_OP_FLUSH 0x02000000 #define INST_FLUSH_MAP_CACHE 0x00000001 #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) /* Registers in the i810 host-pci bridge pci config space which affect * the i810 graphics operations. */ #define SMRAM_MISCC 0x70 #define GMS 0x000000c0 #define GMS_DISABLE 0x00000000 #define GMS_ENABLE_BARE 0x00000040 #define GMS_ENABLE_512K 0x00000080 #define GMS_ENABLE_1M 0x000000c0 #define USMM 0x00000030 #define USMM_DISABLE 0x00000000 #define USMM_TSEG_ZERO 0x00000010 #define USMM_TSEG_512K 0x00000020 #define USMM_TSEG_1M 0x00000030 #define GFX_MEM_WIN_SIZE 0x00010000 #define GFX_MEM_WIN_32M 0x00010000 #define GFX_MEM_WIN_64M 0x00000000 /* Overkill? I don't know. Need to figure out top of mem to make the * SMRAM calculations come out. Linux seems to have problems * detecting it all on its own, so this seems a reasonable double * check to any user supplied 'mem=...' boot param. * * ... unfortunately this reg doesn't work according to spec on the * test hardware. */ #define WHTCFG_PAMR_DRP 0x50 #define SYS_DRAM_ROW_0_SHIFT 16 #define SYS_DRAM_ROW_1_SHIFT 20 #define DRAM_MASK 0x0f #define DRAM_VALUE_0 0 #define DRAM_VALUE_1 8 /* No 2 value defined */ #define DRAM_VALUE_3 16 #define DRAM_VALUE_4 16 #define DRAM_VALUE_5 24 #define DRAM_VALUE_6 32 #define DRAM_VALUE_7 32 #define DRAM_VALUE_8 48 #define DRAM_VALUE_9 64 #define DRAM_VALUE_A 64 #define DRAM_VALUE_B 96 #define DRAM_VALUE_C 128 #define DRAM_VALUE_D 128 #define DRAM_VALUE_E 192 #define DRAM_VALUE_F 256 /* nice one, geezer */ #define LM_FREQ_MASK 0x10 #define LM_FREQ_133 0x10 #define LM_FREQ_100 0x00 /* These are 3d state registers, but the state is invarient, so we let * the X server handle it: */ /* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135 */ #define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1) #define CC1_UPDATE_KILL_WRITE (1<<28) #define CC1_ENABLE_KILL_WRITE (1<<27) #define CC1_DISABLE_KILL_WRITE 0 #define CC1_UPDATE_COLOR_IDX (1<<26) #define CC1_UPDATE_CHROMA_LOW (1<<25) #define CC1_UPDATE_CHROMA_HI (1<<24) #define CC1_CHROMA_LOW_MASK ((1<<24)-1) #define CC2_COLOR_IDX_SHIFT 24 #define CC2_COLOR_IDX_MASK (0xff<<24) #define CC2_CHROMA_HI_MASK ((1<<24)-1) #define GFX_CMD_CONTEXT_SEL ((0<<29)|(0x5<<23)) #define CS_UPDATE_LOAD (1<<17) #define CS_UPDATE_USE (1<<16) #define CS_UPDATE_LOAD (1<<17) #define CS_LOAD_CTX0 0 #define CS_LOAD_CTX1 (1<<8) #define CS_USE_CTX0 0 #define CS_USE_CTX1 (1<<0) /* I810 LCD/TV registers */ #define LCD_TV_HTOTAL 0x60000 #define LCD_TV_C 0x60018 #define LCD_TV_OVRACT 0x6001C #define LCD_TV_ENABLE (1 << 31) #define LCD_TV_VGAMOD (1 << 28) /* I830 CRTC registers */ #define HTOTAL_A 0x60000 #define HBLANK_A 0x60004 #define HSYNC_A 0x60008 #define VTOTAL_A 0x6000c #define VBLANK_A 0x60010 #define VSYNC_A 0x60014 #define PIPEASRC 0x6001c #define BCLRPAT_A 0x60020 #define VSYNCSHIFT_A 0x60028 #define HTOTAL_B 0x61000 #define HBLANK_B 0x61004 #define HSYNC_B 0x61008 #define VTOTAL_B 0x6100c #define VBLANK_B 0x61010 #define VSYNC_B 0x61014 #define PIPEBSRC 0x6101c #define BCLRPAT_B 0x61020 #define VSYNCSHIFT_B 0x61028 #define PP_STATUS 0x61200 # define PP_ON (1 << 31) /** * Indicates that all dependencies of the panel are on: * * - PLL enabled * - pipe enabled * - LVDS/DVOB/DVOC on */ # define PP_READY (1 << 30) # define PP_SEQUENCE_NONE (0 << 28) # define PP_SEQUENCE_ON (1 << 28) # define PP_SEQUENCE_OFF (2 << 28) # define PP_SEQUENCE_MASK 0x30000000 #define PP_CONTROL 0x61204 # define POWER_DOWN_ON_RESET (1 << 1) # define POWER_TARGET_ON (1 << 0) #define PP_ON_DELAYS 0x61208 #define PP_OFF_DELAYS 0x6120c #define PP_DIVISOR 0x61210 #define PFIT_CONTROL 0x61230 # define PFIT_ENABLE (1 << 31) /* Pre-965 */ # define VERT_INTERP_DISABLE (0 << 10) # define VERT_INTERP_BILINEAR (1 << 10) # define VERT_INTERP_MASK (3 << 10) # define VERT_AUTO_SCALE (1 << 9) # define HORIZ_INTERP_DISABLE (0 << 6) # define HORIZ_INTERP_BILINEAR (1 << 6) # define HORIZ_INTERP_MASK (3 << 6) # define HORIZ_AUTO_SCALE (1 << 5) # define PANEL_8TO6_DITHER_ENABLE (1 << 3) /* 965+ */ # define PFIT_PIPE_MASK (3 << 29) # define PFIT_PIPE_SHIFT 29 # define PFIT_SCALING_MODE_MASK (7 << 26) # define PFIT_SCALING_AUTO (0 << 26) # define PFIT_SCALING_PROGRAMMED (1 << 26) # define PFIT_SCALING_PILLAR (2 << 26) # define PFIT_SCALING_LETTER (3 << 26) # define PFIT_FILTER_SELECT_MASK (3 << 24) # define PFIT_FILTER_FUZZY (0 << 24) # define PFIT_FILTER_CRISP (1 << 24) # define PFIT_FILTER_MEDIAN (2 << 24) #define PFIT_PGM_RATIOS 0x61234 /* Pre-965 */ # define PFIT_VERT_SCALE_SHIFT 20 # define PFIT_VERT_SCALE_MASK 0xfff00000 # define PFIT_HORIZ_SCALE_SHIFT 4 # define PFIT_HORIZ_SCALE_MASK 0x0000fff0 /* 965+ */ # define PFIT_VERT_SCALE_SHIFT_965 16 # define PFIT_VERT_SCALE_MASK_965 0x1fff0000 # define PFIT_HORIZ_SCALE_SHIFT_965 0 # define PFIT_HORIZ_SCALE_MASK_965 0x00001fff #define DPLL_A 0x06014 #define DPLL_B 0x06018 # define DPLL_VCO_ENABLE (1 << 31) # define DPLL_DVO_HIGH_SPEED (1 << 30) # define DPLL_SYNCLOCK_ENABLE (1 << 29) # define DPLL_VGA_MODE_DIS (1 << 28) # define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ # define DPLLB_MODE_LVDS (2 << 26) /* i915 */ # define DPLL_MODE_MASK (3 << 26) # define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ # define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ # define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ # define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ # define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ # define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ # define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */ /** * The i830 generation, in DAC/serial mode, defines p1 as two plus this * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. */ # define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 /** * The i830 generation, in LVDS mode, defines P1 as the bit number set within * this field (only one bit may be set). */ # define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 # define DPLL_FPA01_P1_POST_DIV_SHIFT 16 # define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15 /* Ironlake */ # define DPLL_FPA0_P1_POST_DIV_SHIFT 16 # define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ # define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ # define PLL_REF_INPUT_DREFCLK (0 << 13) # define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ # define PLL_REF_INPUT_SUPER_SSC (1 << 13) /* Ironlake: 120M SSC */ # define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */ # define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) # define PLL_REF_INPUT_MASK (3 << 13) # define PLL_REF_INPUT_DMICLK (5 << 13) /* Ironlake: DMI refclk */ # define PLL_LOAD_PULSE_PHASE_SHIFT 9 /* * Parallel to Serial Load Pulse phase selection. * Selects the phase for the 10X DPLL clock for the PCIe * digital display port. The range is 4 to 13; 10 or more * is just a flip delay. The default is 6 */ # define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) # define DISPLAY_RATE_SELECT_FPA1 (1 << 8) /* Ironlake */ # define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT 9 # define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK (7 << 9) # define PLL_REF_SDVO_HDMI_MULTIPLIER(x) (((x)-1)<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) # define DPLL_FPA1_P1_POST_DIV_SHIFT 0 # define DPLL_FPA1_P1_POST_DIV_MASK 0xff /** * SDVO multiplier for 945G/GM. Not used on 965. * * \sa DPLL_MD_UDI_MULTIPLIER_MASK */ # define SDVO_MULTIPLIER_MASK 0x000000ff # define SDVO_MULTIPLIER_SHIFT_HIRES 4 # define SDVO_MULTIPLIER_SHIFT_VGA 0 /** @defgroup DPLL_MD * @{ */ /** Pipe A SDVO/UDI clock multiplier/divider register for G965. */ #define DPLL_A_MD 0x0601c /** Pipe B SDVO/UDI clock multiplier/divider register for G965. */ #define DPLL_B_MD 0x06020 /** * UDI pixel divider, controlling how many pixels are stuffed into a packet. * * Value is pixels minus 1. Must be set to 1 pixel for SDVO. */ # define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 # define DPLL_MD_UDI_DIVIDER_SHIFT 24 /** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ # define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 # define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 /** * SDVO/UDI pixel multiplier. * * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus * clock rate is 10 times the DPLL clock. At low resolution/refresh rate * modes, the bus rate would be below the limits, so SDVO allows for stuffing * dummy bytes in the datastream at an increased clock rate, with both sides of * the link knowing how many bytes are fill. * * So, for a mode with a dotclock of 65Mhz, we would want to double the clock * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be * set to 130Mhz, and the SDVO multiplier set to 2x in this register and * through an SDVO command. * * This register field has values of multiplication factor minus 1, with * a maximum multiplier of 5 for SDVO. */ # define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 # define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 /** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. * This best be set to the default value (3) or the CRT won't work. No, * I don't entirely understand what this does... */ # define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 /** @} */ #define DPLL_TEST 0x606c # define DPLLB_TEST_SDVO_DIV_1 (0 << 22) # define DPLLB_TEST_SDVO_DIV_2 (1 << 22) # define DPLLB_TEST_SDVO_DIV_4 (2 << 22) # define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) # define DPLLB_TEST_N_BYPASS (1 << 19) # define DPLLB_TEST_M_BYPASS (1 << 18) # define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) # define DPLLA_TEST_N_BYPASS (1 << 3) # define DPLLA_TEST_M_BYPASS (1 << 2) # define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) #define D_STATE 0x6104 #define DSPCLK_GATE_D 0x6200 # define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ # define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ # define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ # define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ # define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ # define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ # define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ # define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ # define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ # define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ # define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ # define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ # define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ # define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ # define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ # define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ # define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ # define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ # define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ # define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) # define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) # define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) # define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) # define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ # define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ # define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) # define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) /** * This bit must be set on the 830 to prevent hangs when turning off the * overlay scaler. */ # define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) # define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) # define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) # define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ # define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ #define RENCLK_GATE_D1 0x6204 # define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ # define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ # define PC_FE_CLOCK_GATE_DISABLE (1 << 11) # define PC_BE_CLOCK_GATE_DISABLE (1 << 10) # define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) # define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) # define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) # define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) # define MAG_CLOCK_GATE_DISABLE (1 << 5) /** This bit must be unset on 855,865 */ # define MECI_CLOCK_GATE_DISABLE (1 << 4) # define DCMP_CLOCK_GATE_DISABLE (1 << 3) # define MEC_CLOCK_GATE_DISABLE (1 << 2) # define MECO_CLOCK_GATE_DISABLE (1 << 1) /** This bit must be set on 855,865. */ # define SV_CLOCK_GATE_DISABLE (1 << 0) # define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) # define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) # define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) # define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) # define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) # define I915_WM_CLOCK_GATE_DISABLE (1 << 11) # define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) # define I915_PI_CLOCK_GATE_DISABLE (1 << 9) # define I915_DI_CLOCK_GATE_DISABLE (1 << 8) # define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) # define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) # define I915_SC_CLOCK_GATE_DISABLE (1 << 5) # define I915_FL_CLOCK_GATE_DISABLE (1 << 4) # define I915_DM_CLOCK_GATE_DISABLE (1 << 3) # define I915_PS_CLOCK_GATE_DISABLE (1 << 2) # define I915_CC_CLOCK_GATE_DISABLE (1 << 1) # define I915_BY_CLOCK_GATE_DISABLE (1 << 0) # define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) /** This bit must always be set on 965G/965GM */ # define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) # define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) # define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) # define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) # define I965_GW_CLOCK_GATE_DISABLE (1 << 25) # define I965_TD_CLOCK_GATE_DISABLE (1 << 24) /** This bit must always be set on 965G */ # define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) # define I965_IC_CLOCK_GATE_DISABLE (1 << 22) # define I965_EU_CLOCK_GATE_DISABLE (1 << 21) # define I965_IF_CLOCK_GATE_DISABLE (1 << 20) # define I965_TC_CLOCK_GATE_DISABLE (1 << 19) # define I965_SO_CLOCK_GATE_DISABLE (1 << 17) # define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) # define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) # define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) # define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) # define I965_EM_CLOCK_GATE_DISABLE (1 << 12) # define I965_UC_CLOCK_GATE_DISABLE (1 << 11) # define I965_SI_CLOCK_GATE_DISABLE (1 << 6) # define I965_MT_CLOCK_GATE_DISABLE (1 << 5) # define I965_PL_CLOCK_GATE_DISABLE (1 << 4) # define I965_DG_CLOCK_GATE_DISABLE (1 << 3) # define I965_QC_CLOCK_GATE_DISABLE (1 << 2) # define I965_FT_CLOCK_GATE_DISABLE (1 << 1) # define I965_DM_CLOCK_GATE_DISABLE (1 << 0) #define RENCLK_GATE_D2 0x6208 #define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) #define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) #define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) #define RAMCLK_GATE_D 0x6210 /* CRL only */ #define DEUC 0x6214 /* CRL only */ /* * This is a PCI config space register to manipulate backlight brightness * It is used when the BLM_LEGACY_MODE is turned on. When enabled, the first * byte of this config register sets brightness within the range from * 0 to 0xff */ #define LEGACY_BACKLIGHT_BRIGHTNESS 0xf4 #define BLC_PWM_CTL 0x61254 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) #define BACKLIGHT_MODULATION_FREQ_SHIFT2 (16) /** * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. * * The actual value is this field multiplied by two. */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) #define BACKLIGHT_MODULATION_FREQ_MASK2 (0xffff << 16) #define BLM_LEGACY_MODE (1 << 16) /** * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. * * This field must be no greater than the number of cycles in the complete * backlight modulation cycle. */ #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) /* On 965+ backlight control is in another register */ #define BLC_PWM_CTL2 0x61250 #define BLM_LEGACY_MODE2 (1 << 30) #define BLM_CTL 0x61260 #define BLM_THRESHOLD_0 0x61270 #define BLM_THRESHOLD_1 0x61274 #define BLM_THRESHOLD_2 0x61278 #define BLM_THRESHOLD_3 0x6127c #define BLM_THRESHOLD_4 0x61280 #define BLM_THRESHOLD_5 0x61284 #define BLM_ACCUMULATOR_0 0x61290 #define BLM_ACCUMULATOR_1 0x61294 #define BLM_ACCUMULATOR_2 0x61298 #define BLM_ACCUMULATOR_3 0x6129c #define BLM_ACCUMULATOR_4 0x612a0 #define BLM_ACCUMULATOR_5 0x612a4 #define FPA0 0x06040 #define FPA1 0x06044 #define FPB0 0x06048 #define FPB1 0x0604c # define FP_N_DIV_MASK 0x003f0000 # define FP_N_IGD_DIV_MASK 0x00ff0000 # define FP_N_DIV_SHIFT 16 # define FP_M1_DIV_MASK 0x00003f00 # define FP_M1_DIV_SHIFT 8 # define FP_M2_DIV_MASK 0x0000003f # define FP_M2_IGD_DIV_MASK 0x000000ff # define FP_M2_DIV_SHIFT 0 #define PORT_HOTPLUG_EN 0x61110 # define HDMIB_HOTPLUG_INT_EN (1 << 29) # define HDMIC_HOTPLUG_INT_EN (1 << 28) # define HDMID_HOTPLUG_INT_EN (1 << 27) # define SDVOB_HOTPLUG_INT_EN (1 << 26) # define SDVOC_HOTPLUG_INT_EN (1 << 25) # define TV_HOTPLUG_INT_EN (1 << 18) # define CRT_HOTPLUG_INT_EN (1 << 9) # define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) /* must use period 64 on GM45 according to docs */ # define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) # define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) # define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) # define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) # define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) # define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) # define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) # define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) # define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) # define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) # define CRT_HOTPLUG_FORCE_DETECT (1 << 3) # define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) # define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) # define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ # define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f #define PORT_HOTPLUG_STAT 0x61114 # define HDMIB_HOTPLUG_INT_STATUS (1 << 29) # define HDMIC_HOTPLUG_INT_STATUS (1 << 28) # define HDMID_HOTPLUG_INT_STATUS (1 << 27) # define CRT_HOTPLUG_INT_STATUS (1 << 11) # define TV_HOTPLUG_INT_STATUS (1 << 10) # define CRT_HOTPLUG_MONITOR_MASK (3 << 8) # define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) # define CRT_HOTPLUG_MONITOR_MONO (2 << 8) # define CRT_HOTPLUG_MONITOR_NONE (0 << 8) # define SDVOC_HOTPLUG_INT_STATUS (1 << 7) # define SDVOB_HOTPLUG_INT_STATUS (1 << 6) #define SDVOB 0x61140 #define SDVOC 0x61160 #define SDVO_ENABLE (1 << 31) #define SDVO_PIPE_B_SELECT (1 << 30) #define SDVO_STALL_SELECT (1 << 29) #define SDVO_INTERRUPT_ENABLE (1 << 26) /** * 915G/GM SDVO pixel multiplier. * * Programmed value is multiplier - 1, up to 5x. * * \sa DPLL_MD_UDI_MULTIPLIER_MASK */ #define SDVO_PORT_MULTIPLY_MASK (7 << 23) #define SDVO_PORT_MULTIPLY_SHIFT 23 #define SDVO_PHASE_SELECT_MASK (15 << 19) #define SDVO_PHASE_SELECT_DEFAULT (6 << 19) #define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) #define SDVOC_GANG_MODE (1 << 16) #define SDVO_ENCODING_SDVO (0x0 << 10) #define SDVO_ENCODING_HDMI (0x2 << 10) /** Requird for HDMI operation */ #define SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9) #define SDVO_COLOR_NOT_FULL_RANGE (1 << 8) #define SDVO_BORDER_ENABLE (1 << 7) #define SDVO_AUDIO_ENABLE (1 << 6) /** New with 965, default is to be set */ #define SDVO_VSYNC_ACTIVE_HIGH (1 << 4) /** New with 965, default is to be set */ #define SDVO_HSYNC_ACTIVE_HIGH (1 << 3) /** 915/945 only, read-only bit */ #define SDVOB_PCIE_CONCURRENCY (1 << 3) #define SDVO_DETECTED (1 << 2) /* Bits to be preserved when writing */ #define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) #define SDVOC_PRESERVE_MASK (1 << 17) #define UDIB_SVB_SHB_CODES 0x61144 #define UDIB_SHA_BLANK_CODES 0x61148 #define UDIB_START_END_FILL_CODES 0x6114c #define SDVOUDI 0x61150 #define I830_HTOTAL_MASK 0xfff0000 #define I830_HACTIVE_MASK 0x7ff #define I830_HBLANKEND_MASK 0xfff0000 #define I830_HBLANKSTART_MASK 0xfff #define I830_HSYNCEND_MASK 0xfff0000 #define I830_HSYNCSTART_MASK 0xfff #define I830_VTOTAL_MASK 0xfff0000 #define I830_VACTIVE_MASK 0x7ff #define I830_VBLANKEND_MASK 0xfff0000 #define I830_VBLANKSTART_MASK 0xfff #define I830_VSYNCEND_MASK 0xfff0000 #define I830_VSYNCSTART_MASK 0xfff #define I830_PIPEA_HORZ_MASK 0x7ff0000 #define I830_PIPEA_VERT_MASK 0x7ff #define ADPA 0x61100 #define ADPA_DAC_ENABLE (1<<31) #define ADPA_DAC_DISABLE 0 #define ADPA_PIPE_SELECT_MASK (1<<30) #define ADPA_PIPE_A_SELECT 0 #define ADPA_PIPE_B_SELECT (1<<30) #define ADPA_USE_VGA_HVPOLARITY (1<<15) #define ADPA_SETS_HVPOLARITY 0 #define ADPA_VSYNC_CNTL_DISABLE (1<<11) #define ADPA_VSYNC_CNTL_ENABLE 0 #define ADPA_HSYNC_CNTL_DISABLE (1<<10) #define ADPA_HSYNC_CNTL_ENABLE 0 #define ADPA_VSYNC_ACTIVE_HIGH (1<<4) #define ADPA_VSYNC_ACTIVE_LOW 0 #define ADPA_HSYNC_ACTIVE_HIGH (1<<3) #define ADPA_HSYNC_ACTIVE_LOW 0 #define DVOA 0x61120 #define DVOB 0x61140 #define DVOC 0x61160 #define DVO_ENABLE (1 << 31) #define DVO_PIPE_B_SELECT (1 << 30) #define DVO_PIPE_STALL_UNUSED (0 << 28) #define DVO_PIPE_STALL (1 << 28) #define DVO_PIPE_STALL_TV (2 << 28) #define DVO_PIPE_STALL_MASK (3 << 28) #define DVO_USE_VGA_SYNC (1 << 15) #define DVO_DATA_ORDER_I740 (0 << 14) #define DVO_DATA_ORDER_FP (1 << 14) #define DVO_VSYNC_DISABLE (1 << 11) #define DVO_HSYNC_DISABLE (1 << 10) #define DVO_VSYNC_TRISTATE (1 << 9) #define DVO_HSYNC_TRISTATE (1 << 8) #define DVO_BORDER_ENABLE (1 << 7) #define DVO_DATA_ORDER_GBRG (1 << 6) #define DVO_DATA_ORDER_RGGB (0 << 6) #define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) #define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) #define DVO_VSYNC_ACTIVE_HIGH (1 << 4) #define DVO_HSYNC_ACTIVE_HIGH (1 << 3) #define DVO_BLANK_ACTIVE_HIGH (1 << 2) #define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ #define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ #define DVO_PRESERVE_MASK (0x7<<24) #define DVOA_SRCDIM 0x61124 #define DVOB_SRCDIM 0x61144 #define DVOC_SRCDIM 0x61164 #define DVO_SRCDIM_HORIZONTAL_SHIFT 12 #define DVO_SRCDIM_VERTICAL_SHIFT 0 /** @defgroup LVDS * @{ */ /** * This register controls the LVDS output enable, pipe selection, and data * format selection. * * All of the clock/data pairs are force powered down by power sequencing. */ #define LVDS 0x61180 /** * Enables the LVDS port. This bit must be set before DPLLs are enabled, as * the DPLL semantics change when the LVDS is assigned to that pipe. */ # define LVDS_PORT_EN (1 << 31) /** Selects pipe B for LVDS data. Must be set on pre-965. */ # define LVDS_PIPEB_SELECT (1 << 30) /* on 965, dithering is enabled in this register, not PFIT_CONTROL */ # define LVDS_DITHER_ENABLE (1 << 25) /* * Selects between .0 and .1 formats: * * 0 = 1x18.0, 2x18.0, 1x24.0 or 2x24.0 * 1 = 1x24.1 or 2x24.1 */ # define LVDS_DATA_FORMAT_DOT_ONE (1 << 24) /* Using LE instead of HS on second channel control signal */ # define LVDS_LE_CONTROL_ENABLE (1 << 23) /* Using LF instead of VS on second channel control signal */ # define LVDS_LF_CONTROL_ENABLE (1 << 22) /* invert vsync signal polarity */ # define LVDS_VSYNC_POLARITY_INVERT (1 << 21) /* invert hsync signal polarity */ # define LVDS_HSYNC_POLARITY_INVERT (1 << 20) /* invert display enable signal polarity */ # define LVDS_DE_POLARITY_INVERT (1 << 19) /* * Control signals for second channel, ignored in single channel modes */ /* send DE, HS, VS on second channel */ # define LVDS_SECOND_CHANNEL_DE_HS_VS (0 << 17) # define LVDS_SECOND_CHANNEL_RESERVED (1 << 17) /* Send zeros instead of DE, HS, VS on second channel */ # define LVDS_SECOND_CHANNEL_ZEROS (2 << 17) /* Set DE=0, HS=LE, VS=LF on second channel */ # define LVDS_SECOND_CHANNEL_HS_VS (3 << 17) /* * Send duplicate data for channel reserved bits, otherwise send zeros */ # define LVDS_CHANNEL_DUP_RESERVED (1 << 16) /* * Enable border for unscaled (or aspect-scaled) display */ # define LVDS_BORDER_ENABLE (1 << 15) /* * Tri-state the LVDS buffers when powered down, otherwise * they are set to 0V */ # define LVDS_POWER_DOWN_TRI_STATE (1 << 10) /** * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per * pixel. */ # define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) # define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) # define LVDS_A0A2_CLKA_POWER_UP (3 << 8) /** * Controls the A3 data pair, which contains the additional LSBs for 24 bit * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be * on. */ # define LVDS_A3_POWER_MASK (3 << 6) # define LVDS_A3_POWER_DOWN (0 << 6) # define LVDS_A3_POWER_UP (3 << 6) /** * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP * is set. */ # define LVDS_CLKB_POWER_MASK (3 << 4) # define LVDS_CLKB_POWER_DOWN (0 << 4) # define LVDS_CLKB_POWER_UP (3 << 4) /** * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 * setting for whether we are in dual-channel mode. The B3 pair will * additionally only be powered up when LVDS_A3_POWER_UP is set. */ # define LVDS_B0B3_POWER_MASK (3 << 2) # define LVDS_B0B3_POWER_DOWN (0 << 2) # define LVDS_B0B3_POWER_UP (3 << 2) /** @} */ #define DP_B 0x64100 #define DPB_AUX_CH_CTL 0x64110 #define DPB_AUX_CH_DATA1 0x64114 #define DPB_AUX_CH_DATA2 0x64118 #define DPB_AUX_CH_DATA3 0x6411c #define DPB_AUX_CH_DATA4 0x64120 #define DPB_AUX_CH_DATA5 0x64124 #define DP_C 0x64200 #define DPC_AUX_CH_CTL 0x64210 #define DPC_AUX_CH_DATA1 0x64214 #define DPC_AUX_CH_DATA2 0x64218 #define DPC_AUX_CH_DATA3 0x6421c #define DPC_AUX_CH_DATA4 0x64220 #define DPC_AUX_CH_DATA5 0x64224 #define DP_D 0x64300 #define DPD_AUX_CH_CTL 0x64310 #define DPD_AUX_CH_DATA1 0x64314 #define DPD_AUX_CH_DATA2 0x64318 #define DPD_AUX_CH_DATA3 0x6431c #define DPD_AUX_CH_DATA4 0x64320 #define DPD_AUX_CH_DATA5 0x64324 /* * Two channel clock control. Turn this on if you need clkb for two channel mode * Overridden by global LVDS power sequencing */ /* clkb off */ # define LVDS_CLKB_POWER_DOWN (0 << 4) /* powered up, but clkb forced to 0 */ # define LVDS_CLKB_POWER_PARTIAL (1 << 4) /* clock B running */ # define LVDS_CLKB_POWER_UP (3 << 4) /* * Two channel mode B0-B2 control. Sets state when power is on. * Set to POWER_DOWN in single channel mode, other settings enable * two channel mode. The CLKB power control controls whether that clock * is enabled during two channel mode. * */ /* Everything is off, including B3 and CLKB */ # define LVDS_B_POWER_DOWN (0 << 2) /* B0, B1, B2 and data lines forced to 0. timing is active */ # define LVDS_B_POWER_PARTIAL (1 << 2) /* data lines active (both timing and colour) */ # define LVDS_B_POWER_UP (3 << 2) /** @defgroup TV_CTL * @{ */ #define TV_CTL 0x68000 /** Enables the TV encoder */ # define TV_ENC_ENABLE (1 << 31) /** Sources the TV encoder input from pipe B instead of A. */ # define TV_ENC_PIPEB_SELECT (1 << 30) /** Outputs composite video (DAC A only) */ # define TV_ENC_OUTPUT_COMPOSITE (0 << 28) /** Outputs SVideo video (DAC B/C) */ # define TV_ENC_OUTPUT_SVIDEO (1 << 28) /** Outputs Component video (DAC A/B/C) */ # define TV_ENC_OUTPUT_COMPONENT (2 << 28) /** Outputs Composite and SVideo (DAC A/B/C) */ # define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) # define TV_TRILEVEL_SYNC (1 << 21) /** Enables slow sync generation (945GM only) */ # define TV_SLOW_SYNC (1 << 20) /** Selects 4x oversampling for 480i and 576p */ # define TV_OVERSAMPLE_4X (0 << 18) /** Selects 2x oversampling for 720p and 1080i */ # define TV_OVERSAMPLE_2X (1 << 18) /** Selects no oversampling for 1080p */ # define TV_OVERSAMPLE_NONE (2 << 18) /** Selects 8x oversampling */ # define TV_OVERSAMPLE_8X (3 << 18) /** Selects progressive mode rather than interlaced */ # define TV_PROGRESSIVE (1 << 17) /** Sets the colorburst to PAL mode. Required for non-M PAL modes. */ # define TV_PAL_BURST (1 << 16) /** Field for setting delay of Y compared to C */ # define TV_YC_SKEW_MASK (7 << 12) /** Enables a fix for 480p/576p standard definition modes on the 915GM only */ # define TV_ENC_SDP_FIX (1 << 11) /** * Enables a fix for the 915GM only. * * Not sure what it does. */ # define TV_ENC_C0_FIX (1 << 10) /** Bits that must be preserved by software */ # define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) # define TV_FUSE_STATE_MASK (3 << 4) /** Read-only state that reports all features enabled */ # define TV_FUSE_STATE_ENABLED (0 << 4) /** Read-only state that reports that Macrovision is disabled in hardware*/ # define TV_FUSE_STATE_NO_MACROVISION (1 << 4) /** Read-only state that reports that TV-out is disabled in hardware. */ # define TV_FUSE_STATE_DISABLED (2 << 4) /** Normal operation */ # define TV_TEST_MODE_NORMAL (0 << 0) /** Encoder test pattern 1 - combo pattern */ # define TV_TEST_MODE_PATTERN_1 (1 << 0) /** Encoder test pattern 2 - full screen vertical 75% color bars */ # define TV_TEST_MODE_PATTERN_2 (2 << 0) /** Encoder test pattern 3 - full screen horizontal 75% color bars */ # define TV_TEST_MODE_PATTERN_3 (3 << 0) /** Encoder test pattern 4 - random noise */ # define TV_TEST_MODE_PATTERN_4 (4 << 0) /** Encoder test pattern 5 - linear color ramps */ # define TV_TEST_MODE_PATTERN_5 (5 << 0) /** * This test mode forces the DACs to 50% of full output. * * This is used for load detection in combination with TVDAC_SENSE_MASK */ # define TV_TEST_MODE_MONITOR_DETECT (7 << 0) # define TV_TEST_MODE_MASK (7 << 0) /** @} */ /** @defgroup TV_DAC * @{ */ #define TV_DAC 0x68004 /** * Reports that DAC state change logic has reported change (RO). * * This gets cleared when TV_DAC_STATE_EN is cleared */ # define TVDAC_STATE_CHG (1 << 31) # define TVDAC_SENSE_MASK (7 << 28) /** Reports that DAC A voltage is above the detect threshold */ # define TVDAC_A_SENSE (1 << 30) /** Reports that DAC B voltage is above the detect threshold */ # define TVDAC_B_SENSE (1 << 29) /** Reports that DAC C voltage is above the detect threshold */ # define TVDAC_C_SENSE (1 << 28) /** * Enables DAC state detection logic, for load-based TV detection. * * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set * to off, for load detection to work. */ # define TVDAC_STATE_CHG_EN (1 << 27) /** Sets the DAC A sense value to high */ # define TVDAC_A_SENSE_CTL (1 << 26) /** Sets the DAC B sense value to high */ # define TVDAC_B_SENSE_CTL (1 << 25) /** Sets the DAC C sense value to high */ # define TVDAC_C_SENSE_CTL (1 << 24) /** Overrides the ENC_ENABLE and DAC voltage levels */ # define DAC_CTL_OVERRIDE (1 << 7) /** Sets the slew rate. Must be preserved in software */ # define ENC_TVDAC_SLEW_FAST (1 << 6) # define DAC_A_1_3_V (0 << 4) # define DAC_A_1_1_V (1 << 4) # define DAC_A_0_7_V (2 << 4) # define DAC_A_MASK (3 << 4) # define DAC_B_1_3_V (0 << 2) # define DAC_B_1_1_V (1 << 2) # define DAC_B_0_7_V (2 << 2) # define DAC_B_MASK (3 << 2) # define DAC_C_1_3_V (0 << 0) # define DAC_C_1_1_V (1 << 0) # define DAC_C_0_7_V (2 << 0) # define DAC_C_MASK (3 << 0) /** @} */ /** * CSC coefficients are stored in a floating point format with 9 bits of * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with * -1 (0x3) being the only legal negative value. */ #define TV_CSC_Y 0x68010 # define TV_RY_MASK 0x07ff0000 # define TV_RY_SHIFT 16 # define TV_GY_MASK 0x00000fff # define TV_GY_SHIFT 0 #define TV_CSC_Y2 0x68014 # define TV_BY_MASK 0x07ff0000 # define TV_BY_SHIFT 16 /** * Y attenuation for component video. * * Stored in 1.9 fixed point. */ # define TV_AY_MASK 0x000003ff # define TV_AY_SHIFT 0 #define TV_CSC_U 0x68018 # define TV_RU_MASK 0x07ff0000 # define TV_RU_SHIFT 16 # define TV_GU_MASK 0x000007ff # define TV_GU_SHIFT 0 #define TV_CSC_U2 0x6801c # define TV_BU_MASK 0x07ff0000 # define TV_BU_SHIFT 16 /** * U attenuation for component video. * * Stored in 1.9 fixed point. */ # define TV_AU_MASK 0x000003ff # define TV_AU_SHIFT 0 #define TV_CSC_V 0x68020 # define TV_RV_MASK 0x0fff0000 # define TV_RV_SHIFT 16 # define TV_GV_MASK 0x000007ff # define TV_GV_SHIFT 0 #define TV_CSC_V2 0x68024 # define TV_BV_MASK 0x07ff0000 # define TV_BV_SHIFT 16 /** * V attenuation for component video. * * Stored in 1.9 fixed point. */ # define TV_AV_MASK 0x000007ff # define TV_AV_SHIFT 0 /** @defgroup TV_CSC_KNOBS * @{ */ #define TV_CLR_KNOBS 0x68028 /** 2s-complement brightness adjustment */ # define TV_BRIGHTNESS_MASK 0xff000000 # define TV_BRIGHTNESS_SHIFT 24 /** Contrast adjustment, as a 2.6 unsigned floating point number */ # define TV_CONTRAST_MASK 0x00ff0000 # define TV_CONTRAST_SHIFT 16 /** Saturation adjustment, as a 2.6 unsigned floating point number */ # define TV_SATURATION_MASK 0x0000ff00 # define TV_SATURATION_SHIFT 8 /** Hue adjustment, as an integer phase angle in degrees */ # define TV_HUE_MASK 0x000000ff # define TV_HUE_SHIFT 0 /** @} */ /** @defgroup TV_CLR_LEVEL * @{ */ #define TV_CLR_LEVEL 0x6802c /** Controls the DAC level for black */ # define TV_BLACK_LEVEL_MASK 0x01ff0000 # define TV_BLACK_LEVEL_SHIFT 16 /** Controls the DAC level for blanking */ # define TV_BLANK_LEVEL_MASK 0x000001ff # define TV_BLANK_LEVEL_SHIFT 0 /* @} */ /** @defgroup TV_H_CTL_1 * @{ */ #define TV_H_CTL_1 0x68030 /** Number of pixels in the hsync. */ # define TV_HSYNC_END_MASK 0x1fff0000 # define TV_HSYNC_END_SHIFT 16 /** Total number of pixels minus one in the line (display and blanking). */ # define TV_HTOTAL_MASK 0x00001fff # define TV_HTOTAL_SHIFT 0 /** @} */ /** @defgroup TV_H_CTL_2 * @{ */ #define TV_H_CTL_2 0x68034 /** Enables the colorburst (needed for non-component color) */ # define TV_BURST_ENA (1 << 31) /** Offset of the colorburst from the start of hsync, in pixels minus one. */ # define TV_HBURST_START_SHIFT 16 # define TV_HBURST_START_MASK 0x1fff0000 /** Length of the colorburst */ # define TV_HBURST_LEN_SHIFT 0 # define TV_HBURST_LEN_MASK 0x0001fff /** @} */ /** @defgroup TV_H_CTL_3 * @{ */ #define TV_H_CTL_3 0x68038 /** End of hblank, measured in pixels minus one from start of hsync */ # define TV_HBLANK_END_SHIFT 16 # define TV_HBLANK_END_MASK 0x1fff0000 /** Start of hblank, measured in pixels minus one from start of hsync */ # define TV_HBLANK_START_SHIFT 0 # define TV_HBLANK_START_MASK 0x0001fff /** @} */ /** @defgroup TV_V_CTL_1 * @{ */ #define TV_V_CTL_1 0x6803c /** XXX */ # define TV_NBR_END_SHIFT 16 # define TV_NBR_END_MASK 0x07ff0000 /** XXX */ # define TV_VI_END_F1_SHIFT 8 # define TV_VI_END_F1_MASK 0x00003f00 /** XXX */ # define TV_VI_END_F2_SHIFT 0 # define TV_VI_END_F2_MASK 0x0000003f /** @} */ /** @defgroup TV_V_CTL_2 * @{ */ #define TV_V_CTL_2 0x68040 /** Length of vsync, in half lines */ # define TV_VSYNC_LEN_MASK 0x07ff0000 # define TV_VSYNC_LEN_SHIFT 16 /** Offset of the start of vsync in field 1, measured in one less than the * number of half lines. */ # define TV_VSYNC_START_F1_MASK 0x00007f00 # define TV_VSYNC_START_F1_SHIFT 8 /** * Offset of the start of vsync in field 2, measured in one less than the * number of half lines. */ # define TV_VSYNC_START_F2_MASK 0x0000007f # define TV_VSYNC_START_F2_SHIFT 0 /** @} */ /** @defgroup TV_V_CTL_3 * @{ */ #define TV_V_CTL_3 0x68044 /** Enables generation of the equalization signal */ # define TV_EQUAL_ENA (1 << 31) /** Length of vsync, in half lines */ # define TV_VEQ_LEN_MASK 0x007f0000 # define TV_VEQ_LEN_SHIFT 16 /** Offset of the start of equalization in field 1, measured in one less than * the number of half lines. */ # define TV_VEQ_START_F1_MASK 0x0007f00 # define TV_VEQ_START_F1_SHIFT 8 /** * Offset of the start of equalization in field 2, measured in one less than * the number of half lines. */ # define TV_VEQ_START_F2_MASK 0x000007f # define TV_VEQ_START_F2_SHIFT 0 /** @} */ /** @defgroup TV_V_CTL_4 * @{ */ #define TV_V_CTL_4 0x68048 /** * Offset to start of vertical colorburst, measured in one less than the * number of lines from vertical start. */ # define TV_VBURST_START_F1_MASK 0x003f0000 # define TV_VBURST_START_F1_SHIFT 16 /** * Offset to the end of vertical colorburst, measured in one less than the * number of lines from the start of NBR. */ # define TV_VBURST_END_F1_MASK 0x000000ff # define TV_VBURST_END_F1_SHIFT 0 /** @} */ /** @defgroup TV_V_CTL_5 * @{ */ #define TV_V_CTL_5 0x6804c /** * Offset to start of vertical colorburst, measured in one less than the * number of lines from vertical start. */ # define TV_VBURST_START_F2_MASK 0x003f0000 # define TV_VBURST_START_F2_SHIFT 16 /** * Offset to the end of vertical colorburst, measured in one less than the * number of lines from the start of NBR. */ # define TV_VBURST_END_F2_MASK 0x000000ff # define TV_VBURST_END_F2_SHIFT 0 /** @} */ /** @defgroup TV_V_CTL_6 * @{ */ #define TV_V_CTL_6 0x68050 /** * Offset to start of vertical colorburst, measured in one less than the * number of lines from vertical start. */ # define TV_VBURST_START_F3_MASK 0x003f0000 # define TV_VBURST_START_F3_SHIFT 16 /** * Offset to the end of vertical colorburst, measured in one less than the * number of lines from the start of NBR. */ # define TV_VBURST_END_F3_MASK 0x000000ff # define TV_VBURST_END_F3_SHIFT 0 /** @} */ /** @defgroup TV_V_CTL_7 * @{ */ #define TV_V_CTL_7 0x68054 /** * Offset to start of vertical colorburst, measured in one less than the * number of lines from vertical start. */ # define TV_VBURST_START_F4_MASK 0x003f0000 # define TV_VBURST_START_F4_SHIFT 16 /** * Offset to the end of vertical colorburst, measured in one less than the * number of lines from the start of NBR. */ # define TV_VBURST_END_F4_MASK 0x000000ff # define TV_VBURST_END_F4_SHIFT 0 /** @} */ /** @defgroup TV_SC_CTL_1 * @{ */ #define TV_SC_CTL_1 0x68060 /** Turns on the first subcarrier phase generation DDA */ # define TV_SC_DDA1_EN (1 << 31) /** Turns on the first subcarrier phase generation DDA */ # define TV_SC_DDA2_EN (1 << 30) /** Turns on the first subcarrier phase generation DDA */ # define TV_SC_DDA3_EN (1 << 29) /** Sets the subcarrier DDA to reset frequency every other field */ # define TV_SC_RESET_EVERY_2 (0 << 24) /** Sets the subcarrier DDA to reset frequency every fourth field */ # define TV_SC_RESET_EVERY_4 (1 << 24) /** Sets the subcarrier DDA to reset frequency every eighth field */ # define TV_SC_RESET_EVERY_8 (2 << 24) /** Sets the subcarrier DDA to never reset the frequency */ # define TV_SC_RESET_NEVER (3 << 24) /** Sets the peak amplitude of the colorburst.*/ # define TV_BURST_LEVEL_MASK 0x00ff0000 # define TV_BURST_LEVEL_SHIFT 16 /** Sets the increment of the first subcarrier phase generation DDA */ # define TV_SCDDA1_INC_MASK 0x00000fff # define TV_SCDDA1_INC_SHIFT 0 /** @} */ /** @defgroup TV_SC_CTL_2 * @{ */ #define TV_SC_CTL_2 0x68064 /** Sets the rollover for the second subcarrier phase generation DDA */ # define TV_SCDDA2_SIZE_MASK 0x7fff0000 # define TV_SCDDA2_SIZE_SHIFT 16 /** Sets the increent of the second subcarrier phase generation DDA */ # define TV_SCDDA2_INC_MASK 0x00007fff # define TV_SCDDA2_INC_SHIFT 0 /** @} */ /** @defgroup TV_SC_CTL_3 * @{ */ #define TV_SC_CTL_3 0x68068 /** Sets the rollover for the third subcarrier phase generation DDA */ # define TV_SCDDA3_SIZE_MASK 0x7fff0000 # define TV_SCDDA3_SIZE_SHIFT 16 /** Sets the increent of the third subcarrier phase generation DDA */ # define TV_SCDDA3_INC_MASK 0x00007fff # define TV_SCDDA3_INC_SHIFT 0 /** @} */ /** @defgroup TV_WIN_POS * @{ */ #define TV_WIN_POS 0x68070 /** X coordinate of the display from the start of horizontal active */ # define TV_XPOS_MASK 0x1fff0000 # define TV_XPOS_SHIFT 16 /** Y coordinate of the display from the start of vertical active (NBR) */ # define TV_YPOS_MASK 0x00000fff # define TV_YPOS_SHIFT 0 /** @} */ /** @defgroup TV_WIN_SIZE * @{ */ #define TV_WIN_SIZE 0x68074 /** Horizontal size of the display window, measured in pixels*/ # define TV_XSIZE_MASK 0x1fff0000 # define TV_XSIZE_SHIFT 16 /** * Vertical size of the display window, measured in pixels. * * Must be even for interlaced modes. */ # define TV_YSIZE_MASK 0x00000fff # define TV_YSIZE_SHIFT 0 /** @} */ /** @defgroup TV_FILTER_CTL_1 * @{ */ #define TV_FILTER_CTL_1 0x68080 /** * Enables automatic scaling calculation. * * If set, the rest of the registers are ignored, and the calculated values can * be read back from the register. */ # define TV_AUTO_SCALE (1 << 31) /** * Disables the vertical filter. * * This is required on modes more than 1024 pixels wide */ # define TV_V_FILTER_BYPASS (1 << 29) /** Enables adaptive vertical filtering */ # define TV_VADAPT (1 << 28) # define TV_VADAPT_MODE_MASK (3 << 26) /** Selects the least adaptive vertical filtering mode */ # define TV_VADAPT_MODE_LEAST (0 << 26) /** Selects the moderately adaptive vertical filtering mode */ # define TV_VADAPT_MODE_MODERATE (1 << 26) /** Selects the most adaptive vertical filtering mode */ # define TV_VADAPT_MODE_MOST (3 << 26) /** * Sets the horizontal scaling factor. * * This should be the fractional part of the horizontal scaling factor divided * by the oversampling rate. TV_HSCALE should be less than 1, and set to: * * (src width - 1) / ((oversample * dest width) - 1) */ # define TV_HSCALE_FRAC_MASK 0x00003fff # define TV_HSCALE_FRAC_SHIFT 0 /** @} */ /** @defgroup TV_FILTER_CTL_2 * @{ */ #define TV_FILTER_CTL_2 0x68084 /** * Sets the integer part of the 3.15 fixed-point vertical scaling factor. * * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) */ # define TV_VSCALE_INT_MASK 0x00038000 # define TV_VSCALE_INT_SHIFT 15 /** * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. * * \sa TV_VSCALE_INT_MASK */ # define TV_VSCALE_FRAC_MASK 0x00007fff # define TV_VSCALE_FRAC_SHIFT 0 /** @} */ /** @defgroup TV_FILTER_CTL_3 * @{ */ #define TV_FILTER_CTL_3 0x68088 /** * Sets the integer part of the 3.15 fixed-point vertical scaling factor. * * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) * * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. */ # define TV_VSCALE_IP_INT_MASK 0x00038000 # define TV_VSCALE_IP_INT_SHIFT 15 /** * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. * * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. * * \sa TV_VSCALE_IP_INT_MASK */ # define TV_VSCALE_IP_FRAC_MASK 0x00007fff # define TV_VSCALE_IP_FRAC_SHIFT 0 /** @} */ /** @defgroup TV_CC_CONTROL * @{ */ #define TV_CC_CONTROL 0x68090 # define TV_CC_ENABLE (1 << 31) /** * Specifies which field to send the CC data in. * * CC data is usually sent in field 0. */ # define TV_CC_FID_MASK (1 << 27) # define TV_CC_FID_SHIFT 27 /** Sets the horizontal position of the CC data. Usually 135. */ # define TV_CC_HOFF_MASK 0x03ff0000 # define TV_CC_HOFF_SHIFT 16 /** Sets the vertical position of the CC data. Usually 21 */ # define TV_CC_LINE_MASK 0x0000003f # define TV_CC_LINE_SHIFT 0 /** @} */ /** @defgroup TV_CC_DATA * @{ */ #define TV_CC_DATA 0x68094 # define TV_CC_RDY (1 << 31) /** Second word of CC data to be transmitted. */ # define TV_CC_DATA_2_MASK 0x007f0000 # define TV_CC_DATA_2_SHIFT 16 /** First word of CC data to be transmitted. */ # define TV_CC_DATA_1_MASK 0x0000007f # define TV_CC_DATA_1_SHIFT 0 /** @} */ /** @{ */ #define TV_H_LUMA_0 0x68100 #define TV_H_LUMA_59 0x681ec #define TV_H_CHROMA_0 0x68200 #define TV_H_CHROMA_59 0x682ec #define TV_V_LUMA_0 0x68300 #define TV_V_LUMA_42 0x683a8 #define TV_V_CHROMA_0 0x68400 #define TV_V_CHROMA_42 0x684a8 /** @} */ #define PIPEA_DSL 0x70000 #define PIPEACONF 0x70008 #define PIPEACONF_ENABLE (1<<31) #define PIPEACONF_DISABLE 0 #define PIPEACONF_DOUBLE_WIDE (1<<30) #define I965_PIPECONF_ACTIVE (1<<30) #define PIPEACONF_SINGLE_WIDE 0 #define PIPEACONF_PIPE_UNLOCKED 0 #define PIPEACONF_PIPE_LOCKED (1<<25) #define PIPEACONF_PALETTE 0 #define PIPEACONF_GAMMA (1<<24) /* Ironlake: gamma */ #define PIPECONF_PALETTE_8BIT (0<<24) #define PIPECONF_PALETTE_10BIT (1<<24) #define PIPECONF_PALETTE_12BIT (2<<24) #define PIPECONF_FORCE_BORDER (1<<25) #define PIPECONF_PROGRESSIVE (0 << 21) #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) /* Ironlake */ #define PIPECONF_MSA_TIMING_DELAY (0<<18) /* for eDP */ #define PIPECONF_NO_DYNAMIC_RATE_CHANGE (0 << 16) #define PIPECONF_NO_ROTATION (0<<14) #define PIPECONF_FULL_COLOR_RANGE (0<<13) #define PIPECONF_CE_COLOR_RANGE (1<<13) #define PIPECONF_COLOR_SPACE_RGB (0<<11) #define PIPECONF_COLOR_SPACE_YUV601 (1<<11) #define PIPECONF_COLOR_SPACE_YUV709 (2<<11) #define PIPECONF_CONNECT_DEFAULT (0<<9) #define PIPECONF_8BPP (0<<5) #define PIPECONF_10BPP (1<<5) #define PIPECONF_6BPP (2<<5) #define PIPECONF_12BPP (3<<5) #define PIPECONF_ENABLE_DITHER (1<<4) #define PIPECONF_DITHER_SPATIAL (0<<2) #define PIPECONF_DITHER_ST1 (1<<2) #define PIPECONF_DITHER_ST2 (2<<2) #define PIPECONF_DITHER_TEMPORAL (3<<2) #define PIPEAGCMAXRED 0x70010 #define PIPEAGCMAXGREEN 0x70014 #define PIPEAGCMAXBLUE 0x70018 #define PIPEASTAT 0x70024 # define FIFO_UNDERRUN (1 << 31) # define CRC_ERROR_ENABLE (1 << 29) # define CRC_DONE_ENABLE (1 << 28) # define GMBUS_EVENT_ENABLE (1 << 27) # define VSYNC_INT_ENABLE (1 << 25) # define DLINE_COMPARE_ENABLE (1 << 24) # define DPST_EVENT_ENABLE (1 << 23) # define LBLC_EVENT_ENABLE (1 << 22) # define OFIELD_INT_ENABLE (1 << 21) # define EFIELD_INT_ENABLE (1 << 20) # define SVBLANK_INT_ENABLE (1 << 18) # define VBLANK_INT_ENABLE (1 << 17) # define OREG_UPDATE_ENABLE (1 << 16) # define CRC_ERROR_INT_STATUS (1 << 13) # define CRC_DONE_INT_STATUS (1 << 12) # define GMBUS_INT_STATUS (1 << 11) # define VSYNC_INT_STATUS (1 << 9) # define DLINE_COMPARE_STATUS (1 << 8) # define DPST_EVENT_STATUS (1 << 7) # define LBLC_EVENT_STATUS (1 << 6) # define OFIELD_INT_STATUS (1 << 5) # define EFIELD_INT_STATUS (1 << 4) # define SVBLANK_INT_STATUS (1 << 2) # define VBLANK_INT_STATUS (1 << 1) # define OREG_UPDATE_STATUS (1 << 0) #define DSPARB 0x70030 #define DSPARB_CSTART_SHIFT 7 #define DSPARB_BSTART_SHIFT 0 #define DSPARB_BEND_SHIFT 9 /* on 855 */ #define DSPARB_AEND_SHIFT 0 #define DSPFW1 0x70034 #define DSPFW2 0x70038 #define DSPFW3 0x7003c /* * The two pipe frame counter registers are not synchronized, so * reading a stable value is somewhat tricky. The following code * should work: * * do { * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT; * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >> PIPE_FRAME_LOW_SHIFT); * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >> PIPE_FRAME_HIGH_SHIFT); * } while (high1 != high2); * frame = (high1 << 8) | low1; */ #define PIPEAFRAMEHIGH 0x70040 #define PIPE_FRAME_HIGH_MASK 0x0000ffff #define PIPE_FRAME_HIGH_SHIFT 0 #define PIPEAFRAMEPIXEL 0x70044 #define PIPE_FRAME_LOW_MASK 0xff000000 #define PIPE_FRAME_LOW_SHIFT 24 /* * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register * and is 24 bits wide. */ #define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_SHIFT 0 /* * Computing GMCH M and N values. * * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes * * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz) * * The GMCH value is used internally */ #define PIPEA_GMCH_DATA_M 0x70050 /* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */ #define PIPE_GMCH_DATA_M_TU_SIZE_MASK (0x3f << 25) #define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25 #define PIPE_GMCH_DATA_M_MASK (0xffffff) #define PIPEA_GMCH_DATA_N 0x70054 #define PIPE_GMCH_DATA_N_MASK (0xffffff) /* * Computing Link M and N values. * * Link M / N = pixel_clock / ls_clk * * (the DP spec calls pixel_clock the 'strm_clk') * * The Link value is transmitted in the Main Stream * Attributes and VB-ID. */ #define PIPEA_DP_LINK_M 0x70060 #define PIPEA_DP_LINK_M_MASK (0xffffff) #define PIPEA_DP_LINK_N 0x70064 #define PIPEA_DP_LINK_N_MASK (0xffffff) #define PIPEB_DSL 0x71000 #define PIPEBCONF 0x71008 #define PIPEBCONF_ENABLE (1<<31) #define PIPEBCONF_DISABLE 0 #define PIPEBCONF_DOUBLE_WIDE (1<<30) #define PIPEBCONF_DISABLE 0 #define PIPEBCONF_GAMMA (1<<24) #define PIPEBCONF_PALETTE 0 #define PIPEBGCMAXRED 0x71010 #define PIPEBGCMAXGREEN 0x71014 #define PIPEBGCMAXBLUE 0x71018 #define PIPEBSTAT 0x71024 #define PIPEBFRAMEHIGH 0x71040 #define PIPEBFRAMEPIXEL 0x71044 #define PIPEB_GMCH_DATA_M 0x71050 #define PIPEB_GMCH_DATA_N 0x71054 #define PIPEB_DP_LINK_M 0x71060 #define PIPEB_DP_LINK_N 0x71064 #define DSPACNTR 0x70180 #define DSPBCNTR 0x71180 #define DISPLAY_PLANE_ENABLE (1<<31) #define DISPLAY_PLANE_DISABLE 0 #define DISPLAY_PLANE_TILED (1<<10) #define DISPPLANE_GAMMA_ENABLE (1<<30) #define DISPPLANE_GAMMA_DISABLE 0 #define DISPPLANE_PIXFORMAT_MASK (0xf<<26) #define DISPPLANE_8BPP (0x2<<26) #define DISPPLANE_15_16BPP (0x4<<26) #define DISPPLANE_16BPP (0x5<<26) #define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) /* Ironlake: BGRX */ #define DISPPLANE_32BPP (0x7<<26) /* Ironlake: not support */ /* Ironlake */ #define DISPPLANE_32BPP_10 (0x8<<26) /* 2:10:10:10 */ #define DISPPLANE_32BPP_BGRX (0xa<<26) #define DISPPLANE_64BPP (0xc<<26) #define DISPPLANE_32BPP_RGBX (0xe<<26) #define DISPPLANE_STEREO_ENABLE (1<<25) #define DISPPLANE_STEREO_DISABLE 0 #define DISPPLANE_SEL_PIPE_MASK (1<<24) #define DISPPLANE_SEL_PIPE_A 0 /* Ironlake: don't use */ #define DISPPLANE_SEL_PIPE_B (1<<24) #define DISPPLANE_NORMAL_RANGE (0<<25) #define DISPPLANE_EXT_RANGE (1<<25) /* Ironlake */ #define DISPPLANE_CSC_BYPASS (0<<24) #define DISPPLANE_CSC_PASSTHROUGH (1<<24) #define DISPPLANE_SRC_KEY_ENABLE (1<<22) #define DISPPLANE_SRC_KEY_DISABLE 0 #define DISPPLANE_LINE_DOUBLE (1<<20) #define DISPPLANE_NO_LINE_DOUBLE 0 #define DISPPLANE_STEREO_POLARITY_FIRST 0 #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) /* plane B only */ #define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) #define DISPPLANE_ALPHA_TRANS_DISABLE 0 #define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 #define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) /* Ironlake */ #define DISPPLANE_X_TILE (1<<10) #define DISPPLANE_LINEAR (0<<10) #define DSPABASE 0x70184 /* Ironlake */ #define DSPALINOFF 0x70184 #define DSPASTRIDE 0x70188 #define DSPBBASE 0x71184 /* Ironlake */ #define DSPBLINOFF 0x71184 #define DSPBADDR DSPBBASE #define DSPBSTRIDE 0x71188 #define DSPAKEYVAL 0x70194 #define DSPAKEYMASK 0x70198 #define DSPAPOS 0x7018C /* reserved */ #define DSPASIZE 0x70190 #define DSPBPOS 0x7118C #define DSPBSIZE 0x71190 #define DSPASURF 0x7019C #define DSPATILEOFF 0x701A4 #define DSPBSURF 0x7119C #define DSPBTILEOFF 0x711A4 #define VGACNTRL 0x71400 # define VGA_DISP_DISABLE (1 << 31) # define VGA_2X_MODE (1 << 30) # define VGA_PIPE_B_SELECT (1 << 29) /* Various masks for reserved bits, etc. */ #define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \ (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \ (1<<2)|(1<<1)|1|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))) #define I830_FWATER2_MASK ~(0) #define DV0A_RESERVED ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1) #define DV0B_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1) #define VGA0_N_DIVISOR_MASK ((1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) #define VGA0_M1_DIVISOR_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) #define VGA0_M2_DIVISOR_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) #define VGA0_M1M2N_RESERVED ~(VGA0_N_DIVISOR_MASK|VGA0_M1_DIVISOR_MASK|VGA0_M2_DIVISOR_MASK) #define VGA0_POSTDIV_MASK ((1<<7)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) #define VGA1_POSTDIV_MASK ((1<<15)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) #define VGA_POSTDIV_RESERVED ~(VGA0_POSTDIV_MASK|VGA1_POSTDIV_MASK|(1<<7)|(1<<15)) #define DPLLA_POSTDIV_MASK ((1<<23)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) #define DPLLA_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<22)|(1<<15)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) #define ADPA_RESERVED ((1<<2)|(1<<1)|1|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) #define SUPER_WORD 32 #define BURST_A_MASK ((1<<11)|(1<<10)|(1<<9)|(1<<8)) #define BURST_B_MASK ((1<<26)|(1<<25)|(1<<24)) #define WATER_A_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) #define WATER_B_MASK ((1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) #define WATER_RESERVED ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<7)|(1<<6)) #define PIPEACONF_RESERVED ((1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff) #define PIPEBCONF_RESERVED ((1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff) #define DSPACNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0xffff) #define DSPBCNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0x7ffe) #define I830_GMCH_CTRL 0x52 #define I830_GMCH_ENABLED 0x4 #define I830_GMCH_MEM_MASK 0x1 #define I830_GMCH_MEM_64M 0x1 #define I830_GMCH_MEM_128M 0 #define I830_GMCH_GMS_MASK 0x70 #define I830_GMCH_GMS_DISABLED 0x00 #define I830_GMCH_GMS_LOCAL 0x10 #define I830_GMCH_GMS_STOLEN_512 0x20 #define I830_GMCH_GMS_STOLEN_1024 0x30 #define I830_GMCH_GMS_STOLEN_8192 0x40 #define I830_RDRAM_CHANNEL_TYPE 0x03010 #define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) #define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) #define I855_GMCH_GMS_MASK (0xF << 4) #define I855_GMCH_GMS_DISABLED 0x00 #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) #define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) #define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) #define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) #define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) #define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) #define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) #define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) #define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) #define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) #define I915_GCFGC 0xf0 #define I915_LOW_FREQUENCY_ENABLE (1 << 7) #define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) #define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) #define I915_DISPLAY_CLOCK_MASK (7 << 4) #define I855_HPLLCC 0xc0 #define I855_CLOCK_CONTROL_MASK (3 << 0) #define I855_CLOCK_133_200 (0 << 0) #define I855_CLOCK_100_200 (1 << 0) #define I855_CLOCK_100_133 (2 << 0) #define I855_CLOCK_166_250 (3 << 0) /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) #define COLOR_BLT_WRITE_ALPHA (1<<21) #define COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4)) #define XY_COLOR_BLT_WRITE_ALPHA (1<<21) #define XY_COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_TILED (1<<11) #define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1) #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) #define XY_SRC_COPY_BLT_DST_TILED (1<<11) #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4) #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22)) #define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7) #define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) #define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) #define XY_MONO_PAT_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_PAT_BLT_WRITE_RGB (1<<20) #define XY_MONO_SRC_BLT_CMD ((0x2<<29)|(0x54<<22)|(0x6)) #define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_SRC_BLT_WRITE_RGB (1<<20) #define STATE3D_FOG_MODE ((3<<29)|(0x1d<<24)|(0x89<<16)|2) #define FOG_MODE_VERTEX (1<<31) #define DISABLE_TEX_TRANSFORM (1<<28) #define TEXTURE_SET(x) (x<<29) #define STATE3D_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define DISABLE_PERSPECTIVE_DIVIDE (1<<29) #define MI_SET_CONTEXT (0x18<<23) #define CTXT_NO_RESTORE (1) #define CTXT_PALETTE_SAVE_DISABLE (1<<3) #define CTXT_PALETTE_RESTORE_DISABLE (1<<2) /* Dword 0 */ #define MI_VERTEX_BUFFER (0x17<<23) #define MI_VERTEX_BUFFER_IDX(x) (x<<20) #define MI_VERTEX_BUFFER_PITCH(x) (x<<13) #define MI_VERTEX_BUFFER_WIDTH(x) (x<<6) /* Dword 1 */ #define MI_VERTEX_BUFFER_DISABLE (1) /* Overlay Flip */ #define MI_OVERLAY_FLIP (0x11<<23) #define MI_OVERLAY_FLIP_CONTINUE (0<<21) #define MI_OVERLAY_FLIP_ON (1<<21) #define MI_OVERLAY_FLIP_OFF (2<<21) /* Wait for Events */ #define MI_WAIT_FOR_EVENT (0x03<<23) #define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18) #define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17) #define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) #define MI_WAIT_FOR_PIPEB_VBLANK (1<<7) #define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5) #define MI_WAIT_FOR_PIPEA_VBLANK (1<<3) #define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<1) /* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */ #define MI_LOAD_SCAN_LINES_INCL (0x12<<23) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20) /* Flush */ #define MI_FLUSH (0x04<<23) #define MI_WRITE_DIRTY_STATE (1<<4) #define MI_END_SCENE (1<<3) #define MI_GLOBAL_SNAPSHOT_COUNT_RESET (1<<3) #define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2) #define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1) #define MI_INVALIDATE_MAP_CACHE (1<<0) /* broadwater flush bits */ #define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3) /* Noop */ #define MI_NOOP 0x00 #define MI_NOOP_WRITE_ID (1<<22) #define MI_NOOP_ID_MASK (1<<22 - 1) #define STATE3D_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x01<<16)) /* Batch */ #define MI_BATCH_BUFFER ((0x30 << 23) | 1) #define MI_BATCH_BUFFER_START (0x31 << 23) #define MI_BATCH_BUFFER_END (0xA << 23) #define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE_I965 (1 << 8) /* STATE3D_FOG_MODE stuff */ #define ENABLE_FOG_SOURCE (1<<27) #define ENABLE_FOG_CONST (1<<24) #define ENABLE_FOG_DENSITY (1<<23) #define MAX_DISPLAY_PIPES 2 typedef enum { CrtIndex = 0, TvIndex, DfpIndex, LfpIndex, Crt2Index, Tv2Index, Dfp2Index, Lfp2Index, NumDisplayTypes } DisplayType; /* What's connected to the pipes (as reported by the BIOS) */ #define PIPE_ACTIVE_MASK 0xff #define PIPE_CRT_ACTIVE (1 << CrtIndex) #define PIPE_TV_ACTIVE (1 << TvIndex) #define PIPE_DFP_ACTIVE (1 << DfpIndex) #define PIPE_LCD_ACTIVE (1 << LfpIndex) #define PIPE_CRT2_ACTIVE (1 << Crt2Index) #define PIPE_TV2_ACTIVE (1 << Tv2Index) #define PIPE_DFP2_ACTIVE (1 << Dfp2Index) #define PIPE_LCD2_ACTIVE (1 << Lfp2Index) #define PIPE_SIZED_DISP_MASK (PIPE_DFP_ACTIVE | \ PIPE_LCD_ACTIVE | \ PIPE_DFP2_ACTIVE) #define PIPE_A_SHIFT 0 #define PIPE_B_SHIFT 8 #define PIPE_SHIFT(n) ((n) == 0 ? \ PIPE_A_SHIFT : PIPE_B_SHIFT) /* * Some BIOS scratch area registers. The 845 (and 830?) store the amount * of video memory available to the BIOS in SWF1. */ #define SWF0 0x71410 #define SWF1 0x71414 #define SWF2 0x71418 #define SWF3 0x7141c #define SWF4 0x71420 #define SWF5 0x71424 #define SWF6 0x71428 /* * 855 scratch registers. */ #define SWF00 0x70410 #define SWF01 0x70414 #define SWF02 0x70418 #define SWF03 0x7041c #define SWF04 0x70420 #define SWF05 0x70424 #define SWF06 0x70428 #define SWF10 SWF0 #define SWF11 SWF1 #define SWF12 SWF2 #define SWF13 SWF3 #define SWF14 SWF4 #define SWF15 SWF5 #define SWF16 SWF6 #define SWF30 0x72414 #define SWF31 0x72418 #define SWF32 0x7241c /* * Overlay registers. These are overlay registers accessed via MMIO. * Those loaded via the overlay register page are defined in i830_video.c. */ #define OVADD 0x30000 #define DOVSTA 0x30008 #define OC_BUF (0x3<<20) #define OGAMC5 0x30010 #define OGAMC4 0x30014 #define OGAMC3 0x30018 #define OGAMC2 0x3001c #define OGAMC1 0x30020 #define OGAMC0 0x30024 /* * Palette registers */ #define PALETTE_A 0x0a000 #define PALETTE_B 0x0a800 /* Framebuffer compression */ #define FBC_CFB_BASE 0x03200 /* 4k page aligned */ #define FBC_LL_BASE 0x03204 /* 4k page aligned */ #define FBC_CONTROL 0x03208 #define FBC_CTL_EN (1<<31) #define FBC_CTL_PERIODIC (1<<30) #define FBC_CTL_INTERVAL_SHIFT (16) #define FBC_CTL_UNCOMPRESSIBLE (1<<14) #define FBC_CTL_STRIDE_SHIFT (5) #define FBC_CTL_FENCENO (1<<0) #define FBC_COMMAND 0x0320c #define FBC_CMD_COMPRESS (1<<0) #define FBC_STATUS 0x03210 #define FBC_STAT_COMPRESSING (1<<31) #define FBC_STAT_COMPRESSED (1<<30) #define FBC_STAT_MODIFIED (1<<29) #define FBC_STAT_CURRENT_LINE (1<<0) #define FBC_CONTROL2 0x03214 #define FBC_CTL_FENCE_DBL (0<<4) #define FBC_CTL_IDLE_IMM (0<<2) #define FBC_CTL_IDLE_FULL (1<<2) #define FBC_CTL_IDLE_LINE (2<<2) #define FBC_CTL_IDLE_DEBUG (3<<2) #define FBC_CTL_CPU_FENCE (1<<1) #define FBC_CTL_PLANEA (0<<0) #define FBC_CTL_PLANEB (1<<0) #define FBC_FENCE_OFF 0x0321b #define FBC_MOD_NUM 0x03220 #define FBC_TAG_DEBUG 0x03300 #define FBC_LL_SIZE (1536) #define FBC_LL_PAD (32) /* Framebuffer compression version 2 */ #define DPFC_CB_BASE 0x3200 #define DPFC_CONTROL 0x3208 #define DPFC_CTL_EN (1<<31) #define DPFC_CTL_PLANEA (0<<30) #define DPFC_CTL_PLANEB (1<<30) #define DPFC_CTL_FENCE_EN (1<<29) #define DPFC_CTL_LIMIT_1X (0<<6) #define DPFC_CTL_LIMIT_2X (1<<6) #define DPFC_CTL_LIMIT_4X (2<<6) #define DPFC_RECOMP_CTL 0x320c #define DPFC_RECOMP_STALL_EN (1<<27) #define DPFC_RECOMP_STALL_WM_SHIFT (16) #define DPFC_RECOMP_STALL_WM_MASK (0x07ff0000) #define DPFC_RECOMP_TIMER_COUNT_SHIFT (0) #define DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f) #define DPFC_STATUS 0x3210 #define DPFC_INVAL_SEG_SHIFT (16) #define DPFC_INVAL_SEG_MASK (0x07ff0000) #define DPFC_COMP_SEG_SHIFT (0) #define DPFC_COMP_SEG_MASK (0x000003ff) #define DPFC_STATUS2 0x3214 #define DPFC_FENCE_YOFF 0x3218 #define PEG_BAND_GAP_DATA 0x14d68 #define MCHBAR_RENDER_STANDBY 0x111B8 #define RENDER_STANDBY_ENABLE (1 << 30) /* Ironlake */ /* warmup time in us */ #define WARMUP_PCH_REF_CLK_SSC_MOD 1 #define WARMUP_PCH_FDI_RECEIVER_PLL 25 #define WARMUP_PCH_DPLL 50 #define WARMUP_CPU_DP_PLL 20 #define WARMUP_CPU_FDI_TRANSMITTER_PLL 10 #define WARMUP_DMI_LATENCY 20 #define FDI_TRAIN_PATTERN_1_TIME 0.5 #define FDI_TRAIN_PATTERN_2_TIME 1.5 #define FDI_ONE_IDLE_PATTERN_TIME 31 #define CPU_VGACNTRL 0x41000 #define DIGITAL_PORT_HOTPLUG_CNTRL 0x44030 #define DIGITAL_PORTA_HOTPLUG_ENABLE (1 << 4) #define DIGITAL_PORTA_SHORT_PULSE_2MS (0 << 2) #define DIGITAL_PORTA_SHORT_PULSE_4_5MS (1 << 2) #define DIGITAL_PORTA_SHORT_PULSE_6MS (2 << 2) #define DIGITAL_PORTA_SHORT_PULSE_100MS (3 << 2) #define DIGITAL_PORTA_NO_DETECT (0 << 0) #define DIGITAL_PORTA_LONG_PULSE_DETECT_MASK (1 << 1) #define DIGITAL_PORTA_SHORT_PULSE_DETECT_MASK (1 << 0) /* refresh rate hardware control */ #define RR_HW_CTL 0x45300 #define RR_HW_LOW_POWER_FRAMES_MASK 0xff #define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 #define FDI_PLL_BIOS_0 0x46000 #define FDI_PLL_BIOS_1 0x46004 #define FDI_PLL_BIOS_2 0x46008 #define DISPLAY_PORT_PLL_BIOS_0 0x4600c #define DISPLAY_PORT_PLL_BIOS_1 0x46010 #define DISPLAY_PORT_PLL_BIOS_2 0x46014 #define FDI_PLL_FREQ_CTL 0x46030 #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 #define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff #define PIPEA_DATA_M1 0x60030 #define TU_SIZE(x) (((x)-1) << 25) /* default size 64 */ #define TU_SIZE_MASK 0x7e000000 #define PIPEA_DATA_M1_OFFSET 0 #define PIPEA_DATA_N1 0x60034 #define PIPEA_DATA_N1_OFFSET 0 #define PIPEA_DATA_M2 0x60038 #define PIPEA_DATA_M2_OFFSET 0 #define PIPEA_DATA_N2 0x6003c #define PIPEA_DATA_N2_OFFSET 0 #define PIPEA_LINK_M1 0x60040 #define PIPEA_LINK_M1_OFFSET 0 #define PIPEA_LINK_N1 0x60044 #define PIPEA_LINK_N1_OFFSET 0 #define PIPEA_LINK_M2 0x60048 #define PIPEA_LINK_M2_OFFSET 0 #define PIPEA_LINK_N2 0x6004c #define PIPEA_LINK_N2_OFFSET 0 /* PIPEB timing regs are same start from 0x61000 */ #define PIPEB_DATA_M1 0x61030 #define PIPEB_DATA_M1_OFFSET 0 #define PIPEB_DATA_N1 0x61034 #define PIPEB_DATA_N1_OFFSET 0 #define PIPEB_DATA_M2 0x61038 #define PIPEB_DATA_M2_OFFSET 0 #define PIPEB_DATA_N2 0x6103c #define PIPEB_DATA_N2_OFFSET 0 #define PIPEB_LINK_M1 0x61040 #define PIPEB_LINK_M1_OFFSET 0 #define PIPEB_LINK_N1 0x61044 #define PIPEB_LINK_N1_OFFSET 0 #define PIPEB_LINK_M2 0x61048 #define PIPEB_LINK_M2_OFFSET 0 #define PIPEB_LINK_N2 0x6104c #define PIPEB_LINK_N2_OFFSET 0 /* PIPECONF for pipe A/B addr is same */ /* cusor A is only connected to pipe A, cursor B is connected to pipe B. Otherwise no change. */ /* Plane A/B, DSPACNTR/DSPBCNTR addr not changed */ /* CPU panel fitter */ #define PFA_CTL_1 0x68080 #define PFB_CTL_1 0x68880 #define PF_ENABLE (1<<31) #define PFA_WIN_POS 0x68070 #define PFB_WIN_POS 0x68870 #define PFA_WIN_SIZE 0x68074 #define PFB_WIN_SIZE 0x68874 /* legacy palette */ #define LGC_PALETTE_A 0x4a000 #define LGC_PALETTE_B 0x4a800 /* interrupts */ #define DE_MASTER_IRQ_CONTROL (1 << 31) #define DE_SPRITEB_FLIP_DONE (1 << 29) #define DE_SPRITEA_FLIP_DONE (1 << 28) #define DE_PLANEB_FLIP_DONE (1 << 27) #define DE_PLANEA_FLIP_DONE (1 << 26) #define DE_PCU_EVENT (1 << 25) #define DE_GTT_FAULT (1 << 24) #define DE_POISON (1 << 23) #define DE_PERFORM_COUNTER (1 << 22) #define DE_PCH_EVENT (1 << 21) #define DE_AUX_CHANNEL_A (1 << 20) #define DE_DP_A_HOTPLUG (1 << 19) #define DE_GSE (1 << 18) #define DE_PIPEB_VBLANK (1 << 15) #define DE_PIPEB_EVEN_FIELD (1 << 14) #define DE_PIPEB_ODD_FIELD (1 << 13) #define DE_PIPEB_LINE_COMPARE (1 << 12) #define DE_PIPEB_VSYNC (1 << 11) #define DE_PIPEB_FIFO_UNDERRUN (1 << 8) #define DE_PIPEA_VBLANK (1 << 7) #define DE_PIPEA_EVEN_FIELD (1 << 6) #define DE_PIPEA_ODD_FIELD (1 << 5) #define DE_PIPEA_LINE_COMPARE (1 << 4) #define DE_PIPEA_VSYNC (1 << 3) #define DE_PIPEA_FIFO_UNDERRUN (1 << 0) #define DEISR 0x44000 #define DEIMR 0x44004 #define DEIIR 0x44008 #define DEIER 0x4400c /* GT interrupt */ #define GT_SYNC_STATUS (1 << 2) #define GT_USER_INTERRUPT (1 << 0) #define GTISR 0x44010 #define GTIMR 0x44014 #define GTIIR 0x44018 #define GTIER 0x4401c /* PCH */ /* south display engine interrupt */ #define SDE_CRT_HOTPLUG (1 << 11) #define SDE_PORTD_HOTPLUG (1 << 10) #define SDE_PORTC_HOTPLUG (1 << 9) #define SDE_PORTB_HOTPLUG (1 << 8) #define SDE_SDVOB_HOTPLUG (1 << 6) #define SDEISR 0xc4000 #define SDEIMR 0xc4004 #define SDEIIR 0xc4008 #define SDEIER 0xc400c /* digital port hotplug */ #define PCH_PORT_HOTPLUG 0xc4030 #define PORTD_HOTPLUG_ENABLE (1 << 20) #define PORTD_PULSE_DURATION_2ms (0) #define PORTD_PULSE_DURATION_4_5ms (1 << 18) #define PORTD_PULSE_DURATION_6ms (2 << 18) #define PORTD_PULSE_DURATION_100ms (3 << 18) #define PORTD_HOTPLUG_NO_DETECT (0) #define PORTD_HOTPLUG_SHORT_DETECT (1 << 16) #define PORTD_HOTPLUG_LONG_DETECT (1 << 17) #define PORTC_HOTPLUG_ENABLE (1 << 12) #define PORTC_PULSE_DURATION_2ms (0) #define PORTC_PULSE_DURATION_4_5ms (1 << 10) #define PORTC_PULSE_DURATION_6ms (2 << 10) #define PORTC_PULSE_DURATION_100ms (3 << 10) #define PORTC_HOTPLUG_NO_DETECT (0) #define PORTC_HOTPLUG_SHORT_DETECT (1 << 8) #define PORTC_HOTPLUG_LONG_DETECT (1 << 9) #define PORTB_HOTPLUG_ENABLE (1 << 4) #define PORTB_PULSE_DURATION_2ms (0) #define PORTB_PULSE_DURATION_4_5ms (1 << 2) #define PORTB_PULSE_DURATION_6ms (2 << 2) #define PORTB_PULSE_DURATION_100ms (3 << 2) #define PORTB_HOTPLUG_NO_DETECT (0) #define PORTB_HOTPLUG_SHORT_DETECT (1 << 0) #define PORTB_HOTPLUG_LONG_DETECT (1 << 1) #define PCH_GPIOA 0xc5010 #define PCH_GPIOB 0xc5014 #define PCH_GPIOC 0xc5018 #define PCH_GPIOD 0xc501c #define PCH_GPIOE 0xc5020 #define PCH_GPIOF 0xc5024 #define PCH_GMBUS0 0xc5100 #define PCH_GMBUS1 0xc5104 #define PCH_GMBUS2 0xc5108 #define PCH_GMBUS3 0xc510c #define PCH_GMBUS4 0xc5110 #define PCH_GMBUS5 0xc5120 #define PCH_DPLL_A 0xc6014 #define PCH_DPLL_B 0xc6018 #define PCH_FPA0 0xc6040 #define PCH_FPA1 0xc6044 #define PCH_FPB0 0xc6048 #define PCH_FPB1 0xc604c #define PCH_DPLL_TEST 0xc606c #define PCH_DREF_CONTROL 0xC6200 #define DREF_CONTROL_MASK 0x7fc3 #define DREF_CPU_SOURCE_OUTPUT_DISABLE (0<<13) #define DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD (2<<13) #define DREF_CPU_SOURCE_OUTPUT_NONSPREAD (3<<13) #define DREF_SSC_SOURCE_DISABLE (0<<11) #define DREF_SSC_SOURCE_ENABLE (2<<11) #define DREF_NONSPREAD_SOURCE_DISABLE (0<<9) #define DREF_NONSPREAD_SOURCE_ENABLE (2<<9) #define DREF_SUPERSPREAD_SOURCE_DISABLE (0<<7) #define DREF_SUPERSPREAD_SOURCE_ENABLE (2<<7) #define DREF_SSC4_DOWNSPREAD (0<<6) #define DREF_SSC4_CENTERSPREAD (1<<6) #define DREF_SSC1_DISABLE (0<<1) #define DREF_SSC1_ENABLE (1<<1) #define DREF_SSC4_DISABLE (0) #define DREF_SSC4_ENABLE (1) #define PCH_RAWCLK_FREQ 0xc6204 #define FDL_TP1_TIMER_SHIFT 12 #define FDL_TP1_TIMER_MASK (3<<12) #define FDL_TP2_TIMER_SHIFT 10 #define FDL_TP2_TIMER_MASK (3<<10) #define RAWCLK_FREQ_MASK 0x3ff #define PCH_DPLL_TMR_CFG 0xc6208 #define PCH_SSC4_PARMS 0xc6210 #define PCH_SSC4_AUX_PARMS 0xc6214 /* transcoder */ #define TRANS_HTOTAL_A 0xe0000 #define TRANS_HTOTAL_SHIFT 16 #define TRANS_HACTIVE_SHIFT 0 #define TRANS_HBLANK_A 0xe0004 #define TRANS_HBLANK_END_SHIFT 16 #define TRANS_HBLANK_START_SHIFT 0 #define TRANS_HSYNC_A 0xe0008 #define TRANS_HSYNC_END_SHIFT 16 #define TRANS_HSYNC_START_SHIFT 0 #define TRANS_VTOTAL_A 0xe000c #define TRANS_VTOTAL_SHIFT 16 #define TRANS_VACTIVE_SHIFT 0 #define TRANS_VBLANK_A 0xe0010 #define TRANS_VBLANK_END_SHIFT 16 #define TRANS_VBLANK_START_SHIFT 0 #define TRANS_VSYNC_A 0xe0014 #define TRANS_VSYNC_END_SHIFT 16 #define TRANS_VSYNC_START_SHIFT 0 #define TRANSA_DATA_M1 0xe0030 #define TRANSA_DATA_N1 0xe0034 #define TRANSA_DATA_M2 0xe0038 #define TRANSA_DATA_N2 0xe003c #define TRANSA_DP_LINK_M1 0xe0040 #define TRANSA_DP_LINK_N1 0xe0044 #define TRANSA_DP_LINK_M2 0xe0048 #define TRANSA_DP_LINK_N2 0xe004c #define TRANS_HTOTAL_B 0xe1000 #define TRANS_HBLANK_B 0xe1004 #define TRANS_HSYNC_B 0xe1008 #define TRANS_VTOTAL_B 0xe100c #define TRANS_VBLANK_B 0xe1010 #define TRANS_VSYNC_B 0xe1014 #define TRANSB_DATA_M1 0xe1030 #define TRANSB_DATA_N1 0xe1034 #define TRANSB_DATA_M2 0xe1038 #define TRANSB_DATA_N2 0xe103c #define TRANSB_DP_LINK_M1 0xe1040 #define TRANSB_DP_LINK_N1 0xe1044 #define TRANSB_DP_LINK_M2 0xe1048 #define TRANSB_DP_LINK_N2 0xe104c #define TRANSACONF 0xf0008 #define TRANSBCONF 0xf1008 #define TRANS_DISABLE (0<<31) #define TRANS_ENABLE (1<<31) #define TRANS_STATE_MASK (1<<30) #define TRANS_STATE_DISABLE (0<<30) #define TRANS_STATE_ENABLE (1<<30) #define TRANS_FSYNC_DELAY_HB1 (0<<27) #define TRANS_FSYNC_DELAY_HB2 (1<<27) #define TRANS_FSYNC_DELAY_HB3 (2<<27) #define TRANS_FSYNC_DELAY_HB4 (3<<27) #define TRANS_DP_AUDIO_ONLY (1<<26) #define TRANS_DP_VIDEO_AUDIO (0<<26) #define TRANS_PROGRESSIVE (0<<21) #define TRANS_8BPC (0<<5) #define TRANS_10BPC (1<<5) #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) #define FDI_RXA_CHICKEN 0xc200c #define FDI_RXB_CHICKEN 0xc2010 #define FDI_RX_PHASE_SYNC_POINTER_ENABLE (1) /* CPU: FDI_TX */ #define FDI_TXA_CTL 0x60100 #define FDI_TXB_CTL 0x61100 #define FDI_TX_DISABLE (0<<31) #define FDI_TX_ENABLE (1<<31) #define FDI_LINK_TRAIN_PATTERN_1 (0<<28) #define FDI_LINK_TRAIN_PATTERN_2 (1<<28) #define FDI_LINK_TRAIN_PATTERN_IDLE (2<<28) #define FDI_LINK_TRAIN_NONE (3<<28) #define FDI_LINK_TRAIN_VOLTAGE_0_4V (0<<25) #define FDI_LINK_TRAIN_VOLTAGE_0_6V (1<<25) #define FDI_LINK_TRAIN_VOLTAGE_0_8V (2<<25) #define FDI_LINK_TRAIN_VOLTAGE_1_2V (3<<25) #define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0<<22) #define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22) #define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2<<22) #define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3<<22) #define FDI_DP_PORT_WIDTH_X1 (0<<19) #define FDI_DP_PORT_WIDTH_X2 (1<<19) #define FDI_DP_PORT_WIDTH_X3 (2<<19) #define FDI_DP_PORT_WIDTH_X4 (3<<19) #define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) /* Ironlake: hardwired to 1 */ #define FDI_TX_PLL_ENABLE (1<<14) /* both Tx and Rx */ #define FDI_SCRAMBLING_ENABLE (0<<7) #define FDI_SCRAMBLING_DISABLE (1<<7) /* FDI_RX, FDI_X is hard-wired to Transcoder_X */ #define FDI_RXA_CTL 0xf000c #define FDI_RXB_CTL 0xf100c #define FDI_RX_ENABLE (1<<31) #define FDI_RX_DISABLE (0<<31) /* train, dp width same as FDI_TX */ #define FDI_DP_PORT_WIDTH_X8 (7<<19) #define FDI_8BPC (0<<16) #define FDI_10BPC (1<<16) #define FDI_6BPC (2<<16) #define FDI_12BPC (3<<16) #define FDI_LINK_REVERSE_OVERWRITE (1<<15) #define FDI_DMI_LINK_REVERSE_MASK (1<<14) #define FDI_RX_PLL_ENABLE (1<<13) #define FDI_FS_ERR_CORRECT_ENABLE (1<<11) #define FDI_FE_ERR_CORRECT_ENABLE (1<<10) #define FDI_FS_ERR_REPORT_ENABLE (1<<9) #define FDI_FE_ERR_REPORT_ENABLE (1<<8) #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) #define FDI_SEL_RAWCLK (0<<4) #define FDI_SEL_PCDCLK (1<<4) #define FDI_RXA_MISC 0xf0010 #define FDI_RXB_MISC 0xf1010 #define FDI_RXA_TUSIZE1 0xf0030 #define FDI_RXA_TUSIZE2 0xf0038 #define FDI_RXB_TUSIZE1 0xf1030 #define FDI_RXB_TUSIZE2 0xf1038 /* FDI_RX interrupt register format */ #define FDI_RX_INTER_LANE_ALIGN (1<<10) #define FDI_RX_SYMBOL_LOCK (1<<9) /* train 2 */ #define FDI_RX_BIT_LOCK (1<<8) /* train 1 */ #define FDI_RX_TRAIN_PATTERN_2_FAIL (1<<7) #define FDI_RX_FS_CODE_ERR (1<<6) #define FDI_RX_FE_CODE_ERR (1<<5) #define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1<<4) #define FDI_RX_HDCP_LINK_FAIL (1<<3) #define FDI_RX_PIXEL_FIFO_OVERFLOW (1<<2) #define FDI_RX_CROSS_CLOCK_OVERFLOW (1<<1) #define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1<<0) #define FDI_RXA_IIR 0xf0014 #define FDI_RXA_IMR 0xf0018 #define FDI_RXB_IIR 0xf1014 #define FDI_RXB_IMR 0xf1018 #define FDI_PLL_CTL_1 0xfe000 #define FDI_PLL_CTL_2 0xfe004 /* CRT */ #define PCH_ADPA 0xe1100 #define ADPA_TRANS_SELECT_MASK (1<<30) #define ADPA_TRANS_A_SELECT 0 #define ADPA_TRANS_B_SELECT (1<<30) /* HPD is here */ #define ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */ #define ADPA_CRT_HOTPLUG_MONITOR_NONE (0<<24) #define ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24) #define ADPA_CRT_HOTPLUG_MONITOR_COLOR (3<<24) #define ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24) #define ADPA_CRT_HOTPLUG_ENABLE (1<<23) #define ADPA_CRT_HOTPLUG_PERIOD_64 (0<<22) #define ADPA_CRT_HOTPLUG_PERIOD_128 (1<<22) #define ADPA_CRT_HOTPLUG_WARMUP_5MS (0<<21) #define ADPA_CRT_HOTPLUG_WARMUP_10MS (1<<21) #define ADPA_CRT_HOTPLUG_SAMPLE_2S (0<<20) #define ADPA_CRT_HOTPLUG_SAMPLE_4S (1<<20) #define ADPA_CRT_HOTPLUG_VOLTAGE_40 (0<<18) #define ADPA_CRT_HOTPLUG_VOLTAGE_50 (1<<18) #define ADPA_CRT_HOTPLUG_VOLTAGE_60 (2<<18) #define ADPA_CRT_HOTPLUG_VOLTAGE_70 (3<<18) #define ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17) #define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) /* polarity control not changed */ /* or SDVOB */ #define HDMIB 0xe1140 #define PORT_ENABLE (1 << 31) #define TRANSCODER_A (0) #define TRANSCODER_B (1 << 30) #define COLOR_FORMAT_8bpc (0) #define COLOR_FORMAT_12bpc (3 << 26) #define SDVOB_HOTPLUG_ENABLE (1 << 23) #define SDVO_ENCODING (0) #define TMDS_ENCODING (2 << 10) #define NULL_PACKET_VSYNC_ENABLE (1 << 9) #define SDVOB_BORDER_ENABLE (1 << 7) #define AUDIO_ENABLE (1 << 6) #define VSYNC_ACTIVE_HIGH (1 << 4) #define HSYNC_ACTIVE_HIGH (1 << 3) #define PORT_DETECTED (1 << 2) #define HDMIC 0xe1150 #define HDMID 0xe1160 #define PCH_LVDS 0xe1180 #define AUD_CONFIG 0x62000 #define AUD_DEBUG 0x62010 #define AUD_VID_DID 0x62020 #define AUD_RID 0x62024 #define AUD_SUBN_CNT 0x62028 #define AUD_FUNC_GRP 0x62040 #define AUD_SUBN_CNT2 0x62044 #define AUD_GRP_CAP 0x62048 #define AUD_PWRST 0x6204c #define AUD_SUPPWR 0x62050 #define AUD_SID 0x62054 #define AUD_OUT_CWCAP 0x62070 #define AUD_OUT_PCMSIZE 0x62074 #define AUD_OUT_STR 0x62078 #define AUD_OUT_DIG_CNVT 0x6207c #define AUD_OUT_CH_STR 0x62080 #define AUD_OUT_STR_DESC 0x62084 #define AUD_PINW_CAP 0x620a0 #define AUD_PIN_CAP 0x620a4 #define AUD_PINW_CONNLNG 0x620a8 #define AUD_PINW_CONNLST 0x620ac #define AUD_PINW_CNTR 0x620b0 #define AUD_PINW_UNSOLRESP 0x620b8 #define AUD_CNTL_ST 0x620b4 #define AUD_PINW_CONFIG 0x620bc #define AUD_HDMIW_STATUS 0x620d4 #define AUD_HDMIW_HDMIEDID 0x6210c #define AUD_HDMIW_INFOFR 0x62118 #define AUD_CONV_CHCNT 0x62120 #define AUD_CTS_ENABLE 0x62128 #define VIDEO_DIP_CTL 0x61170 #endif /* _I810_REG_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_ring.h000066400000000000000000000066631267532330400246730ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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. **************************************************************************/ #ifndef _INTEL_RING_H #define _INTEL_RING_H #define OUT_RING(n) do { \ if (I810_DEBUG & DEBUG_VERBOSE_RING) \ ErrorF("OUT_RING %lx: %x, (mask %x)\n", \ (unsigned long)(outring), (unsigned int)(n), ringmask); \ *(volatile unsigned int *)(virt + outring) = n; \ outring += 4; ringused += 4; \ outring &= ringmask; \ } while (0) #define ADVANCE_LP_RING() do { \ if (ringused > needed) \ FatalError("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \ __FUNCTION__, ringused, needed); \ else if (ringused < needed) \ FatalError("%s: ADVANCE_LP_RING: under-used allocation %d/%d\n ", \ __FUNCTION__, ringused, needed); \ pI810->LpRing->tail = outring; \ pI810->LpRing->space -= ringused; \ if (outring & 0x07) \ FatalError("%s: ADVANCE_LP_RING: " \ "outring (0x%x) isn't on a QWord boundary\n", \ __FUNCTION__, outring); \ OUTREG(LP_RING + RING_TAIL, outring); \ } while (0) /* * XXX Note: the head/tail masks are different for 810 and i830. * If the i810 always sets the higher bits to 0, then this shouldn't be * a problem. Check this! */ #define DO_RING_IDLE() do { \ int _head; \ int _tail; \ do { \ _head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; \ _tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK; \ DELAY(10); \ } while (_head != _tail); \ } while( 0) #define BEGIN_LP_RING(n) \ unsigned int outring, ringmask, ringused = 0; \ volatile unsigned char *virt; \ unsigned needed; \ if ((n) & 1) \ ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \ if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ DO_RING_IDLE(); \ needed = (n) * 4; \ if (pI810->LpRing->space < needed) \ WaitRingFunc(pScrn, needed, 0); \ outring = pI810->LpRing->tail; \ ringmask = pI810->LpRing->tail_mask; \ virt = pI810->LpRing->virtual_start; \ if (I810_DEBUG & DEBUG_VERBOSE_RING) \ ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); #endif /* _INTEL_RING_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_video.c000066400000000000000000001073121267532330400250260ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i810_video.c: i810 Xv driver. Based on the mga Xv driver by Mark Vojkovich. * * Authors: * Jonathan Bian * Offscreen Images: * Matt Sottek */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "regionstr.h" #include "i810.h" #include "xf86xv.h" #include #include "dixstruct.h" #include "fourcc.h" #define OFF_DELAY 250 /* milliseconds */ #define FREE_DELAY 15000 #define OFF_TIMER 0x01 #define FREE_TIMER 0x02 #define CLIENT_VIDEO_ON 0x04 #define TIMER_MASK (OFF_TIMER | FREE_TIMER) static void I810InitOffscreenImages(ScreenPtr); static XF86VideoAdaptorPtr I810SetupImageVideo(ScreenPtr); static void I810StopVideo(ScrnInfoPtr, pointer, Bool); static int I810SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); static int I810GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); static void I810QueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer); static int I810PutImage( ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer, DrawablePtr); static int I810QueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); static void I810BlockHandler(BLOCKHANDLER_ARGS_DECL); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) static Atom xvBrightness, xvContrast, xvColorKey; #define IMAGE_MAX_WIDTH 1440 #define IMAGE_FAST_WIDTH 720 #define IMAGE_MAX_HEIGHT 1080 #define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) #define OVERLAY_UPDATE(p) OUTREG(0x30000, p | 0x80000000); /* * OV0CMD - Overlay Command Register */ #define VERTICAL_CHROMINANCE_FILTER 0x70000000 #define VC_SCALING_OFF 0x00000000 #define VC_LINE_REPLICATION 0x10000000 #define VC_UP_INTERPOLATION 0x20000000 #define VC_PIXEL_DROPPING 0x50000000 #define VC_DOWN_INTERPOLATION 0x60000000 #define VERTICAL_LUMINANCE_FILTER 0x0E000000 #define VL_SCALING_OFF 0x00000000 #define VL_LINE_REPLICATION 0x02000000 #define VL_UP_INTERPOLATION 0x04000000 #define VL_PIXEL_DROPPING 0x0A000000 #define VL_DOWN_INTERPOLATION 0x0C000000 #define HORIZONTAL_CHROMINANCE_FILTER 0x01C00000 #define HC_SCALING_OFF 0x00000000 #define HC_LINE_REPLICATION 0x00400000 #define HC_UP_INTERPOLATION 0x00800000 #define HC_PIXEL_DROPPING 0x01400000 #define HC_DOWN_INTERPOLATION 0x01800000 #define HORIZONTAL_LUMINANCE_FILTER 0x00380000 #define HL_SCALING_OFF 0x00000000 #define HL_LINE_REPLICATION 0x00080000 #define HL_UP_INTERPOLATION 0x00100000 #define HL_PIXEL_DROPPING 0x00280000 #define HL_DOWN_INTERPOLATION 0x00300000 #define Y_ADJUST 0x00010000 #define OV_BYTE_ORDER 0x0000C000 #define UV_SWAP 0x00004000 #define Y_SWAP 0x00008000 #define Y_AND_UV_SWAP 0x0000C000 #define SOURCE_FORMAT 0x00003C00 #define RGB_555 0x00000800 #define RGB_565 0x00000C00 #define YUV_422 0x00002000 #define YUV_411 0x00002400 #define YUV_420 0x00003000 #define YUV_410 0x00003800 #define BUFFER_AND_FIELD 0x00000006 #define BUFFER0_FIELD0 0x00000000 #define BUFFER1_FIELD0 0x00000004 #define OVERLAY_ENABLE 0x00000001 #define UV_VERT_BUF1 0x02 #define UV_VERT_BUF0 0x04 /* * DOV0STA - Display/Overlay 0 Status Register */ #define DOV0STA 0x30008 #define MINUV_SCALE 0x1 #define RGB16ToColorKey(c) \ (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) #define RGB15ToColorKey(c) \ (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) void I810InitVideo(ScreenPtr screen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); XF86VideoAdaptorPtr *adaptors = NULL; int num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); if (pScrn->bitsPerPixel != 8) { XF86VideoAdaptorPtr newAdaptor; newAdaptor = I810SetupImageVideo(screen); I810InitOffscreenImages(screen); if (newAdaptor) { XF86VideoAdaptorPtr *newAdaptors; newAdaptors = realloc(adaptors, (num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr)); if (newAdaptors != NULL) { newAdaptors[num_adaptors++] = newAdaptor; adaptors = newAdaptors; } } } if (num_adaptors) xf86XVScreenInit(screen, adaptors, num_adaptors); free(adaptors); } /* *INDENT-OFF* */ /* client libraries expect an encoding */ static XF86VideoEncodingRec DummyEncoding[1] = { { 0, "XV_IMAGE", IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, {1, 1} } }; #define NUM_FORMATS 3 static XF86VideoFormatRec Formats[NUM_FORMATS] = { {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; #define NUM_ATTRIBUTES 3 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} }; #define NUM_IMAGES 6 #define I810_RV15 0x35315652 #define I810_RV16 0x36315652 static XF86ImageRec Images[NUM_IMAGES] = { { I810_RV15, XvRGB, LSBFirst, {'R','V','1','5', 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 16, XvPacked, 1, 15, 0x7C00, 0x03E0, 0x001F, 0, 0, 0, 0, 0, 0, 0, 0, 0, {'R','V','B',0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, XvTopToBottom }, { I810_RV16, XvRGB, LSBFirst, {'R','V','1','6', 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 16, XvPacked, 1, 16, 0xF800, 0x07E0, 0x001F, 0, 0, 0, 0, 0, 0, 0, 0, 0, {'R','V','B',0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, XvTopToBottom }, XVIMAGE_YUY2, XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY }; /* *INDENT-ON* */ typedef struct { uint32_t OBUF_0Y; uint32_t OBUF_1Y; uint32_t OBUF_0U; uint32_t OBUF_0V; uint32_t OBUF_1U; uint32_t OBUF_1V; uint32_t OV0STRIDE; uint32_t YRGB_VPH; uint32_t UV_VPH; uint32_t HORZ_PH; uint32_t INIT_PH; uint32_t DWINPOS; uint32_t DWINSZ; uint32_t SWID; uint32_t SWIDQW; uint32_t SHEIGHT; uint32_t YRGBSCALE; uint32_t UVSCALE; uint32_t OV0CLRC0; uint32_t OV0CLRC1; uint32_t DCLRKV; uint32_t DCLRKM; uint32_t SCLRKVH; uint32_t SCLRKVL; uint32_t SCLRKM; uint32_t OV0CONF; uint32_t OV0CMD; } I810OverlayRegRec, *I810OverlayRegPtr; typedef struct { uint32_t YBuf0offset; uint32_t UBuf0offset; uint32_t VBuf0offset; uint32_t YBuf1offset; uint32_t UBuf1offset; uint32_t VBuf1offset; unsigned char currentBuf; int brightness; int contrast; RegionRec clip; uint32_t colorKey; uint32_t videoStatus; Time offTime; Time freeTime; FBLinearPtr linear; } I810PortPrivRec, *I810PortPrivPtr; #define GET_PORT_PRIVATE(pScrn) \ (I810PortPrivPtr)((I810PTR(pScrn))->adaptor->pPortPrivates[0].ptr) static void I810ResetVideo(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); /* * Default to maximum image size in YV12 */ overlay->YRGB_VPH = 0; overlay->UV_VPH = 0; overlay->HORZ_PH = 0; overlay->INIT_PH = 0; overlay->DWINPOS = 0; overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH; overlay->SWID = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 15); overlay->SWIDQW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12); overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15); overlay->YRGBSCALE = 0x80004000; /* scale factor 1 */ overlay->UVSCALE = 0x80004000; /* scale factor 1 */ overlay->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ overlay->OV0CLRC1 = 0x80; /* saturation: bypass */ /* * Enable destination color keying */ switch(pScrn->depth) { case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); overlay->DCLRKM = 0x80070307; break; case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); overlay->DCLRKM = 0x80070707; break; default: overlay->DCLRKV = pPriv->colorKey; overlay->DCLRKM = 0x80000000; break; } overlay->SCLRKVH = 0; overlay->SCLRKVL = 0; overlay->SCLRKM = 0; /* source color key disable */ overlay->OV0CONF = 0; /* two 720 pixel line buffers */ overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | YUV_420; OVERLAY_UPDATE(pI810->OverlayPhysical); } static XF86VideoAdaptorPtr I810SetupImageVideo(ScreenPtr screen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); I810Ptr pI810 = I810PTR(pScrn); XF86VideoAdaptorPtr adapt; I810PortPrivPtr pPriv; if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + sizeof(I810PortPrivRec) + sizeof(DevUnion)))) return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; adapt->name = "I810 Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = DummyEncoding; adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; adapt->pPortPrivates = (DevUnion*)(&adapt[1]); pPriv = (I810PortPrivPtr)(&adapt->pPortPrivates[1]); adapt->pPortPrivates[0].ptr = (pointer)(pPriv); adapt->pAttributes = Attributes; adapt->nImages = NUM_IMAGES; adapt->nAttributes = NUM_ATTRIBUTES; adapt->pImages = Images; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; adapt->GetStill = NULL; adapt->StopVideo = I810StopVideo; adapt->SetPortAttribute = I810SetPortAttribute; adapt->GetPortAttribute = I810GetPortAttribute; adapt->QueryBestSize = I810QueryBestSize; adapt->PutImage = I810PutImage; adapt->QueryImageAttributes = I810QueryImageAttributes; pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1); pPriv->videoStatus = 0; pPriv->brightness = 0; pPriv->contrast = 64; pPriv->linear = NULL; pPriv->currentBuf = 0; /* gotta uninit this someplace */ REGION_NULL(screen, &pPriv->clip); pI810->adaptor = adapt; pI810->BlockHandler = screen->BlockHandler; screen->BlockHandler = I810BlockHandler; xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvContrast = MAKE_ATOM("XV_CONTRAST"); xvColorKey = MAKE_ATOM("XV_COLORKEY"); I810ResetVideo(pScrn); return adapt; } /* I810ClipVideo - Takes the dst box in standard X BoxRec form (top and left edges inclusive, bottom and right exclusive). The new dst box is returned. The source boundaries are given (x1, y1 inclusive, x2, y2 exclusive) and returned are the new source boundaries in 16.16 fixed point. */ static void I810ClipVideo( BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2, BoxPtr extents, /* extents of the clip region */ INT32 width, INT32 height ){ INT32 vscale, hscale, delta; int diff; hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); *x1 <<= 16; *x2 <<= 16; *y1 <<= 16; *y2 <<= 16; diff = extents->x1 - dst->x1; if(diff > 0) { dst->x1 = extents->x1; *x1 += diff * hscale; } diff = dst->x2 - extents->x2; if(diff > 0) { dst->x2 = extents->x2; *x2 -= diff * hscale; } diff = extents->y1 - dst->y1; if(diff > 0) { dst->y1 = extents->y1; *y1 += diff * vscale; } diff = dst->y2 - extents->y2; if(diff > 0) { dst->y2 = extents->y2; *y2 -= diff * vscale; } if(*x1 < 0) { diff = (- *x1 + hscale - 1)/ hscale; dst->x1 += diff; *x1 += diff * hscale; } delta = *x2 - (width << 16); if(delta > 0) { diff = (delta + hscale - 1)/ hscale; dst->x2 -= diff; *x2 -= diff * hscale; } if(*y1 < 0) { diff = (- *y1 + vscale - 1)/ vscale; dst->y1 += diff; *y1 += diff * vscale; } delta = *y2 - (height << 16); if(delta > 0) { diff = (delta + vscale - 1)/ vscale; dst->y2 -= diff; *y2 -= diff * vscale; } } static void I810StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) { I810PortPrivPtr pPriv = (I810PortPrivPtr)data; I810Ptr pI810 = I810PTR(pScrn); I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); REGION_EMPTY(pScrn->screen, &pPriv->clip); if(shutdown) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { overlay->OV0CMD &= 0xFFFFFFFE; OVERLAY_UPDATE(pI810->OverlayPhysical); } if(pPriv->linear) { xf86FreeOffscreenLinear(pPriv->linear); pPriv->linear = NULL; } pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { pPriv->videoStatus |= OFF_TIMER; pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } } } static int I810SetPortAttribute( ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data ){ I810PortPrivPtr pPriv = (I810PortPrivPtr)data; I810Ptr pI810 = I810PTR(pScrn); I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); if(attribute == xvBrightness) { if((value < -128) || (value > 127)) return BadValue; pPriv->brightness = value; overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); OVERLAY_UPDATE(pI810->OverlayPhysical); } else if(attribute == xvContrast) { if((value < 0) || (value > 255)) return BadValue; pPriv->contrast = value; overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); OVERLAY_UPDATE(pI810->OverlayPhysical); } else if(attribute == xvColorKey) { pPriv->colorKey = value; switch(pScrn->depth) { case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); break; case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); break; default: overlay->DCLRKV = pPriv->colorKey; break; } OVERLAY_UPDATE(pI810->OverlayPhysical); REGION_EMPTY(pScrn->screen, &pPriv->clip); } else return BadMatch; return Success; } static int I810GetPortAttribute( ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data ){ I810PortPrivPtr pPriv = (I810PortPrivPtr)data; if(attribute == xvBrightness) { *value = pPriv->brightness; } else if(attribute == xvContrast) { *value = pPriv->contrast; } else if(attribute == xvColorKey) { *value = pPriv->colorKey; } else return BadMatch; return Success; } static void I810QueryBestSize( ScrnInfoPtr pScrn, Bool motion, short vid_w, short vid_h, short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h, pointer data ){ if(vid_w > (drw_w << 1)) drw_w = vid_w >> 1; if(vid_h > (drw_h << 1)) drw_h = vid_h >> 1; *p_w = drw_w; *p_h = drw_h; } static void I810CopyPackedData( ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, int dstPitch, int top, int left, int h, int w ) { I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; unsigned char *src, *dst; src = buf + (top*srcPitch) + (left<<1); if (pPriv->currentBuf == 0) dst = pI810->FbBase + pPriv->YBuf0offset; else dst = pI810->FbBase + pPriv->YBuf1offset; w <<= 1; while(h--) { memcpy(dst, src, w); src += srcPitch; dst += dstPitch; } } static void I810CopyPlanarData( ScrnInfoPtr pScrn, unsigned char *buf, int srcPitch, int dstPitch, /* of chroma */ int srcH, int top, int left, int h, int w, int id ) { I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; int i; unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3; /* Copy Y data */ src1 = buf + (top*srcPitch) + left; if (pPriv->currentBuf == 0) dst1 = pI810->FbBase + pPriv->YBuf0offset; else dst1 = pI810->FbBase + pPriv->YBuf1offset; for (i = 0; i < h; i++) { memcpy(dst1, src1, w); src1 += srcPitch; dst1 += dstPitch << 1; } /* Copy V data for YV12, or U data for I420 */ src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) dst2 = pI810->FbBase + pPriv->UBuf0offset; else dst2 = pI810->FbBase + pPriv->VBuf0offset; } else { if (id == FOURCC_I420) dst2 = pI810->FbBase + pPriv->UBuf1offset; else dst2 = pI810->FbBase + pPriv->VBuf1offset; } for (i = 0; i < h/2; i++) { memcpy(dst2, src2, w/2); src2 += srcPitch>>1; dst2 += dstPitch; } /* Copy U data for YV12, or V data for I420 */ src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1); if (pPriv->currentBuf == 0) { if (id == FOURCC_I420) dst3 = pI810->FbBase + pPriv->VBuf0offset; else dst3 = pI810->FbBase + pPriv->UBuf0offset; } else { if (id == FOURCC_I420) dst3 = pI810->FbBase + pPriv->VBuf1offset; else dst3 = pI810->FbBase + pPriv->UBuf1offset; } for (i = 0; i < h/2; i++) { memcpy(dst3, src3, w/2); src3 += srcPitch>>1; dst3 += dstPitch; } } static void I810DisplayVideo( ScrnInfoPtr pScrn, int id, short width, short height, int dstPitch, /* of chroma for 4:2:0 */ int x1, int y1, int x2, int y2, BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h ){ I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); int xscaleInt, xscaleFract, yscaleInt, yscaleFract; int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0; unsigned int swidth; switch(id) { case FOURCC_YV12: case FOURCC_I420: swidth = ALIGN(width, 8); overlay->SWID = (swidth << 15) | swidth; overlay->SWIDQW = (swidth << 12) | (swidth >> 3); break; case FOURCC_UYVY: case FOURCC_YUY2: default: swidth = ALIGN(width, 4) << 1; overlay->SWID = swidth; overlay->SWIDQW = swidth >> 3; break; } /* wide video formats (>720 pixels) are special */ if( swidth > IMAGE_FAST_WIDTH ) { overlay->OV0CONF = 1; /* one 1440 pixel line buffer */ } else { overlay->OV0CONF = 0; /* two 720 pixel line buffers */ } overlay->SHEIGHT = height | (height << 15); overlay->DWINPOS = (dstBox->y1 << 16) | (dstBox->x1); overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | (dstBox->x2 - dstBox->x1); /* buffer locations */ overlay->OBUF_0Y = pPriv->YBuf0offset; overlay->OBUF_1Y = pPriv->YBuf1offset; overlay->OBUF_0U = pPriv->UBuf0offset; overlay->OBUF_0V = pPriv->VBuf0offset; overlay->OBUF_1U = pPriv->UBuf1offset; overlay->OBUF_1V = pPriv->VBuf1offset; /* * Calculate horizontal and vertical scaling factors, default to 1:1 */ overlay->YRGBSCALE = 0x80004000; overlay->UVSCALE = 0x80004000; /* * Initially, YCbCr and Overlay Enable and * vertical chrominance up interpolation and horozontal chrominance * up interpolation */ overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | OVERLAY_ENABLE; if ((drw_w != src_w) || (drw_h != src_h)) { xscaleInt = (src_w / drw_w) & 0x3; xscaleFract = (src_w << 12) / drw_w; yscaleInt = (src_h / drw_h) & 0x3; yscaleFract = (src_h << 12) / drw_h; overlay->YRGBSCALE = (xscaleInt << 15) | ((xscaleFract & 0xFFF) << 3) | (yscaleInt) | ((yscaleFract & 0xFFF) << 20); if (drw_w > src_w) { /* horizontal up-scaling */ overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); } if (drw_h > src_h) { /* vertical up-scaling */ overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); } if (drw_w < src_w) { /* horizontal down-scaling */ overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); } if (drw_h < src_h) { /* vertical down-scaling */ overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); } /* now calculate the UV scaling factor */ if (xscaleFract) { xscaleFractUV = xscaleFract >> MINUV_SCALE; overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION; overlay->OV0CMD |= HC_UP_INTERPOLATION; } if (xscaleInt) { xscaleIntUV = xscaleInt >> MINUV_SCALE; if (xscaleIntUV) { overlay->OV0CMD &= ~HC_UP_INTERPOLATION; } } if (yscaleFract) { yscaleFractUV = yscaleFract >> MINUV_SCALE; overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION; overlay->OV0CMD |= VC_UP_INTERPOLATION; } if (yscaleInt) { yscaleIntUV = yscaleInt >> MINUV_SCALE; if (yscaleIntUV) { overlay->OV0CMD &= ~VC_UP_INTERPOLATION; overlay->OV0CMD |= VC_DOWN_INTERPOLATION; } } overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | ((yscaleFractUV & 0xFFF) << 20); } switch(id) { case FOURCC_YV12: case FOURCC_I420: /* set UV vertical phase to -0.25 */ overlay->UV_VPH = 0x30003000; overlay->INIT_PH = UV_VERT_BUF0 | UV_VERT_BUF1; overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16); overlay->OV0CMD &= ~SOURCE_FORMAT; overlay->OV0CMD |= YUV_420; break; case I810_RV15: case I810_RV16: overlay->UV_VPH = 0; overlay->INIT_PH = 0; overlay->OV0STRIDE = dstPitch; overlay->OV0CMD &= ~SOURCE_FORMAT; overlay->OV0CMD |= (id==I810_RV15 ? RGB_555 : RGB_565); overlay->OV0CMD &= ~OV_BYTE_ORDER; break; case FOURCC_UYVY: case FOURCC_YUY2: default: overlay->UV_VPH = 0; overlay->INIT_PH = 0; overlay->OV0STRIDE = dstPitch; overlay->OV0CMD &= ~SOURCE_FORMAT; overlay->OV0CMD |= YUV_422; overlay->OV0CMD &= ~OV_BYTE_ORDER; if (id == FOURCC_UYVY) overlay->OV0CMD |= Y_SWAP; break; } overlay->OV0CMD &= ~BUFFER_AND_FIELD; if (pPriv->currentBuf == 0) overlay->OV0CMD |= BUFFER0_FIELD0; else overlay->OV0CMD |= BUFFER1_FIELD0; OVERLAY_UPDATE(pI810->OverlayPhysical); } static FBLinearPtr I810AllocateMemory( ScrnInfoPtr pScrn, FBLinearPtr linear, int size ){ ScreenPtr screen; FBLinearPtr new_linear; if(linear) { if(linear->size >= size) return linear; if(xf86ResizeOffscreenLinear(linear, size)) return linear; xf86FreeOffscreenLinear(linear); } screen = xf86ScrnToScreen(pScrn); new_linear = xf86AllocateOffscreenLinear(screen, size, 4, NULL, NULL, NULL); if(!new_linear) { int max_size; xf86QueryLargestOffscreenLinear(screen, &max_size, 4, PRIORITY_EXTREME); if(max_size < size) return NULL; xf86PurgeUnlockedOffscreenAreas(screen); new_linear = xf86AllocateOffscreenLinear(screen, size, 4, NULL, NULL, NULL); } return new_linear; } static int I810PutImage( ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char* buf, short width, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr pDraw ){ I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = (I810PortPrivPtr)data; INT32 x1, x2, y1, y2; int srcPitch, dstPitch; int top, left, npixels, nlines, size, loops; BoxRec dstBox; /* Clip */ x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dstBox.x1 = drw_x; dstBox.x2 = drw_x + drw_w; dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h; I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, REGION_EXTENTS(pScrn->screen, clipBoxes), width, height); if((x1 >= x2) || (y1 >= y2)) return Success; /* * Fix for 4 pixel granularity of AdjustFrame * unless boarder is clipped by frame */ dstBox.x1 -= (pScrn->frameX0 & ((dstBox.x1 == pScrn->frameX0) ? ~0x0UL : ~0x3UL)); dstBox.x2 -= (pScrn->frameX0 & ~0x3); dstBox.y1 -= pScrn->frameY0; dstBox.y2 -= pScrn->frameY0; switch(id) { case FOURCC_YV12: case FOURCC_I420: srcPitch = ALIGN(width, 4); dstPitch = ALIGN((width >> 1), 8); /* of chroma */ size = dstPitch * height * 3; break; case FOURCC_UYVY: case FOURCC_YUY2: default: srcPitch = (width << 1); dstPitch = ALIGN(srcPitch, 8); size = dstPitch * height; break; } if(!(pPriv->linear = I810AllocateMemory(pScrn, pPriv->linear, (pScrn->bitsPerPixel == 16) ? size : (size >> 1)))) return BadAlloc; /* fixup pointers */ pPriv->YBuf0offset = pPriv->linear->offset * pI810->cpp; pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height >> 1); pPriv->YBuf1offset = (pPriv->linear->offset * pI810->cpp) + size; pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height >> 1); /* Make sure this buffer isn't in use */ loops = 0; while (loops < 1000000) { if(((INREG(DOV0STA)&0x00100000)>>20) == pPriv->currentBuf) { break; } loops++; } if(loops >= 1000000) { pPriv->currentBuf = !pPriv->currentBuf; } /* buffer swap */ if (pPriv->currentBuf == 0) pPriv->currentBuf = 1; else pPriv->currentBuf = 0; /* copy data */ top = y1 >> 16; left = (x1 >> 16) & ~1; npixels = ALIGN(((x2 + 0xffff) >> 16), 2) - left; switch(id) { case FOURCC_YV12: case FOURCC_I420: top &= ~1; nlines = ALIGN(((y2 + 0xffff) >> 16), 2) - top; I810CopyPlanarData(pScrn, buf, srcPitch, dstPitch, height, top, left, nlines, npixels, id); break; case FOURCC_UYVY: case FOURCC_YUY2: default: nlines = ((y2 + 0xffff) >> 16) - top; I810CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines, npixels); break; } /* update cliplist */ if(!REGION_EQUAL(pScrn->screen, &pPriv->clip, clipBoxes)) { REGION_COPY(pScrn->screen, &pPriv->clip, clipBoxes); /* draw these */ xf86XVFillKeyHelperDrawable(pDraw, pPriv->colorKey, clipBoxes); } I810DisplayVideo(pScrn, id, width, height, dstPitch, x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); pPriv->videoStatus = CLIENT_VIDEO_ON; return Success; } static int I810QueryImageAttributes( ScrnInfoPtr pScrn, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets ){ int size, tmp; if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; *w = (*w + 1) & ~1; if(offsets) offsets[0] = 0; switch(id) { /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: if(pitches) pitches[0] = *w; size = *w * *h; break; case FOURCC_YV12: case FOURCC_I420: *h = (*h + 1) & ~1; size = (*w + 3) & ~3; if(pitches) pitches[0] = size; size *= *h; if(offsets) offsets[1] = size; tmp = ((*w >> 1) + 3) & ~3; if(pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if(offsets) offsets[2] = size; size += tmp; break; case FOURCC_UYVY: case FOURCC_YUY2: default: size = *w << 1; if(pitches) pitches[0] = size; size *= *h; break; } return size; } static void I810BlockHandler (BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); screen->BlockHandler = pI810->BlockHandler; (*screen->BlockHandler) (BLOCKHANDLER_ARGS); screen->BlockHandler = I810BlockHandler; if(pPriv->videoStatus & TIMER_MASK) { UpdateCurrentTime(); if(pPriv->videoStatus & OFF_TIMER) { if(pPriv->offTime < currentTime.milliseconds) { /* Turn off the overlay */ overlay->OV0CMD &= 0xFFFFFFFE; OVERLAY_UPDATE(pI810->OverlayPhysical); pPriv->videoStatus = FREE_TIMER; pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; } } else { /* FREE_TIMER */ if(pPriv->freeTime < currentTime.milliseconds) { if(pPriv->linear) { xf86FreeOffscreenLinear(pPriv->linear); pPriv->linear = NULL; } pPriv->videoStatus = 0; } } } } /*************************************************************************** * Offscreen Images ***************************************************************************/ typedef struct { FBLinearPtr linear; Bool isOn; } OffscreenPrivRec, * OffscreenPrivPtr; static int I810AllocateSurface( ScrnInfoPtr pScrn, int id, unsigned short w, unsigned short h, XF86SurfacePtr surface ){ FBLinearPtr linear; int pitch, size, bpp; OffscreenPrivPtr pPriv; I810Ptr pI810 = I810PTR(pScrn); if((w > 1024) || (h > 1024)) return BadAlloc; w = ALIGN(w, 2); pitch = ALIGN((w << 1), 16); bpp = pScrn->bitsPerPixel >> 3; size = ((pitch * h) + bpp - 1) / bpp; if(!(linear = I810AllocateMemory(pScrn, NULL, size))) return BadAlloc; surface->width = w; surface->height = h; if(!(surface->pitches = malloc(sizeof(int)))) { xf86FreeOffscreenLinear(linear); return BadAlloc; } if(!(surface->offsets = malloc(sizeof(int)))) { free(surface->pitches); xf86FreeOffscreenLinear(linear); return BadAlloc; } if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { free(surface->pitches); free(surface->offsets); xf86FreeOffscreenLinear(linear); return BadAlloc; } pPriv->linear = linear; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; surface->offsets[0] = linear->offset * bpp; surface->devPrivate.ptr = (pointer)pPriv; memset(pI810->FbBase + surface->offsets[0],0,size); return Success; } static int I810StopSurface( XF86SurfacePtr surface ){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) { I810Ptr pI810 = I810PTR(surface->pScrn); I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); overlay->OV0CMD &= 0xFFFFFFFE; OVERLAY_UPDATE(pI810->OverlayPhysical); pPriv->isOn = FALSE; } return Success; } static int I810FreeSurface( XF86SurfacePtr surface ){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) { I810StopSurface(surface); } xf86FreeOffscreenLinear(pPriv->linear); free(surface->pitches); free(surface->offsets); free(surface->devPrivate.ptr); return Success; } static int I810GetSurfaceAttribute( ScrnInfoPtr pScrn, Atom attribute, INT32 *value ){ return I810GetPortAttribute(pScrn, attribute, value, GET_PORT_PRIVATE(pScrn)); } static int I810SetSurfaceAttribute( ScrnInfoPtr pScrn, Atom attribute, INT32 value ){ return I810SetPortAttribute(pScrn, attribute, value, GET_PORT_PRIVATE(pScrn)); } static int I810DisplaySurface( XF86SurfacePtr surface, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, RegionPtr clipBoxes ){ OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; ScrnInfoPtr pScrn = surface->pScrn; I810Ptr pI810 = I810PTR(pScrn); I810PortPrivPtr pI810Priv = GET_PORT_PRIVATE(pScrn); INT32 x1, y1, x2, y2; INT32 loops = 0; BoxRec dstBox; x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dstBox.x1 = drw_x; dstBox.x2 = drw_x + drw_w; dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h; I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, REGION_EXTENTS(screenInfo.screens[0], clipBoxes), surface->width, surface->height); /* * Fix for 4 pixel granularity of AdjustFrame * unless boarder is clipped by frame */ dstBox.x1 -= (pScrn->frameX0 & ((dstBox.x1 == pScrn->frameX0) ? ~0x0UL : ~0x3UL)); dstBox.x2 -= (pScrn->frameX0 & ~0x3); dstBox.y1 -= pScrn->frameY0; dstBox.y2 -= pScrn->frameY0; /* fixup pointers */ pI810Priv->YBuf0offset = surface->offsets[0]; pI810Priv->YBuf1offset = pI810Priv->YBuf0offset; /* wait for the last rendered buffer to be flipped in */ while (((INREG(DOV0STA)&0x00100000)>>20) != pI810Priv->currentBuf) { if(loops == 200000) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); break; } loops++; } /* buffer swap */ if (pI810Priv->currentBuf == 0) pI810Priv->currentBuf = 1; else pI810Priv->currentBuf = 0; I810ResetVideo(pScrn); I810DisplayVideo(pScrn, surface->id, surface->width, surface->height, surface->pitches[0], x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); xf86XVFillKeyHelper(pScrn->pScreen, pI810Priv->colorKey, clipBoxes); pPriv->isOn = TRUE; /* we've prempted the XvImage stream so set its free timer */ if(pI810Priv->videoStatus & CLIENT_VIDEO_ON) { REGION_EMPTY(pScrn->screen, & pI810Priv->clip); UpdateCurrentTime(); pI810Priv->videoStatus = FREE_TIMER; pI810Priv->freeTime = currentTime.milliseconds + FREE_DELAY; pScrn->pScreen->BlockHandler = I810BlockHandler; } return Success; } static void I810InitOffscreenImages(ScreenPtr screen) { XF86OffscreenImagePtr offscreenImages; /* need to free this someplace */ if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) { return; } offscreenImages[0].image = &Images[0]; offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; offscreenImages[0].alloc_surface = I810AllocateSurface; offscreenImages[0].free_surface = I810FreeSurface; offscreenImages[0].display = I810DisplaySurface; offscreenImages[0].stop = I810StopSurface; offscreenImages[0].setAttribute = I810SetSurfaceAttribute; offscreenImages[0].getAttribute = I810GetSurfaceAttribute; offscreenImages[0].max_width = 1024; offscreenImages[0].max_height = 1024; offscreenImages[0].num_attributes = 1; offscreenImages[0].attributes = Attributes; if (!xf86XVRegisterOffscreenImages(screen, offscreenImages, 1)) free(offscreenImages); } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_wmark.c000066400000000000000000000166561267532330400250530ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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: * Keith Whitwell */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "i810.h" struct wm_info { double freq; unsigned int wm; }; static struct wm_info i810_wm_8_100[] = { {0, 0x22003000}, {25.2, 0x22003000}, {28.0, 0x22003000}, {31.5, 0x22003000}, {36.0, 0x22007000}, {40.0, 0x22007000}, {45.0, 0x22007000}, {49.5, 0x22008000}, {50.0, 0x22008000}, {56.3, 0x22008000}, {65.0, 0x22008000}, {75.0, 0x22008000}, {78.8, 0x22008000}, {80.0, 0x22008000}, {94.0, 0x22008000}, {96.0, 0x22107000}, {99.0, 0x22107000}, {108.0, 0x22107000}, {121.0, 0x22107000}, {128.9, 0x22107000}, {132.0, 0x22109000}, {135.0, 0x22109000}, {157.5, 0x2210b000}, {162.0, 0x2210b000}, {175.5, 0x2210b000}, {189.0, 0x2220e000}, {202.5, 0x2220e000} }; static struct wm_info i810_wm_16_100[] = { {0, 0x22004000}, {25.2, 0x22006000}, {28.0, 0x22006000}, {31.5, 0x22007000}, {36.0, 0x22007000}, {40.0, 0x22007000}, {45.0, 0x22007000}, {49.5, 0x22009000}, {50.0, 0x22009000}, {56.3, 0x22108000}, {65.0, 0x2210e000}, {75.0, 0x2210e000}, {78.8, 0x2210e000}, {80.0, 0x22210000}, {94.5, 0x22210000}, {96.0, 0x22210000}, {99.0, 0x22210000}, {108.0, 0x22210000}, {121.0, 0x22210000}, {128.9, 0x22210000}, {132.0, 0x22314000}, {135.0, 0x22314000}, {157.5, 0x22415000}, {162.0, 0x22416000}, {175.5, 0x22416000}, {189.0, 0x22416000}, {195.0, 0x22416000}, {202.5, 0x22416000} }; static struct wm_info i810_wm_24_100[] = { {0, 0x22006000}, {25.2, 0x22009000}, {28.0, 0x22009000}, {31.5, 0x2200a000}, {36.0, 0x2210c000}, {40.0, 0x2210c000}, {45.0, 0x2210c000}, {49.5, 0x22111000}, {50.0, 0x22111000}, {56.3, 0x22111000}, {65.0, 0x22214000}, {75.0, 0x22214000}, {78.8, 0x22215000}, {80.0, 0x22216000}, {94.5, 0x22218000}, {96.0, 0x22418000}, {99.0, 0x22418000}, {108.0, 0x22418000}, {121.0, 0x22418000}, {128.9, 0x22419000}, {132.0, 0x22519000}, {135.0, 0x4441d000}, {157.5, 0x44419000}, {162.0, 0x44419000}, {175.5, 0x44419000}, {189.0, 0x44419000}, {195.0, 0x44419000}, {202.5, 0x44419000} }; #if 0 /* not used */ static struct wm_info i810_wm_32_100[] = { {0, 0x2210b000}, {60, 0x22415000}, /* 0x314000 works too */ {80, 0x22419000} /* 0x518000 works too */ }; #endif static struct wm_info i810_wm_8_133[] = { {0, 0x22003000}, {25.2, 0x22003000}, {28.0, 0x22003000}, {31.5, 0x22003000}, {36.0, 0x22007000}, {40.0, 0x22007000}, {45.0, 0x22007000}, {49.5, 0x22008000}, {50.0, 0x22008000}, {56.3, 0x22008000}, {65.0, 0x22008000}, {75.0, 0x22008000}, {78.8, 0x22008000}, {80.0, 0x22008000}, {94.0, 0x22008000}, {96.0, 0x22107000}, {99.0, 0x22107000}, {108.0, 0x22107000}, {121.0, 0x22107000}, {128.9, 0x22107000}, {132.0, 0x22109000}, {135.0, 0x22109000}, {157.5, 0x2210b000}, {162.0, 0x2210b000}, {175.5, 0x2210b000}, {189.0, 0x2220e000}, {202.5, 0x2220e000} }; static struct wm_info i810_wm_16_133[] = { {0, 0x22004000}, {25.2, 0x22006000}, {28.0, 0x22006000}, {31.5, 0x22007000}, {36.0, 0x22007000}, {40.0, 0x22007000}, {45.0, 0x22007000}, {49.5, 0x22009000}, {50.0, 0x22009000}, {56.3, 0x22108000}, {65.0, 0x2210e000}, {75.0, 0x2210e000}, {78.8, 0x2210e000}, {80.0, 0x22210000}, {94.5, 0x22210000}, {96.0, 0x22210000}, {99.0, 0x22210000}, {108.0, 0x22210000}, {121.0, 0x22210000}, {128.9, 0x22210000}, {132.0, 0x22314000}, {135.0, 0x22314000}, {157.5, 0x22415000}, {162.0, 0x22416000}, {175.5, 0x22416000}, {189.0, 0x22416000}, {195.0, 0x22416000}, {202.5, 0x22416000} }; static struct wm_info i810_wm_24_133[] = { {0, 0x22006000}, {25.2, 0x22009000}, {28.0, 0x22009000}, {31.5, 0x2200a000}, {36.0, 0x2210c000}, {40.0, 0x2210c000}, {45.0, 0x2210c000}, {49.5, 0x22111000}, {50.0, 0x22111000}, {56.3, 0x22111000}, {65.0, 0x22214000}, {75.0, 0x22214000}, {78.8, 0x22215000}, {80.0, 0x22216000}, {94.5, 0x22218000}, {96.0, 0x22418000}, {99.0, 0x22418000}, {108.0, 0x22418000}, {121.0, 0x22418000}, {128.9, 0x22419000}, {132.0, 0x22519000}, {135.0, 0x4441d000}, {157.5, 0x44419000}, {162.0, 0x44419000}, {175.5, 0x44419000}, {189.0, 0x44419000}, {195.0, 0x44419000}, {202.5, 0x44419000} }; #define Elements(x) (sizeof(x)/sizeof(*x)) /* * I810CalcFIFO -- * * Calculate burst length and FIFO watermark. */ unsigned int I810CalcWatermark(ScrnInfoPtr pScrn, double freq, Bool dcache) { I810Ptr pI810 = I810PTR(pScrn); struct wm_info *tab; int nr; int i; if (pI810->LmFreqSel == 100) { switch (pScrn->bitsPerPixel) { case 8: tab = i810_wm_8_100; nr = Elements(i810_wm_8_100); break; case 16: tab = i810_wm_16_100; nr = Elements(i810_wm_16_100); break; case 24: tab = i810_wm_24_100; nr = Elements(i810_wm_24_100); break; default: return 0; } } else { switch (pScrn->bitsPerPixel) { case 8: tab = i810_wm_8_133; nr = Elements(i810_wm_8_133); break; case 16: tab = i810_wm_16_133; nr = Elements(i810_wm_16_133); break; case 24: tab = i810_wm_24_133; nr = Elements(i810_wm_24_133); break; default: return 0; } } for (i = 0; i < nr && tab[i].freq < freq; i++) ; if (i == nr) i--; xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "chose watermark 0x%x: (tab.freq %.1f)\n", tab[i].wm, tab[i].freq); /* None of these values (sourced from intel) have watermarks for * the dcache memory. Fake it for now by using the same watermark * for both... * * Update: this is probably because dcache isn't real useful as * framebuffer memory, so intel's drivers don't need watermarks * for that memory because they never use it to feed the ramdacs. * We do use it in the fallback mode, so keep the watermarks for * now. */ if (dcache) return (tab[i].wm & ~0xffffff) | ((tab[i].wm >> 12) & 0xfff); else return tab[i].wm; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/i810_xaa.c000066400000000000000000000223761267532330400244770ustar00rootroot00000000000000 /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * Authors: * Keith Whitwell * */ #include "xorg-server.h" #include "xf86.h" #include "xaarop.h" #include "i810.h" static void I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty, int fg, int bg, int rop, unsigned int planemask) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SetupFor8x8PatternColorExpand\n"); /* FULL_MONO_PAT_BLT, p176 */ pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9); pI810->BR[18] = bg; pI810->BR[19] = fg; pI810->BR[13] = (pScrn->displayWidth * pI810->cpp); pI810->BR[13] |= I810PatternROP[rop] << 16; if (bg == -1) pI810->BR[13] |= BR13_MONO_PATN_TRANS; } static void I810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty, int x, int y, int w, int h) { I810Ptr pI810 = I810PTR(pScrn); int addr = pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp; if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810Subsequent8x8PatternColorExpand\n"); { BEGIN_LP_RING(12); OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN)); OUT_RING(pI810->BR[13]); OUT_RING((h << 16) | (w * pI810->cpp)); OUT_RING(addr); OUT_RING(pI810->BR[13] & 0xFFFF); /* src pitch */ OUT_RING(addr); /* src addr */ OUT_RING(0); /* transparency color */ OUT_RING(pI810->BR[18]); /* bg */ OUT_RING(pI810->BR[19]); /* fg */ OUT_RING(pattx); /* pattern data */ OUT_RING(patty); OUT_RING(0); ADVANCE_LP_RING(); } } static void I810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); XAAInfoRecPtr infoPtr = pI810->AccelInfoRec; if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers) I810Sync(pScrn); infoPtr->ScanlineColorExpandBuffers[0] = pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf]; if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf); pI810->nextColorExpandBuf++; } static void I810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n", fg, bg, rop, planemask); pI810->BR[13] = (pScrn->displayWidth * pI810->cpp); pI810->BR[13] |= I810CopyROP[rop] << 16; pI810->BR[13] |= (1 << 27); if (bg == -1) pI810->BR[13] |= BR13_MONO_TRANSPCY; pI810->BR[18] = bg; pI810->BR[19] = fg; I810GetNextScanlineColorExpandBuffer(pScrn); } static void I810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill " "%d,%d %dx%x %d\n", x, y, w, h, skipleft); pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06; pI810->BR[9] = (pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp); pI810->BR[14] = ((1 << 16) | (w * pI810->cpp)); pI810->BR[11] = ((w + 31) / 32) - 1; } static void I810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { I810Ptr pI810 = I810PTR(pScrn); pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] - pI810->FbBase); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n", bufno, pI810->BR[12]); { BEGIN_LP_RING(8); OUT_RING(pI810->BR[0]); OUT_RING(pI810->BR[13]); OUT_RING(pI810->BR[14]); OUT_RING(pI810->BR[9]); OUT_RING(pI810->BR[11]); OUT_RING(pI810->BR[12]); /* srcaddr */ OUT_RING(pI810->BR[18]); OUT_RING(pI810->BR[19]); ADVANCE_LP_RING(); } /* Advance to next scanline. */ pI810->BR[9] += pScrn->displayWidth * pI810->cpp; I810GetNextScanlineColorExpandBuffer(pScrn); } /* Emit on gaining VT? */ #if 0 static void I810EmitInvarientState(ScrnInfoPtr pScrn) { I810Ptr pI810 = I810PTR(pScrn); BEGIN_LP_RING(10); OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0); OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); OUT_RING(0); OUT_RING(GFX_OP_COLOR_CHROMA_KEY); OUT_RING(CC1_UPDATE_KILL_WRITE | CC1_DISABLE_KILL_WRITE | CC1_UPDATE_COLOR_IDX | CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0); OUT_RING(0); OUT_RING(0); /* OUT_RING( CMD_OP_Z_BUFFER_INFO ); */ /* OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */ ADVANCE_LP_RING(); } #endif /* The following function sets up the supported acceleration. Call it * from the FbInit() function in the SVGA driver, or before ScreenInit * in a monolithic server. */ Bool I810AccelInit(ScreenPtr pScreen) { XAAInfoRecPtr infoPtr; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); I810Ptr pI810 = I810PTR(pScrn); if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) ErrorF("I810AccelInit\n"); pI810->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; pI810->bufferOffset = 0; infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; infoPtr->Flags |= PIXMAP_CACHE; /* Sync */ infoPtr->Sync = I810Sync; /* Solid filled rectangles */ { infoPtr->SolidFillFlags = NO_PLANEMASK; infoPtr->SetupForSolidFill = I810SetupForSolidFill; infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect; } /* Screen to screen copy * - the transparency op hangs the blit engine, disable for now. */ { infoPtr->ScreenToScreenCopyFlags = (0 | NO_PLANEMASK | NO_TRANSPARENCY | 0); infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy; infoPtr->SubsequentScreenToScreenCopy = I810SubsequentScreenToScreenCopy; } /* 8x8 pattern fills */ { infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill; infoPtr->SubsequentMono8x8PatternFillRect = I810SubsequentMono8x8PatternFillRect; infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK | 0); } /* 8x8 color fills - not considered useful for XAA. */ /* Scanline color expansion - Use the same scheme as the 3.3 driver. * */ if (pI810->Scratch.Size != 0) { int i; int width = ALIGN(pScrn->displayWidth, 32) / 8; int nr_buffers = pI810->Scratch.Size / width; unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start; pI810->NumScanlineColorExpandBuffers = nr_buffers; pI810->ScanlineColorExpandBuffers = (unsigned char **) xnfcalloc(nr_buffers, sizeof(unsigned char *)); for (i = 0; i < nr_buffers; i++, ptr += width) pI810->ScanlineColorExpandBuffers[i] = ptr; infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST | 0); infoPtr->ScanlineColorExpandBuffers = (unsigned char **) xnfcalloc(1, sizeof(unsigned char *)); infoPtr->NumScanlineColorExpandBuffers = 1; infoPtr->ScanlineColorExpandBuffers[0] = pI810->ScanlineColorExpandBuffers[0]; pI810->nextColorExpandBuf = 0; infoPtr->SetupForScanlineCPUToScreenColorExpandFill = I810SetupForScanlineCPUToScreenColorExpandFill; infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = I810SubsequentScanlineCPUToScreenColorExpandFill; infoPtr->SubsequentColorExpandScanline = I810SubsequentColorExpandScanline; } /* Possible todo: Image writes w/ non-GXCOPY rop. */ I810SelectBuffer(pScrn, I810_SELECT_FRONT); return XAAInit(pScreen, infoPtr); } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/xvmc/000077500000000000000000000000001267532330400237645ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/xvmc/I810XvMC.c000066400000000000000000004034671267532330400253250ustar00rootroot00000000000000/*************************************************************************** Copyright 2001 Intel Corporation. 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 INTEL, 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 libI810XvMC.c ** ** Authors: ** Matt Sottek ** Bob Paauwe ** ** ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "I810XvMC.h" static int error_base; static int event_base; /*************************************************************************** // Function: i810_get_free_buffer // Description: Allocates a free dma page using kernel ioctls, then // programs the data into the already allocated dma buffer list. // Arguments: pI810XvMC private data structure from the current context. // Notes: We faked the drmMapBufs for the i810's security so now we have // to insert an allocated page into the correct spot in the faked // list to keep up appearances. // Concept for this function was taken from Mesa sources. // Returns: drmBufPtr containing the information about the allocated page. ***************************************************************************/ drmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC) { drmI810DMA dma; drmBufPtr buf; dma.granted = 0; dma.request_size = 4096; while(!dma.granted) { if(GET_BUFFER(pI810XvMC, dma) || !dma.granted) FLUSH(pI810XvMC); } /* No DMA granted */ buf = &(pI810XvMC->dmabufs->list[dma.request_idx]); buf->idx = dma.request_idx; buf->used = 0; buf->total = dma.request_size; buf->address = (drmAddress)dma.virtual; return buf; } /*************************************************************************** // Function: free_privContext // Description: Free's the private context structure if the reference // count is 0. ***************************************************************************/ void i810_free_privContext(i810XvMCContext *pI810XvMC) { I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); pI810XvMC->ref--; if(!pI810XvMC->ref) { drmUnmapBufs(pI810XvMC->dmabufs); drmUnmap(pI810XvMC->overlay.address,pI810XvMC->overlay.size); drmUnmap(pI810XvMC->surfaces.address,pI810XvMC->surfaces.size); drmClose(pI810XvMC->fd); free(pI810XvMC->dmabufs->list); free(pI810XvMC); } I810_UNLOCK(pI810XvMC); } /*************************************************************************** // Function: XvMCCreateContext // Description: Create a XvMC context for the given surface parameters. // Arguments: // display - Connection to the X server. // port - XvPortID to use as avertised by the X connection. // surface_type_id - Unique identifier for the Surface type. // width - Width of the surfaces. // height - Height of the surfaces. // flags - one or more of the following // XVMC_DIRECT - A direct rendered context is requested. // // Notes: surface_type_id and width/height parameters must match those // returned by XvMCListSurfaceTypes. // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { i810XvMCContext *pI810XvMC; int priv_count; uint *priv_data; uint magic; Status ret; int major, minor; /* Verify Obvious things first */ if(context == NULL) { return XvMCBadContext; } if(!(flags & XVMC_DIRECT)) { /* Indirect */ printf("Indirect Rendering not supported!\nUsing Direct."); } /* Limit use to root for now */ if(geteuid()) { printf("Use of XvMC on i810 is currently limited to root\n"); return BadAccess; } /* FIXME: Check $DISPLAY for legal values here */ context->surface_type_id = surface_type_id; context->width = (unsigned short)width; context->height = (unsigned short)height; 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(i810XvMCContext)); if(!context->privData) { printf("Unable to allocate resources for XvMC context.\n"); return BadAlloc; } pI810XvMC = (i810XvMCContext *)context->privData; /* Verify the XvMC extension exists */ if(! XvMCQueryExtension(display, &event_base, &error_base)) { printf("XvMC Extension is not available!\n"); return BadAlloc; } /* Verify XvMC version */ ret = XvMCQueryVersion(display, &major, &minor); if(ret) { printf("XvMCQuery Version Failed, unable to determine protocol version\n"); } /* FIXME: Check Major and Minor here */ /* Check for drm */ if(! drmAvailable()) { printf("Direct Rendering is not available on this system!\n"); return BadAlloc; } /* Build the Attribute Atoms, and Initialize the ones that exist in Xv. */ pI810XvMC->xv_colorkey = XInternAtom(display,"XV_COLORKEY",0); if(!pI810XvMC->xv_colorkey) { return XvBadPort; } ret = XvGetPortAttribute(display,port,pI810XvMC->xv_colorkey, &pI810XvMC->colorkey); if(ret) { return ret; } pI810XvMC->xv_brightness = XInternAtom(display,"XV_BRIGHTNESS",0); pI810XvMC->xv_saturation = XInternAtom(display,"XV_SATURATION",0); pI810XvMC->xv_contrast = XInternAtom(display,"XV_CONTRAST",0); pI810XvMC->brightness = 0; pI810XvMC->saturation = 0x80; /* 1.0 in 3.7 format */ pI810XvMC->contrast = 0x40; /* 1.0 in 3.6 format */ /* Open DRI Device */ if((pI810XvMC->fd = drmOpen("i810",NULL)) < 0) { printf("DRM Device for i810 could not be opened.\n"); free(pI810XvMC); return BadAccess; } /* !pI810XvMC->fd */ /* Get magic number and put it in privData for passing */ drmGetMagic(pI810XvMC->fd,&magic); context->flags = (unsigned long)magic; /* Pass control to the X server to create a drm_context_t for us and validate the with/height and flags. */ if((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { printf("Unable to create XvMC Context.\n"); return ret; } /* X server returns a structure like this: drm_context_t fbBase OverlayOffset OverlaySize SurfacesOffset SurfacesSize busIdString = 9 char + 1 */ if(priv_count != 9) { printf("_xvmc_create_context() returned incorrect data size!\n"); printf("\tExpected 9, got %d\n",priv_count); _xvmc_destroy_context(display, context); free(pI810XvMC); return BadAlloc; } pI810XvMC->drmcontext = priv_data[0]; pI810XvMC->fb_base = priv_data[1]; pI810XvMC->overlay.offset = priv_data[2] + priv_data[1]; pI810XvMC->overlay.size = priv_data[3]; pI810XvMC->surfaces.offset = priv_data[4] + priv_data[1]; pI810XvMC->surfaces.size = priv_data[5]; strncpy(pI810XvMC->busIdString,(char *)&priv_data[6],9); pI810XvMC->busIdString[9] = '\0'; /* Must free the private data we were passed from X */ free(priv_data); /* Initialize private context values */ pI810XvMC->current = 0; pI810XvMC->lock = 0; pI810XvMC->last_flip = 0; pI810XvMC->dual_prime = 0; /* Map dma Buffers: Not really, this would be a drmMapBufs but due to the i810 security model we have to just create an empty data structure to fake it. */ pI810XvMC->dmabufs = (drmBufMapPtr)malloc(sizeof(drmBufMap)); if(pI810XvMC->dmabufs == NULL) { printf("Dma Bufs could not be mapped.\n"); _xvmc_destroy_context(display, context); free(pI810XvMC); return BadAlloc; } /* pI810XvMC->dmabufs == NULL */ memset(pI810XvMC->dmabufs, 0, sizeof(drmBufMap)); pI810XvMC->dmabufs->list = (drmBufPtr)malloc(sizeof(drmBuf) * I810_DMA_BUF_NR); if(pI810XvMC->dmabufs->list == NULL) { printf("Dma Bufs could not be mapped.\n"); _xvmc_destroy_context(display, context); free(pI810XvMC); return BadAlloc; } /* pI810XvMC->dmabufs->list == NULL */ memset(pI810XvMC->dmabufs->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR); /* Map the Overlay memory */ if(drmMap(pI810XvMC->fd,pI810XvMC->overlay.offset, pI810XvMC->overlay.size,&(pI810XvMC->overlay.address)) < 0) { printf("Unable to map Overlay at offset 0x%x and size 0x%x\n", (unsigned int)pI810XvMC->overlay.offset,pI810XvMC->overlay.size); _xvmc_destroy_context(display, context); free(pI810XvMC->dmabufs->list); free(pI810XvMC); return BadAlloc; } /* drmMap() < 0 */ /* Overlay Regs are offset 1024 into Overlay Map */ pI810XvMC->oregs = (i810OverlayRec *) ((unsigned char *)pI810XvMC->overlay.address + 1024); /* Map Surfaces */ if(drmMap(pI810XvMC->fd,pI810XvMC->surfaces.offset, pI810XvMC->surfaces.size,&(pI810XvMC->surfaces.address)) < 0) { printf("Unable to map XvMC Surfaces.\n"); _xvmc_destroy_context(display, context); free(pI810XvMC->dmabufs->list); free(pI810XvMC); return BadAlloc; } /* drmMap() < 0 */ /* There is a tiny chance that someone was using the overlay and issued a flip that hasn't finished. To be 100% sure I'll just take the lock and sleep for the worst case time for a flip. */ I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); usleep(20000); /* 1/50th Sec for 50hz refresh */ /* Set up Overlay regs with Initial Values */ pI810XvMC->oregs->YRGB_VPH = 0; pI810XvMC->oregs->UV_VPH = 0; pI810XvMC->oregs->HORZ_PH = 0; pI810XvMC->oregs->INIT_PH = 0; pI810XvMC->oregs->DWINPOS = 0; pI810XvMC->oregs->DWINSZ = (I810_XVMC_MAXHEIGHT << 16) | I810_XVMC_MAXWIDTH; pI810XvMC->oregs->SWID = I810_XVMC_MAXWIDTH | (I810_XVMC_MAXWIDTH << 15); pI810XvMC->oregs->SWIDQW = (I810_XVMC_MAXWIDTH >> 3) | (I810_XVMC_MAXWIDTH << 12); pI810XvMC->oregs->SHEIGHT = I810_XVMC_MAXHEIGHT | (I810_XVMC_MAXHEIGHT << 15); pI810XvMC->oregs->YRGBSCALE = 0x80004000; /* scale factor 1 */ pI810XvMC->oregs->UVSCALE = 0x80004000; /* scale factor 1 */ pI810XvMC->oregs->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ pI810XvMC->oregs->OV0CLRC1 = 0x80; /* saturation: bypass */ /* Destination Colorkey Setup */ pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); pI810XvMC->oregs->DCLRKM = 0x80070307; pI810XvMC->oregs->SCLRKVH = 0; pI810XvMC->oregs->SCLRKVL = 0; pI810XvMC->oregs->SCLRKM = 0; /* source color key disable */ pI810XvMC->oregs->OV0CONF = 0; /* two 720 pixel line buffers */ pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | YUV_420; pI810XvMC->ref = 1; I810_UNLOCK(pI810XvMC); return Success; } /*************************************************************************** // Function: XvMCDestroyContext // Description: Destorys the specified context. // // Arguments: // display - Specifies the connection to the server. // context - The context to be destroyed. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) { i810XvMCContext *pI810XvMC; if(context == NULL) { return (error_base + XvMCBadContext); } if(context->privData == NULL) { return (error_base + XvMCBadContext); } pI810XvMC = (i810XvMCContext *)context->privData; /* Turn off the overlay */ if(pI810XvMC->last_flip) { I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); /* Make sure last flip is done */ BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST; pI810XvMC->current = !pI810XvMC->current; if(pI810XvMC->current == 1) { pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; } else { pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; } OVERLAY_FLIP(pI810XvMC); pI810XvMC->last_flip++; /* Wait for the flip */ BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); I810_UNLOCK(pI810XvMC); } /* Pass Control to the X server to destroy the drm_context_t */ _xvmc_destroy_context(display, context); i810_free_privContext(pI810XvMC); context->privData = NULL; return Success; } /*************************************************************************** // Function: XvMCCreateSurface ***************************************************************************/ _X_EXPORT Status XvMCCreateSurface( Display *display, XvMCContext *context, XvMCSurface *surface) { i810XvMCContext *pI810XvMC; i810XvMCSurface *pI810Surface; int priv_count; uint *priv_data; Status ret; if((surface == NULL) || (context == NULL) || (display == NULL)){ return BadValue; } pI810XvMC = (i810XvMCContext *)context->privData; if(pI810XvMC == NULL) { return (error_base + XvMCBadContext); } surface->privData = (i810XvMCSurface *)malloc(sizeof(i810XvMCSurface)); if(!surface->privData) { return BadAlloc; } pI810Surface = (i810XvMCSurface *)surface->privData; /* Initialize private values */ pI810Surface->privContext = pI810XvMC; pI810Surface->last_render = 0; pI810Surface->last_flip = 0; pI810Surface->second_field = 0; if((ret = _xvmc_create_surface(display, context, surface, &priv_count, &priv_data))) { free(pI810Surface); printf("Unable to create XvMCSurface.\n"); return ret; } /* _xvmc_create_subpicture returns 2 uints with the offset into the DRM map for the Y surface and UV surface. */ if(priv_count != 2) { printf("_xvmc_create_surface() return incorrect data size.\n"); printf("Expected 2 got %d\n",priv_count); free(priv_data); free(pI810Surface); return BadAlloc; } /* Data == Client Address, offset == Physical address offset */ pI810Surface->data = pI810XvMC->surfaces.address; pI810Surface->offset = pI810XvMC->surfaces.offset; /* i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch and the Tiler need 512k aligned surfaces, basically we are stuck with fixed memory with pitch 1024 for Y data. UV = 512. */ pI810Surface->pitch = 10; if((surface->surface_type_id == FOURCC_UYVY) || (surface->surface_type_id == FOURCC_YUY2)) { /* This is not implemented server side. */ pI810Surface->pitch++; } /* offsets[0,1,2] == Offsets from either data or offset for the Y U and V surfaces. */ pI810Surface->offsets[0] = priv_data[0]; if(((unsigned long)pI810Surface->data + pI810Surface->offsets[0]) & 4095) { printf("XvMCCreateSurface: Surface offset 0 is not 4096 aligned\n"); } if((surface->surface_type_id == FOURCC_UYVY) || (surface->surface_type_id == FOURCC_YUY2)) { /* Packed surface, not fully implemented */ pI810Surface->offsets[1] = 0; pI810Surface->offsets[2] = 0; } else { /* Planar surface */ pI810Surface->offsets[1] = priv_data[1]; if(((unsigned long)pI810Surface->data + pI810Surface->offsets[1]) & 2047) { printf("XvMCCreateSurface: Surface offset 1 is not 2048 aligned\n"); } pI810Surface->offsets[2] = ((unsigned long)pI810Surface->offsets[1] + (1<<(pI810Surface->pitch - 1)) * 288); if(((unsigned long)pI810Surface->data + pI810Surface->offsets[2]) & 2047) { printf("XvMCCreateSurface: Surface offset 2 is not 2048 aligned\n"); } } /* Free data returned from xvmc_create_surface */ free(priv_data); /* Clear the surface to 0 */ memset((void *)((unsigned long)pI810Surface->data + (unsigned long)pI810Surface->offsets[0]), 0, ((1<pitch) * surface->height)); switch(surface->surface_type_id) { case FOURCC_YV12: case FOURCC_I420: /* Destination buffer info command */ pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + pI810Surface->offsets[0]) & ~0xfc000fff) | (pI810Surface->pitch - 9)); pI810Surface->dbi1u = ((((unsigned int)pI810Surface->offset + pI810Surface->offsets[1]) & ~0xfc000fff) | (pI810Surface->pitch - 10)); pI810Surface->dbi1v = ((((unsigned int)pI810Surface->offset + pI810Surface->offsets[2]) & ~0xfc000fff) | (pI810Surface->pitch - 10)); /* Destination buffer variables command */ pI810Surface->dbv1 = (0x8<<20) | (0x8<<16); /* Map info command */ pI810Surface->mi1y = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 3); pI810Surface->mi1u = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); pI810Surface->mi1v = (0x1<<24) | (1<<9) | (pI810Surface->pitch - 4); pI810Surface->mi2y = (((unsigned int)surface->height - 1)<<16) | ((unsigned int)surface->width - 1); pI810Surface->mi2u = (((unsigned int)surface->height - 1)<<15) | (((unsigned int)surface->width - 1)>>1); pI810Surface->mi2v = pI810Surface->mi2u; pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + pI810Surface->offsets[0]) & ~0x0000000f; pI810Surface->mi3u = ((unsigned int)pI810Surface->offset + pI810Surface->offsets[1]) & ~0x0000000f; pI810Surface->mi3v = ((unsigned int)pI810Surface->offset + pI810Surface->offsets[2]) & ~0x0000000f; break; case FOURCC_UYVY: case FOURCC_YUY2: default: /* Destination buffer info command */ pI810Surface->dbi1y = ((((unsigned int)pI810Surface->offset + pI810Surface->offsets[0]) & ~0xfc000fff) | (pI810Surface->pitch - 9)); /* Destination buffer variables command */ if(surface->surface_type_id == FOURCC_YUY2) { pI810Surface->dbv1 = 0x5<<8; pI810Surface->mi1y = 0x5<<24 | pI810Surface->pitch | 0x1<<21; } else { pI810Surface->dbv1 = 0x4<<8; pI810Surface->mi1y = 0x5<<24 | (pI810Surface->pitch - 3); } pI810Surface->mi2y = (((unsigned int)surface->width - 1)<<16) | ((unsigned int)surface->height - 1); pI810Surface->mi3y = ((unsigned int)pI810Surface->offset + pI810Surface->offsets[0]) & ~0xfc000fff; break; } pI810XvMC->ref++; return Success; } /*************************************************************************** // Function: XvMCDestroySurface ***************************************************************************/ _X_EXPORT Status XvMCDestroySurface(Display *display, XvMCSurface *surface) { i810XvMCSurface *pI810Surface; i810XvMCContext *pI810XvMC; if((display == NULL) || (surface == NULL)) { return BadValue; } if(surface->privData == NULL) { return (error_base + XvMCBadSurface); } pI810Surface = (i810XvMCSurface *)surface->privData; if(pI810Surface->last_flip) { XvMCSyncSurface(display,surface); } pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; _xvmc_destroy_surface(display,surface); i810_free_privContext(pI810XvMC); free(pI810Surface); surface->privData = NULL; return Success; } /*************************************************************************** // Function: XvMCCreateBlocks ***************************************************************************/ _X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *block) { if((display == NULL) || (context == NULL) || (num_blocks == 0)) { return BadValue; } block->blocks = (short *)malloc(num_blocks<<6 * sizeof(short)); if(block->blocks == NULL) { return BadAlloc; } block->num_blocks = num_blocks; block->context_id = context->context_id; block->privData = NULL; return Success; } /*************************************************************************** // Function: XvMCDestroyBlocks ***************************************************************************/ _X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) { if(display == NULL) { return BadValue; } free(block->blocks); block->num_blocks = 0; block->context_id = 0; block->privData = NULL; return Success; } /*************************************************************************** // Function: XvMCCreateMacroBlocks ***************************************************************************/ _X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks) { if((display == NULL) || (context == NULL) || (blocks == NULL) || (num_blocks == 0)) { return BadValue; } memset(blocks,0,sizeof(XvMCMacroBlockArray)); blocks->context_id = context->context_id; blocks->privData = NULL; blocks->macro_blocks = (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock)); if(blocks->macro_blocks == NULL) { return BadAlloc; } blocks->num_blocks = num_blocks; return Success; } /*************************************************************************** // Function: XvMCDestroyMacroBlocks ***************************************************************************/ _X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) { if((display == NULL) || (block == NULL)) { return BadValue; } if(block->macro_blocks) { free(block->macro_blocks); } block->context_id = 0; block->num_blocks = 0; block->privData = NULL; return Success; } /*************************************************************************** // Function: dp (Debug Print) // Description: This function prints out in hex i * uint32_t at the address // supplied. This enables you to print out the dma buffers from // within the debugger even though they are not in your address space. ***************************************************************************/ void dp(unsigned int *address, unsigned int i) { int j; printf("DebugPrint:\n"); for(j=0; jaddress; *data++ = CMD_FLUSH; *data++ = BOOLEAN_ENA_2; *data++ = CMD_FLUSH; *data++ = DEST_BUFFER_INFO; *data++ = privTarget->dbi1y; *data++ = DEST_BUFFER_VAR; *data++ = privTarget->dbv1; /* Past Surface */ *data++ = CMD_MAP_INFO; *data++ = privPast->mi1y; *data++ = privPast->mi2y; *data++ = privPast->mi3y; /* Future Surface */ *data++ = CMD_MAP_INFO; *data++ = privFuture->mi1y | 0x1<<28; *data++ = privFuture->mi2y; *data++ = privFuture->mi3y; mc.idx = pDMA->idx; mc.used = (unsigned long)data - (unsigned long)pDMA->address; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } static __inline__ void renderError(void) { printf("Invalid Macroblock Parameters found.\n"); return; } /*************************************************************************** // Function: renderIntrainFrame // Description: inline function that sets hardware parameters for an Intra // encoded macroblock in a Frame picture. ***************************************************************************/ static __inline__ void renderIntrainFrame(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb, short *block_ptr) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Y Blocks */ *dy++ = GFXBLOCK + 68; *dy++ = (1<<30) | (3<<28) | (0xf<<24); *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<4); *dy++ = (16<<16) | 16; *dy++ = 0; *dy++ = 0; PACK_INTRA_DATA(dy,block_ptr,256); dy += 64; block_ptr += 256; /* End Y Blocks */ /* U Block */ *du++ = GFXBLOCK + 20; *du++ = (2<<30) | (1<<28) | (1<<23); *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); *du++ = (8<<16) | 8; *du++ = 0; *du++ = 0; PACK_INTRA_DATA(du,block_ptr,64); du += 16; block_ptr += 64; /* V Block */ *dv++ = GFXBLOCK + 20; *dv++ = (3<<30) | (1<<28) | (1<<22); *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); *dv++ = (8<<16) | 8; *dv++ = 0; *dv++ = 0; PACK_INTRA_DATA(dv,block_ptr,64); dv += 16; block_ptr += 64; *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderIntrainFrameDCT1 // Description: inline function that sets hardware parameters for an Intra // encoded macroblock in a Frame picture with DCT type 1. ***************************************************************************/ static __inline__ void renderIntrainFrameDCT1(uint **datay,uint **datau, uint **datav,XvMCMacroBlock *mb, short *block_ptr,uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Y Blocks */ *dy++ = GFXBLOCK + 36; *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x2<<6); *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); *dy++ = (8<<16) | 16; *dy++ = 0; *dy++ = 0; PACK_INTRA_DATA(dy,block_ptr,128); dy += 32; block_ptr += 128; /* Second Y block */ *dy++ = GFXBLOCK + 36; *dy++ = (1<<30) | (2<<28) | (0x3<<26) | (0x3<<6); *dy++ = ((uint)mb->x<<20) | ((uint)mb->y<<3); *dy++ = (8<<16) | 16; *dy++ = 0; *dy++ = 0; PACK_INTRA_DATA(dy,block_ptr,128); dy += 32; block_ptr += 128; /* End Y Blocks */ /* U Block */ *du++ = GFXBLOCK + 20; *du++ = (2<<30) | (1<<28) | (1<<23); *du++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); *du++ = (8<<16) | 8; *du++ = 0; *du++ = 0; PACK_INTRA_DATA(du,block_ptr,64); du += 16; block_ptr += 64; /* V Block */ *dv++ = GFXBLOCK + 20; *dv++ = (3<<30) | (1<<28) | (1<<22); *dv++ = (((uint)mb->x)<<19) | (((uint)mb->y)<<3); *dv++ = (8<<16) | 8; *dv++ = 0; *dv++ = 0; PACK_INTRA_DATA(dv,block_ptr,64); dv += 16; block_ptr += 64; *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderIntrainField // Description: inline function that sets hardware parameters for an Intra // encoded macroblock in Field pictures. ***************************************************************************/ static __inline__ void renderIntrainField(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, uint ps) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); uint dw1 = drps_table[~ps & 0x1]; /* Y Blocks */ *dy++ = GFXBLOCK + 68; *dy++ = (1<<30) | (3<<28) | (0xf<<24) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; *dy++ = 0; *dy++ = 0; PACK_INTRA_DATA(dy,block_ptr,256); dy += 64; block_ptr += 256; /* End Y Blocks */ xy >>= 1; /* U Block */ *du++ = GFXBLOCK + 20; *du++ = (2<<30) | (1<<28) | (1<<23) | dw1; *du++ = xy; *du++ = (8<<16) | 8; *du++ = 0; *du++ = 0; PACK_INTRA_DATA(du,block_ptr,64); du += 16; block_ptr += 64; /* V Block */ *dv++ = GFXBLOCK + 20; *dv++ = (3<<30) | (1<<28) | (1<<22) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; *dv++ = 0; *dv++ = 0; PACK_INTRA_DATA(dv,block_ptr,64); dv += 16; block_ptr += 64; *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderFieldinField // Description: inline function that sets hardware parameters for a Field // encoded macroblock in a Field Picture. ***************************************************************************/ static __inline__ void renderFieldinField(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, uint ps, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ short fmv[2]; short bmv[2]; /* gfxblock dword 1 */ uint dw1; uint parity = ~ps & XVMC_TOP_FIELD; uint ysize = y_frame_bytes[mb->coded_block_pattern]; uint usize = u_frame_bytes[mb->coded_block_pattern]; uint vsize = v_frame_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); /* i810 Specific flag used to identify the second field in a P frame */ if(flags & 0x80000000) { /* P Frame */ if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == parity) { /* Same parity, use reference field (map0) */ dw1 = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | (((uint)mb->coded_block_pattern)<<22); fmv[0] = mb->PMV[0][0][1]; fmv[1] = mb->PMV[0][0][0]; bmv[0] = 0; bmv[1] = 0; } else { /* Opposite parity, set up as if it were backward motion and use map1. */ dw1 = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | (((uint)mb->coded_block_pattern)<<22); bmv[0] = mb->PMV[0][0][1]; bmv[1] = mb->PMV[0][0][0]; fmv[0] = 0; fmv[1] = 0; } } else { dw1 = type_table[mb->macroblock_type & 0xf] | drps_table[~ps & 0x1] | mvfs_table[mb->motion_vertical_field_select & 3] | (((uint)mb->coded_block_pattern)<<22); fmv[0] = mb->PMV[0][0][1]; fmv[1] = mb->PMV[0][0][0]; bmv[0] = mb->PMV[0][1][1]; bmv[1] = mb->PMV[0][1][0]; } /* Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; *dy++ = *(uint *)fmv; *dy++ = *(uint *)bmv; PACK_CORR_DATA(dy,block_ptr,ysize); block_ptr = (short *)((unsigned long)block_ptr + ysize); /* End Y Blocks */ fmv[0] /= 2; fmv[1] /= 2; bmv[0] /= 2; bmv[1] /= 2; xy >>= 1; /* U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; *du++ = *(uint *)fmv; *du++ = *(uint *)bmv; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; *dv++ = *(uint *)fmv; *dv++ = *(uint *)bmv; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: render16x8inField // Description: inline function that sets hardware parameters for a 16x8 // encoded macroblock in a field picture. ***************************************************************************/ static __inline__ void render16x8inField(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, uint ps, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ short fmv[4]; short bmv[4]; /* gfxblock dword 1 */ uint dw1[2]; uint y1size = y_first_field_bytes[mb->coded_block_pattern]; uint y2size = y_second_field_bytes[mb->coded_block_pattern]; uint usize = u_field_bytes[mb->coded_block_pattern]; uint vsize = v_field_bytes[mb->coded_block_pattern]; uint parity = ~ps & XVMC_TOP_FIELD; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); /* i810 Specific flag used to identify the second field in a P frame */ if(flags & 0x80000000) { /* P Frame */ if((mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD) == parity) { /* Same parity, use reference field (map0) */ dw1[0] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | (((uint)mb->coded_block_pattern)<<22); fmv[0] = mb->PMV[0][0][1]; fmv[1] = mb->PMV[0][0][0]; bmv[0] = 0; bmv[1] = 0; } else { /* Opposite parity, set up as if it were backward motion and use map1. */ dw1[0] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | (((uint)mb->coded_block_pattern)<<22); bmv[0] = mb->PMV[0][0][1]; bmv[1] = mb->PMV[0][0][0]; fmv[0] = 0; fmv[1] = 0; } if((mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD) == (parity<<2)) { /* Same parity, use reference field (map0) */ dw1[1] = 1<<12 | ((0x2 + parity)<<6) | ((0x2 + parity)<<3) | ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); fmv[2] = mb->PMV[1][0][1]; fmv[3] = mb->PMV[1][0][0]; bmv[2] = 0; bmv[3] = 0; } else { /* Opposite parity, set up as if it were backward motion and use map1. */ dw1[1] = 2<<12 | ((0x2 + parity)<<6) | (0x3 - parity) | ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); bmv[2] = mb->PMV[1][0][1]; bmv[3] = mb->PMV[1][0][0]; fmv[2] = 0; fmv[3] = 0; } } else { dw1[0] = type_table[mb->macroblock_type & 0xf] | drps_table[~ps & 0x1] | mvfs_table[mb->motion_vertical_field_select & 3] | (((uint)mb->coded_block_pattern)<<22); dw1[1] = type_table[mb->macroblock_type & 0xf] | drps_table[~ps & 0x1] | mvfs_table[(mb->motion_vertical_field_select>>2) & 0x3] | ((((uint)mb->coded_block_pattern<<22) & (0x3<<22)) | (((uint)mb->coded_block_pattern<<24) & (0x3<<26))); fmv[0] = mb->PMV[0][0][1]; fmv[1] = mb->PMV[0][0][0]; fmv[2] = mb->PMV[1][0][1]; fmv[3] = mb->PMV[1][0][0]; bmv[0] = mb->PMV[0][1][1]; bmv[1] = mb->PMV[0][1][0]; bmv[2] = mb->PMV[1][1][1]; bmv[3] = mb->PMV[1][1][0]; } /* First Y Block */ *dy++ = GFXBLOCK + 4 + (y1size>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = *(uint *)fmv; *dy++ = *(uint *)bmv; PACK_CORR_DATA(dy,block_ptr,y1size); block_ptr = (short *)((unsigned long)block_ptr + y1size); /* Second Y Block */ *dy++ = GFXBLOCK + 4 + (y2size>>2); *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = (xy + 8); *dy++ = (8<<16) | 16; *dy++ = *(uint *)&fmv[2]; *dy++ = *(uint *)&bmv[2]; PACK_CORR_DATA(dy,block_ptr,y2size); block_ptr = (short *)((unsigned long)block_ptr + y2size); /* End Y Blocks */ fmv[0] /= 2; fmv[1] /= 2; fmv[2] /= 2; fmv[3] /= 2; bmv[0] /= 2; bmv[1] /= 2; bmv[2] /= 2; bmv[3] /= 2; xy >>= 1; /* U Blocks */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = *(uint *)fmv; *du++ = *(uint *)bmv; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* Second U block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = (xy + 4); *du++ = (4<<16) | 8; *du++ = *(uint *)&fmv[2]; *du++ = *(uint *)&bmv[2]; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* End U Blocks */ /* V Blocks */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = *(uint *)fmv; *dv++ = *(uint *)bmv; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); /* Second V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = (xy + 4); *dv++ = (4<<16) | 8; *dv++ = *(uint *)&fmv[2]; *dv++ = *(uint *)&bmv[2]; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); /* End V Blocks */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderDualPrimeinField // Description: inline function that sets hardware parameters for a Dual // prime encoded macroblock in a field picture. ***************************************************************************/ static __inline__ void renderDualPrimeinField(uint **datay,uint **datau, uint **datav,XvMCMacroBlock *mb, short *block_ptr,uint ps, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ short fmv[2]; short bmv[2]; /* gfxblock dword 1 */ uint dw1; uint ysize = y_frame_bytes[mb->coded_block_pattern]; uint usize = u_frame_bytes[mb->coded_block_pattern]; uint vsize = v_frame_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); if(ps & XVMC_TOP_FIELD) { dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 2<<6 | 2<<3 | 3; } else { dw1 = (mb->coded_block_pattern<<22) | 3<<12 | 3<<6 | 3<<3 | 2; } fmv[0] = mb->PMV[0][0][1]; fmv[1] = mb->PMV[0][0][0]; bmv[0] = mb->PMV[0][1][1]; bmv[1] = mb->PMV[0][1][0]; /* Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; *dy++ = *(uint *)fmv; *dy++ = *(uint *)bmv; PACK_CORR_DATA(dy,block_ptr,ysize); block_ptr = (short *)((unsigned long)block_ptr + ysize); /* End Y Blocks */ fmv[0] /= 2; fmv[1] /= 2; bmv[0] /= 2; bmv[1] /= 2; xy >>= 1; /* U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; *du++ = *(uint *)fmv; *du++ = *(uint *)bmv; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; *dv++ = *(uint *)fmv; *dv++ = *(uint *)bmv; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderFieldinFrame // Description: inline function that sets hardware parameters for a Field // encoded macroblock in a frame picture. ***************************************************************************/ typedef union { short s[4]; uint u[2]; } su_t; static __inline__ void renderFieldinFrame(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; uint y1size = y_first_field_bytes[mb->coded_block_pattern]; uint y2size = y_second_field_bytes[mb->coded_block_pattern]; uint usize = u_field_bytes[mb->coded_block_pattern]; uint vsize = v_field_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | mvfs_table[mb->motion_vertical_field_select & 3] | (((uint)mb->coded_block_pattern)<<22); dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | mvfs_table[mb->motion_vertical_field_select>>2] | (((mb->coded_block_pattern & 0x3) | ((mb->coded_block_pattern & 0xc)<<2))<<22); fmv.s[0] = mb->PMV[0][0][1]/2; fmv.s[1] = mb->PMV[0][0][0]; fmv.s[2] = mb->PMV[1][0][1]/2; fmv.s[3] = mb->PMV[1][0][0]; bmv.s[0] = mb->PMV[0][1][1]/2; bmv.s[1] = mb->PMV[0][1][0]; bmv.s[2] = mb->PMV[1][1][1]/2; bmv.s[3] = mb->PMV[1][1][0]; /* First Y Block */ *dy++ = GFXBLOCK + 4 + (y1size>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0]; PACK_CORR_DATA(dy,block_ptr,y1size); block_ptr = (short *)((unsigned long)block_ptr + y1size); /* Second Y Block */ *dy++ = GFXBLOCK + 4 + (y2size>>2); *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[1]; *dy++ = bmv.u[1]; PACK_CORR_DATA(dy,block_ptr,y2size); block_ptr = (short *)((unsigned long)block_ptr + y2size); /* End Y Blocks */ fmv.s[0] /= 2; fmv.s[1] /= 2; fmv.s[2] /= 2; fmv.s[3] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; bmv.s[2] /= 2; bmv.s[3] /= 2; xy >>= 1; /* U Blocks */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; if(usize) { PACK_CORR_DATA_SHORT(du,block_ptr); } /* Second U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[1]; *du++ = bmv.u[1]; if(usize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End U Blocks */ /* V Blocks */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; if(vsize) { PACK_CORR_DATA_SHORT(dv,block_ptr); } /* Second V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[1]; *dv++ = bmv.u[1]; if(vsize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End V Blocks */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderFieldinFrameDCT0 // Description: inline function that sets hardware parameters for a Field // encoded macroblock in a frame picture with DCT0. ***************************************************************************/ static __inline__ void renderFieldinFrameDCT0(uint **datay,uint **datau, uint **datav,XvMCMacroBlock *mb, short *block_ptr,uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; /* CBP */ uint cbp = (uint)mb->coded_block_pattern; /* gfxblock dword 1 */ uint dw1[2]; short * top_left_b = NULL; short * top_right_b = NULL; short * bottom_left_b = NULL; short * bottom_right_b = NULL; unsigned int ysize = y_dct0_field_bytes[cbp]; unsigned int usize = u_field_bytes[cbp]; unsigned int vsize = v_field_bytes[cbp]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); dw1[0] = type_table[mb->macroblock_type & 0xf] | (0x2<<6) | mvfs_table[mb->motion_vertical_field_select & 3] | ((cbp | ((cbp<<2) & 0x30))<<22); dw1[1] = type_table[mb->macroblock_type & 0xf] | (0x3<<6) | mvfs_table[mb->motion_vertical_field_select>>2] | ((cbp | ((cbp<<2) & 0x30))<<22); fmv.s[0] = mb->PMV[0][0][1]/2; fmv.s[1] = mb->PMV[0][0][0]; fmv.s[2] = mb->PMV[1][0][1]/2; fmv.s[3] = mb->PMV[1][0][0]; bmv.s[0] = mb->PMV[0][1][1]/2; bmv.s[1] = mb->PMV[0][1][0]; bmv.s[2] = mb->PMV[1][1][1]/2; bmv.s[3] = mb->PMV[1][1][0]; /* The i810 cannot use DCT0 directly with field motion, we have to interlace the data for it. We use a zero block when the CBP has one half of the to-be-interlaced data but not the other half. */ top_left_b = &empty_block[0]; if(cbp & 0x20) { top_left_b = block_ptr; block_ptr += 64; } top_right_b = &empty_block[0]; if(cbp & 0x10) { top_right_b = block_ptr; block_ptr += 64; } bottom_left_b = &empty_block[0]; if(cbp & 0x8) { bottom_left_b = block_ptr; block_ptr += 64; } bottom_right_b = &empty_block[0]; if(cbp & 0x4) { bottom_right_b = block_ptr; block_ptr += 64; } /* First Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0]; if(dw1[0] & (1<<27)) { PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } if(dw1[0] & (1<<26)) { PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); } /* Second Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[1]; *dy++ = bmv.u[1]; if(dw1[1] & (1<<27)) { top_left_b = (short *)((unsigned long)top_left_b + 16); bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } if(dw1[1] & (1<<26)) { top_right_b = (short *)((unsigned long)top_right_b + 16); bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); } /* End Y Blocks */ fmv.s[0] /= 2; fmv.s[1] /= 2; fmv.s[2] /= 2; fmv.s[3] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; bmv.s[2] /= 2; bmv.s[3] /= 2; xy >>= 1; /* U Blocks */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; if(usize) { PACK_CORR_DATA_SHORT(du,block_ptr); } /* Second U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[1]; *du++ = bmv.u[1]; if(usize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End U Blocks */ /* V Blocks */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; if(vsize) { PACK_CORR_DATA_SHORT(dv,block_ptr); } /* Second V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[1]; *dv++ = bmv.u[1]; if(vsize) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End V Blocks */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderFrameinFrame // Description: inline function that sets hardware parameters for a Frame // encoded macroblock in a frame picture. ***************************************************************************/ static __inline__ void renderFrameinFrame(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb,short *block_ptr, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; /* gfxblock dword 1 */ uint dw1; unsigned int ysize = y_frame_bytes[mb->coded_block_pattern]; unsigned int usize = u_frame_bytes[mb->coded_block_pattern]; unsigned int vsize = v_frame_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); dw1 = type_table[mb->macroblock_type & 0xf] | (((uint)mb->coded_block_pattern)<<22); fmv.s[0] = mb->PMV[0][0][1]; fmv.s[1] = mb->PMV[0][0][0]; bmv.s[0] = mb->PMV[0][1][1]; bmv.s[1] = mb->PMV[0][1][0]; /* Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0]; PACK_CORR_DATA(dy,block_ptr,ysize); block_ptr = (short *)((unsigned long)block_ptr + ysize); /* End Y Blocks */ fmv.s[0] /= 2; fmv.s[1] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; xy >>= 1; /* U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* End U Block */ /* V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); /* End V Block */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderFrameinFrameDCT1 // Description: inline function that sets hardware parameters for a Frame // encoded macroblock in a frame picture with DCT type 1. ***************************************************************************/ static __inline__ void renderFrameinFrameDCT1(uint **datay,uint **datau, uint **datav,XvMCMacroBlock *mb, short *block_ptr,uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; short * top_left_b = NULL; short * top_right_b = NULL; short * bottom_left_b = NULL; short * bottom_right_b = NULL; uint temp_bp = 0; uint ysize = y_dct1_frame_bytes[mb->coded_block_pattern]; uint usize = u_frame_bytes[mb->coded_block_pattern]; uint vsize = v_frame_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<4); uint dw1 = type_table[mb->macroblock_type & 0xf] | (((uint)mb->coded_block_pattern)<<22); fmv.s[0] = mb->PMV[0][0][1]; fmv.s[1] = mb->PMV[0][0][0]; bmv.s[0] = mb->PMV[0][1][1]; bmv.s[1] = mb->PMV[0][1][0]; /* It is easiest to find out what blocks are in need of reading first rather than as we go. */ top_left_b = &empty_block[0]; if(dw1 & (1<<27)) { temp_bp |= (1<<25); top_left_b = block_ptr; block_ptr += 64; } top_right_b = &empty_block[0]; if(dw1 & (1<<26)) { temp_bp |= (1<<24); top_right_b = block_ptr; block_ptr += 64; } bottom_left_b = &empty_block[0]; if(dw1 & (1<<25)) { temp_bp |= (1<<27); bottom_left_b = block_ptr; block_ptr += 64; } bottom_right_b = &empty_block[0]; if(dw1 & (1<<24)) { temp_bp |= (1<<26); bottom_right_b = block_ptr; block_ptr += 64; } dw1 |= temp_bp; /* Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (3<<28) | dw1; *dy++ = xy; *dy++ = (16<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0]; if(dw1 & (1<<27)) { PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); top_left_b = (short *)((unsigned long)top_left_b + 64); bottom_left_b = (short *)((unsigned long)bottom_left_b + 64); } if(dw1 & (1<<26)) { PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); top_right_b = (short *)((unsigned long)top_right_b + 64); bottom_right_b = (short *)((unsigned long)bottom_right_b + 64); } if(dw1 & (1<<27)) { PACK_CORR_DATA_1to0(dy,top_left_b,bottom_left_b); } if(dw1 & (1<<26)) { PACK_CORR_DATA_1to0(dy,top_right_b,bottom_right_b); } /* End Y Block */ fmv.s[0] /= 2; fmv.s[1] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; xy >>= 1; /* U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1; *du++ = xy; *du++ = (8<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; PACK_CORR_DATA(du,block_ptr,usize); block_ptr = (short *)((unsigned long)block_ptr + usize); /* V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1; *dv++ = xy; *dv++ = (8<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; PACK_CORR_DATA(dv,block_ptr,vsize); block_ptr = (short *)((unsigned long)block_ptr + vsize); *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderDualPrimeinFrame // Description: inline function that sets hardware parameters for a Dual // Prime encoded macroblock in a frame picture with dct 1. ***************************************************************************/ static __inline__ void renderDualPrimeinFrame(uint **datay,uint **datau, uint **datav,XvMCMacroBlock *mb, short *block_ptr,uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; uint y1size = y_first_field_bytes[mb->coded_block_pattern]; uint y2size = y_second_field_bytes[mb->coded_block_pattern]; uint usize = u_field_bytes[mb->coded_block_pattern]; uint vsize = v_field_bytes[mb->coded_block_pattern]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); /* Past Surface (map 0) is used for same parity prediction, Future surface (map 1) is used for opposite. */ dw1[0] = (((uint)mb->coded_block_pattern)<<22) | 3<<12 | 2<<6 | 2<<3 | 3; dw1[1] = (((mb->coded_block_pattern & 0x3) | ((mb->coded_block_pattern & 0xc)<<2))<<22) | 3<<12 | 3<<6 | 3<<3 | 2; fmv.s[0] = mb->PMV[0][0][1]; fmv.s[1] = mb->PMV[0][0][0]; bmv.s[0] = mb->PMV[1][0][1]; bmv.s[1] = mb->PMV[1][0][0]; fmv.s[2] = mb->PMV[0][0][1]; fmv.s[3] = mb->PMV[0][0][0]; bmv.s[2] = mb->PMV[1][1][1]; bmv.s[3] = mb->PMV[1][1][0]; /* First Y Block */ *dy++ = GFXBLOCK + 4 + (y1size>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0];; PACK_CORR_DATA(dy,block_ptr,y1size); block_ptr = (short *)((unsigned long)block_ptr + y1size); /* Second Y Block */ *dy++ = GFXBLOCK + 4 + (y2size>>2); *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[1]; *dy++ = bmv.u[1]; PACK_CORR_DATA(dy,block_ptr,y2size); block_ptr = (short *)((unsigned long)block_ptr + y2size); fmv.s[0] /= 2; fmv.s[1] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; fmv.s[2] /= 2; fmv.s[3] /= 2; bmv.s[2] /= 2; bmv.s[3] /= 2; xy >>= 1; /* U Blocks */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; if(dw1[0] & (1<<23)) { PACK_CORR_DATA_SHORT(du,block_ptr); } /* Second U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[1]; *du++ = bmv.u[1]; if(dw1[1] & (1<<23)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End U Blocks */ /* V Blocks */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; if(dw1[0] & (1<<22)) { PACK_CORR_DATA_SHORT(dv,block_ptr); } /* Second V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[1]; *dv++ = bmv.u[1]; if(dw1[1] & (1<<22)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End V Blocks */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: renderDualPrimeinFrameDCT0 // Description: inline function that sets hardware parameters for a Dual // Prime encoded macroblock in a frame picture with dct 0. ***************************************************************************/ static __inline__ void renderDualPrimeinFrameDCT0(uint **datay,uint **datau, uint **datav, XvMCMacroBlock *mb, short *block_ptr, uint flags) { register uint *dy = *datay; register uint *du = *datau; register uint *dv = *datav; /* Motion Vectors */ su_t fmv; su_t bmv; /* gfxblock dword 1 */ uint dw1[2]; short * top_left_b = NULL; short * top_right_b = NULL; short * bottom_left_b = NULL; short * bottom_right_b = NULL; uint cbp = (uint)mb->coded_block_pattern; uint ysize = y_dct0_field_bytes[cbp]; uint usize = u_field_bytes[cbp]; uint vsize = v_field_bytes[cbp]; uint xy = ((uint)mb->x<<20) | ((uint)mb->y<<3); /* Past Surface (map 0) is used for same parity prediction, Future surface (map 1) is used for opposite. */ dw1[0] = ((cbp | ((cbp<<2) & 0x30))<<22) | 3<<12 | 2<<6 | 2<<3 | 3; dw1[1] = ((cbp | ((cbp<<2) & 0x30))<<22) | 3<<12 | 3<<6 | 3<<3 | 2; fmv.s[0] = mb->PMV[0][0][1]; fmv.s[1] = mb->PMV[0][0][0]; bmv.s[0] = mb->PMV[1][0][1]; bmv.s[1] = mb->PMV[1][0][0]; fmv.s[2] = mb->PMV[0][0][1]; fmv.s[3] = mb->PMV[0][0][0]; bmv.s[2] = mb->PMV[1][1][1]; bmv.s[3] = mb->PMV[1][1][0]; /* The i810 cannot use DCT0 directly with field motion, we have to interlace the data for it. We use a zero block when the CBP has one half of the to-be-interlaced data but not the other half. */ top_left_b = &empty_block[0]; if(cbp & 0x20) { top_left_b = block_ptr; block_ptr += 64; } top_right_b = &empty_block[0]; if(cbp & 0x10) { top_right_b = block_ptr; block_ptr += 64; } bottom_left_b = &empty_block[0]; if(cbp & 0x8) { bottom_left_b = block_ptr; block_ptr += 64; } bottom_right_b = &empty_block[0]; if(cbp & 0x4) { bottom_right_b = block_ptr; block_ptr += 64; } /* First Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (2<<28) | dw1[0]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[0]; *dy++ = bmv.u[0]; if(cbp & 0x20) { PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } if(cbp & 0x10) { PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); } /* Second Y Block */ *dy++ = GFXBLOCK + 4 + (ysize>>2); *dy++ = (1<<30) | (2<<28) | dw1[1]; *dy++ = xy; *dy++ = (8<<16) | 16; *dy++ = fmv.u[1]; *dy++ = bmv.u[1]; if(cbp & 0x20) { top_left_b = (short *)((unsigned long)top_left_b + 16); bottom_left_b = (short *)((unsigned long)bottom_left_b + 16); PACK_CORR_DATA_0to1(dy,top_left_b,bottom_left_b); } if(cbp & 0x10) { top_right_b = (short *)((unsigned long)top_right_b + 16); bottom_right_b = (short *)((unsigned long)bottom_right_b + 16); PACK_CORR_DATA_0to1(dy,top_right_b,bottom_right_b); } /* End Y Blocks */ fmv.s[0] /= 2; fmv.s[1] /= 2; bmv.s[0] /= 2; bmv.s[1] /= 2; fmv.s[2] /= 2; fmv.s[3] /= 2; bmv.s[2] /= 2; bmv.s[3] /= 2; xy >>= 1; /* U Blocks */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[0]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[0]; *du++ = bmv.u[0]; if(cbp & (1<<23)) { PACK_CORR_DATA_SHORT(du,block_ptr); } /* Second U Block */ *du++ = GFXBLOCK + 4 + (usize>>2); *du++ = (2<<30) | (1<<28) | dw1[1]; *du++ = xy; *du++ = (4<<16) | 8; *du++ = fmv.u[1]; *du++ = bmv.u[1]; if(cbp & (1<<23)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(du,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End U Blocks */ /* V Blocks */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[0]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[0]; *dv++ = bmv.u[0]; if(cbp & (1<<22)) { PACK_CORR_DATA_SHORT(dv,block_ptr); } /* Second V Block */ *dv++ = GFXBLOCK + 4 + (vsize>>2); *dv++ = (3<<30) | (1<<28) | dw1[1]; *dv++ = xy; *dv++ = (4<<16) | 8; *dv++ = fmv.u[1]; *dv++ = bmv.u[1]; if(cbp & (1<<22)) { block_ptr = (short *)((unsigned long)block_ptr + 16); PACK_CORR_DATA_SHORT(dv,block_ptr); block_ptr = (short *)((unsigned long)block_ptr + 112); } /* End V Blocks */ *datay = dy; *datau = du; *datav = dv; } /*************************************************************************** // Function: XvMCRenderSurface // Description: This function does the actual HWMC. Given a list of // macroblock structures it dispatched the hardware commands to execute // them. DMA buffer containing Y data are dispatched as they fill up // U and V DMA buffers are queued until all Y's are done. This minimizes // the context flipping and flushing required when switching between Y // U and V surfaces. ***************************************************************************/ #define UV_QUEUE 14 _X_EXPORT 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) { /* Dma Data Structures */ drmBufPtr pDMAy = NULL,pDMAu[UV_QUEUE],pDMAv[UV_QUEUE]; int u_index = 0,v_index = 0; int dirty_context = 1; /* Block Pointer */ short *block_ptr; /* Current Macroblock Pointer */ XvMCMacroBlock *mb; drm_i810_mc_t mc; int i,j; i810XvMCSurface *privTarget; i810XvMCSurface *privFuture = NULL; i810XvMCSurface *privPast = NULL; i810XvMCContext *pI810XvMC; /* DMA Pointers set to NULL */ uint *datay = NULL; uint *datau = NULL; uint *datav = NULL; /* Check Parameters for validity */ if((target_surface == NULL) || (context == NULL) || (display == NULL)) { printf("Error, Invalid Target,Context, or DIsplay!\n"); return BadValue; } if(num_macroblocks == 0) {return Success;} if((macroblock_array == NULL) || (blocks == NULL)) {return BadValue;} if(context->privData == NULL) {return BadValue;} pI810XvMC = (i810XvMCContext *)context->privData; if(target_surface->privData == NULL) { printf("Error, Invalid Target Surface!\n"); return BadValue; } privTarget = (i810XvMCSurface *)target_surface->privData; if(macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { printf("Error, Too many macroblocks requested for MB array size.\n"); return BadValue; } /* Test For YV12 Surface */ if(context->surface_type_id != FOURCC_YV12) { printf("Error, HWMC only possible on YV12 Surfaces\n"); return BadValue; } /* P Frame Test */ if(past_surface == NULL) { /* Just to avoid some ifs later. */ privPast = privTarget; } else { if(past_surface->privData == NULL) { printf("Error, Invalid Past Surface!\n"); return BadValue; } privPast = (i810XvMCSurface *)past_surface->privData; } /* B Frame Test */ if(future_surface == NULL) { privFuture = privTarget; if(pI810XvMC->dual_prime) { privFuture = privPast; /* I810 Specific flag for marking when dual prime is in use. */ flags |= 0x40000000; } /* References are different for the Second Field Picture. The i810 needs to know if it is the second field picture in a P picture. We use a Private flag to mark this. */ if(flags & XVMC_SECOND_FIELD) { /* I810 Specific flag for marking second fields. */ flags |= 0x80000000; } } else { if((future_surface->privData == NULL) || (past_surface == NULL)) { printf("Error, Invalid Future Surface or No Past Surface!\n"); return BadValue; } privFuture = (i810XvMCSurface *)future_surface->privData; /* Undo Second Field flag since the second field in B frames is just like the first. */ flags &= ~0x80000000; } /* Lock For DMA */ I810_LOCK(pI810XvMC,0); for(i=first_macroblock; i<(num_macroblocks + first_macroblock); i++) { /* Set up values needed for each macroblock */ mb = ¯oblock_array->macro_blocks[i]; block_ptr = &(blocks->blocks[mb->index<<6]); /* Lockup can happen if the coordinates are too far out of range */ if(mb->x > target_surface->width>>4) { mb->x = 0; } if(mb->y > target_surface->height>>4) { mb->y = 0; } /* If buffers are almost full dispatch them */ if(datay) { pDMAy->used = (unsigned long)datay - (unsigned long)pDMAy->address; if(pDMAy->used > 3520) { if(dirty_context) { dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); } dirty_context = 0; mc.idx = pDMAy->idx; mc.used = pDMAy->used; datay = NULL; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } /* datay near full */ } /* if(datay) */ if(datau) { pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; if(pDMAu[u_index]->used > 3904) { u_index++; datau = NULL; if(u_index == UV_QUEUE) { for(j=0; jidx; mc.used = pDMAu[j]->used; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } u_index = 0; dirty_context = 1; } /* if(u_index == UV_QUEUE) */ } /* datau near full */ } /* if(datau) */ if(datav) { pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; if(pDMAv[v_index]->used > 3904) { v_index++; datav = NULL; if(v_index == UV_QUEUE) { for(j=0; jidx; mc.used = pDMAv[j]->used; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } v_index = 0; dirty_context = 1; } /* if(v_index == UV_QUEUE) */ } /* datav near full */ } /* if(datav) */ /* Allocate buffers if this is the first loop,or if we just dispatched */ if(datay == NULL) { pDMAy = i810_get_free_buffer(pI810XvMC); datay = pDMAy->address; }/* if(datay == NULL) */ if(datau == NULL) { pDMAu[u_index] = i810_get_free_buffer(pI810XvMC); datau = pDMAu[u_index]->address; if(u_index == 0) { *datau++ = CMD_FLUSH; *datau++ = BOOLEAN_ENA_2; *datau++ = CMD_FLUSH; *datau++ = DEST_BUFFER_INFO; *datau++ = privTarget->dbi1u; *datau++ = DEST_BUFFER_VAR; *datau++ = privTarget->dbv1; /* Past Surface */ *datau++ = CMD_MAP_INFO; *datau++ = privPast->mi1u; *datau++ = privPast->mi2u; *datau++ = privPast->mi3u; /* Future Surface */ *datau++ = CMD_MAP_INFO; *datau++ = privFuture->mi1u | 0x1<<28; *datau++ = privFuture->mi2u; *datau++ = privFuture->mi3u; } } /* if(datau == NULL) */ if(datav == NULL) { pDMAv[v_index] = i810_get_free_buffer(pI810XvMC); datav = pDMAv[v_index]->address; if(v_index == 0) { *datav++ = CMD_FLUSH; *datav++ = BOOLEAN_ENA_2; *datav++ = CMD_FLUSH; *datav++ = DEST_BUFFER_INFO; *datav++ = privTarget->dbi1v; *datav++ = DEST_BUFFER_VAR; *datav++ = privTarget->dbv1; /* Past Surface */ *datav++ = CMD_MAP_INFO; *datav++ = privPast->mi1v; *datav++ = privPast->mi2v; *datav++ = privPast->mi3v; /* Future Surface */ *datav++ = CMD_MAP_INFO; *datav++ = privFuture->mi1v | 0x1<<28; *datav++ = privFuture->mi2v; *datav++ = privFuture->mi3v; } }/* if(datav == NULL) */ /* Catch no pattern case */ if(!(mb->macroblock_type & 0x8)) { mb->coded_block_pattern = 0; } if(mb->motion_type == XVMC_PREDICTION_DUAL_PRIME) { /* By default the maps will not be set up for dual prime. We have to change them. */ if(!pI810XvMC->dual_prime) { pI810XvMC->dual_prime = 1; privFuture = privPast; /* Y */ *datay++ = CMD_MAP_INFO; *datay++ = privFuture->mi1y | 0x1<<28; *datay++ = privFuture->mi2y; *datay++ = privFuture->mi3y; /* U */ *datau++ = CMD_MAP_INFO; *datau++ = privFuture->mi1u | 0x1<<28; *datau++ = privFuture->mi2u; *datau++ = privFuture->mi3u; /* V */ *datav++ = CMD_MAP_INFO; *datav++ = privFuture->mi1v | 0x1<<28; *datav++ = privFuture->mi2v; *datav++ = privFuture->mi3v; } } if((pI810XvMC->dual_prime) && (mb->motion_type != XVMC_PREDICTION_DUAL_PRIME)) { pI810XvMC->dual_prime = 0; privFuture = privTarget; /* Y */ *datay++ = CMD_MAP_INFO; *datay++ = privFuture->mi1y | 0x1<<28; *datay++ = privFuture->mi2y; *datay++ = privFuture->mi3y; /* U */ *datau++ = CMD_MAP_INFO; *datau++ = privFuture->mi1u | 0x1<<28; *datau++ = privFuture->mi2u; *datau++ = privFuture->mi3u; /* V */ *datav++ = CMD_MAP_INFO; *datav++ = privFuture->mi1v | 0x1<<28; *datav++ = privFuture->mi2v; *datav++ = privFuture->mi3v; } /* Frame Picture */ if((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Intra Blocks */ if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { if(mb->dct_type) { renderIntrainFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); continue; } renderIntrainFrame(&datay,&datau,&datav,mb,block_ptr); continue; } switch((mb->motion_type & 0x3) | (mb->dct_type<<2)) { case 0x2: /* Frame DCT0 */ renderFrameinFrame(&datay,&datau,&datav,mb,block_ptr,flags); continue; case 0x5: /* Field DCT1 */ renderFieldinFrame(&datay,&datau,&datav,mb,block_ptr,flags); continue; case 0x6: /* Frame DCT1 */ renderFrameinFrameDCT1(&datay,&datau,&datav,mb,block_ptr,flags); continue; case 0x1: /* Field DCT0 */ renderFieldinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); continue; case 0x3: /* Dual Prime DCT0 */ renderDualPrimeinFrame(&datay,&datau,&datav,mb,block_ptr,flags); continue; case 0x7: /* Dual Prime DCT1 */ renderDualPrimeinFrameDCT0(&datay,&datau,&datav,mb,block_ptr,flags); continue; default: /* No Motion Type */ renderError(); continue; } /* Switch */ } /* Frame Picture */ /* Field Pictures */ if(mb->macroblock_type & XVMC_MB_TYPE_INTRA) { renderIntrainField(&datay,&datau,&datav,mb,block_ptr,picture_structure); continue; } switch(mb->motion_type & 0x3) { case 0x1: /* Field Motion */ renderFieldinField(&datay,&datau,&datav,mb,block_ptr,picture_structure, flags); continue; case 0x2: /* 16x8 Motion */ render16x8inField(&datay,&datau,&datav,mb,block_ptr,picture_structure, flags); continue; case 0x3: /* Dual Prime */ renderDualPrimeinField(&datay,&datau,&datav,mb,block_ptr, picture_structure,flags); continue; default: /* No Motion Type */ renderError(); continue; } continue; } /* for each Macroblock */ /* Dispatch remaining DMA buffers */ if(dirty_context) { dispatchYContext(privTarget,privPast,privFuture,pI810XvMC); } mc.idx = pDMAy->idx; mc.used = (unsigned long)datay - (unsigned long)pDMAy->address; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); pDMAu[u_index]->used = (unsigned long)datau - (unsigned long)pDMAu[u_index]->address; for(j=0; j<=u_index; j++) { mc.idx = pDMAu[j]->idx; mc.used = pDMAu[j]->used; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } pDMAv[v_index]->used = (unsigned long)datav - (unsigned long)pDMAv[v_index]->address; for(j=0; j<=v_index; j++) { mc.idx = pDMAv[j]->idx; mc.used = pDMAv[j]->used; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); } I810_UNLOCK(pI810XvMC); return Success; } /*************************************************************************** // Function: XvMCPutSurface // Description: // Arguments: // display: Connection to X server // surface: Surface to be displayed // draw: X Drawable on which to display the surface // srcx: X coordinate of the top left corner of the region to be // displayed within the surface. // srcy: Y coordinate of the top left corner of the region to be // displayed within the surface. // srcw: Width of the region to be displayed. // srch: Height of the region to be displayed. // destx: X cordinate of the top left corner of the destination region // in the drawable coordinates. // desty: Y cordinate of the top left corner of the destination region // in the drawable coordinates. // destw: Width of the destination region. // desth: Height of the destination region. // flags: One or more of the following. // XVMC_TOP_FIELD - Display only the Top field of the surface. // XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. // XVMC_FRAME_PICTURE - Display both fields or frame. // // Info: Portions of this function derived from i810_video.c (XFree86) // // This function is organized so that we wait as long as possible before // touching the overlay registers. Since we don't know that the last // flip has happened yet we want to give the overlay as long as // possible to catch up before we have to check on its progress. This // makes it unlikely that we have to wait on the last flip. ***************************************************************************/ _X_EXPORT 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) { i810XvMCContext *pI810XvMC; i810XvMCSurface *pI810Surface; i810OverlayRecPtr pORegs; unsigned int ysrc_offset,uvsrc_offset; Box extents; uint window_width,window_height; unsigned int xscaleInt = 0,xscaleFract = 0,yscaleInt = 0,yscaleFract = 0; unsigned int xscaleFractUV = 0,xscaleIntUV = 0,yscaleFractUV = 0; unsigned int yscaleIntUV = 0,yPitch = 0,uvPitch = 0; unsigned int ovcmd = 0; uint d; double xscale,yscale; int diff; int clipped_srcx, clipped_srcy, clipped_destx, clipped_desty; int clipped_srcw, clipped_srch, clipped_destw, clipped_desth; uint x1,y1,root_width,root_height; int x2 = 0, y2 = 0,unused; uint nChilds; int stat; Window win,root,parent,*pChilds; if((display == NULL) || (surface == NULL)) { return BadValue; } if(surface->privData == NULL) { return (error_base + XvMCBadSurface); } pI810Surface = (i810XvMCSurface *)surface->privData; pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; pORegs = (i810OverlayRecPtr)pI810XvMC->oregs; switch(surface->surface_type_id) { case FOURCC_YV12: case FOURCC_I420: yPitch = (srcw + 7) & ~7; uvPitch = ((srcw>>1) + 7) & ~7; if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { srch = srch>>1; } break; case FOURCC_UYVY: case FOURCC_YUY2: default: /* FIXME: Non Planar not fully implemented. */ return BadValue; yPitch = ((srcw + 7) & ~7) << 1; break; }/* switch(surface->surface_type_id) */ /* FIXME: This should be using the DRI's clip rect but that isn't all hooked up yet. This has some latency but we get by. */ win = draw; XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); if(nChilds) XFree(pChilds); XGetGeometry(display,win, &root, &x2, &y2, &window_width, &window_height, &d, &d); x1 = x2; y1 = y2; win = parent; do { XQueryTree(display,win,&root,&parent,&pChilds,&nChilds); if(nChilds) XFree(pChilds); XGetGeometry(display,win, &root, &x2, &y2, &d, &d, &d, &d); x1 += x2; y1 += y2; win = parent; }while(win != root); XGetGeometry(display,root, &root, &unused, &unused, &root_width, &root_height, &d, &d); /* Left edge of Video window clipped to screen */ extents.x1 = 0; if(x1 > extents.x1) { extents.x1 = x1; } /* Right edge of Video window clipped to screen */ extents.x2 = root_width; if(extents.x2 > (x1 + window_width)) { extents.x2 = x1 + window_width; } /* Top edge of Video window clipped to screen */ extents.y1 = 0; if(y1 > extents.y1) { extents.y1 = y1; } /* Bottom edge of Video window clipped to screen */ extents.y2 = root_height; if(extents.y2 > (y1 + window_height)) { extents.y2 = y1 + window_height; } /* Clipping is more difficult than is seems. We need to keep the scaling factors even if the destination window needs to be clipped. We clip the destination window first then apply a scaled version to the source window. */ /* Put destination coords in screen coords */ destx += x1; desty += y1; /* Scale factors requested */ xscale = (double)srcw / (double)destw; yscale = (double)srch / (double)desth; /* If destination window needs to be clipped we actually adjust both the src and dest window so as to keep the scaling that was requested */ clipped_srcx = srcx; clipped_srcy = srcy; clipped_destx = destx; clipped_desty = desty; clipped_srcw = srcw; clipped_srch = srch; clipped_destw = destw; clipped_desth = desth; /* Clip to the source surface boundaries */ if(clipped_srcx < 0) { clipped_destx += (0 - clipped_srcx) / xscale; clipped_srcw -= clipped_srcx; clipped_destw -= clipped_srcx / xscale; clipped_srcx = 0; } if((clipped_srcw + clipped_srcx) > surface->width) { clipped_srcw = surface->width - clipped_srcx; clipped_destw -= (clipped_srcw - srcw) / xscale; } if(clipped_srcy < 0) { clipped_desty += (0 - clipped_srcy) / yscale; clipped_srch -= clipped_srcy; clipped_desth -= clipped_srcy / yscale; clipped_srcy = 0; } if((clipped_srch + clipped_srcy) > surface->height) { clipped_srch = surface->height - clipped_srcy; clipped_desth -= (clipped_srch - srch) / yscale; } /* Clip to the extents */ if(clipped_destx < extents.x1) { diff = extents.x1 - clipped_destx; clipped_srcx += diff * xscale; clipped_srcw -= diff * xscale; clipped_destw -= diff; clipped_destx = extents.x1; } diff = (clipped_destx + clipped_destw) - extents.x2; if(diff > 0) { clipped_destw -= diff; clipped_srcw -= diff * xscale; } if(clipped_desty < extents.y1) { diff = extents.y1 - clipped_desty; clipped_srcy += diff * yscale; clipped_srch -= diff * yscale; clipped_desth -= diff; clipped_desty = 0; } diff = (clipped_desty + clipped_desth) - extents.y2; if(diff > 0) { clipped_desth -= diff; clipped_srch -= diff * yscale; } /* If the whole window is clipped turn off the overlay */ if((clipped_destx + clipped_destw < extents.x1) || (clipped_desty + clipped_desth < extents.y1) || (clipped_destx > extents.x2) || (clipped_desty > extents.y2)) { return XvMCHideSurface(display, surface); } /* Adjust the source offset width and height according to the clipped destination window. */ ysrc_offset = ((clipped_srcx + 1) & ~1) + ((clipped_srcy + 1) & ~1) * (1<pitch); uvsrc_offset = (clipped_srcx>>1) + (clipped_srcy>>1) * (1<<(pI810Surface->pitch - 1)); /* Initially, YCbCr and Overlay Enable and vertical chrominance up interpolation and horozontal chrominance up interpolation */ ovcmd = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | OVERLAY_ENABLE; if ((clipped_destw != clipped_srcw) || (clipped_desth != clipped_srch)) { xscaleInt = (clipped_srcw / clipped_destw) & 0x3; xscaleFract = (clipped_srcw << 12) / clipped_destw; yscaleInt = (clipped_srch / clipped_desth) & 0x3; yscaleFract = (clipped_srch << 12) / clipped_desth; if (clipped_destw > clipped_srcw) { /* horizontal up-scaling */ ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; ovcmd |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); } if (clipped_desth > clipped_srch) { /* vertical up-scaling */ ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; ovcmd &= ~VERTICAL_LUMINANCE_FILTER; ovcmd |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); } if (clipped_destw < clipped_srcw) { /* horizontal down-scaling */ ovcmd &= ~HORIZONTAL_CHROMINANCE_FILTER; ovcmd &= ~HORIZONTAL_LUMINANCE_FILTER; ovcmd |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); } if (clipped_desth < clipped_srch) { /* vertical down-scaling */ ovcmd &= ~VERTICAL_CHROMINANCE_FILTER; ovcmd &= ~VERTICAL_LUMINANCE_FILTER; ovcmd |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); } /* now calculate the UV scaling factor */ if (xscaleFract) { xscaleFractUV = xscaleFract >> MINUV_SCALE; ovcmd &= ~HC_DOWN_INTERPOLATION; ovcmd |= HC_UP_INTERPOLATION; } if (xscaleInt) { xscaleIntUV = xscaleInt >> MINUV_SCALE; if (xscaleIntUV) { ovcmd &= ~HC_UP_INTERPOLATION; } } if (yscaleFract) { yscaleFractUV = yscaleFract >> MINUV_SCALE; ovcmd &= ~VC_DOWN_INTERPOLATION; ovcmd |= VC_UP_INTERPOLATION; } if (yscaleInt) { yscaleIntUV = yscaleInt >> MINUV_SCALE; if (yscaleIntUV) { ovcmd &= ~VC_UP_INTERPOLATION; ovcmd |= VC_DOWN_INTERPOLATION; } } }/* if((destw != srcw) || (desth != srch)) */ /* Lock the DRM */ I810_LOCK(pI810XvMC,0); /* Block until rendering on this surface is finished */ stat = XVMC_RENDERING; while(stat & XVMC_RENDERING) { XvMCGetSurfaceStatus(display,surface,&stat); } /* Block until the last flip is finished */ if(pI810XvMC->last_flip) { BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); } pI810XvMC->current = !pI810XvMC->current; pORegs->OV0CMD = ovcmd; if ((clipped_destw != clipped_srcw) || (clipped_desth != clipped_srch)) { pORegs->YRGBSCALE = (xscaleInt << 15) | ((xscaleFract & 0xFFF) << 3) | (yscaleInt) | ((yscaleFract & 0xFFF) << 20); pORegs->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | ((yscaleFractUV & 0xFFF) << 20); } else { /* Normal 1:1 scaling */ pORegs->YRGBSCALE = 0x80004000; pORegs->UVSCALE = 0x80004000; } pORegs->SHEIGHT = clipped_srch | (clipped_srch << 15); pORegs->DWINPOS = (clipped_desty << 16) | clipped_destx; pORegs->DWINSZ = ((clipped_desth<< 16) | (clipped_destw)); /* Attributes */ pORegs->OV0CLRC0 = ((pI810XvMC->contrast & 0x1ff)<<8) | (pI810XvMC->brightness & 0xff); pORegs->OV0CLRC1 = (pI810XvMC->saturation & 0x3ff); /* Destination Colorkey Setup */ pI810XvMC->oregs->DCLRKV = RGB16ToColorKey(pI810XvMC->colorkey); /* buffer locations, add the offset from the clipping */ if(pI810XvMC->current) { pORegs->OBUF_1Y = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[0] + ysrc_offset; pORegs->OBUF_1V = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; pORegs->OBUF_1U = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; } else { pORegs->OBUF_0Y = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[0] + ysrc_offset; pORegs->OBUF_0V = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[2] + uvsrc_offset; pORegs->OBUF_0U = (unsigned long)pI810Surface->offset + (unsigned long)pI810Surface->offsets[1] + uvsrc_offset; } switch(surface->surface_type_id) { case FOURCC_YV12: case FOURCC_I420: pORegs->SWID = (uvPitch << 16) | yPitch; pORegs->SWIDQW = (uvPitch << 13) | (yPitch >> 3); pORegs->OV0STRIDE = (1<pitch) | ((1<pitch) << 15); pORegs->OV0CMD &= ~SOURCE_FORMAT; pORegs->OV0CMD |= YUV_420; if((flags & XVMC_FRAME_PICTURE) != XVMC_FRAME_PICTURE) { /* Top Field Only */ if(flags & XVMC_TOP_FIELD) { if(pI810XvMC->current == 1) { pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | BUFFER1_FIELD0); } else { pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | BUFFER0_FIELD0); } pORegs->YRGB_VPH = 1<<15 | 1<<31; pORegs->UV_VPH = 3<<14 | 3<<30; pORegs->INIT_PH = 0x06 | 0x18; } /* Bottom Field Only */ else { if(pI810XvMC->current == 1) { pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | BUFFER1_FIELD1); } else { pORegs->OV0CMD |= (VERTICAL_PHASE_BOTH | FLIP_TYPE_FIELD | BUFFER0_FIELD1); } pORegs->YRGB_VPH = 0; pORegs->UV_VPH = 7<<29 | 7<<13; pORegs->INIT_PH = 0x06; } } /* Frame Picture */ else { if(pI810XvMC->current == 1) { pORegs->OV0CMD |= BUFFER1_FIELD0; } else { pORegs->OV0CMD |= BUFFER0_FIELD0; } pORegs->YRGB_VPH = 0; pORegs->UV_VPH = 0; pORegs->INIT_PH = 0; } break; case FOURCC_UYVY: case FOURCC_YUY2: default: pORegs->SWID = srcw; pORegs->SWIDQW = srcw >> 3; pORegs->OV0STRIDE = pI810Surface->pitch; pORegs->OV0CMD &= ~SOURCE_FORMAT; pORegs->OV0CMD |= YUV_422; pORegs->OV0CMD &= ~OV_BYTE_ORDER; if (surface->surface_type_id == FOURCC_UYVY) { pORegs->OV0CMD |= Y_SWAP; } pORegs->OV0CMD &= ~BUFFER_AND_FIELD; if(pI810XvMC->current == 1) { pORegs->OV0CMD |= BUFFER1_FIELD0; } else { pORegs->OV0CMD |= BUFFER0_FIELD0; } break; } /* switch(surface->surface_type_id) */ OVERLAY_FLIP(pI810XvMC); /* The Overlay only flips when it knows you changed something. So the first time change stuff while it is watching to be sure. */ if(!pI810XvMC->last_flip) { pORegs->OV0CMD &= ~0x4; if(pI810XvMC->current == 1) { pORegs->OV0CMD |= BUFFER1_FIELD0; } else { pORegs->OV0CMD |= BUFFER0_FIELD0; } } pI810Surface->last_flip = ++pI810XvMC->last_flip; I810_UNLOCK(pI810XvMC); return Success; } /*************************************************************************** // Function: XvMCSyncSurface // Arguments: // display - Connection to the X server // surface - The surface to synchronize // Info: // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCSyncSurface(Display *display,XvMCSurface *surface) { Status ret; int stat=0; /* FIXME: Perhaps a timer here to prevent lockup? FIXME: Perhaps a usleep to not be busy waiting? */ do { ret = XvMCGetSurfaceStatus(display,surface,&stat); }while(!ret && (stat & XVMC_RENDERING)); return ret; } /*************************************************************************** // Function: XvMCFlushSurface // Description: // This function commits pending rendering requests to ensure that they // wll be completed in a finite amount of time. // Arguments: // display - Connection to X server // surface - Surface to flush // Info: // This command is a noop for i810 because we always dispatch buffers in // render. There is little gain to be had with 4k buffers. // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface *surface) { return Success; } /*************************************************************************** // Function: XvMCGetSurfaceStatus // Description: // Arguments: // display: connection to X server // surface: The surface to query // stat: One of the Following // XVMC_RENDERING - The last XvMCRenderSurface command has not // completed. // XVMC_DISPLAYING - The surface is currently being displayed or a // display is pending. ***************************************************************************/ _X_EXPORT Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) { i810XvMCSurface *privSurface; i810XvMCContext *pI810XvMC; int temp; if((display == NULL) || (surface == NULL) || (stat == NULL)) { return BadValue; } if(surface->privData == NULL) { return BadValue; } *stat = 0; privSurface = surface->privData; pI810XvMC = privSurface->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSurface); } I810_LOCK(pI810XvMC,0); if(privSurface->last_flip) { /* This can not happen */ if(pI810XvMC->last_flip < privSurface->last_flip) { printf("Error: Context last flip is less than surface last flip.\n"); return BadValue; } /* If the context has 2 or more flips after this surface it cannot be displaying. Don't bother to check. */ if(!(pI810XvMC->last_flip > (privSurface->last_flip + 1))) { /* If this surface was the last flipped it is either displaying or about to be so don't bother checking. */ if(pI810XvMC->last_flip == privSurface->last_flip) { *stat |= XVMC_DISPLAYING; } else { /* In this case there has been one more flip since our surface's but we need to check if it is finished or not. */ temp = GET_FSTATUS(pI810XvMC); if(((temp & (1<<20))>>20) != pI810XvMC->current) { *stat |= XVMC_DISPLAYING; } } } } if(privSurface->last_render && (privSurface->last_render > GET_RSTATUS(pI810XvMC))) { *stat |= XVMC_RENDERING; } I810_UNLOCK(pI810XvMC); return Success; } /*************************************************************************** // // Surface manipulation functions // ***************************************************************************/ /*************************************************************************** // Function: XvMCHideSurface // Description: Stops the display of a surface. // Arguments: // display - Connection to the X server. // surface - surface to be hidden. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCHideSurface(Display *display, XvMCSurface *surface) { i810XvMCSurface *pI810Surface; i810XvMCContext *pI810XvMC; int ss, xx; /* Did we get a good display and surface passed into us? */ if(display == NULL) { return BadValue; } if(surface == NULL) { return (error_base + XvMCBadSurface); } XvMCSyncSurface(display, surface); /* Get surface private data pointer */ if(surface->privData == NULL) { return (error_base + XvMCBadSurface); } pI810Surface = (i810XvMCSurface *)surface->privData; /* Get the status of the surface, if it is not currently displayed we don't need to worry about it. */ if((xx = XvMCGetSurfaceStatus(display, surface, &ss)) != Success) { return xx; } if(! (ss & XVMC_DISPLAYING)) { return Success; } /* Get the associated context pointer */ pI810XvMC = (i810XvMCContext *)pI810Surface->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSurface); } if(pI810XvMC->last_flip) { I810_LOCK(pI810XvMC,DRM_LOCK_QUIESCENT); /* Make sure last flip is done */ BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current); /* Set the registers to turn the overlay off */ pI810XvMC->oregs->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST; pI810XvMC->current = !pI810XvMC->current; if(pI810XvMC->current == 1) { pI810XvMC->oregs->OV0CMD |= BUFFER1_FIELD0; } else { pI810XvMC->oregs->OV0CMD |= BUFFER0_FIELD0; } OVERLAY_FLIP(pI810XvMC); /* Increment the context flip but not the surface. This way no surface has the last flip #. */ pI810XvMC->last_flip++; /* Now wait until the hardware reads the registers and makes the change. */ BLOCK_OVERLAY(pI810XvMC,pI810XvMC->current) I810_UNLOCK(pI810XvMC); } return Success; } /*************************************************************************** // // Functions that deal with subpictures // ***************************************************************************/ /*************************************************************************** // Function: XvMCCreateSubpicture // Description: This creates a subpicture by filling out the XvMCSubpicture // structure passed to it and returning Success. // Arguments: // display - Connection to the X server. // context - The context to create the subpicture for. // subpicture - Pre-allocated XvMCSubpicture structure to be filled in. // width - of subpicture // height - of subpicture // xvimage_id - The id describing the XvImage format. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCCreateSubpicture(Display *display, XvMCContext *context, XvMCSubpicture *subpicture, unsigned short width, unsigned short height, int xvimage_id) { i810XvMCContext *pI810XvMC; i810XvMCSubpicture *pI810Subpicture; int priv_count; uint *priv_data; Status ret; if((subpicture == NULL) || (context == NULL) || (display == NULL)){ return BadValue; } pI810XvMC = (i810XvMCContext *)context->privData; if(pI810XvMC == NULL) { return (error_base + XvMCBadContext); } subpicture->context_id = context->context_id; subpicture->xvimage_id = xvimage_id; /* These need to be checked to make sure they are not too big! */ subpicture->width = width; subpicture->height = height; subpicture->privData = (i810XvMCSubpicture *)malloc(sizeof(i810XvMCSubpicture)); if(!subpicture->privData) { return BadAlloc; } pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; if((ret = _xvmc_create_subpicture(display, context, subpicture, &priv_count, &priv_data))) { printf("Unable to create XvMCSubpicture.\n"); return ret; } if(priv_count != 1) { printf("_xvmc_create_subpicture() returned incorrect data size.\n"); printf("Expected 1 got %d\n",priv_count); free(priv_data); return BadAlloc; } /* Data == Client Address, offset == Physical address offset */ pI810Subpicture->data = pI810XvMC->surfaces.address; pI810Subpicture->offset = pI810XvMC->surfaces.offset; /* Initialize private values */ pI810Subpicture->privContext = pI810XvMC; pI810Subpicture->last_render = 0; pI810Subpicture->last_flip = 0; /* Based on the xvimage_id we will need to set the other values */ subpicture->num_palette_entries = 16; subpicture->entry_bytes = 3; strcpy(subpicture->component_order,"YUV"); /* i810's MC Engine needs surfaces of 2^x (x= 9,10,11,12) pitch and the Tiler need 512k aligned surfaces, basically we are stuck with fixed memory with pitch 1024. */ pI810Subpicture->pitch = 10; /* offsets[0] == offset into the map described by either address (Client memeory address) or offset (physical offset from fb base) */ pI810Subpicture->offsets[0] = priv_data[0]; if(((unsigned long)pI810Subpicture->data + pI810Subpicture->offsets[0]) & 4095) { printf("XvMCCreateSubpicture: Subpicture offset 0 is not 4096 aligned\n"); } /* Free data returned from xvmc_create_surface */ free(priv_data); /* Clear the surface to 0 */ memset((void *)((unsigned long)pI810Subpicture->data + (unsigned long)pI810Subpicture->offsets[0]), 0, ((1<pitch) * subpicture->height)); switch(subpicture->xvimage_id) { case FOURCC_IA44: case FOURCC_AI44: /* Destination buffer info command */ pI810Subpicture->dbi1 = ((((unsigned int)pI810Subpicture->offset + pI810Subpicture->offsets[0]) & ~0xfc000fff) | (pI810Subpicture->pitch - 9)); /* Destination buffer variables command */ pI810Subpicture->dbv1 = (0x8<<20) | (0x8<<16); /* Map info command */ pI810Subpicture->mi1 = (0x0<<24) | (3<<21) | (1<<9) | (pI810Subpicture->pitch - 3); pI810Subpicture->mi2 = (((unsigned int)subpicture->height - 1)<<16) | ((unsigned int)subpicture->width - 1); pI810Subpicture->mi3 = ((unsigned int)pI810Subpicture->offset + pI810Subpicture->offsets[0]) & ~0xfc00000f; break; default: free(subpicture->privData); return BadMatch; } pI810XvMC->ref++; return Success; } /*************************************************************************** // Function: XvMCClearSubpicture // Description: Clear the area of the given subpicture to "color". // structure passed to it and returning Success. // Arguments: // display - Connection to the X server. // subpicture - Subpicture to clear. // x, y, width, height - rectangle in the subpicture to clear. // color - The data to file the rectangle with. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture, short x, short y, unsigned short width, unsigned short height, unsigned int color) { i810XvMCContext *pI810XvMC; i810XvMCSubpicture *pI810Subpicture; int i; if((subpicture == NULL) || (display == NULL)){ return BadValue; } if(!subpicture->privData) { return (error_base + XvMCBadSubpicture); } pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSubpicture); } if((x < 0) || (x + width > subpicture->width)) { return BadValue; } if((y < 0) || (y + height > subpicture->height)) { return BadValue; } for(i=y; idata + (unsigned long)pI810Subpicture->offsets[0] + x + (1<pitch) * i),(char)color,width); } return Success; } /*************************************************************************** // Function: XvMCCompositeSubpicture // Description: Composite the XvImae on the subpicture. This composit uses // non-premultiplied alpha. Destination alpha is utilized // except for with indexed subpictures. Indexed subpictures // use a simple "replace". // Arguments: // display - Connection to the X server. // subpicture - Subpicture to clear. // image - the XvImage to be used as the source of the composite. // srcx, srcy, width, height - The rectangle from the image to be used. // dstx, dsty - location in the subpicture to composite the source. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture, XvImage *image, short srcx, short srcy, unsigned short width, unsigned short height, short dstx, short dsty) { i810XvMCContext *pI810XvMC; i810XvMCSubpicture *pI810Subpicture; int i; if((subpicture == NULL) || (display == NULL)){ return BadValue; } if(!subpicture->privData) { return (error_base + XvMCBadSubpicture); } pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSubpicture); } if((srcx < 0) || (srcx + width > image->width)) { return BadValue; } if((dstx < 0) || (dstx + width > subpicture->width)) { return BadValue; } if((srcy < 0) || (srcy + height > image->height)) { return BadValue; } if((dsty < 0) || (dsty + height > subpicture->height)) { return BadValue; } for(i=0; idata + (unsigned long)pI810Subpicture->offsets[0] + dstx + (1<pitch) * (i + dsty)), (void *)((unsigned long)image->data + (unsigned long)image->offsets[0] + srcx + image->pitches[0] * (i + srcy)) ,width); } return Success; } /*************************************************************************** // Function: XvMCDestroySubpicture // Description: Destroys the specified subpicture. // Arguments: // display - Connection to the X server. // subpicture - Subpicture to be destroyed. // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) { i810XvMCSubpicture *pI810Subpicture; i810XvMCContext *pI810XvMC; if((display == NULL) || (subpicture == NULL)) { return BadValue; } if(!subpicture->privData) { return (error_base + XvMCBadSubpicture); } pI810Subpicture = (i810XvMCSubpicture *)subpicture->privData; pI810XvMC = (i810XvMCContext *)pI810Subpicture->privContext; if(!pI810XvMC) { return (error_base + XvMCBadSubpicture); } if(pI810Subpicture->last_render) { XvMCSyncSubpicture(display,subpicture); } _xvmc_destroy_subpicture(display,subpicture); i810_free_privContext(pI810XvMC); free(pI810Subpicture); subpicture->privData = NULL; return Success; } /*************************************************************************** // Function: XvMCSetSubpicturePalette // Description: Set the subpictures palette // Arguments: // display - Connection to the X server. // subpicture - Subpiture to set palette for. // palette - A pointer to an array holding the palette data. The array // is num_palette_entries * entry_bytes in size. // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, unsigned char *palette) { i810XvMCSubpicture *privSubpicture; int i,j; if((display == NULL) || (subpicture == NULL)) { return BadValue; } if(subpicture->privData == NULL) { return (error_base + XvMCBadSubpicture); } privSubpicture = (i810XvMCSubpicture *)subpicture->privData; j=0; for(i=0; i<16; i++) { privSubpicture->palette[0][i] = palette[j++]; privSubpicture->palette[1][i] = palette[j++]; privSubpicture->palette[2][i] = palette[j++]; } return Success; } /*************************************************************************** // Function: XvMCBlendSubpicture // Description: // The behavior of this function is different depending on whether // or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. // i810 only support frontend behavior. // // XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): // // XvMCBlendSubpicture is a no-op in this case. // // Arguments: // display - Connection to the X server. // subpicture - The subpicture to be blended into the video. // target_surface - The surface to be displayed with the blended subpic. // source_surface - Source surface prior to blending. // subx, suby, subw, subh - The rectangle from the subpicture to use. // surfx, surfy, surfw, surfh - The rectangle in the surface to blend // blend the subpicture rectangle into. Scaling can ocure if // XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. // // Returns: Status ***************************************************************************/ _X_EXPORT 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) { return BadMatch; } /*************************************************************************** // Function: XvMCBlendSubpicture2 // Description: // The behavior of this function is different depending on whether // or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. // i810 only supports frontend blending. // // XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): // // XvMCBlendSubpicture2 blends the source_surface and subpicture and // puts it in the target_surface. This does not effect the status of // the source surface but will cause the target_surface to query // XVMC_RENDERING until the blend is completed. // // Arguments: // display - Connection to the X server. // subpicture - The subpicture to be blended into the video. // target_surface - The surface to be displayed with the blended subpic. // source_surface - Source surface prior to blending. // subx, suby, subw, subh - The rectangle from the subpicture to use. // surfx, surfy, surfw, surfh - The rectangle in the surface to blend // blend the subpicture rectangle into. Scaling can ocure if // XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. // // Returns: Status ***************************************************************************/ _X_EXPORT 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) { drmBufPtr pDMA; unsigned int *data; i810XvMCContext *pI810XvMC; i810XvMCSubpicture *privSubpicture; i810XvMCSurface *privTarget; i810XvMCSurface *privSource; drm_i810_mc_t mc; int i,j; if(display == NULL) { return BadValue; } if(subpicture == NULL) { return (error_base + XvMCBadSubpicture); } if((target_surface == NULL) || (source_surface == NULL)) { return (error_base + XvMCBadSurface); } if((subpicture->xvimage_id != FOURCC_AI44) && (subpicture->xvimage_id != FOURCC_IA44)) { return (error_base + XvMCBadSubpicture); } if(!subpicture->privData) { return (error_base + XvMCBadSubpicture); } privSubpicture = (i810XvMCSubpicture *)subpicture->privData; pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSubpicture); } if(!target_surface->privData) { return (error_base + XvMCBadSurface); } privTarget = (i810XvMCSurface *)target_surface->privData; if(!source_surface->privData) { return (error_base + XvMCBadSurface); } privSource = (i810XvMCSurface *)source_surface->privData; /* Check that size isn't bigger than subpicture */ if((subx + subw) > subpicture->width) { return BadValue; } if((suby + subh) > subpicture->height) { return BadValue; } /* Check that dest isn't bigger than surface */ if((surfx + surfw) > target_surface->width) { return BadValue; } if((surfy + surfh) > target_surface->height) { return BadValue; } /* Make sure surfaces match */ if(target_surface->width != source_surface->width) { return BadValue; } if(target_surface->height != source_surface->height) { return BadValue; } /* Lock For DMA */ I810_LOCK(pI810XvMC,0); /* Allocate DMA buffer */ pDMA = i810_get_free_buffer(pI810XvMC); data = pDMA->address; /* Copy Y data first */ /* SOURCE_COPY_BLT */ *data++ = (2<<29) | (0x43<<22) | 0x4; *data++ = (0xcc<<16) | (1<<26) | (1<pitch); *data++ = (target_surface->height<<16) | target_surface->width; *data++ = privTarget->offset + privTarget->offsets[0]; *data++ = (1<pitch); *data++ = privSource->offset + privSource->offsets[0]; /* Select Context 1 for loading */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<8); *data++ = CMD_FLUSH; /* Load Palette */ *data++ = MAP_PALETTE_LOAD; /* 16 levels of alpha for each Y */ switch(subpicture->xvimage_id) { case FOURCC_IA44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (j<<12) | (j<<8) | privSubpicture->palette[0][i]; } } break; case FOURCC_AI44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (i<<12) | (i<<8) | privSubpicture->palette[0][j]; } } break; } /* TARGET */ /* *data++ = CMD_FLUSH; */ /* *data++ = BOOLEAN_ENA_2; */ *data++ = CMD_FLUSH; *data++ = DEST_BUFFER_INFO; *data++ = privTarget->dbi1y; *data++ = DEST_BUFFER_VAR; *data++ = privTarget->dbv1; /* ALPHA */ *data++ = CMD_MAP_INFO; *data++ = privSubpicture->mi1; *data++ = privSubpicture->mi2; *data++ = privSubpicture->mi3; *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); *data++ = BOOLEAN_ENA_1; *data++ = SRC_DEST_BLEND_MONO | (0x940); /* Map Filter */ *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (0x224); /* Use context 1 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<16) | 1; *data++ = CMD_FLUSH; /* Drawing Rect Info */ *data++ = DRAWING_RECT_INFO; *data++ = 0x0; *data++ = 0x0; *data++ = 0x0; *data++ = 0x0; *data++ = 0x0; /* GFXPRIMITIVE RECTANGLE */ *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; /* Bottom Right Vertex */ *(float *)data++ = (float) (surfx + surfw); *(float *)data++ = (float) (surfy + surfh); *(float *)data++ = (float) (subx + subw); *(float *)data++ = (float) (suby + subh); /* Bottom Left Vertex */ *(float *)data++ = (float) surfx; *(float *)data++ = (float) (surfy + surfh); *(float *)data++ = (float) subx; *(float *)data++ = (float) (suby + subh); /* Top Left Vertex */ *(float *)data++ = (float) surfx; *(float *)data++ = (float) surfy; *(float *)data++ = (float) subx; *(float *)data++ = (float) suby; /* Load and Use Context 0 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<16); *data++ = CMD_FLUSH; /* U data */ /* SOURCE_COPY_BLT */ *data++ = (2<<29) | (0x43<<22) | 0x4; *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); *data++ = (target_surface->height<<15) | (target_surface->width>>1); *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[1]; *data++ = (1<<(privSource->pitch - 1)); *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[1]; /* Context 1 select */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<8); *data++ = CMD_FLUSH; /* ALPHA PALETTE */ *data++ = MAP_PALETTE_LOAD; /* 16 levels of alpha for each Y */ switch(subpicture->xvimage_id) { case FOURCC_IA44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (j<<12) | (j<<8) | privSubpicture->palette[2][i]; } } break; case FOURCC_AI44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (i<<12) | (i<<8) | privSubpicture->palette[2][j]; } } break; } /* TARGET */ *data++ = CMD_FLUSH; *data++ = BOOLEAN_ENA_2; *data++ = CMD_FLUSH; *data++ = DEST_BUFFER_INFO; *data++ = privTarget->dbi1u; *data++ = DEST_BUFFER_VAR; *data++ = privTarget->dbv1; /* ALPHA */ *data++ = CMD_MAP_INFO; *data++ = privSubpicture->mi1; *data++ = privSubpicture->mi2; *data++ = privSubpicture->mi3; *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); *data++ = BOOLEAN_ENA_1; *data++ = SRC_DEST_BLEND_MONO | (0x940); /* Map Filter */ *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); /* Use context 1 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<16) | 1; *data++ = CMD_FLUSH; /* Drawing Rect Info */ *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; *data++ = 0; *data++ = 0; *data++ = 0; *data++ = 0; *data++ = 0; /* Rectangle */ *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; /* Bottom Right */ *(float *)data++ = (float) ((surfx + surfw)>>1); *(float *)data++ = (float) ((surfy + surfh)>>1); *(float *)data++ = (float) subx + subw; *(float *)data++ = (float) suby + subh; /* Bottom Left */ *(float *)data++ = (float) (surfx>>1); *(float *)data++ = (float) ((surfy + surfh)>>1); *(float *)data++ = (float) subx; *(float *)data++ = (float) suby + subh; /* Top Left */ *(float *)data++ = (float) (surfx>>1); *(float *)data++ = (float) (surfy>>1); *(float *)data++ = (float) subx; *(float *)data++ = (float) suby; /* Load and Use Context 0 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<16); *data++ = CMD_FLUSH; /* V data */ /* SOURCE_COPY_BLT */ *data++ = (2<<29) | (0x43<<22) | 0x4; *data++ = (0xcc<<16) | (1<<26) | (1<<(privTarget->pitch - 1)); *data++ = (target_surface->height<<15) | (target_surface->width>>1); *data++ = (unsigned long)privTarget->offset + (unsigned long)privTarget->offsets[2]; *data++ = (1<<(privSource->pitch - 1)); *data++ = (unsigned long)privSource->offset + (unsigned long)privSource->offsets[2]; /* Context 1 select */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<8); *data++ = CMD_FLUSH; /* ALPHA PALETTE */ *data++ = MAP_PALETTE_LOAD; /* 16 levels of alpha for each Y */ switch(subpicture->xvimage_id) { case FOURCC_IA44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (j<<12) | (j<<8) | privSubpicture->palette[1][i]; } } break; case FOURCC_AI44: for(i=0; i<16; i++) { for(j=0; j<16; j++) { *data++ = (i<<12) | (i<<8) | privSubpicture->palette[1][j]; } } break; } /* TARGET */ *data++ = CMD_FLUSH; *data++ = BOOLEAN_ENA_2; *data++ = CMD_FLUSH; *data++ = DEST_BUFFER_INFO; *data++ = privTarget->dbi1v; *data++ = DEST_BUFFER_VAR; *data++ = privTarget->dbv1; /* ALPHA */ *data++ = CMD_MAP_INFO; *data++ = privSubpicture->mi1; *data++ = privSubpicture->mi2; *data++ = privSubpicture->mi3; *data++ = VERTEX_FORMAT | (1<<8) | (3<<1); *data++ = BOOLEAN_ENA_1; *data++ = SRC_DEST_BLEND_MONO | (0x940); /* Map Filter */ *data++ = (3<<29) | (0x1c<<24) | (2<<19) | (1<<16) | (0x224); /* Use context 1 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<16) | 1; *data++ = CMD_FLUSH; /* Drawing Rect Info */ *data++ = (3<<29) | (0x1d<<24) | (0x80<<16) | 3; *data++ = 0; *data++ = 0; *data++ = 0; *data++ = 0; *data++ = 0; /* Rectangle */ *data++ = (3<<29) | (0x1f<<24) | (0x7<<18) | 11; /* Bottom Right */ *(float *)data++ = (float) ((surfx + surfw)>>1); *(float *)data++ = (float) ((surfy + surfh)>>1); *(float *)data++ = (float) subx + subw; *(float *)data++ = (float) suby + subh; /* Bottom Left */ *(float *)data++ = (float) (surfx>>1); *(float *)data++ = (float) ((surfy + surfh)>>1); *(float *)data++ = (float) subx; *(float *)data++ = (float) suby + subh; /* Top Left */ *(float *)data++ = (float) (surfx>>1); *(float *)data++ = (float) (surfy>>1); *(float *)data++ = (float) subx; *(float *)data++ = (float) suby; /* Load and Use Context 0 */ *data++ = CMD_FLUSH; *data++ = (5<<23) | (1<<17) | (1<<16); *data++ = CMD_FLUSH; /* Dispatch */ pDMA->used = (unsigned long)data - (unsigned long)pDMA->address; mc.idx = pDMA->idx; mc.used = pDMA->used; mc.last_render = ++pI810XvMC->last_render; privTarget->last_render = pI810XvMC->last_render; I810_MC(pI810XvMC,mc); I810_UNLOCK(pI810XvMC); return Success; } /*************************************************************************** // Function: XvMCSyncSubpicture // Description: This function blocks until all composite/clear requests on // the subpicture have been complete. // Arguments: // display - Connection to the X server. // subpicture - The subpicture to synchronize // // Returns: Status ***************************************************************************/ _X_EXPORT Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) { Status ret; int stat=0; do { ret = XvMCGetSubpictureStatus(display,subpicture,&stat); }while(!ret && (stat & XVMC_RENDERING)); return ret; } /*************************************************************************** // Function: XvMCFlushSubpicture // Description: This function commits pending composite/clear requests to // ensure that they will be completed in a finite amount of // time. // Arguments: // display - Connection to the X server. // subpicture - The subpicture whos compsiting should be flushed // // Returns: Status // NOTES: i810 always dispatches commands so flush is a no-op ***************************************************************************/ _X_EXPORT Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) { if(display == NULL) { return BadValue; } if(subpicture == NULL) { return (error_base + XvMCBadSubpicture); } return Success; } /*************************************************************************** // Function: XvMCGetSubpictureStatus // Description: This function gets the current status of a subpicture // // Arguments: // display - Connection to the X server. // subpicture - The subpicture whos status is being queried // stat - The status of the subpicture. It can be any of the following // OR'd together: // XVMC_RENDERING - Last composite or clear request not completed // XVMC_DISPLAYING - Suppicture currently being displayed. // // Returns: Status // Notes: i810 always blends into a third surface so the subpicture is // never actually displaying, only a copy of it is displaying. We only // have to worry about the rendering case. ***************************************************************************/ _X_EXPORT Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, int *stat) { i810XvMCSubpicture *privSubpicture; i810XvMCContext *pI810XvMC; if((display == NULL) || (stat == NULL)) { return BadValue; } if((subpicture == NULL) || (subpicture->privData == NULL)) { return (error_base + XvMCBadSubpicture); } *stat = 0; privSubpicture = (i810XvMCSubpicture *)subpicture->privData; pI810XvMC = (i810XvMCContext *)privSubpicture->privContext; if(pI810XvMC == NULL) { return (error_base + XvMCBadSubpicture); } I810_LOCK(pI810XvMC,0); if(privSubpicture->last_render && (privSubpicture->last_render > GET_RSTATUS(pI810XvMC))) { *stat |= XVMC_RENDERING; } I810_UNLOCK(pI810XvMC); return Success; } #define NUM_XVMC_ATTRIBUTES 4 static XvAttribute I810_XVMC_ATTRIBUTES[] = { {XvGettable | XvSettable, 0, 0xffffff, "XV_COLORKEY"}, {XvGettable | XvSettable, -127, +127, "XV_BRIGHTNESS"}, {XvGettable | XvSettable, 0, 0x1ff, "XV_CONTRAST"}, {XvGettable | XvSettable, 0, 0x3ff, "XV_SATURATION"} }; /*************************************************************************** // Function: XvMCQueryAttributes // Description: An array of XvAttributes of size "number" is returned by // this function. If there are no attributes, NULL is returned and number // is set to 0. The array may be freed with free(). // // Arguments: // display - Connection to the X server. // context - The context whos attributes we are querying. // number - The number of returned atoms. // // Returns: // An array of XvAttributes. // Notes: // For i810 we support these Attributes: // XV_COLORKEY: The colorkey value, initialized from the Xv value at // context creation time. // XV_BRIGHTNESS // XV_CONTRAST // XV_SATURATION ***************************************************************************/ _X_EXPORT XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context, int *number) { i810XvMCContext *pI810XvMC; XvAttribute *attributes; if(number == NULL) { return NULL; } if(display == NULL) { *number = 0; return NULL; } if(context == NULL) { *number = 0; return NULL; } pI810XvMC = context->privData; if(pI810XvMC == NULL) { *number = 0; return NULL; } attributes = (XvAttribute *)malloc(NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute)); if(attributes == NULL) { *number = 0; return NULL; } memcpy(attributes,I810_XVMC_ATTRIBUTES,(NUM_XVMC_ATTRIBUTES * sizeof(XvAttribute))); *number = NUM_XVMC_ATTRIBUTES; return attributes; } /*************************************************************************** // Function: XvMCSetAttribute // Description: This function sets a context-specific attribute. // // Arguments: // display - Connection to the X server. // context - The context whos attributes we are querying. // attribute - The X atom of the attribute to be changed. // value - The new value for the attribute. // // Returns: // Status // Notes: // For i810 we support these Attributes: // XV_COLORKEY: The colorkey value, initialized from the Xv value at // context creation time. // XV_BRIGHTNESS // XV_CONTRAST // XV_SATURATION ***************************************************************************/ _X_EXPORT Status XvMCSetAttribute(Display *display, XvMCContext *context, Atom attribute, int value) { i810XvMCContext *pI810XvMC; if(display == NULL) { return BadValue; } if(context == NULL) { return (error_base + XvMCBadContext); } pI810XvMC = context->privData; if(pI810XvMC == NULL) { return (error_base + XvMCBadContext); } if(attribute == pI810XvMC->xv_colorkey) { if((value < I810_XVMC_ATTRIBUTES[0].min_value) || (value > I810_XVMC_ATTRIBUTES[0].max_value)) { return BadValue; } pI810XvMC->colorkey = value; return Success; } if(attribute == pI810XvMC->xv_brightness) { if((value < I810_XVMC_ATTRIBUTES[1].min_value) || (value > I810_XVMC_ATTRIBUTES[1].max_value)) { return BadValue; } pI810XvMC->brightness = value; return Success; } if(attribute == pI810XvMC->xv_saturation) { if((value < I810_XVMC_ATTRIBUTES[2].min_value) || (value > I810_XVMC_ATTRIBUTES[2].max_value)) { return BadValue; } pI810XvMC->saturation = value; return Success; } if(attribute == pI810XvMC->xv_contrast) { if((value < I810_XVMC_ATTRIBUTES[3].min_value) || (value > I810_XVMC_ATTRIBUTES[3].max_value)) { return BadValue; } pI810XvMC->contrast = value; return Success; } return BadValue; } /*************************************************************************** // Function: XvMCGetAttribute // Description: This function queries a context-specific attribute and // returns the value. // // Arguments: // display - Connection to the X server. // context - The context whos attributes we are querying. // attribute - The X atom of the attribute to be queried // value - The returned attribute value // // Returns: // Status // Notes: // For i810 we support these Attributes: // XV_COLORKEY: The colorkey value, initialized from the Xv value at // context creation time. // XV_BRIGHTNESS // XV_CONTRAST // XV_SATURATION ***************************************************************************/ _X_EXPORT Status XvMCGetAttribute(Display *display, XvMCContext *context, Atom attribute, int *value) { i810XvMCContext *pI810XvMC; if(display == NULL) { return BadValue; } if(context == NULL) { return (error_base + XvMCBadContext); } pI810XvMC = context->privData; if(pI810XvMC == NULL) { return (error_base + XvMCBadContext); } if(value == NULL) { return BadValue; } if(attribute == pI810XvMC->xv_colorkey) { *value = pI810XvMC->colorkey; return Success; } if(attribute == pI810XvMC->xv_brightness) { *value = pI810XvMC->brightness; return Success; } if(attribute == pI810XvMC->xv_saturation) { *value = pI810XvMC->saturation; return Success; } if(attribute == pI810XvMC->xv_contrast) { *value = pI810XvMC->contrast; return Success; } return BadValue; } xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/xvmc/I810XvMC.h000066400000000000000000000330371267532330400253220ustar00rootroot00000000000000/*************************************************************************** Copyright 2001 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /*************************************************************************** * libI810XvMC.h: MC Driver i810 includes * * Authors: * Matt Sottek * * ***************************************************************************/ #ifndef I810XVMC_H #define I810XVMC_H /* #define XVMC_DEBUG(x) do {x; }while(0); */ #define XVMC_DEBUG(x) #include #include "xf86drm.h" #include "../i810_common.h" #include /*************************************************************************** // i810OverlayRec: Structure that is used to reference the overlay // register memory. A i810OverlayRecPtr is set to the address of the // allocated overlay registers. ***************************************************************************/ typedef struct _i810OverlayRec { unsigned int OBUF_0Y; unsigned int OBUF_1Y; unsigned int OBUF_0U; unsigned int OBUF_0V; unsigned int OBUF_1U; unsigned int OBUF_1V; unsigned int OV0STRIDE; unsigned int YRGB_VPH; unsigned int UV_VPH; unsigned int HORZ_PH; unsigned int INIT_PH; unsigned int DWINPOS; unsigned int DWINSZ; unsigned int SWID; unsigned int SWIDQW; unsigned int SHEIGHT; unsigned int YRGBSCALE; unsigned int UVSCALE; unsigned int OV0CLRC0; unsigned int OV0CLRC1; unsigned int DCLRKV; unsigned int DCLRKM; unsigned int SCLRKVH; unsigned int SCLRKVL; unsigned int SCLRKM; unsigned int OV0CONF; unsigned int OV0CMD; } i810OverlayRec, *i810OverlayRecPtr; /*************************************************************************** // i810XvMCDrmMap: Holds the data about the DRM maps ***************************************************************************/ typedef struct _i810XvMCDrmMap { drm_handle_t offset; drmAddress address; unsigned int size; } i810XvMCDrmMap, *i810XvMCDrmMapPtr; /*************************************************************************** // i810XvMCContext: Private Context data referenced via the privData // pointer in the XvMCContext structure. ***************************************************************************/ typedef struct _i810XvMCContext { int fd; /* File descriptor for /dev/dri */ i810XvMCDrmMap overlay; i810XvMCDrmMap surfaces; drmBufMapPtr dmabufs; /* Data structure to hold available dma buffers */ drm_context_t drmcontext; unsigned int last_render; unsigned int last_flip; unsigned short ref; unsigned short current; int lock; /* Lightweight lock to avoid locking twice */ char busIdString[10]; /* PCI:0:1:0 or PCI:0:2:0 */ i810OverlayRecPtr oregs; unsigned int dual_prime; /* Flag to identify when dual prime is in use. */ unsigned int fb_base; Atom xv_colorkey; Atom xv_brightness; Atom xv_contrast; Atom xv_saturation; int brightness; int saturation; int contrast; int colorkey; } i810XvMCContext; /*************************************************************************** // i810XvMCSurface: Private data structure for each XvMCSurface. This // structure is referenced by the privData pointer in the XvMCSurface // structure. ***************************************************************************/ typedef struct _i810XvMCSurface { unsigned int pitch; unsigned int dbi1y; /* Destination buffer info command word 1 for Y */ unsigned int dbi1u; /* Destination buffer info command word 1 for U */ unsigned int dbi1v; /* Destination buffer info command word 1 for V */ unsigned int dbv1; /* Destination buffer variables command word 1 */ unsigned int mi1y; /* Map Info command word 1 (Minus bit 28) for Y */ unsigned int mi1u; /* Map Info command word 1 (Minus bit 28) for U */ unsigned int mi1v; /* Map Info command word 1 (Minus bit 28) for V */ unsigned int mi2y; /* Map info command word 2 for y */ unsigned int mi2u; /* Map info command word 2 for y */ unsigned int mi2v; /* Map info command word 2 for y */ unsigned int mi3y; /* Map info command word 3 */ unsigned int mi3u; /* Map info command word 3 */ unsigned int mi3v; /* Map info command word 3 */ unsigned int last_render; unsigned int last_flip; unsigned int second_field; /* Flags a surface that is only half done */ drmAddress data; drm_handle_t offset; unsigned int offsets[3]; i810XvMCContext *privContext; } i810XvMCSurface; /*************************************************************************** // i810XvMCSubpicture: Private data structure for each XvMCSubpicture. This // structure is referenced by the privData pointer in the XvMCSubpicture // structure. ***************************************************************************/ typedef struct _i810XvMCSubpicture { unsigned int pitch; unsigned int dbi1; /* Destination buffer info command word 1 */ unsigned int dbv1; /* Destination buffer variables command word */ unsigned int mi1; /* Map Info command word 1 (Minus bit 28) */ unsigned int mi2; /* Map info command word 2 */ unsigned int mi3; /* Map info command word 3 */ unsigned int last_render; unsigned int last_flip; drmAddress data; drm_handle_t offset; unsigned int offsets[1]; unsigned char palette[3][16]; i810XvMCContext *privContext; } i810XvMCSubpicture; typedef struct _Box { int x1,y1,x2,y2; } Box, *BoxPtr; /*************************************************************************** // drm_i810_overlay_t: Structure returned by overlay info ioctl. // NOTE: If you change this structure you will have to change the equiv. // structure in the kernel. ***************************************************************************/ typedef struct _drm_i810_overlay_t { unsigned int offset; unsigned int physical; } drm_i810_overlay_t; /*************************************************************************** // drm_i810_dma_t: Structure used by dma allocation ioctl. // NOTE: If you change this structure you will have to change the equiv. // structure in the kernel. ***************************************************************************/ typedef struct _drm_i810_dma { void *virtual; int request_idx; int request_size; int granted; } drm_i810_dma_t; /*************************************************************************** // drm_i810_mc_t: Structure used by mc dispatch ioctl. // NOTE: If you change this structure you will have to change the equiv. // structure in the kernel. ***************************************************************************/ typedef struct _drm_i810_mc { int idx; /* buffer index */ int used; /* nr bytes in use */ int num_blocks; /* number of GFXBlocks */ int *length; /* List of lengths for GFXBlocks */ unsigned int last_render; /* Last render request */ } drm_i810_mc_t; /* Subpicture fourcc */ #define FOURCC_IA44 0x34344149 /* Static Parameters */ #define I810_XVMC_MAXWIDTH 720 #define I810_XVMC_MAXHEIGHT 576 #define I810_DEFAULT16_COLORKEY 31 #define I810_DMA_BUF_NR 256 /* COMMANDS */ #define CMD_FLUSH ((4<<23) | 0x1) #define BOOLEAN_ENA_1 ((3<<29) | (3<<24) | (3<<2)) #define BOOLEAN_ENA_2 ((3<<29) | (4<<24) | (3<<16) | (1<<3) | (1<<2)) #define DEST_BUFFER_INFO (0x15<<23) #define DEST_BUFFER_VAR ((0x3<<29) | (0x1d<<24) | (0x85<<16)) #define DRAWING_RECT_INFO ((3<<29) | (0x1d<<24) | (0x80<<16) | 3) #define GFXBLOCK ((0x3<<29) | (0x1e<<24)) #define CMD_MAP_INFO ((0x3<<29) | (0x1d<<24) | 0x2) #define MAP_PALETTE_LOAD ((3<<29) | (0x1d<<24) | (0x82<<16) | 0xff) #define VERTEX_FORMAT ((3<<29) | (0x5<<24)) #define SRC_DEST_BLEND_MONO ((3<<29) | (8<<24)) /* Bit Patterns */ /* * OV0CMD - Overlay Command Register */ #define VERTICAL_CHROMINANCE_FILTER 0x70000000 #define VC_SCALING_OFF 0x00000000 #define VC_LINE_REPLICATION 0x10000000 #define VC_UP_INTERPOLATION 0x20000000 #define VC_PIXEL_DROPPING 0x50000000 #define VC_DOWN_INTERPOLATION 0x60000000 #define VERTICAL_LUMINANCE_FILTER 0x0E000000 #define VL_SCALING_OFF 0x00000000 #define VL_LINE_REPLICATION 0x02000000 #define VL_UP_INTERPOLATION 0x04000000 #define VL_PIXEL_DROPPING 0x0A000000 #define VL_DOWN_INTERPOLATION 0x0C000000 #define HORIZONTAL_CHROMINANCE_FILTER 0x01C00000 #define HC_SCALING_OFF 0x00000000 #define HC_LINE_REPLICATION 0x00400000 #define HC_UP_INTERPOLATION 0x00800000 #define HC_PIXEL_DROPPING 0x01400000 #define HC_DOWN_INTERPOLATION 0x01800000 #define HORIZONTAL_LUMINANCE_FILTER 0x00380000 #define HL_SCALING_OFF 0x00000000 #define HL_LINE_REPLICATION 0x00080000 #define HL_UP_INTERPOLATION 0x00100000 #define HL_PIXEL_DROPPING 0x00280000 #define HL_DOWN_INTERPOLATION 0x00300000 #define Y_ADJUST 0x00010000 #define OV_BYTE_ORDER 0x0000C000 #define UV_SWAP 0x00004000 #define Y_SWAP 0x00008000 #define Y_AND_UV_SWAP 0x0000C000 #define SOURCE_FORMAT 0x00003C00 #define RGB_555 0x00000800 #define RGB_565 0x00000C00 #define YUV_422 0x00002000 #define YUV_411 0x00002400 #define YUV_420 0x00003000 #define YUV_410 0x00003800 #define VERTICAL_PHASE_BOTH 0x00000020 #define FLIP_TYPE_FIELD 0x00000020 #define FLIP_TYPE_FRAME 0x00000000 #define BUFFER_AND_FIELD 0x00000006 #define BUFFER0_FIELD0 0x00000000 #define BUFFER0_FIELD1 0x00000002 #define BUFFER1_FIELD0 0x00000004 #define BUFFER1_FIELD1 0x00000006 #define OVERLAY_ENABLE 0x00000001 /* * DOV0STA - Display/Overlay 0 Status Register */ #define DOV0STA 0x30008 #define OV0ADD 0x30000 #define MINUV_SCALE 0x1 #define RGB16ToColorKey(c) \ (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) /* Locking Macros lightweight lock used to prevent relocking */ #define I810_LOCK(c,f) \ if(!c->lock) { \ drmGetLock(c->fd, c->drmcontext, f); \ } \ c->lock++; #define I810_UNLOCK(c) \ c->lock--; \ if(!c->lock) { \ drmUnlock(c->fd, c->drmcontext); \ } /* Block until the passed in value (n) is the active buffer on the overlay. */ #define BLOCK_OVERLAY(c,n) \ do { \ int temp,i=0; \ while(i < 100000) { \ temp = GET_FSTATUS(c); \ if(((temp & (1<<20))>>20) == n) { \ break; \ } \ usleep(10); \ } \ if(i == 100000) { \ printf("Overlay Lockup.\n"); \ return BadAlloc; \ } \ }while(0); #define OVERLAY_INFO(c,i) drmCommandRead(c->fd, DRM_I810_OV0INFO, &i, sizeof(i)) #define OVERLAY_FLIP(c) drmCommandNone(c->fd, DRM_I810_OV0FLIP) #define GET_FSTATUS(c) drmCommandNone(c->fd, DRM_I810_FSTATUS) #define I810_MC(c,mc) drmCommandWrite(c->fd, DRM_I810_MC, &mc, sizeof(mc)) #define GET_RSTATUS(c) drmCommandNone(c->fd, DRM_I810_RSTATUS) #define GET_BUFFER(c,dma) drmCommandWriteRead(c->fd, DRM_I810_GETBUF, &dma, sizeof(drmI810DMA)) #define FLUSH(c) drmCommandNone(c->fd, DRM_I810_FLUSH) /* Definitions for temporary wire protocol hooks to be replaced when a HW independent libXvMC is created. */ 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); /* Prototypes */ drmBufPtr i810_get_free_buffer(i810XvMCContext *pI810XvMC); void i810_free_privContext(i810XvMCContext *pI810XvMC); void dp(unsigned int *address, unsigned int i); #endif xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/i810/xvmc/Makefile.am000066400000000000000000000004561267532330400260250ustar00rootroot00000000000000if XVMC lib_LTLIBRARIES=libI810XvMC.la endif libI810XvMC_la_SOURCES = I810XvMC.c \ I810XvMC.h AM_CFLAGS = $(CWARNFLAGS) $(XORG_CFLAGS) $(DRM_CFLAGS) $(DRI1_CFLAGS) -DTRUE=1 -DFALSE=0 libI810XvMC_la_LDFLAGS = -version-number 1:0:0 libI810XvMC_la_LIBADD = $(DRI1_LIBS) $(DRM_LIBS) $(XVMCLIB_LIBS) xserver-xorg-video-intel-2.99.917+git20160325/src/legacy/legacy.h000066400000000000000000000002161267532330400237420ustar00rootroot00000000000000/* The old i810 (only) driver. */ const OptionInfoRec *lg_i810_available_options(int chipid, int busid); Bool lg_i810_init(ScrnInfoPtr scrn); xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/000077500000000000000000000000001267532330400240705ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/Makefile.am000066400000000000000000000131061267532330400261250ustar00rootroot00000000000000INTEL_G4A = \ exa_sf.g4a \ exa_sf_mask.g4a \ exa_wm_src_affine.g4a \ exa_wm_src_projective.g4a \ exa_wm_src_sample_argb.g4a \ exa_wm_src_sample_a.g4a \ exa_wm_src_sample_planar.g4a \ exa_wm_mask_affine.g4a \ exa_wm_mask_projective.g4a \ exa_wm_mask_sample_argb.g4a \ exa_wm_mask_sample_a.g4a \ exa_wm_noca.g4a \ exa_wm_ca.g4a \ exa_wm_ca_srcalpha.g4a \ exa_wm_write.g4a \ exa_wm_yuv_rgb.g4a \ exa_wm_xy.g4a \ $(NULL) INTEL_G4I = \ exa_wm.g4i \ exa_wm_affine.g4i \ exa_wm_projective.g4i \ exa_wm_sample_planar.g4i \ exa_wm_src_sample_argb.g4i \ $(NULL) INTEL_G4B = \ exa_sf.g4b \ exa_sf_mask.g4b \ exa_wm_src_affine.g4b \ exa_wm_src_projective.g4b \ exa_wm_src_sample_argb.g4b \ exa_wm_src_sample_a.g4b \ exa_wm_src_sample_planar.g4b \ exa_wm_mask_affine.g4b \ exa_wm_mask_projective.g4b \ exa_wm_mask_sample_argb.g4b \ exa_wm_mask_sample_a.g4b \ exa_wm_noca.g4b \ exa_wm_ca.g4b \ exa_wm_ca_srcalpha.g4b \ exa_wm_write.g4b \ exa_wm_yuv_rgb.g4b \ exa_wm_xy.g4b \ $(NULL) INTEL_G4B_GEN5 = \ exa_sf.g4b.gen5 \ exa_sf_mask.g4b.gen5 \ exa_wm_src_affine.g4b.gen5 \ exa_wm_src_projective.g4b.gen5 \ exa_wm_src_sample_argb.g4b.gen5 \ exa_wm_src_sample_a.g4b.gen5 \ exa_wm_src_sample_planar.g4b.gen5 \ exa_wm_mask_affine.g4b.gen5 \ exa_wm_mask_projective.g4b.gen5 \ exa_wm_mask_sample_argb.g4b.gen5 \ exa_wm_mask_sample_a.g4b.gen5 \ exa_wm_noca.g4b.gen5 \ exa_wm_ca.g4b.gen5 \ exa_wm_ca_srcalpha.g4b.gen5 \ exa_wm_write.g4b.gen5 \ exa_wm_yuv_rgb.g4b.gen5 \ exa_wm_xy.g4b.gen5 \ $(NULL) INTEL_G5A = \ exa_sf.g5a \ exa_sf_mask.g5a \ exa_wm_src_affine.g5a \ exa_wm_src_projective.g5a \ exa_wm_src_sample_argb.g5a \ exa_wm_src_sample_a.g5a \ exa_wm_src_sample_planar.g5a \ exa_wm_mask_affine.g5a \ exa_wm_mask_projective.g5a \ exa_wm_mask_sample_argb.g5a \ exa_wm_mask_sample_a.g5a \ exa_wm_noca.g5a \ exa_wm_ca.g5a \ exa_wm_ca_srcalpha.g5a \ exa_wm_write.g5a \ exa_wm_yuv_rgb.g5a \ exa_wm_xy.g5a \ $(NULL) INTEL_G5B = \ exa_sf.g5b \ exa_sf_mask.g5b \ exa_wm_src_affine.g5b \ exa_wm_src_projective.g5b \ exa_wm_src_sample_argb.g5b \ exa_wm_src_sample_a.g5b \ exa_wm_src_sample_planar.g5b \ exa_wm_mask_affine.g5b \ exa_wm_mask_projective.g5b \ exa_wm_mask_sample_argb.g5b \ exa_wm_mask_sample_a.g5b \ exa_wm_noca.g5b \ exa_wm_ca.g5b \ exa_wm_ca_srcalpha.g5b \ exa_wm_write.g5b \ exa_wm_yuv_rgb.g5b \ exa_wm_xy.g5b \ $(NULL) INTEL_G6I = \ exa_wm_affine.g6i \ exa_wm_write.g6i \ $(NULL) INTEL_G6A = \ exa_wm_src_affine.g6a \ exa_wm_src_projective.g6a \ exa_wm_src_sample_argb.g6a \ exa_wm_src_sample_planar.g6a \ exa_wm_src_sample_a.g6a \ exa_wm_mask_affine.g6a \ exa_wm_mask_projective.g6a \ exa_wm_mask_sample_argb.g6a \ exa_wm_mask_sample_a.g6a \ exa_wm_ca.g6a \ exa_wm_ca_srcalpha.g6a \ exa_wm_noca.g6a \ exa_wm_write.g6a \ exa_wm_yuv_rgb.g6a \ $(NULL) INTEL_G6B = \ exa_wm_src_affine.g6b \ exa_wm_src_projective.g6b \ exa_wm_src_sample_argb.g6b \ exa_wm_src_sample_planar.g6b \ exa_wm_src_sample_a.g6b \ exa_wm_mask_affine.g6b \ exa_wm_mask_projective.g6b \ exa_wm_mask_sample_argb.g6b \ exa_wm_mask_sample_a.g6b \ exa_wm_ca.g6b \ exa_wm_ca_srcalpha.g6b \ exa_wm_noca.g6b \ exa_wm_write.g6b \ exa_wm_yuv_rgb.g6b \ $(NULL) INTEL_G7A = \ exa_wm_mask_affine.g7a \ exa_wm_mask_projective.g7a \ exa_wm_mask_sample_a.g7a \ exa_wm_mask_sample_argb.g7a \ exa_wm_src_affine.g7a \ exa_wm_src_projective.g7a \ exa_wm_src_sample_a.g7a \ exa_wm_src_sample_argb.g7a \ exa_wm_src_sample_planar.g7a \ exa_wm_write.g7a \ exa_wm_yuv_rgb.g7a \ $(NULL) INTEL_G7B = \ exa_wm_mask_affine.g7b \ exa_wm_mask_projective.g7b \ exa_wm_mask_sample_a.g7b \ exa_wm_mask_sample_argb.g7b \ exa_wm_src_affine.g7b \ exa_wm_src_projective.g7b \ exa_wm_src_sample_a.g7b \ exa_wm_src_sample_argb.g7b \ exa_wm_src_sample_planar.g7b \ exa_wm_write.g7b \ exa_wm_yuv_rgb.g7b \ $(NULL) INTEL_G8A = \ exa_wm_src_affine.g8a \ exa_wm_src_sample_argb.g8a \ exa_wm_src_sample_planar.g8a \ exa_wm_write.g8a \ exa_wm_yuv_rgb.g8a \ $(NULL) INTEL_G8B = \ exa_wm_src_affine.g8b \ exa_wm_src_sample_argb.g8b \ exa_wm_src_sample_planar.g8b \ exa_wm_write.g8b \ exa_wm_yuv_rgb.g8b \ $(NULL) EXTRA_DIST = \ $(INTEL_G4A) \ $(INTEL_G4I) \ $(INTEL_G4B) \ $(INTEL_G4B_GEN5)\ $(INTEL_G5A) \ $(INTEL_G5B) \ $(INTEL_G6A) \ $(INTEL_G6B) \ $(INTEL_G6I) \ $(INTEL_G7A) \ $(INTEL_G7B) \ $(INTEL_G8A) \ $(INTEL_G8B) if HAVE_GEN4ASM SUFFIXES = .g4a .g4b .g5a .g5b .g6a .g6b .g7a .g7b .g8b .g4a.g4b: $(AM_V_GEN)m4 -I$(srcdir) -s $< > $*.g4m && @INTEL_GEN4ASM@ -o $@ $*.g4m && @INTEL_GEN4ASM@ -g 5 -o $@.gen5 $*.g4m && rm $*.g4m .g5a.g5b: $(AM_V_GEN)m4 -I$(srcdir) -s $< > $*.g5m && @INTEL_GEN4ASM@ -g 5 -o $@ $*.g5m && rm $*.g5m .g6a.g6b: $(AM_V_GEN)m4 -I$(srcdir) -s $< > $*.g6m && @INTEL_GEN4ASM@ -g 6 -o $@ $*.g6m && rm $*.g6m .g7a.g7b: $(AM_V_GEN)m4 -I$(srcdir) -s $< > $*.g7m && @INTEL_GEN4ASM@ -g 7 -o $@ $*.g7m && rm $*.g7m .g8a.g8b: $(AM_V_GEN)m4 -I$(srcdir) -s $< > $*.g8m && @INTEL_GEN4ASM@ -g 8 -o $@ $*.g8m && rm $*.g8m $(INTEL_G4B): $(INTEL_GEN4ASM) $(INTEL_G4I) $(INTEL_G5B): $(INTEL_GEN4ASM) $(INTEL_G4I) $(INTEL_G6B): $(INTEL_GEN4ASM) $(INTEL_G4I) $(INTEL_G6I) $(INTEL_G7B): $(INTEL_GEN4ASM) $(INTEL_G4I) $(INTEL_G6I) $(INTEL_G8B): $(INTEL_GEN4ASM) $(INTEL_G4I) $(INTEL_G6I) BUILT_SOURCES=$(INTEL_G4B) $(INTEL_G4B_GEN5) $(INTEL_G5B) $(INTEL_G6B) $(INTEL_G7B) $(INTEL_G8B) clean-local: -rm -f $(BUILT_SOURCES) endif xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf.g4a000066400000000000000000000057321267532330400257410ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * */ /* * Inputs (note all sub-register addresses are bytes, not float indices) * * Note that the vertices will have been reordered: * * V0 is topmost (leftmost among topmost) (upper left) * V1 is next clockwise (lower right) * V2 is remaining (lower left) * * V0 ...................... XX * | . * | . * | . * V2------------------------V1 * * G0 thread state -- just pass along * * G1 and G2 are fixed by SF spec * * G1.0 reserved * G1.4 Provoking vertex * G1.8 Determinant * G1.12 X1 - X0 * G1.16 X2 - X0 * G1.20 Y1 - Y0 * G1.24 Y2 - Y0 * G1.30 reserved * * G2.0 Z0 * G2.4 1/W0 * G2.8 Z1 * G2.12 1/W1 * G2.16 Z2 * G2.20 1/W2 * G2.24 reserved * G2.30 reserved * * G3 is V0 Vertex Attribute Data from URB (upper left) * * G3.0 u0 * G3.4 v0 * * G4 is V1 Vertex Attribute Data from URB (lower right) * * G4.0 u1 * G4.4 v1 * * G5 is V2 Vertex Attribute Data from URB (lower left) * */ /* Compute inverses of the input deltas */ send (4) 0 g6<1>F g1.12<4,4,1>F math inv mlen 1 rlen 1 { align1 }; /* texture location at V0 */ mov (4) m3<1>F g3<4,4,1>F { align1 }; /* compute V1 - V2 (motion in X) for texture coordinates */ add (4) g7<1>F g4<4,4,1>F -g5<4,4,1>F { align1 }; /* multiply by 1/dx */ mul (4) m1<1>F g7<4,4,1>F g6.0<0,1,0>F { align1 }; /* Compute V2 - V0 (motion in Y) for texture coordinates */ add (4) g7<1>F g5<4,4,1>F -g3<4,4,1>F { align1 }; /* multiply by 1/dy */ mul (4) m2<1>F g7<4,4,1>F g6.8<0,1,0>F {align1 }; /* and we're done */ send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT }; nop; nop; nop; nop; nop; nop; nop; nop; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf.g4b000066400000000000000000000014711267532330400257360ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x0069002c, 0x01110001 }, { 0x00400001, 0x206003be, 0x00690060, 0x00000000 }, { 0x00400040, 0x20e077bd, 0x00690080, 0x006940a0 }, { 0x00400041, 0x202077be, 0x006900e0, 0x000000c0 }, { 0x00400040, 0x20e077bd, 0x006900a0, 0x00694060 }, { 0x00400041, 0x204077be, 0x006900e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf.g4b.gen5000066400000000000000000000014711267532330400265730ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x1069002c, 0x02100001 }, { 0x00400001, 0x206003be, 0x00690060, 0x00000000 }, { 0x00400040, 0x20e077bd, 0x00690080, 0x006940a0 }, { 0x00400041, 0x202077be, 0x006900e0, 0x000000c0 }, { 0x00400040, 0x20e077bd, 0x006900a0, 0x00694060 }, { 0x00400041, 0x204077be, 0x006900e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x648d0000, 0x8808c800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf.g5a000066400000000000000000000056621267532330400257440ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * */ /* * Inputs (note all sub-register addresses are bytes, not float indices) * * Note that the vertices will have been reordered: * * V0 is topmost (leftmost among topmost) (upper left) * V1 is next clockwise (lower right) * V2 is remaining (lower left) * * V0 ...................... XX * | . * | . * | . * V2------------------------V1 * * G0 thread state -- just pass along * * G1 and G2 are fixed by SF spec * * G1.0 reserved * G1.4 Provoking vertex * G1.8 Determinant * G1.12 X1 - X0 * G1.16 X2 - X0 * G1.20 Y1 - Y0 * G1.24 Y2 - Y0 * G1.30 reserved * * G2.0 Z0 * G2.4 1/W0 * G2.8 Z1 * G2.12 1/W1 * G2.16 Z2 * G2.20 1/W2 * G2.24 reserved * G2.30 reserved * * G3 is V0 Vertex Attribute Data from URB (upper left) * * G3.0 u0 * G3.4 v0 * * G4 is V1 Vertex Attribute Data from URB (lower right) * * G4.0 u1 * G4.4 v1 * * G5 is V2 Vertex Attribute Data from URB (lower left) * */ /* Compute inverses of the input deltas */ send (4) 0 g6<1>F g1.12<4,4,1>F math inv mlen 1 rlen 1 { align1 }; /* texture location at V0 */ mov (4) m3<1>F g3<4,4,1>F { align1 }; /* compute V1 - V2 (motion in X) for texture coordinates */ add (4) g7<1>F g4<4,4,1>F -g5<4,4,1>F { align1 }; /* multiply by 1/dx */ mul (4) m1<1>F g7<4,4,1>F g6.0<0,1,0>F { align1 }; /* Compute V2 - V0 (motion in Y) for texture coordinates */ add (4) g7<1>F g5<4,4,1>F -g3<4,4,1>F { align1 }; /* multiply by 1/dy */ mul (4) m2<1>F g7<4,4,1>F g6.8<0,1,0>F {align1 }; /* and we're done */ send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf.g5b000066400000000000000000000006011267532330400257310ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x1069002c, 0x02100001 }, { 0x00400001, 0x206003be, 0x00690060, 0x00000000 }, { 0x00400040, 0x20e077bd, 0x00690080, 0x006940a0 }, { 0x00400041, 0x202077be, 0x006900e0, 0x000000c0 }, { 0x00400040, 0x20e077bd, 0x006900a0, 0x00694060 }, { 0x00400041, 0x204077be, 0x006900e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x648d0000, 0x8808c800 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf_mask.g4a000066400000000000000000000060031267532330400267440ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * Wang Zhenyu */ /* * Inputs (note all sub-register addresses are bytes, not float indices) * * Note that the vertices will have been reordered: * * V0 is topmost (leftmost among topmost) (upper left) * V1 is next clockwise (lower right) * V2 is remaining (lower left) * * V0 ...................... XX * | . * | . * | . * V2------------------------V1 * * G0 thread state -- just pass along * * G1 and G2 are fixed by SF spec * * G1.0 reserved * G1.4 Provoking vertex * G1.8 Determinant * G1.12 X1 - X0 * G1.16 X2 - X0 * G1.20 Y1 - Y0 * G1.24 Y2 - Y0 * G1.30 reserved * * G2.0 Z0 * G2.4 1/W0 * G2.8 Z1 * G2.12 1/W1 * G2.16 Z2 * G2.20 1/W2 * G2.24 reserved * G2.30 reserved * * G3 is V0 Vertex Attribute Data from URB (upper left) * * G3.0 u0 * G3.4 v0 * * G4 is V1 Vertex Attribute Data from URB (lower right) * * G4.0 u1 * G4.4 v1 * * G5 is V2 Vertex Attribute Data from URB (lower left) * */ /* Compute inverses of the input deltas */ send (4) 0 g6<1>F g1.12<4,4,1>F math inv mlen 1 rlen 1 { align1 }; /* texture location at V0 */ mov (8) m3<1>F g3<8,8,1>F { align1 }; /* compute V1 - V2 (motion in X) for texture coordinates */ add (8) g7<1>F g4<8,8,1>F -g5<8,8,1>F { align1 }; /* multiply by 1/dx */ mul (8) m1<1>F g7<8,8,1>F g6.0<0,1,0>F { align1 }; /* Compute V2 - V0 (motion in Y) for texture coordinates */ add (8) g7<1>F g5<8,8,1>F -g3<8,8,1>F { align1 }; /* multiply by 1/dy */ mul (8) m2<1>F g7<8,8,1>F g6.8<0,1,0>F {align1 }; /* and we're done */ send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT }; nop; nop; nop; nop; nop; nop; nop; nop; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf_mask.g4b000066400000000000000000000014711267532330400267510ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x0069002c, 0x01110001 }, { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 }, { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d40a0 }, { 0x00600041, 0x202077be, 0x008d00e0, 0x000000c0 }, { 0x00600040, 0x20e077bd, 0x008d00a0, 0x008d4060 }, { 0x00600041, 0x204077be, 0x008d00e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x008d0000, 0x8640c800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf_mask.g4b.gen5000066400000000000000000000014711267532330400276060ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x1069002c, 0x02100001 }, { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 }, { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d40a0 }, { 0x00600041, 0x202077be, 0x008d00e0, 0x000000c0 }, { 0x00600040, 0x20e077bd, 0x008d00a0, 0x008d4060 }, { 0x00600041, 0x204077be, 0x008d00e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x648d0000, 0x8808c800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf_mask.g5a000066400000000000000000000057331267532330400267560ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * Wang Zhenyu */ /* * Inputs (note all sub-register addresses are bytes, not float indices) * * Note that the vertices will have been reordered: * * V0 is topmost (leftmost among topmost) (upper left) * V1 is next clockwise (lower right) * V2 is remaining (lower left) * * V0 ...................... XX * | . * | . * | . * V2------------------------V1 * * G0 thread state -- just pass along * * G1 and G2 are fixed by SF spec * * G1.0 reserved * G1.4 Provoking vertex * G1.8 Determinant * G1.12 X1 - X0 * G1.16 X2 - X0 * G1.20 Y1 - Y0 * G1.24 Y2 - Y0 * G1.30 reserved * * G2.0 Z0 * G2.4 1/W0 * G2.8 Z1 * G2.12 1/W1 * G2.16 Z2 * G2.20 1/W2 * G2.24 reserved * G2.30 reserved * * G3 is V0 Vertex Attribute Data from URB (upper left) * * G3.0 u0 * G3.4 v0 * * G4 is V1 Vertex Attribute Data from URB (lower right) * * G4.0 u1 * G4.4 v1 * * G5 is V2 Vertex Attribute Data from URB (lower left) * */ /* Compute inverses of the input deltas */ send (4) 0 g6<1>F g1.12<4,4,1>F math inv mlen 1 rlen 1 { align1 }; /* texture location at V0 */ mov (8) m3<1>F g3<8,8,1>F { align1 }; /* compute V1 - V2 (motion in X) for texture coordinates */ add (8) g7<1>F g4<8,8,1>F -g5<8,8,1>F { align1 }; /* multiply by 1/dx */ mul (8) m1<1>F g7<8,8,1>F g6.0<0,1,0>F { align1 }; /* Compute V2 - V0 (motion in Y) for texture coordinates */ add (8) g7<1>F g5<8,8,1>F -g3<8,8,1>F { align1 }; /* multiply by 1/dy */ mul (8) m2<1>F g7<8,8,1>F g6.8<0,1,0>F {align1 }; /* and we're done */ send (8) 0 null g0<8,8,1>F urb 0 transpose used complete mlen 4 rlen 0 { align1 EOT }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_sf_mask.g5b000066400000000000000000000006011267532330400267440ustar00rootroot00000000000000 { 0x00400031, 0x20c01fbd, 0x1069002c, 0x02100001 }, { 0x00600001, 0x206003be, 0x008d0060, 0x00000000 }, { 0x00600040, 0x20e077bd, 0x008d0080, 0x008d40a0 }, { 0x00600041, 0x202077be, 0x008d00e0, 0x000000c0 }, { 0x00600040, 0x20e077bd, 0x008d00a0, 0x008d4060 }, { 0x00600041, 0x204077be, 0x008d00e0, 0x000000c8 }, { 0x00600031, 0x20001fbc, 0x648d0000, 0x8808c800 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm.g4i000066400000000000000000000110411267532330400257520ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Input parameters */ /* Destination X/Y */ define(`dst_x_uw', `g1.8<2,4,0>UW') define(`dst_y_uw', `g1.10<2,4,0>UW') define(`screen_x0', `g1.0<0,1,0>F') define(`screen_y0', `g1.4<0,1,0>F') /* Source transformation parameters */ define(`src_du_dx', `g3.0<0,1,0>F') define(`src_du_dy', `g3.4<0,1,0>F') define(`src_uo', `g3.12<0,1,0>F') define(`src_dv_dx', `g3.16<0,1,0>F') define(`src_dv_dy', `g3.20<0,1,0>F') define(`src_vo', `g3.28<0,1,0>F') define(`src_dw_dx', `g4.0<0,1,0>F') define(`src_dw_dy', `g4.4<0,1,0>F') define(`src_wo', `g4.12<0,1,0>F') define(`mask_du_dx', `g5.0<0,1,0>F') define(`mask_du_dy', `g5.4<0,1,0>F') define(`mask_uo', `g5.12<0,1,0>F') define(`mask_dv_dx', `g5.16<0,1,0>F') define(`mask_dv_dy', `g5.20<0,1,0>F') define(`mask_vo', `g5.28<0,1,0>F') define(`mask_dw_dx', `g6.0<0,1,0>F') define(`mask_dw_dy', `g6.4<0,1,0>F') define(`mask_wo', `g6.12<0,1,0>F') /* * Local variables. Pairs must be aligned on even reg boundary */ /* this holds the X dest coordinates */ define(`dst_x', `g8') define(`dst_x_0', `dst_x') define(`dst_x_1', `g9') /* this holds the Y dest coordinates */ define(`dst_y', `g10') define(`dst_y_0', `dst_y') define(`dst_y_1', `g11') /* When computing x * dn/dx, use this */ define(`temp_x', `g30') define(`temp_x_0', `temp_x') define(`temp_x_1', `g31') /* When computing y * dn/dy, use this */ define(`temp_y', `g28') define(`temp_y_0', temp_y) define(`temp_y_1', `g29') /* when loading x/y, use these to hold them in UW format */ define(`temp_x_uw', temp_x) define(`temp_y_uw', temp_y) /* compute source and mask u/v to this pair to send to sampler */ define(`src_msg', `m1') define(`src_msg_ind',`1') define(`src_u', `m2') define(`src_v', `m4') define(`src_w', `g12') define(`src_w_0', `src_w') define(`src_w_1', `g13') define(`mask_msg', `m7') define(`mask_msg_ind',`7') define(`mask_u', `m8') define(`mask_v', `m10') define(`mask_w', `src_w') define(`mask_w_0', `src_w_0') define(`mask_w_1', `src_w_1') /* sample src to these registers */ define(`src_sample_base', `g14') define(`src_sample_r', `g14') define(`src_sample_r_01', `g14') define(`src_sample_r_23', `g15') define(`src_sample_g', `g16') define(`src_sample_g_01', `g16') define(`src_sample_g_23', `g17') define(`src_sample_b', `g18') define(`src_sample_b_01', `g18') define(`src_sample_b_23', `g19') define(`src_sample_a', `g20') define(`src_sample_a_01', `g20') define(`src_sample_a_23', `g21') /* sample mask to these registers */ define(`mask_sample_base', `g22') define(`mask_sample_r', `g22') define(`mask_sample_r_01', `g22') define(`mask_sample_r_23', `g23') define(`mask_sample_g', `g24') define(`mask_sample_g_01', `g24') define(`mask_sample_g_23', `g25') define(`mask_sample_b', `g26') define(`mask_sample_b_01', `g26') define(`mask_sample_b_23', `g27') define(`mask_sample_a', `g28') define(`mask_sample_a_01', `g28') define(`mask_sample_a_23', `g29') /* data port SIMD16 send registers */ define(`data_port_msg_0', `m0') define(`data_port_msg_0_ind', `0') define(`data_port_msg_1', `m1') define(`data_port_r_01', `m2') define(`data_port_g_01', `m3') define(`data_port_b_01', `m4') define(`data_port_a_01', `m5') define(`data_port_r_23', `m6') define(`data_port_g_23', `m7') define(`data_port_b_23', `m8') define(`data_port_a_23', `m9') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_affine.g4i000066400000000000000000000035331267532330400272710ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Fragment to compute src u/v values under an affine transform */ /********** Compute u *************/ mul (16) temp_x<1>F dst_x<8,8,1>F du_dx { compr align1 }; mul (16) temp_y<1>F dst_y<8,8,1>F du_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) u<1>F temp_x<8,8,1>F uo { compr align1 }; /********** Compute v *************/ mul (16) temp_x<1>F dst_x<8,8,1>F dv_dx { compr align1 }; mul (16) temp_y<1>F dst_y<8,8,1>F dv_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) v<1>F temp_x<8,8,1>F vo { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_affine.g6i000066400000000000000000000026421267532330400272730ustar00rootroot00000000000000/* * Copyright © 2010-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ /* U */ pln (8) ul<1>F a0_a_x bl { align1 }; /* pixel 0-7 */ pln (8) uh<1>F a0_a_x bh { align1 }; /* pixel 8-15 */ /* V */ pln (8) vl<1>F a0_a_y bl { align1 }; /* pixel 0-7 */ pln (8) vh<1>F a0_a_y bh { align1 }; /* pixel 8-15 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g4a000066400000000000000000000033571267532330400264200ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') /* mul mask rgba channels to src */ mul (16) src_sample_r_01<1>F src_sample_r_01<8,8,1>F mask_sample_r_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F src_sample_g_01<8,8,1>F mask_sample_g_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F src_sample_b_01<8,8,1>F mask_sample_b_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F src_sample_a_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g4b000066400000000000000000000003341267532330400264110ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d02c0 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0300 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0340 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g4b.gen5000066400000000000000000000003341267532330400272460ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d02c0 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0300 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0340 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g5a000066400000000000000000000033571267532330400264210ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') /* mul mask rgba channels to src */ mul (16) src_sample_r_01<1>F src_sample_r_01<8,8,1>F mask_sample_r_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F src_sample_g_01<8,8,1>F mask_sample_g_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F src_sample_b_01<8,8,1>F mask_sample_b_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F src_sample_a_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g5b000066400000000000000000000003341267532330400264120ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d02c0 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0300 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0340 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g6a000077700000000000000000000000001267532330400307252exa_wm_ca.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca.g6b000066400000000000000000000003341267532330400264130ustar00rootroot00000000000000 { 0x00800041, 0x21c077bd, 0x008d01c0, 0x008d02c0 }, { 0x00800041, 0x220077bd, 0x008d0200, 0x008d0300 }, { 0x00800041, 0x224077bd, 0x008d0240, 0x008d0340 }, { 0x00800041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g4a000066400000000000000000000033131267532330400302650ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') mul (16) src_sample_r_01<1>F mask_sample_r_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F mask_sample_g_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F mask_sample_b_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F mask_sample_a_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g4b000066400000000000000000000003341267532330400302660ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d02c0, 0x008d0280 }, { 0x00802041, 0x220077bd, 0x008d0300, 0x008d0280 }, { 0x00802041, 0x224077bd, 0x008d0340, 0x008d0280 }, { 0x00802041, 0x228077bd, 0x008d0380, 0x008d0280 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g4b.gen5000066400000000000000000000003341267532330400311230ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d02c0, 0x008d0280 }, { 0x00802041, 0x220077bd, 0x008d0300, 0x008d0280 }, { 0x00802041, 0x224077bd, 0x008d0340, 0x008d0280 }, { 0x00802041, 0x228077bd, 0x008d0380, 0x008d0280 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g5a000066400000000000000000000033131267532330400302660ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') mul (16) src_sample_r_01<1>F mask_sample_r_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F mask_sample_g_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F mask_sample_b_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F mask_sample_a_01<8,8,1>F src_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g5b000066400000000000000000000003341267532330400302670ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d02c0, 0x008d0280 }, { 0x00802041, 0x220077bd, 0x008d0300, 0x008d0280 }, { 0x00802041, 0x224077bd, 0x008d0340, 0x008d0280 }, { 0x00802041, 0x228077bd, 0x008d0380, 0x008d0280 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g6a000077700000000000000000000000001267532330400344572exa_wm_ca_srcalpha.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_ca_srcalpha.g6b000066400000000000000000000003341267532330400302700ustar00rootroot00000000000000 { 0x00800041, 0x21c077bd, 0x008d02c0, 0x008d0280 }, { 0x00800041, 0x220077bd, 0x008d0300, 0x008d0280 }, { 0x00800041, 0x224077bd, 0x008d0340, 0x008d0280 }, { 0x00800041, 0x228077bd, 0x008d0380, 0x008d0280 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g4a000066400000000000000000000027631267532330400303000ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') define(`du_dx', `mask_du_dx') define(`du_dy', `mask_du_dy') define(`uo', `mask_uo') define(`dv_dx', `mask_dv_dx') define(`dv_dy', `mask_dv_dy') define(`vo', `mask_vo') define(`u', `mask_u') define(`v', `mask_v') include(`exa_wm_affine.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g4b000066400000000000000000000006701267532330400302740ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000a0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000a4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x210077be, 0x008d03c0, 0x000000ac }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000b0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000b4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x214077be, 0x008d03c0, 0x000000bc }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g4b.gen5000066400000000000000000000006701267532330400311310ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000a0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000a4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x210077be, 0x008d03c0, 0x000000ac }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000b0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000b4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x214077be, 0x008d03c0, 0x000000bc }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g5a000066400000000000000000000026121267532330400302720ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ include(`exa_wm.g4i') line (16) null mask_du_dx dst_x<8,8,1>F { compr align1 }; mac (16) mask_u mask_du_dy dst_y<8,8,1>F { compr align1 }; line (16) null mask_dv_dx dst_x<8,8,1>F { compr align1 }; mac (16) mask_v mask_dv_dy dst_y<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g5b000066400000000000000000000003341267532330400302720ustar00rootroot00000000000000 { 0x00802059, 0x200077bc, 0x000000a0, 0x008d0100 }, { 0x00802048, 0x210077be, 0x000000a4, 0x008d0140 }, { 0x00802059, 0x200077bc, 0x000000b0, 0x008d0100 }, { 0x00802048, 0x214077be, 0x000000b4, 0x008d0140 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g6a000066400000000000000000000027161267532330400303000ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`ul', `mask_u') define(`uh', `m9') define(`vl', `mask_v') define(`vh', `m11') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g8.0<0,1,0>F') define(`a0_a_y',`g8.16<0,1,0>F') include(`exa_wm_affine.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g6b000066400000000000000000000003341267532330400302730ustar00rootroot00000000000000 { 0x0060005a, 0x210077be, 0x00000100, 0x008d0040 }, { 0x0060005a, 0x212077be, 0x00000100, 0x008d0080 }, { 0x0060005a, 0x214077be, 0x00000110, 0x008d0040 }, { 0x0060005a, 0x216077be, 0x00000110, 0x008d0080 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g7a000066400000000000000000000027111267532330400302740ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`ul', `g72') define(`uh', `g73') define(`vl', `g74') define(`vh', `g75') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g8.0<0,1,0>F') define(`a0_a_y',`g8.16<0,1,0>F') include(`exa_wm_affine.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_affine.g7b000066400000000000000000000003341267532330400302740ustar00rootroot00000000000000 { 0x0060005a, 0x290077bd, 0x00000100, 0x008d0040 }, { 0x0060005a, 0x292077bd, 0x00000100, 0x008d0080 }, { 0x0060005a, 0x294077bd, 0x00000110, 0x008d0040 }, { 0x0060005a, 0x296077bd, 0x00000110, 0x008d0080 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g4a000066400000000000000000000033771267532330400312240ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') define(`du_dx', `mask_du_dx') define(`du_dy', `mask_du_dy') define(`uo', `mask_uo') define(`dv_dx', `mask_dv_dx') define(`dv_dy', `mask_dv_dy') define(`vo', `mask_vo') define(`dw_dx', `mask_dw_dx') define(`dw_dy', `mask_dw_dy') define(`wo', `mask_wo') define(`u', `mask_u') define(`v', `mask_v') define(`w', `mask_w') define(`u_0', `mask_u_0') define(`v_0', `mask_v_0') define(`u_1', `mask_u_1') define(`v_1', `mask_v_1') define(`w_0', `mask_w_0') define(`w_1', `mask_w_1') include(`exa_wm_projective.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g4b000066400000000000000000000015601267532330400312150ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000c0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000c4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000cc }, { 0x00600031, 0x21801fbd, 0x008d03c0, 0x01110001 }, { 0x00600031, 0x21a01fbd, 0x008d03e0, 0x01110001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000a0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000a4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000ac }, { 0x00802041, 0x210077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000b0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000b4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000bc }, { 0x00802041, 0x214077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g4b.gen5000066400000000000000000000015601267532330400320520ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000c0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000c4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000cc }, { 0x00600031, 0x21801fbd, 0x108d03c0, 0x02100001 }, { 0x00600031, 0x21a01fbd, 0x108d03e0, 0x02100001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000a0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000a4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000ac }, { 0x00802041, 0x210077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000b0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000b4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000bc }, { 0x00802041, 0x214077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g5a000066400000000000000000000033771267532330400312250ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') define(`du_dx', `mask_du_dx') define(`du_dy', `mask_du_dy') define(`uo', `mask_uo') define(`dv_dx', `mask_dv_dx') define(`dv_dy', `mask_dv_dy') define(`vo', `mask_vo') define(`dw_dx', `mask_dw_dx') define(`dw_dy', `mask_dw_dy') define(`wo', `mask_wo') define(`u', `mask_u') define(`v', `mask_v') define(`w', `mask_w') define(`u_0', `mask_u_0') define(`v_0', `mask_v_0') define(`u_1', `mask_u_1') define(`v_1', `mask_v_1') define(`w_0', `mask_w_0') define(`w_1', `mask_w_1') include(`exa_wm_projective.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g5b000066400000000000000000000015601267532330400312160ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000c0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000c4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000cc }, { 0x00600031, 0x21801fbd, 0x108d03c0, 0x02100001 }, { 0x00600031, 0x21a01fbd, 0x108d03e0, 0x02100001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000a0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000a4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000ac }, { 0x00802041, 0x210077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x000000b0 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x000000b4 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x000000bc }, { 0x00802041, 0x214077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g6a000066400000000000000000000044361267532330400312230ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`u', `mask_u') define(`ul', `mask_u') define(`uh', `m9') define(`v', `mask_v') define(`vl', `mask_v') define(`vh', `m11') define(`w', `mask_w') define(`wl', `mask_w_0') define(`wh', `mask_w_1') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g8.0<0,1,0>F') define(`a0_a_y',`g8.16<0,1,0>F') define(`a0_a_z',`g9.0<0,1,0>F') /* W */ pln (8) temp_x_0<1>F a0_a_z bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_z bh { align1 }; /* pixel 8-15 */ math (8) wl<1>F temp_x_0<8,8,1>F null inv { align1 }; math (8) wh<1>F temp_x_1<8,8,1>F null inv { align1 }; /* U */ pln (8) temp_x_0<1>F a0_a_x bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_x bh { align1 }; /* pixel 8-15 */ mul (8) ul<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) uh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; /* V */ pln (8) temp_x_0<1>F a0_a_y bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_y bh { align1 }; /* pixel 8-15 */ mul (8) vl<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) vh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g6b000066400000000000000000000012241267532330400312140ustar00rootroot00000000000000 { 0x0060005a, 0x23c077bd, 0x00000120, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000120, 0x008d0080 }, { 0x01600038, 0x218003bd, 0x008d03c0, 0x00000000 }, { 0x01600038, 0x21a003bd, 0x008d03e0, 0x00000000 }, { 0x0060005a, 0x23c077bd, 0x00000100, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000100, 0x008d0080 }, { 0x00600041, 0x210077be, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x212077be, 0x008d03e0, 0x008d01a0 }, { 0x0060005a, 0x23c077bd, 0x00000110, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000110, 0x008d0080 }, { 0x00600041, 0x214077be, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x216077be, 0x008d03e0, 0x008d01a0 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g7a000066400000000000000000000044231267532330400312200ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`u', `g72') define(`ul', `g72') define(`uh', `g73') define(`v', `g74') define(`vl', `g74') define(`vh', `g75') define(`w', `mask_w') define(`wl', `mask_w_0') define(`wh', `mask_w_1') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g8.0<0,1,0>F') define(`a0_a_y',`g8.16<0,1,0>F') define(`a0_a_z',`g9.0<0,1,0>F') /* W */ pln (8) temp_x_0<1>F a0_a_z bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_z bh { align1 }; /* pixel 8-15 */ math (8) wl<1>F temp_x_0<8,8,1>F null inv { align1 }; math (8) wh<1>F temp_x_1<8,8,1>F null inv { align1 }; /* U */ pln (8) temp_x_0<1>F a0_a_x bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_x bh { align1 }; /* pixel 8-15 */ mul (8) ul<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) uh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; /* V */ pln (8) temp_x_0<1>F a0_a_y bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_y bh { align1 }; /* pixel 8-15 */ mul (8) vl<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) vh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_projective.g7b000066400000000000000000000012241267532330400312150ustar00rootroot00000000000000 { 0x0060005a, 0x23c077bd, 0x00000120, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000120, 0x008d0080 }, { 0x01600038, 0x218003bd, 0x008d03c0, 0x00000000 }, { 0x01600038, 0x21a003bd, 0x008d03e0, 0x00000000 }, { 0x0060005a, 0x23c077bd, 0x00000100, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000100, 0x008d0080 }, { 0x00600041, 0x290077bd, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x292077bd, 0x008d03e0, 0x008d01a0 }, { 0x0060005a, 0x23c077bd, 0x00000110, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x00000110, 0x008d0080 }, { 0x00600041, 0x294077bd, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x296077bd, 0x008d03e0, 0x008d01a0 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g4a000066400000000000000000000040311267532330400306170ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load only alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) mask_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* mask_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) mask_msg_ind /* msg reg index */ mask_sample_a_01<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g4b000066400000000000000000000002451267532330400306230ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x23801c09, 0x00000000, 0x02520102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g4b.gen5000066400000000000000000000002451267532330400314600ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x23801c09, 0x20000000, 0x0a2a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g5a000066400000000000000000000040311267532330400306200ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load only alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) mask_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* mask_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) mask_msg_ind /* msg reg index */ mask_sample_a_01<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g5b000066400000000000000000000002451267532330400306240ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x23801c09, 0x20000000, 0x0a2a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g6a000077700000000000000000000000001267532330400353472exa_wm_mask_sample_a.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g6b000066400000000000000000000002451267532330400306250ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x02800031, 0x23801cc9, 0x000000e0, 0x0a2a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g7a000066400000000000000000000040051267532330400306230ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load only alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) g71<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* g71 will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) 71 /* msg reg index */ mask_sample_a_01<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_a.g7b000066400000000000000000000002451267532330400306260ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x28e00021, 0x008d0000, 0x00000000 }, { 0x02800031, 0x23801ca9, 0x000008e0, 0x0a2c0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g4a000066400000000000000000000040231267532330400313130ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load argb */ mov (1) g0.8<1>UD 0x00000000UD { align1 mask_disable }; mov (8) mask_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* mask_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) mask_msg_ind /* msg reg index */ mask_sample_base<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g4b000066400000000000000000000002451267532330400313160ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x22c01c09, 0x00000000, 0x02580102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g4b.gen5000066400000000000000000000002451267532330400321530ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x22c01c09, 0x20000000, 0x0a8a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g5a000066400000000000000000000040231267532330400313140ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load argb */ mov (1) g0.8<1>UD 0x00000000UD { align1 mask_disable }; mov (8) mask_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* mask_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) mask_msg_ind /* msg reg index */ mask_sample_base<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g5b000066400000000000000000000002451267532330400313170ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x07800031, 0x22c01c09, 0x20000000, 0x0a8a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g6a000077700000000000000000000000001267532330400365352exa_wm_mask_sample_argb.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g6b000066400000000000000000000002451267532330400313200ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00022, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22c01cc9, 0x000000e0, 0x0a8a0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g7a000066400000000000000000000037771267532330400313350ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the mask surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load argb */ mov (1) g0.8<1>UD 0x00000000UD { align1 mask_disable }; mov (8) g71<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* g71 will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) 71 /* msg reg index */ mask_sample_base<1>UW /* readback */ null sampler (2,1,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_mask_sample_argb.g7b000066400000000000000000000002451267532330400313210ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22c01ca9, 0x000008e0, 0x0a8c0102 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g4a000066400000000000000000000033611267532330400267500ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') /* mul mask's alpha channel to src */ mul (16) src_sample_r_01<1>F src_sample_r_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F src_sample_g_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F src_sample_b_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F src_sample_a_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g4b000066400000000000000000000003341267532330400267460ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d0380 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0380 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0380 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g4b.gen5000066400000000000000000000003341267532330400276030ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d0380 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0380 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0380 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g5a000066400000000000000000000033611267532330400267510ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Composite src and mask together, no component alpha */ include(`exa_wm.g4i') /* mul mask's alpha channel to src */ mul (16) src_sample_r_01<1>F src_sample_r_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_g_01<1>F src_sample_g_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_b_01<1>F src_sample_b_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; mul (16) src_sample_a_01<1>F src_sample_a_01<8,8,1>F mask_sample_a_01<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g5b000066400000000000000000000003341267532330400267470ustar00rootroot00000000000000 { 0x00802041, 0x21c077bd, 0x008d01c0, 0x008d0380 }, { 0x00802041, 0x220077bd, 0x008d0200, 0x008d0380 }, { 0x00802041, 0x224077bd, 0x008d0240, 0x008d0380 }, { 0x00802041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g6a000077700000000000000000000000001267532330400316172exa_wm_noca.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_noca.g6b000066400000000000000000000003341267532330400267500ustar00rootroot00000000000000 { 0x00800041, 0x21c077bd, 0x008d01c0, 0x008d0380 }, { 0x00800041, 0x220077bd, 0x008d0200, 0x008d0380 }, { 0x00800041, 0x224077bd, 0x008d0240, 0x008d0380 }, { 0x00800041, 0x228077bd, 0x008d0280, 0x008d0380 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_projective.g4i000066400000000000000000000045031267532330400302110ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /********** Compute w *************/ mul (16) temp_x<1>F dst_x<8,8,1>F dw_dx { compr align1 }; mul (16) temp_y<1>F dst_y<8,8,1>F dw_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F wo { compr align1 }; send (8) 0 w_0<1>F temp_x_0<8,8,1>F math inv mlen 1 rlen 1 { align1 }; send (8) 0 w_1<1>F temp_x_1<8,8,1>F math inv mlen 1 rlen 1 { sechalf align1 }; /********** Compute u *************/ mul (16) temp_x<1>F dst_x<8,8,1>F du_dx { compr align1 }; mul (16) temp_y<1>F dst_y<8,8,1>F du_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F uo { compr align1 }; mul (16) u<1>F temp_x<8,8,1>F w<8,8,1>F { compr align1 }; /********** Compute v *************/ mul (16) temp_x<1>F dst_x<8,8,1>F dv_dx { compr align1 }; mul (16) temp_y<1>F dst_y<8,8,1>F dv_dy { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F temp_y<8,8,1>F { compr align1 }; add (16) temp_x<1>F temp_x<8,8,1>F vo { compr align1 }; mul (16) v<1>F temp_x<8,8,1>F w<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_sample_planar.g4i000066400000000000000000000052611267532330400306570ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface in planar format */ /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load r */ mov (1) g0.8<1>UD 0x0000e000UD { align1 mask_disable }; /* src_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ /* sample Y */ mov (8) src_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ send (16) src_msg_ind /* msg reg index */ src_sample_g<1>UW /* readback */ null sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ /* sample U (Cr) */ send (16) src_msg_ind /* msg reg index */ src_sample_r<1>UW /* readback */ null sampler (3,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ /* sample V (Cb) */ send (16) src_msg_ind /* msg reg index */ src_sample_b<1>UW /* readback */ null sampler (5,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g4a000066400000000000000000000030631267532330400301260ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Fragment to compute src u/v values under an affine transform */ include(`exa_wm.g4i') define(`du_dx', `src_du_dx') define(`du_dy', `src_du_dy') define(`uo', `src_uo') define(`dv_dx', `src_dv_dx') define(`dv_dy', `src_dv_dy') define(`vo', `src_vo') define(`u', `src_u') define(`v', `src_v') include(`exa_wm_affine.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g4b000066400000000000000000000006701267532330400301300ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000060 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000064 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x204077be, 0x008d03c0, 0x0000006c }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000070 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000074 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x208077be, 0x008d03c0, 0x0000007c }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g4b.gen5000066400000000000000000000006701267532330400307650ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000060 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000064 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x204077be, 0x008d03c0, 0x0000006c }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000070 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000074 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x208077be, 0x008d03c0, 0x0000007c }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g5a000066400000000000000000000026041267532330400301270ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ include(`exa_wm.g4i') line (16) null src_du_dx dst_x<8,8,1>F { compr align1 }; mac (16) src_u src_du_dy dst_y<8,8,1>F { compr align1 }; line (16) null src_dv_dx dst_x<8,8,1>F { compr align1 }; mac (16) src_v src_dv_dy dst_y<8,8,1>F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g5b000066400000000000000000000003341267532330400301260ustar00rootroot00000000000000 { 0x00802059, 0x200077bc, 0x00000060, 0x008d0100 }, { 0x00802048, 0x204077be, 0x00000064, 0x008d0140 }, { 0x00802059, 0x200077bc, 0x00000070, 0x008d0100 }, { 0x00802048, 0x208077be, 0x00000074, 0x008d0140 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g6a000066400000000000000000000027131267532330400301310ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`ul', `src_u') define(`uh', `m3') define(`vl', `src_v') define(`vh', `m5') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g6.0<0,1,0>F') define(`a0_a_y',`g6.16<0,1,0>F') include(`exa_wm_affine.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g6b000066400000000000000000000003341267532330400301270ustar00rootroot00000000000000 { 0x0060005a, 0x204077be, 0x000000c0, 0x008d0040 }, { 0x0060005a, 0x206077be, 0x000000c0, 0x008d0080 }, { 0x0060005a, 0x208077be, 0x000000d0, 0x008d0040 }, { 0x0060005a, 0x20a077be, 0x000000d0, 0x008d0080 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g7a000066400000000000000000000027111267532330400301300ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`ul', `g66') define(`uh', `g67') define(`vl', `g68') define(`vh', `g69') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g6.0<0,1,0>F') define(`a0_a_y',`g6.16<0,1,0>F') include(`exa_wm_affine.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g7b000066400000000000000000000003341267532330400301300ustar00rootroot00000000000000 { 0x0060005a, 0x284077bd, 0x000000c0, 0x008d0040 }, { 0x0060005a, 0x286077bd, 0x000000c0, 0x008d0080 }, { 0x0060005a, 0x288077bd, 0x000000d0, 0x008d0040 }, { 0x0060005a, 0x28a077bd, 0x000000d0, 0x008d0080 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g8a000077700000000000000000000000001267532330400341622exa_wm_src_affine.g7austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_affine.g8b000066400000000000000000000003341267532330400301310ustar00rootroot00000000000000 { 0x0060005a, 0x28403ae8, 0x3a0000c0, 0x008d0040 }, { 0x0060005a, 0x28603ae8, 0x3a0000c0, 0x008d0080 }, { 0x0060005a, 0x28803ae8, 0x3a0000d0, 0x008d0040 }, { 0x0060005a, 0x28a03ae8, 0x3a0000d0, 0x008d0080 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g4a000066400000000000000000000033511267532330400310500ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') define(`du_dx', `src_du_dx') define(`du_dy', `src_du_dy') define(`uo', `src_uo') define(`dv_dx', `src_dv_dx') define(`dv_dy', `src_dv_dy') define(`vo', `src_vo') define(`dw_dx', `src_dw_dx') define(`dw_dy', `src_dw_dy') define(`wo', `src_wo') define(`u', `src_u') define(`v', `src_v') define(`w', `src_w') define(`u_0', `src_u_0') define(`v_0', `src_v_0') define(`u_1', `src_u_1') define(`v_1', `src_v_1') define(`w_0', `src_w_0') define(`w_1', `src_w_1') include(`exa_wm_projective.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g4b000066400000000000000000000015601267532330400310510ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000080 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000084 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000008c }, { 0x00600031, 0x21801fbd, 0x008d03c0, 0x01110001 }, { 0x00600031, 0x21a01fbd, 0x008d03e0, 0x01110001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000060 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000064 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000006c }, { 0x00802041, 0x204077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000070 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000074 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000007c }, { 0x00802041, 0x208077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g4b.gen5000066400000000000000000000015601267532330400317060ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000080 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000084 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000008c }, { 0x00600031, 0x21801fbd, 0x108d03c0, 0x02100001 }, { 0x00600031, 0x21a01fbd, 0x108d03e0, 0x02100001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000060 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000064 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000006c }, { 0x00802041, 0x204077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000070 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000074 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000007c }, { 0x00802041, 0x208077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g5a000066400000000000000000000033511267532330400310510ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') define(`du_dx', `src_du_dx') define(`du_dy', `src_du_dy') define(`uo', `src_uo') define(`dv_dx', `src_dv_dx') define(`dv_dy', `src_dv_dy') define(`vo', `src_vo') define(`dw_dx', `src_dw_dx') define(`dw_dy', `src_dw_dy') define(`wo', `src_wo') define(`u', `src_u') define(`v', `src_v') define(`w', `src_w') define(`u_0', `src_u_0') define(`v_0', `src_v_0') define(`u_1', `src_u_1') define(`v_1', `src_v_1') define(`w_0', `src_w_0') define(`w_1', `src_w_1') include(`exa_wm_projective.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g5b000066400000000000000000000015601267532330400310520ustar00rootroot00000000000000 { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000080 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000084 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000008c }, { 0x00600031, 0x21801fbd, 0x108d03c0, 0x02100001 }, { 0x00600031, 0x21a01fbd, 0x108d03e0, 0x02100001 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000060 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000064 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000006c }, { 0x00802041, 0x204077be, 0x008d03c0, 0x008d0180 }, { 0x00802041, 0x23c077bd, 0x008d0100, 0x00000070 }, { 0x00802041, 0x238077bd, 0x008d0140, 0x00000074 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x008d0380 }, { 0x00802040, 0x23c077bd, 0x008d03c0, 0x0000007c }, { 0x00802041, 0x208077be, 0x008d03c0, 0x008d0180 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g6a000066400000000000000000000044261267532330400310560ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`u', `src_u') define(`ul', `src_u') define(`uh', `m3') define(`v', `src_v') define(`vl', `src_v') define(`vh', `m5') define(`w', `src_w') define(`wl', `src_w_0') define(`wh', `src_w_1') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g6.0<0,1,0>F') define(`a0_a_y',`g6.16<0,1,0>F') define(`a0_a_z',`g7.0<0,1,0>F') /* W */ pln (8) temp_x_0<1>F a0_a_z bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_z bh { align1 }; /* pixel 8-15 */ math (8) wl<1>F temp_x_0<8,8,1>F null inv { align1 }; math (8) wh<1>F temp_x_1<8,8,1>F null inv { align1 }; /* U */ pln (8) temp_x_0<1>F a0_a_x bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_x bh { align1 }; /* pixel 8-15 */ mul (8) ul<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) uh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; /* V */ pln (8) temp_x_0<1>F a0_a_y bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_y bh { align1 }; /* pixel 8-15 */ mul (8) vl<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) vh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g6b000066400000000000000000000012241267532330400310500ustar00rootroot00000000000000 { 0x0060005a, 0x23c077bd, 0x000000e0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000e0, 0x008d0080 }, { 0x01600038, 0x218003bd, 0x008d03c0, 0x00000000 }, { 0x01600038, 0x21a003bd, 0x008d03e0, 0x00000000 }, { 0x0060005a, 0x23c077bd, 0x000000c0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000c0, 0x008d0080 }, { 0x00600041, 0x204077be, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x206077be, 0x008d03e0, 0x008d01a0 }, { 0x0060005a, 0x23c077bd, 0x000000d0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000d0, 0x008d0080 }, { 0x00600041, 0x208077be, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x20a077be, 0x008d03e0, 0x008d01a0 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g7a000066400000000000000000000044201267532330400310510ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ /* * Fragment to compute src u/v values */ include(`exa_wm.g4i') define(`u', `g66') define(`ul', `g66') define(`uh', `g67') define(`v', `g68') define(`vl', `g68') define(`vh', `g69') define(`w', `src_w') define(`wl', `src_w_0') define(`wh', `src_w_1') define(`bl', `g2.0<8,8,1>F') define(`bh', `g4.0<8,8,1>F') define(`a0_a_x',`g6.0<0,1,0>F') define(`a0_a_y',`g6.16<0,1,0>F') define(`a0_a_z',`g7.0<0,1,0>F') /* W */ pln (8) temp_x_0<1>F a0_a_z bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_z bh { align1 }; /* pixel 8-15 */ math (8) wl<1>F temp_x_0<8,8,1>F null inv { align1 }; math (8) wh<1>F temp_x_1<8,8,1>F null inv { align1 }; /* U */ pln (8) temp_x_0<1>F a0_a_x bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_x bh { align1 }; /* pixel 8-15 */ mul (8) ul<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) uh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; /* V */ pln (8) temp_x_0<1>F a0_a_y bl { align1 }; /* pixel 0-7 */ pln (8) temp_x_1<1>F a0_a_y bh { align1 }; /* pixel 8-15 */ mul (8) vl<1>F temp_x_0<8,8,1>F wl<8,8,1>F { align1 }; mul (8) vh<1>F temp_x_1<8,8,1>F wh<8,8,1>F { align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_projective.g7b000066400000000000000000000012241267532330400310510ustar00rootroot00000000000000 { 0x0060005a, 0x23c077bd, 0x000000e0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000e0, 0x008d0080 }, { 0x01600038, 0x218003bd, 0x008d03c0, 0x00000000 }, { 0x01600038, 0x21a003bd, 0x008d03e0, 0x00000000 }, { 0x0060005a, 0x23c077bd, 0x000000c0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000c0, 0x008d0080 }, { 0x00600041, 0x284077bd, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x286077bd, 0x008d03e0, 0x008d01a0 }, { 0x0060005a, 0x23c077bd, 0x000000d0, 0x008d0040 }, { 0x0060005a, 0x23e077bd, 0x000000d0, 0x008d0080 }, { 0x00600041, 0x288077bd, 0x008d03c0, 0x008d0180 }, { 0x00600041, 0x28a077bd, 0x008d03e0, 0x008d01a0 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g4a000066400000000000000000000040161267532330400304560ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) src_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* src_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) src_msg_ind /* msg reg index */ src_sample_a_01<1>UW /* readback */ null sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g4b000066400000000000000000000002451267532330400304570ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22801c09, 0x00000000, 0x02520001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g4b.gen5000066400000000000000000000002451267532330400313140ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22801c09, 0x20000000, 0x0a2a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g5a000066400000000000000000000040161267532330400304570ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) src_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* src_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) src_msg_ind /* msg reg index */ src_sample_a_01<1>UW /* readback */ null sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g5b000066400000000000000000000002451267532330400304600ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22801c09, 0x20000000, 0x0a2a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g6a000077700000000000000000000000001267532330400350372exa_wm_src_sample_a.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g6b000066400000000000000000000002451267532330400304610ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22801cc9, 0x00000020, 0x0a2a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g7a000066400000000000000000000037751267532330400304740ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load alpha */ mov (1) g0.8<1>UD 0x00007000UD { align1 mask_disable }; mov (8) g65<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* g65 will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) 65 /* msg reg index */ src_sample_a_01<1>UW /* readback */ null sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 2 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_a.g7b000066400000000000000000000002451267532330400304620ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00007000 }, { 0x00600001, 0x28200021, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22801ca9, 0x00000820, 0x0a2c0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g4a000066400000000000000000000025031267532330400311500ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') include(`exa_wm_src_sample_argb.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g4b000066400000000000000000000002451267532330400311520ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x21c01c09, 0x00000000, 0x02580001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g4b.gen5000066400000000000000000000002451267532330400320070ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x21c01c09, 0x20000000, 0x0a8a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g4i000066400000000000000000000037301267532330400311630ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load argb */ mov (1) g0.8<1>UD 0x00000000UD { align1 mask_disable }; mov (8) src_msg<1>UD g0<8,8,1>UD { align1 }; /* copy to msg start reg*/ /* src_msg will be copied with g0, as it contains send desc */ /* emit sampler 'send' cmd */ send (16) src_msg_ind /* msg reg index */ src_sample_base<1>UW /* readback */ null sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 8 { align1 }; /* required message len 5, readback len 8 */ xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g5a000066400000000000000000000035771267532330400311650ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') /* prepare sampler read back gX register, which would be written back to output */ /* use simd16 sampler, param 0 is u, param 1 is v. */ /* 'payload' loading, assuming tex coord start from g4 */ /* load argb */ mov (1) g0.8<1>UD 0x00000000UD { align1 mask_disable }; /* src_msg will be copied with g0, as it contains send desc */ send (16) src_msg_ind /* msg reg index */ src_sample_base<1>UW /* readback */ g0<8,8,1>UW sampler (1,0,F) /* sampler message description, (binding_table,sampler_index,datatype) /* here(src->dst) we should use src_sampler and src_surface */ mlen 5 rlen 8 { align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g5b000066400000000000000000000001561267532330400311540ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x01800031, 0x21c01d29, 0x208d0000, 0x0a8a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g6a000077700000000000000000000000001267532330400362252exa_wm_src_sample_argb.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g6b000066400000000000000000000002451267532330400311540ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x02800031, 0x21c01cc9, 0x00000020, 0x0a8a0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g7a000066400000000000000000000026561267532330400311640ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface */ include(`exa_wm.g4i') undefine(`src_msg') undefine(`src_msg_ind') define(`src_msg', `g65') define(`src_msg_ind', `65') include(`exa_wm_src_sample_argb.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g7b000066400000000000000000000002451267532330400311550ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0000, 0x00000000 }, { 0x02800031, 0x21c01ca9, 0x00000820, 0x0a8c0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g8a000077700000000000000000000000001267532330400362322exa_wm_src_sample_argb.g7austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_argb.g8b000066400000000000000000000002451267532330400311560ustar00rootroot00000000000000 { 0x00000001, 0x2008060c, 0x00000000, 0x00000000 }, { 0x00600001, 0x28200208, 0x008d0000, 0x00000000 }, { 0x02800031, 0x21c00a48, 0x0e000820, 0x0a8c0001 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g4a000066400000000000000000000025221267532330400315130ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface in planar format */ include(`exa_wm.g4i') include(`exa_wm_sample_planar.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g4b000066400000000000000000000004231267532330400315120ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22001c09, 0x00000000, 0x02520001 }, { 0x01800031, 0x21c01c09, 0x00000000, 0x02520003 }, { 0x01800031, 0x22401c09, 0x00000000, 0x02520005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g4b.gen5000066400000000000000000000004231267532330400323470ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22001c09, 0x20000000, 0x0a2a0001 }, { 0x01800031, 0x21c01c09, 0x20000000, 0x0a2a0003 }, { 0x01800031, 0x22401c09, 0x20000000, 0x0a2a0005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g5a000066400000000000000000000025221267532330400315140ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface in planar format */ include(`exa_wm.g4i') include(`exa_wm_sample_planar.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g5b000066400000000000000000000004231267532330400315130ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x01800031, 0x22001c09, 0x20000000, 0x0a2a0001 }, { 0x01800031, 0x21c01c09, 0x20000000, 0x0a2a0003 }, { 0x01800031, 0x22401c09, 0x20000000, 0x0a2a0005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g6a000077700000000000000000000000001267532330400371312exa_wm_src_sample_planar.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g6b000066400000000000000000000004231267532330400315140ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, { 0x00600001, 0x20200022, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22001cc9, 0x00000020, 0x0a2a0001 }, { 0x02800031, 0x21c01cc9, 0x00000020, 0x0a2a0003 }, { 0x02800031, 0x22401cc9, 0x00000020, 0x0a2a0005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g7a000066400000000000000000000026751267532330400315270ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* Sample the src surface in planar format */ include(`exa_wm.g4i') undefine(`src_msg') undefine(`src_msg_ind') define(`src_msg', `g65') define(`src_msg_ind', `65') include(`exa_wm_sample_planar.g4i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g7b000066400000000000000000000004231267532330400315150ustar00rootroot00000000000000 { 0x00000201, 0x20080061, 0x00000000, 0x0000e000 }, { 0x00600001, 0x28200021, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22001ca9, 0x00000820, 0x0a2c0001 }, { 0x02800031, 0x21c01ca9, 0x00000820, 0x0a2c0003 }, { 0x02800031, 0x22401ca9, 0x00000820, 0x0a2c0005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g8a000077700000000000000000000000001267532330400371362exa_wm_src_sample_planar.g7austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_src_sample_planar.g8b000066400000000000000000000004231267532330400315160ustar00rootroot00000000000000 { 0x00000001, 0x2008060c, 0x00000000, 0x0000e000 }, { 0x00600001, 0x28200208, 0x008d0000, 0x00000000 }, { 0x02800031, 0x22000a48, 0x0e000820, 0x0a2c0001 }, { 0x02800031, 0x21c00a48, 0x0e000820, 0x0a2c0003 }, { 0x02800031, 0x22400a48, 0x0e000820, 0x0a2c0005 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g4a000066400000000000000000000050041267532330400271560ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') /* * Prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), * * Note that the SIMD16 write message takes data for the first * two sub-spans followed by the data for the second two sub-spans * instead of having the two sub-spans interleaved by channel. Weird. */ mov (8) data_port_r_01<1>F src_sample_r_01<8,8,1>F { align1 }; mov (8) data_port_g_01<1>F src_sample_g_01<8,8,1>F { align1 }; mov (8) data_port_b_01<1>F src_sample_b_01<8,8,1>F { align1 }; mov (8) data_port_a_01<1>F src_sample_a_01<8,8,1>F { align1 }; mov (8) data_port_r_23<1>F src_sample_r_23<8,8,1>F { sechalf align1 }; mov (8) data_port_g_23<1>F src_sample_g_23<8,8,1>F { sechalf align1 }; mov (8) data_port_b_23<1>F src_sample_b_23<8,8,1>F { sechalf align1 }; mov (8) data_port_a_23<1>F src_sample_a_23<8,8,1>F { sechalf align1 }; /* m0, m1 are all direct passed by PS thread payload */ mov (8) data_port_msg_1<1>UD g1<8,8,1>UD { mask_disable align1 }; /* write */ send (16) data_port_msg_0_ind acc0<1>UW g0<8,8,1>UW write ( 0, /* binding_table */ 8, /* pixel scordboard clear, msg type simd16 single source */ 4, /* render target write */ 0 /* no write commit message */ ) mlen 10 rlen 0 { align1 EOT }; nop; nop; nop; nop; nop; nop; nop; nop; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g4b000066400000000000000000000017361267532330400271670ustar00rootroot00000000000000 { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 }, { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 }, { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 }, { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 }, { 0x00601001, 0x20c003be, 0x008d01e0, 0x00000000 }, { 0x00601001, 0x20e003be, 0x008d0220, 0x00000000 }, { 0x00601001, 0x210003be, 0x008d0260, 0x00000000 }, { 0x00601001, 0x212003be, 0x008d02a0, 0x00000000 }, { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x85a04800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g4b.gen5000066400000000000000000000017361267532330400300240ustar00rootroot00000000000000 { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 }, { 0x00600001, 0x206003be, 0x008d0200, 0x00000000 }, { 0x00600001, 0x208003be, 0x008d0240, 0x00000000 }, { 0x00600001, 0x20a003be, 0x008d0280, 0x00000000 }, { 0x00601001, 0x20c003be, 0x008d01e0, 0x00000000 }, { 0x00601001, 0x20e003be, 0x008d0220, 0x00000000 }, { 0x00601001, 0x210003be, 0x008d0260, 0x00000000 }, { 0x00601001, 0x212003be, 0x008d02a0, 0x00000000 }, { 0x00600201, 0x20200022, 0x008d0020, 0x00000000 }, { 0x00800031, 0x24001d28, 0x548d0000, 0x94084800 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g5a000066400000000000000000000037421267532330400271660ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ include(`exa_wm.g4i') /* * Prepare data in m2-m5 for subspan(1,0), m6-m9 for subspan(3,2), */ mov (16) m130<1>F src_sample_r_01<8,8,1>F { align1 compr }; mov (16) m131<1>F src_sample_g_01<8,8,1>F { align1 compr }; mov (16) m132<1>F src_sample_b_01<8,8,1>F { align1 compr }; mov (16) m133<1>F src_sample_a_01<8,8,1>F { align1 compr }; /* m0, m1 are all direct passed by PS thread payload */ mov (8) data_port_msg_1<1>F g1<8,8,1>F { mask_disable align1 }; /* write */ send (16) data_port_msg_0_ind acc0<1>UW g0<8,8,1>UW write ( 0, /* binding_table */ 8, /* pixel scordboard clear, msg type simd16 single source */ 4, /* render target write */ 0 /* no write commit message */ ) mlen 10 rlen 0 { align1 EOT }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g5b000066400000000000000000000005121267532330400271570ustar00rootroot00000000000000 { 0x00802001, 0x304003be, 0x008d01c0, 0x00000000 }, { 0x00802001, 0x306003be, 0x008d0200, 0x00000000 }, { 0x00802001, 0x308003be, 0x008d0240, 0x00000000 }, { 0x00802001, 0x30a003be, 0x008d0280, 0x00000000 }, { 0x00600201, 0x202003be, 0x008d0020, 0x00000000 }, { 0x00800031, 0x24001d28, 0x548d0000, 0x94084800 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g6a000066400000000000000000000031071267532330400271620ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ include(`exa_wm.g4i') /* * Prepare data in m2-m3 for Red channel, m4-m5 for Green channel, * m6-m7 for Blue and m8-m9 for Alpha channel */ define(`slot_r_00', `m2') define(`slot_r_01', `m3') define(`slot_g_00', `m4') define(`slot_g_01', `m5') define(`slot_b_00', `m6') define(`slot_b_01', `m7') define(`slot_a_00', `m8') define(`slot_a_01', `m9') define(`data_port_msg_2_ind', `2') include(`exa_wm_write.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g6b000066400000000000000000000016471267532330400271720ustar00rootroot00000000000000 { 0x00600001, 0x204003be, 0x008d01c0, 0x00000000 }, { 0x00600001, 0x206003be, 0x008d01e0, 0x00000000 }, { 0x00600001, 0x208003be, 0x008d0200, 0x00000000 }, { 0x00600001, 0x20a003be, 0x008d0220, 0x00000000 }, { 0x00600001, 0x20c003be, 0x008d0240, 0x00000000 }, { 0x00600001, 0x20e003be, 0x008d0260, 0x00000000 }, { 0x00600001, 0x210003be, 0x008d0280, 0x00000000 }, { 0x00600001, 0x212003be, 0x008d02a0, 0x00000000 }, { 0x05800031, 0x24001cc8, 0x00000040, 0x90019000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g6i000066400000000000000000000037761267532330400272060ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ mov (8) slot_r_00<1>F src_sample_r_01<8,8,1>F { align1 }; mov (8) slot_r_01<1>F src_sample_r_23<8,8,1>F { align1 }; mov (8) slot_g_00<1>F src_sample_g_01<8,8,1>F { align1 }; mov (8) slot_g_01<1>F src_sample_g_23<8,8,1>F { align1 }; mov (8) slot_b_00<1>F src_sample_b_01<8,8,1>F { align1 }; mov (8) slot_b_01<1>F src_sample_b_23<8,8,1>F { align1 }; mov (8) slot_a_00<1>F src_sample_a_01<8,8,1>F { align1 }; mov (8) slot_a_01<1>F src_sample_a_23<8,8,1>F { align1 }; /* write */ send (16) data_port_msg_2_ind acc0<1>UW null write ( 0, /* binding_table */ 16, /* pixel scordboard clear, msg type simd16 single source */ 12, /* render target write */ 0, /* no write commit message */ 0 /* headerless render target write */ ) mlen 8 rlen 0 { align1 EOT }; nop; nop; nop; nop; nop; nop; nop; nop; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g7a000066400000000000000000000031301267532330400271570ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ include(`exa_wm.g4i') /* * Prepare data in g66-g67 for Red channel, g68-g69 for Green channel, * g70-g71 for Blue and g72-g73 for Alpha channel */ define(`slot_r_00', `g66') define(`slot_r_01', `g67') define(`slot_g_00', `g68') define(`slot_g_01', `g69') define(`slot_b_00', `g70') define(`slot_b_01', `g71') define(`slot_a_00', `g72') define(`slot_a_01', `g73') define(`data_port_msg_2_ind', `66') include(`exa_wm_write.g6i') xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g7b000066400000000000000000000016471267532330400271730ustar00rootroot00000000000000 { 0x00600001, 0x284003bd, 0x008d01c0, 0x00000000 }, { 0x00600001, 0x286003bd, 0x008d01e0, 0x00000000 }, { 0x00600001, 0x288003bd, 0x008d0200, 0x00000000 }, { 0x00600001, 0x28a003bd, 0x008d0220, 0x00000000 }, { 0x00600001, 0x28c003bd, 0x008d0240, 0x00000000 }, { 0x00600001, 0x28e003bd, 0x008d0260, 0x00000000 }, { 0x00600001, 0x290003bd, 0x008d0280, 0x00000000 }, { 0x00600001, 0x292003bd, 0x008d02a0, 0x00000000 }, { 0x05800031, 0x24001ca8, 0x00000840, 0x90031000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g8a000077700000000000000000000000001267532330400322502exa_wm_write.g7austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_write.g8b000066400000000000000000000016471267532330400271740ustar00rootroot00000000000000 { 0x00600001, 0x28403ae8, 0x008d01c0, 0x00000000 }, { 0x00600001, 0x28603ae8, 0x008d01e0, 0x00000000 }, { 0x00600001, 0x28803ae8, 0x008d0200, 0x00000000 }, { 0x00600001, 0x28a03ae8, 0x008d0220, 0x00000000 }, { 0x00600001, 0x28c03ae8, 0x008d0240, 0x00000000 }, { 0x00600001, 0x28e03ae8, 0x008d0260, 0x00000000 }, { 0x00600001, 0x29003ae8, 0x008d0280, 0x00000000 }, { 0x00600001, 0x29203ae8, 0x008d02a0, 0x00000000 }, { 0x05800031, 0x24000a40, 0x0e000840, 0x90031000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, { 0x0000007e, 0x00000000, 0x00000000, 0x00000000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_xy.g4a000066400000000000000000000035371267532330400264750ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Register assignments: * * x g6/g7 * y g8/g9 * * temp x g10/g11 * temp y g12/g13 * * src w g14/g15 * src u m1/m2 * src v m3/m4 */ /* Fragment to compute per-pixel XY values */ include(`exa_wm.g4i') /* Load X and Y coordinates and compute per-pixel coordinates */ add (16) temp_x_uw<1>UW dst_x_uw 0x10101010V { align1 }; add (16) temp_y_uw<1>UW dst_y_uw 0x11001100V { align1 }; /* subtract screen-space origin of vertex 0 */ add (16) dst_x<1>F temp_x_uw<8,8,1>UW -screen_x0 { compr align1 }; add (16) dst_y<1>F temp_y_uw<8,8,1>UW -screen_y0 { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_xy.g4b000066400000000000000000000003341267532330400264660ustar00rootroot00000000000000 { 0x00800040, 0x23c06d29, 0x00480028, 0x10101010 }, { 0x00800040, 0x23806d29, 0x0048002a, 0x11001100 }, { 0x00802040, 0x2100753d, 0x008d03c0, 0x00004020 }, { 0x00802040, 0x2140753d, 0x008d0380, 0x00004024 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_xy.g4b.gen5000066400000000000000000000003341267532330400273230ustar00rootroot00000000000000 { 0x00800040, 0x23c06d29, 0x00480028, 0x10101010 }, { 0x00800040, 0x23806d29, 0x0048002a, 0x11001100 }, { 0x00802040, 0x2100753d, 0x008d03c0, 0x00004020 }, { 0x00802040, 0x2140753d, 0x008d0380, 0x00004024 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_xy.g5a000066400000000000000000000035371267532330400264760ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Wang Zhenyu * Keith Packard */ /* * Register assignments: * * x g6/g7 * y g8/g9 * * temp x g10/g11 * temp y g12/g13 * * src w g14/g15 * src u m1/m2 * src v m3/m4 */ /* Fragment to compute per-pixel XY values */ include(`exa_wm.g4i') /* Load X and Y coordinates and compute per-pixel coordinates */ add (16) temp_x_uw<1>UW dst_x_uw 0x10101010V { align1 }; add (16) temp_y_uw<1>UW dst_y_uw 0x11001100V { align1 }; /* subtract screen-space origin of vertex 0 */ add (16) dst_x<1>F temp_x_uw<8,8,1>UW -screen_x0 { compr align1 }; add (16) dst_y<1>F temp_y_uw<8,8,1>UW -screen_y0 { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_xy.g5b000066400000000000000000000003341267532330400264670ustar00rootroot00000000000000 { 0x00800040, 0x23c06d29, 0x00480028, 0x10101010 }, { 0x00800040, 0x23806d29, 0x0048002a, 0x11001100 }, { 0x00802040, 0x2100753d, 0x008d03c0, 0x00004020 }, { 0x00802040, 0x2140753d, 0x008d0380, 0x00004024 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g4a000066400000000000000000000063161267532330400275100ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * */ include(`exa_wm.g4i') define(`YCbCr_base', `src_sample_base') define(`Cr', `src_sample_r') define(`Cr_01', `src_sample_r_01') define(`Cr_23', `src_sample_r_23') define(`Y', `src_sample_g') define(`Y_01', `src_sample_g_01') define(`Y_23', `src_sample_g_23') define(`Cb', `src_sample_b') define(`Cb_01', `src_sample_b_01') define(`Cb_23', `src_sample_b_23') define(`Crn', `mask_sample_r') define(`Crn_01', `mask_sample_r_01') define(`Crn_23', `mask_sample_r_23') define(`Yn', `mask_sample_g') define(`Yn_01', `mask_sample_g_01') define(`Yn_23', `mask_sample_g_23') define(`Cbn', `mask_sample_b') define(`Cbn_01', `mask_sample_b_01') define(`Cbn_23', `mask_sample_b_23') /* color space conversion function: * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) */ /* Normalize Y, Cb and Cr: * * Yn = (Y - 16/255) * 1.164 * Crn = Cr - 128 / 255 * Cbn = Cb - 128 / 255 */ add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; /* * R = Y + Cr * 1.596 */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_r<1>F Crn<8,8,1>F 1.596F { compr align1 }; /* * G = Crn * -0.813 + Cbn * -0.392 + Y */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac (16) acc0<1>F Crn<8,8,1>F -0.813F { compr align1 }; mac.sat(16) src_sample_g<1>F Cbn<8,8,1>F -0.392F { compr align1 }; /* * B = Cbn * 2.017 + Y */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_b<1>F Cbn<8,8,1>F 2.017F { compr align1 }; /* * A = 1.0 */ mov (16) src_sample_a<1>F 1.0F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g4b000066400000000000000000000012241267532330400275020ustar00rootroot00000000000000 { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, { 0x80802048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x22407fbd, 0x008d0340, 0x40011687 }, { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g4b.gen5000066400000000000000000000012241267532330400303370ustar00rootroot00000000000000 { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, { 0x80802048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x22407fbd, 0x008d0340, 0x40011687 }, { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g5a000066400000000000000000000063161267532330400275110ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * */ include(`exa_wm.g4i') define(`YCbCr_base', `src_sample_base') define(`Cr', `src_sample_r') define(`Cr_01', `src_sample_r_01') define(`Cr_23', `src_sample_r_23') define(`Y', `src_sample_g') define(`Y_01', `src_sample_g_01') define(`Y_23', `src_sample_g_23') define(`Cb', `src_sample_b') define(`Cb_01', `src_sample_b_01') define(`Cb_23', `src_sample_b_23') define(`Crn', `mask_sample_r') define(`Crn_01', `mask_sample_r_01') define(`Crn_23', `mask_sample_r_23') define(`Yn', `mask_sample_g') define(`Yn_01', `mask_sample_g_01') define(`Yn_23', `mask_sample_g_23') define(`Cbn', `mask_sample_b') define(`Cbn_01', `mask_sample_b_01') define(`Cbn_23', `mask_sample_b_23') /* color space conversion function: * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) */ /* Normalize Y, Cb and Cr: * * Yn = (Y - 16/255) * 1.164 * Crn = Cr - 128 / 255 * Cbn = Cb - 128 / 255 */ add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; /* * R = Y + Cr * 1.596 */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_r<1>F Crn<8,8,1>F 1.596F { compr align1 }; /* * G = Crn * -0.813 + Cbn * -0.392 + Y */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac (16) acc0<1>F Crn<8,8,1>F -0.813F { compr align1 }; mac.sat(16) src_sample_g<1>F Cbn<8,8,1>F -0.392F { compr align1 }; /* * B = Cbn * 2.017 + Y */ mov (16) acc0<1>F Yn<8,8,1>F { compr align1 }; mac.sat(16) src_sample_b<1>F Cbn<8,8,1>F 2.017F { compr align1 }; /* * A = 1.0 */ mov (16) src_sample_a<1>F 1.0F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g5b000066400000000000000000000012241267532330400275030ustar00rootroot00000000000000 { 0x00802040, 0x23007fbd, 0x008d0200, 0xbd808081 }, { 0x00802041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, { 0x00802040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, { 0x00802040, 0x23407fbd, 0x008d0240, 0xbf008084 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x00802048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, { 0x80802048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, { 0x00802001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80802048, 0x22407fbd, 0x008d0340, 0x40011687 }, { 0x00802001, 0x228003fd, 0x00000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g6a000077700000000000000000000000001267532330400331112exa_wm_yuv_rgb.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g6b000066400000000000000000000012241267532330400275040ustar00rootroot00000000000000 { 0x00800040, 0x23007fbd, 0x008d0200, 0xbd808081 }, { 0x00800041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, { 0x00800040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, { 0x00800040, 0x23407fbd, 0x008d0240, 0xbf008084 }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80800048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x00800048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, { 0x80800048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80800048, 0x22407fbd, 0x008d0340, 0x40011687 }, { 0x00800001, 0x228003fd, 0x00000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g7a000077700000000000000000000000001267532330400331122exa_wm_yuv_rgb.g4austar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g7b000066400000000000000000000012241267532330400275050ustar00rootroot00000000000000 { 0x00800040, 0x23007fbd, 0x008d0200, 0xbd808081 }, { 0x00800041, 0x23007fbd, 0x008d0300, 0x3f94fdf4 }, { 0x00800040, 0x22c07fbd, 0x008d01c0, 0xbf008084 }, { 0x00800040, 0x23407fbd, 0x008d0240, 0xbf008084 }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80800048, 0x21c07fbd, 0x008d02c0, 0x3fcc49ba }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x00800048, 0x24007fbc, 0x008d02c0, 0xbf5020c5 }, { 0x80800048, 0x22007fbd, 0x008d0340, 0xbec8b439 }, { 0x00800001, 0x240003bc, 0x008d0300, 0x00000000 }, { 0x80800048, 0x22407fbd, 0x008d0340, 0x40011687 }, { 0x00800001, 0x228003fd, 0x00000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g8a000066400000000000000000000073121267532330400275110ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Keith Packard * Eric Anholt * */ include(`exa_wm.g4i') define(`YCbCr_base', `src_sample_base') define(`Cr', `src_sample_r') define(`Cr_01', `src_sample_r_01') define(`Cr_23', `src_sample_r_23') define(`Y', `src_sample_g') define(`Y_01', `src_sample_g_01') define(`Y_23', `src_sample_g_23') define(`Cb', `src_sample_b') define(`Cb_01', `src_sample_b_01') define(`Cb_23', `src_sample_b_23') define(`Crn', `mask_sample_r') define(`Crn_01', `mask_sample_r_01') define(`Crn_23', `mask_sample_r_23') define(`Yn', `mask_sample_g') define(`Yn_01', `mask_sample_g_01') define(`Yn_23', `mask_sample_g_23') define(`Cbn', `mask_sample_b') define(`Cbn_01', `mask_sample_b_01') define(`Cbn_23', `mask_sample_b_23') /* color space conversion function: * R = Clamp ( 1.164(Y-16/255) + 1.596(Cr-128/255), 0, 1) * G = Clamp ( 1.164(Y-16/255) - 0.813(Cr-128/255) - 0.392(Cb-128/255), 0, 1) * B = Clamp ( 1.164(Y-16/255) + 2.017(Cb-128/255), 0, 1) */ /* Normalize Y, Cb and Cr: * * Yn = (Y - 16/255) * 1.164 * Crn = Cr - 128 / 255 * Cbn = Cb - 128 / 255 */ add (16) Yn<1>F Y<8,8,1>F -0.0627451F { compr align1 }; mul (16) Yn<1>F Yn<8,8,1>F 1.164F { compr align1 }; add (16) Crn<1>F Cr<8,8,1>F -0.501961F { compr align1 }; add (16) Cbn<1>F Cb<8,8,1>F -0.501961F { compr align1 }; /* * R = Y + Cr * 1.596 */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac.sat(8) src_sample_r_01<1>F Crn_01<8,8,1>F 1.596F { compr align1 }; mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; mac.sat(8) src_sample_r_23<1>F Crn_23<8,8,1>F 1.596F { compr align1 }; /* * G = Crn * -0.813 + Cbn * -0.392 + Y */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac (8) acc0<1>F Crn_01<8,8,1>F -0.813F { compr align1 }; mac.sat(8) src_sample_g_01<1>F Cbn_01<8,8,1>F -0.392F { compr align1 }; mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; mac (8) acc0<1>F Crn_23<8,8,1>F -0.813F { compr align1 }; mac.sat(16) src_sample_g_23<1>F Cbn_23<8,8,1>F -0.392F { compr align1 }; /* * B = Cbn * 2.017 + Y */ mov (8) acc0<1>F Yn_01<8,8,1>F { compr align1 }; mac.sat(8) src_sample_b_01<1>F Cbn_01<8,8,1>F 2.017F { compr align1 }; mov (8) acc0<1>F Yn_23<8,8,1>F { compr align1 }; mac.sat(8) src_sample_b_23<1>F Cbn_23<8,8,1>F 2.017F { compr align1 }; /* * A = 1.0 */ mov (16) src_sample_a<1>F 1.0F { compr align1 }; xserver-xorg-video-intel-2.99.917+git20160325/src/render_program/exa_wm_yuv_rgb.g8b000066400000000000000000000020251267532330400275060ustar00rootroot00000000000000 { 0x00800040, 0x23003ae8, 0x3e8d0200, 0xbd808081 }, { 0x00800041, 0x23003ae8, 0x3e8d0300, 0x3f94fdf4 }, { 0x00800040, 0x22c03ae8, 0x3e8d01c0, 0xbf008084 }, { 0x00800040, 0x23403ae8, 0x3e8d0240, 0xbf008084 }, { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, { 0x80600048, 0x21c03ae8, 0x3e8d02c0, 0x3fcc49ba }, { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, { 0x80600048, 0x21e03ae8, 0x3e8d02e0, 0x3fcc49ba }, { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, { 0x00600048, 0x24003ae0, 0x3e8d02c0, 0xbf5020c5 }, { 0x80600048, 0x22003ae8, 0x3e8d0340, 0xbec8b439 }, { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, { 0x00600048, 0x24003ae0, 0x3e8d02e0, 0xbf5020c5 }, { 0x80800048, 0x22203ae8, 0x3e8d0360, 0xbec8b439 }, { 0x00600001, 0x24003ae0, 0x008d0300, 0x00000000 }, { 0x80600048, 0x22403ae8, 0x3e8d0340, 0x40011687 }, { 0x00600001, 0x24003ae0, 0x008d0320, 0x00000000 }, { 0x80600048, 0x22603ae8, 0x3e8d0360, 0x40011687 }, { 0x00800001, 0x22803ee8, 0x38000000, 0x3f800000 }, xserver-xorg-video-intel-2.99.917+git20160325/src/scripts/000077500000000000000000000000001267532330400225515ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/scripts/clock-graph.5c000066400000000000000000000071311267532330400251760ustar00rootroot00000000000000autoload Cairo; import Cairo; library "examples/sort.5c"; import Sort; int width = 1000, height = 200; int min_vco = 1400000000; int max_vco = 2800000000; int min = 0xffffffff; int max = 0; int max_clocks = 2000; int[4][max_clocks] clocks; int[4][max_clocks] vcos; int[4] clock_count = {0...}; int[4] p2vals = {5,10,7,14}; cairo_t cr = Cairo::new(width, height); void calc_p2(int p2i) { int p2 = p2vals[p2i]; int min_p, max_p; clocks[p2i] = (int [max_clocks]){0...}; if (p2 == 7 || p2 == 14) { /* LVDS */ min_p = 7; max_p = 98; } else { /* SDVO/DAC */ min_p = 5; max_p = 80; } for (int m1 = 10; m1 <= 22; m1++) { for (int m2 = 5; m2 <= 9; m2++) { for (int n = 1; n <= 5; n++) { for (int p1 = 1; p1 <= 8; p1++) { int ref = 96000000; int m = 5 * (m1 + 2) + (m2 + 2); int p = p1 * p2; int vco = floor(ref * m / (n + 2)); int clock = floor(vco / p); if (p < min_p || p > max_p) continue; if (m < 70 || m > 120) continue; if (m2 > m1) continue; /* won't happen */ if (vco < min_vco || vco > max_vco) continue; /* printf("clock: %d (%d,%d), %d, " "(%d,%d)\n", floor(clock / 1000), m1, m2, n, p1, p2); */ clocks[p2i][clock_count[p2i]] = clock; vcos[p2i][clock_count[p2i]] = vco; clock_count[p2i]++; } } } } } bool sort_p2(poly a, poly b) { return a > b; } int min_rate = 25000 * 1000; int max_rate = 200000 * 1000; real scale_x(real clock) { int min_x = 75, max_x = width - 50; real frac = (clock - min_rate) / (max_rate - min_rate); return min_x + frac * (max_x - min_x); } for (p2i = 0; p2i < dim(p2vals); p2i++) { int p2 = p2vals[p2i]; calc_p2(p2i); real row_y1 = (p2i + 1) / (dim(p2vals) + 1) * height; real row_y2 = p2i / (dim(p2vals) + 1) * height; /*qsort(&p2vals[p2i], sort_p2);*/ switch (p2) { case 5: set_source_rgb(cr, 1,0,0); break; case 10: set_source_rgb(cr, 0,1,0); break; case 7: set_source_rgb(cr, 0,0,1); break; case 14: set_source_rgb(cr, 0,0,0); break; } /* draw the line for the clock */ for (int i = 0; i < clock_count[p2i]; i++) { int clock = clocks[p2i][i]; real xpos; if (clock < min_rate || clock > max_rate) continue; xpos = scale_x(clock); move_to(cr, xpos, row_y1); line_to(cr, xpos, row_y2); stroke(cr); } set_source_rgb(cr, 1, 1, 1); /* add a mark for the vco value of the clocks at each location */ for (int i = 0; i < clock_count[p2i]; i++) { int clock = clocks[p2i][i]; int vco = vcos[p2i][i]; real mark_center; if (clock < min_rate || clock > max_rate) continue; real xpos = scale_x(clock); real vcofrac = (vco - min_vco) / (max_vco - min_vco); real mark_height = (row_y1 + vcofrac * (row_y2 - row_y1)); move_to(cr, xpos, mark_height - 1); line_to(cr, xpos, mark_height + 1); stroke(cr); } set_source_rgb(cr, 0, 0, 0); string p2label = sprintf("p2 = %d", p2); move_to(cr, 5, (p2i + .5) / (dim(p2vals) + 1) * height + 4); show_text(cr, p2label); } void label_clock(real clock) { real center_x = scale_x(clock); string label = sprintf("%d", floor((clock + 500) / 1000000)); text_extents_t e = text_extents(cr, label); real left_x = center_x - e.x_advance / 2; save(cr); move_to(cr, left_x, height - 20); show_text(cr, label); restore(cr); } label_clock(min_rate); label_clock(max_rate); label_clock(140 * 1000 * 1000); label_clock(115 * 1000 * 1000); label_clock(100 * 1000 * 1000); label_clock(82 * 1000 * 1000); string xlabel = "Clock in Mhz"; text_extents_t e = text_extents(cr, xlabel); move_to(cr, width / 2 - e.x_advance / 2, height - 5); show_text(cr, xlabel); sleep(10); xserver-xorg-video-intel-2.99.917+git20160325/src/scripts/clock.5c000066400000000000000000000013751267532330400241030ustar00rootroot00000000000000int p2 = 14; int min_p, max_p; if (p2 == 7 || p2 == 14) { /* LVDS */ min_p = 7; max_p = 98; } else { /* SDVO/DAC */ min_p = 5; max_p = 80; } for (int m1 = 10; m1 <= 22; m1++) { for (int m2 = 5; m2 <= 9; m2++) { for (int n = 1; n <= 6; n++) { for (int p1 = 1; p1 <= 8; p1++) { int ref = 96000000; int m = 5 * (m1 + 2) + (m2 + 2); int p = p1 * p2; int vco = floor(ref * m / (n + 2)); int clock = floor(vco / p); if (p < min_p || p > max_p) continue; if (m < 70 || m > 120) continue; if (m2 > m1) continue; /* won't happen */ if (vco < 1400000000 || vco > 2800000000) continue; printf("clock: %d (%d,%d),%d,(%d,%d)\n", floor(clock / 1000), m1, m2, n, p1, p2); } } } } xserver-xorg-video-intel-2.99.917+git20160325/src/scripts/fix.5c000066400000000000000000000003611267532330400235700ustar00rootroot00000000000000/* * Convert CSC fix point values to floats */ real fixval (int fix) { int exp = fix >> 9; int mant = fix & ((1 << 9) - 1); real ret; if (exp == 0x7) return 1.0; ret = (2 ** -exp) * mant / (1 << 9); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/src/scripts/tv.5c000066400000000000000000000060651267532330400234420ustar00rootroot00000000000000/* * tv.5c * * Compute tv encoder subcarrier dda constants * * The TV encoder subcarrier must be set precisely to the * required frequency or the cumulative phase errors will be * quite visible in the output. To accomplish this, the TV encoder * has a complex circuit that takes a fixed clock, generated by the PLL * and generates a precise subcarrier clock from that using the following * formula: * * subcarrier = pixel_clock * (S1 + (S2 + (S3/Z3)) / Z2) / 4096 * * Careful selection of the constants will provide the necessarily * precise clock. * * In the code below, S1 is represented by dda1, S2/Z2 by dda2 and S3/Z3 * by dda3. */ typedef struct { int step; int size; } term_t; /* * Find the approximation closest, but no larger than 'v', where * 0 <= v < 1, and the result denominator must be less than 30000. */ term_t approx (rational v) { rational best_dist = 1.0; term_t best; for (int den = 20000; den < 30000; den++) { int num = floor (v * den); term_t approx = { step = num, size = den }; rational dist = v - approx.step/approx.size; if (dist >= 0 && dist < best_dist) { best_dist = dist; best = approx; } } return best; } typedef struct { rational subcarrier; rational pixel; rational result; term_t dda1; term_t dda2; term_t dda3; } dda; /* * Compute the dda constants for the given pixel clock and * desired subcarrier frequency */ dda find_dda (rational pixel, rational subcarrier) { dda d; d.subcarrier = subcarrier; d.pixel = pixel; rational dda1 = subcarrier / pixel * 4096; d.dda1 = (term_t) { step = floor (dda1), size = 4096 }; rational dda2 = dda1 - d.dda1.step; d.dda2 = approx (dda2); rational dda3 = dda2 * d.dda2.size - d.dda2.step; d.dda3 = approx (dda3); /* Compute the resulting pixel clock to compare */ d.result = d.pixel * (d.dda1.step + (d.dda2.step + d.dda3.step/d.dda3.size) / d.dda2.size) / d.dda1.size; return d; } /* * Print out the computed constants */ void print_dda (dda d) { printf ("\t/* desired %9.7f actual %9.7f clock %g */\n", d.subcarrier, d.result, d.pixel); printf ("\t.dda1_inc\t= %6d,\n", d.dda1.step); printf ("\t.dda2_inc\t= %6d,\t.dda2_size\t= %6d,\n", d.dda2.step, d.dda2.step != 0 ? d.dda2.size : 0); printf ("\t.dda3_inc\t= %6d,\t.dda3_size\t= %6d,\n", d.dda3.step, d.dda3.step != 0 ? d.dda3.size : 0); } /* * These are all of the required subcarrier frequencies */ rational[] subcarriers = { /* these are the values we use; for some reason, this generates * a more stable image (at least for NTSC) */ 3.580, 4.434, 3.582, 3.576, 4.430, /* these are the values pulled out of the various specs */ 3.579545, 4.433618, 3.582056, 3.575611, 4.433618 }; /* * We fix the pixel clock to a value which the hardware can * generate exactly */ rational pixel = 107.520; void main () { for (int i = 0; i < dim(subcarriers); i++) { dda d = find_dda (pixel, subcarriers[i]); print_dda (d); } } main (); xserver-xorg-video-intel-2.99.917+git20160325/src/sna/000077500000000000000000000000001267532330400216435ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/sna/Makefile.am000066400000000000000000000072061267532330400237040ustar00rootroot00000000000000# 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. SUBDIRS = brw fb AM_CFLAGS = \ @CWARNFLAGS@ \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/render_program \ $(XORG_CFLAGS) \ $(UDEV_CFLAGS) \ $(DRM_CFLAGS) \ $(NULL) if VALGRIND AM_CFLAGS += $(VALGRIND_CFLAGS) endif noinst_LTLIBRARIES = libsna.la libsna_la_LDFLAGS = -pthread libsna_la_LIBADD = $(UDEV_LIBS) -lm $(DRM_LIBS) brw/libbrw.la fb/libfb.la ../../libobj/libcompat.la libsna_la_SOURCES = \ atomic.h \ blt.c \ compiler.h \ debug.h \ kgem.c \ kgem.h \ rop.h \ sna.h \ sna_accel.c \ sna_acpi.c \ sna_blt.c \ sna_composite.c \ sna_cpu.c \ sna_cpuid.h \ sna_damage.c \ sna_damage.h \ sna_display.c \ sna_display_fake.c \ sna_driver.c \ sna_glyphs.c \ sna_gradient.c \ sna_io.c \ sna_module.h \ sna_render.c \ sna_render.h \ sna_render_inline.h \ sna_reg.h \ sna_stream.c \ sna_trapezoids.h \ sna_trapezoids.c \ sna_trapezoids_boxes.c \ sna_trapezoids_imprecise.c \ sna_trapezoids_mono.c \ sna_trapezoids_precise.c \ sna_tiling.c \ sna_transform.c \ sna_threads.c \ sna_vertex.c \ sna_video.c \ sna_video.h \ sna_video_overlay.c \ sna_video_sprite.c \ sna_video_textured.c \ gen2_render.c \ gen2_render.h \ gen3_render.c \ gen3_render.h \ gen4_common.c \ gen4_common.h \ gen4_render.c \ gen4_render.h \ gen4_source.c \ gen4_source.h \ gen4_vertex.c \ gen4_vertex.h \ gen5_render.c \ gen5_render.h \ gen6_common.c \ gen6_common.h \ gen6_render.c \ gen6_render.h \ gen7_render.c \ gen7_render.h \ gen8_eu.c \ gen8_eu.h \ gen8_render.c \ gen8_render.h \ gen8_vertex.c \ gen8_vertex.h \ xassert.h \ $(NULL) if DRI2 AM_CFLAGS += $(DRI2_CFLAGS) libsna_la_SOURCES += sna_dri2.c libsna_la_LIBADD += $(DRI2_LIBS) @CLOCK_GETTIME_LIBS@ endif if DRI3 AM_CFLAGS += $(DRI3_CFLAGS) libsna_la_SOURCES += sna_dri3.c libsna_la_LIBADD += $(DRI3_LIBS) endif if PRESENT AM_CFLAGS += $(PRESENT_CFLAGS) libsna_la_SOURCES += sna_present.c libsna_la_LIBADD += $(PRESENT_LIBS) endif if XVMC libsna_la_SOURCES += \ sna_video_hwmc.h \ sna_video_hwmc.c \ $(NULL) endif if FULL_DEBUG libsna_la_SOURCES += \ kgem_debug.c \ kgem_debug.h \ kgem_debug_gen2.c \ kgem_debug_gen3.c \ kgem_debug_gen4.c \ kgem_debug_gen5.c \ kgem_debug_gen6.c \ kgem_debug_gen7.c \ $(NULL) endif if HAVE_DOT_GIT git_version.h: $(top_srcdir)/.git/HEAD $(shell sed -e '/ref:/!d' -e 's#ref: *#$(top_srcdir)/.git/#' < $(top_srcdir)/.git/HEAD) @echo "Recording git-tree used for compilation: `git describe`" @V=`git describe`; echo "static const char git_version[] = \"$$V\";" > git_version.h sna_driver.c: git_version.h endif AM_CFLAGS += @NOWARNFLAGS@ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/README000066400000000000000000000033061267532330400225250ustar00rootroot00000000000000SandyBridge's New Acceleration ------------------------------ The guiding principle behind the design is to avoid GPU context switches. On SandyBridge (and beyond), these are especially pernicious because the RENDER and BLT engine are now on different rings and require synchronisation of the various execution units when switching contexts. They were not cheap on early generation, but with the increasing complexity of the GPU, avoiding such serialisations is important. Furthermore, we try very hard to avoid migrating between the CPU and GPU. Every pixmap (apart from temporary "scratch" surfaces which we intend to use on the GPU) is created in system memory. All operations are then done upon this shadow copy until we are forced to move it onto the GPU. Such migration can only be first triggered by: setting the pixmap as the scanout (we obviously need a GPU buffer here), using the pixmap as a DRI buffer (the client expects to perform hardware acceleration and we do not want to disappoint) and lastly using the pixmap as a RENDER target. This last is chosen because when we know we are going to perform hardware acceleration and will continue to do so without fallbacks, using the GPU is much, much faster than the CPU. The heuristic I chose therefore was that if the application uses RENDER, i.e. cairo, then it will only be using those paths and not intermixing core drawing operations and so unlikely to trigger a fallback. The complicating case is front-buffer rendering. So in order to accommodate using RENDER on an application whilst running xterm without a composite manager redirecting all the pixmaps to backing surfaces, we have to perform damage tracking to avoid excess migration of portions of the buffer. xserver-xorg-video-intel-2.99.917+git20160325/src/sna/atomic.h000066400000000000000000000062261267532330400232760ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef ATOMIC_H #define ATOMIC_H #if HAVE_ATOMIC_PRIMITIVES #define HAS_ATOMIC_OPS 1 typedef struct { int atomic; } atomic_t; # define atomic_read(x) ((x)->atomic) # define atomic_set(x, val) ((x)->atomic = (val)) # define atomic_inc(x) ((void) __sync_fetch_and_add (&(x)->atomic, 1)) # define atomic_dec_and_test(x) (__sync_fetch_and_add (&(x)->atomic, -1) == 1) # define atomic_add(x, v) ((void) __sync_add_and_fetch(&(x)->atomic, (v))) # define atomic_dec(x, v) ((void) __sync_sub_and_fetch(&(x)->atomic, (v))) # define atomic_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (&(x)->atomic, oldv, newv) #endif #if HAVE_LIB_ATOMIC_OPS #include #define HAS_ATOMIC_OPS 1 typedef struct { AO_t atomic; } atomic_t; # define atomic_read(x) AO_load_full(&(x)->atomic) # define atomic_set(x, val) AO_store_full(&(x)->atomic, (val)) # define atomic_inc(x) ((void) AO_fetch_and_add1_full(&(x)->atomic)) # define atomic_add(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, (v))) # define atomic_dec(x, v) ((void) AO_fetch_and_add_full(&(x)->atomic, -(v))) # define atomic_dec_and_test(x) (AO_fetch_and_sub1_full(&(x)->atomic) == 1) # define atomic_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(&(x)->atomic, oldv, newv) #endif #if defined(__sun) && !defined(HAS_ATOMIC_OPS) /* Solaris & OpenSolaris */ #include #define HAS_ATOMIC_OPS 1 typedef struct { uint_t atomic; } atomic_t; # define atomic_read(x) (int) ((x)->atomic) # define atomic_set(x, val) ((x)->atomic = (uint_t)(val)) # define atomic_inc(x) (atomic_inc_uint (&(x)->atomic)) # define atomic_dec_and_test(x) (atomic_dec_uint_nv(&(x)->atomic) == 1) # define atomic_add(x, v) (atomic_add_int(&(x)->atomic, (v))) # define atomic_dec(x, v) (atomic_add_int(&(x)->atomic, -(v))) # define atomic_cmpxchg(x, oldv, newv) atomic_cas_uint (&(x)->atomic, oldv, newv) #endif #if ! HAS_ATOMIC_OPS #error xf86-video-intel requires atomic operations, please define them for your CPU/compiler. #endif #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/blt.c000066400000000000000000000747621267532330400226100ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include #if __x86_64__ #define USE_SSE2 1 #endif #if USE_SSE2 #include #if __x86_64__ #define have_sse2() 1 #else enum { MMX = 0x1, MMX_EXTENSIONS = 0x2, SSE = 0x6, SSE2 = 0x8, CMOV = 0x10 }; #ifdef __GNUC__ static unsigned int detect_cpu_features(void) { unsigned int features; unsigned int result = 0; char vendor[13]; vendor[0] = 0; vendor[12] = 0; asm ( "pushf\n" "pop %%eax\n" "mov %%eax, %%ecx\n" "xor $0x00200000, %%eax\n" "push %%eax\n" "popf\n" "pushf\n" "pop %%eax\n" "mov $0x0, %%edx\n" "xor %%ecx, %%eax\n" "jz 1f\n" "mov $0x00000000, %%eax\n" "push %%ebx\n" "cpuid\n" "mov %%ebx, %%eax\n" "pop %%ebx\n" "mov %%eax, %1\n" "mov %%edx, %2\n" "mov %%ecx, %3\n" "mov $0x00000001, %%eax\n" "push %%ebx\n" "cpuid\n" "pop %%ebx\n" "1:\n" "mov %%edx, %0\n" : "=r" (result), "=m" (vendor[0]), "=m" (vendor[4]), "=m" (vendor[8]) :: "%eax", "%ecx", "%edx"); features = 0; if (result) { /* result now contains the standard feature bits */ if (result & (1 << 15)) features |= CMOV; if (result & (1 << 23)) features |= MMX; if (result & (1 << 25)) features |= SSE; if (result & (1 << 26)) features |= SSE2; } return features; } #else static unsigned int detect_cpu_features(void) { return 0; } #endif static bool have_sse2(void) { static int sse2_present = -1; if (sse2_present == -1) sse2_present = detect_cpu_features() & SSE2; return sse2_present; } #endif static inline __m128i xmm_create_mask_32(uint32_t mask) { return _mm_set_epi32(mask, mask, mask, mask); } static inline __m128i xmm_load_128u(const __m128i *src) { return _mm_loadu_si128(src); } static inline void xmm_save_128(__m128i *dst, __m128i data) { _mm_store_si128(dst, data); } #endif fast void memcpy_blt(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { const uint8_t *src_bytes; uint8_t *dst_bytes; int byte_width; assert(src); assert(dst); assert(width && height); assert(bpp >= 8); assert(width*bpp <= 8*src_stride); assert(width*bpp <= 8*dst_stride); DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); bpp /= 8; src_bytes = (const uint8_t *)src + src_stride * src_y + src_x * bpp; dst_bytes = (uint8_t *)dst + dst_stride * dst_y + dst_x * bpp; byte_width = width * bpp; if (byte_width == src_stride && byte_width == dst_stride) { byte_width *= height; height = 1; } switch (byte_width) { case 1: do { *dst_bytes = *src_bytes; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 2: do { *(uint16_t *)dst_bytes = *(const uint16_t *)src_bytes; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 4: do { *(uint32_t *)dst_bytes = *(const uint32_t *)src_bytes; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 8: do { *(uint64_t *)dst_bytes = *(const uint64_t *)src_bytes; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 16: do { ((uint64_t *)dst_bytes)[0] = ((const uint64_t *)src_bytes)[0]; ((uint64_t *)dst_bytes)[1] = ((const uint64_t *)src_bytes)[1]; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; default: do { memcpy(dst_bytes, src_bytes, byte_width); src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; } } static fast_memcpy void memcpy_to_tiled_x__swizzle_0(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { const unsigned tile_width = 512; const unsigned tile_height = 8; const unsigned tile_size = 4096; const unsigned cpp = bpp / 8; const unsigned tile_pixels = tile_width / cpp; const unsigned tile_shift = ffs(tile_pixels) - 1; const unsigned tile_mask = tile_pixels - 1; DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); assert(src != dst); if (src_x | src_y) src = (const uint8_t *)src + src_y * src_stride + src_x * cpp; assert(src_stride >= width * cpp); src_stride -= width * cpp; while (height--) { unsigned w = width * cpp; uint8_t *tile_row = dst; tile_row += dst_y / tile_height * dst_stride * tile_height; tile_row += (dst_y & (tile_height-1)) * tile_width; if (dst_x) { tile_row += (dst_x >> tile_shift) * tile_size; if (dst_x & tile_mask) { const unsigned x = (dst_x & tile_mask) * cpp; const unsigned len = min(tile_width - x, w); memcpy(tile_row + x, src, len); tile_row += tile_size; src = (const uint8_t *)src + len; w -= len; } } while (w >= tile_width) { memcpy(tile_row, src, tile_width); tile_row += tile_size; src = (const uint8_t *)src + tile_width; w -= tile_width; } memcpy(tile_row, src, w); src = (const uint8_t *)src + src_stride + w; dst_y++; } } static fast_memcpy void memcpy_from_tiled_x__swizzle_0(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { const unsigned tile_width = 512; const unsigned tile_height = 8; const unsigned tile_size = 4096; const unsigned cpp = bpp / 8; const unsigned tile_pixels = tile_width / cpp; const unsigned tile_shift = ffs(tile_pixels) - 1; const unsigned tile_mask = tile_pixels - 1; DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); assert(src != dst); if (dst_x | dst_y) dst = (uint8_t *)dst + dst_y * dst_stride + dst_x * cpp; assert(dst_stride >= width * cpp); dst_stride -= width * cpp; while (height--) { unsigned w = width * cpp; const uint8_t *tile_row = src; tile_row += src_y / tile_height * src_stride * tile_height; tile_row += (src_y & (tile_height-1)) * tile_width; if (src_x) { tile_row += (src_x >> tile_shift) * tile_size; if (src_x & tile_mask) { const unsigned x = (src_x & tile_mask) * cpp; const unsigned len = min(tile_width - x, w); memcpy(dst, tile_row + x, len); tile_row += tile_size; dst = (uint8_t *)dst + len; w -= len; } } while (w >= tile_width) { memcpy(dst, tile_row, tile_width); tile_row += tile_size; dst = (uint8_t *)dst + tile_width; w -= tile_width; } memcpy(dst, tile_row, w); dst = (uint8_t *)dst + dst_stride + w; src_y++; } } #define memcpy_to_tiled_x(swizzle) \ fast_memcpy static void \ memcpy_to_tiled_x__##swizzle (const void *src, void *dst, int bpp, \ int32_t src_stride, int32_t dst_stride, \ int16_t src_x, int16_t src_y, \ int16_t dst_x, int16_t dst_y, \ uint16_t width, uint16_t height) \ { \ const unsigned tile_width = 512; \ const unsigned tile_height = 8; \ const unsigned tile_size = 4096; \ const unsigned cpp = bpp / 8; \ const unsigned stride_tiles = dst_stride / tile_width; \ const unsigned swizzle_pixels = 64 / cpp; \ const unsigned tile_pixels = ffs(tile_width / cpp) - 1; \ const unsigned tile_mask = (1 << tile_pixels) - 1; \ unsigned x, y; \ DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", \ __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); \ src = (const uint8_t *)src + src_y * src_stride + src_x * cpp; \ for (y = 0; y < height; ++y) { \ const uint32_t dy = y + dst_y; \ const uint32_t tile_row = \ (dy / tile_height * stride_tiles * tile_size + \ (dy & (tile_height-1)) * tile_width); \ const uint8_t *src_row = (const uint8_t *)src + src_stride * y; \ uint32_t dx = dst_x; \ x = width * cpp; \ if (dx & (swizzle_pixels - 1)) { \ const uint32_t swizzle_bound_pixels = ALIGN(dx + 1, swizzle_pixels); \ const uint32_t length = min(dst_x + width, swizzle_bound_pixels) - dx; \ uint32_t offset = \ tile_row + \ (dx >> tile_pixels) * tile_size + \ (dx & tile_mask) * cpp; \ memcpy((char *)dst + swizzle(offset), src_row, length * cpp); \ src_row += length * cpp; \ x -= length * cpp; \ dx += length; \ } \ while (x >= 64) { \ uint32_t offset = \ tile_row + \ (dx >> tile_pixels) * tile_size + \ (dx & tile_mask) * cpp; \ memcpy((char *)dst + swizzle(offset), src_row, 64); \ src_row += 64; \ x -= 64; \ dx += swizzle_pixels; \ } \ if (x) { \ uint32_t offset = \ tile_row + \ (dx >> tile_pixels) * tile_size + \ (dx & tile_mask) * cpp; \ memcpy((char *)dst + swizzle(offset), src_row, x); \ } \ } \ } #define memcpy_from_tiled_x(swizzle) \ fast_memcpy static void \ memcpy_from_tiled_x__##swizzle (const void *src, void *dst, int bpp, \ int32_t src_stride, int32_t dst_stride, \ int16_t src_x, int16_t src_y, \ int16_t dst_x, int16_t dst_y, \ uint16_t width, uint16_t height) \ { \ const unsigned tile_width = 512; \ const unsigned tile_height = 8; \ const unsigned tile_size = 4096; \ const unsigned cpp = bpp / 8; \ const unsigned stride_tiles = src_stride / tile_width; \ const unsigned swizzle_pixels = 64 / cpp; \ const unsigned tile_pixels = ffs(tile_width / cpp) - 1; \ const unsigned tile_mask = (1 << tile_pixels) - 1; \ unsigned x, y; \ DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", \ __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); \ dst = (uint8_t *)dst + dst_y * dst_stride + dst_x * cpp; \ for (y = 0; y < height; ++y) { \ const uint32_t sy = y + src_y; \ const uint32_t tile_row = \ (sy / tile_height * stride_tiles * tile_size + \ (sy & (tile_height-1)) * tile_width); \ uint8_t *dst_row = (uint8_t *)dst + dst_stride * y; \ uint32_t sx = src_x; \ x = width * cpp; \ if (sx & (swizzle_pixels - 1)) { \ const uint32_t swizzle_bound_pixels = ALIGN(sx + 1, swizzle_pixels); \ const uint32_t length = min(src_x + width, swizzle_bound_pixels) - sx; \ uint32_t offset = \ tile_row + \ (sx >> tile_pixels) * tile_size + \ (sx & tile_mask) * cpp; \ memcpy(dst_row, (const char *)src + swizzle(offset), length * cpp); \ dst_row += length * cpp; \ x -= length * cpp; \ sx += length; \ } \ while (x >= 64) { \ uint32_t offset = \ tile_row + \ (sx >> tile_pixels) * tile_size + \ (sx & tile_mask) * cpp; \ memcpy(dst_row, (const char *)src + swizzle(offset), 64); \ dst_row += 64; \ x -= 64; \ sx += swizzle_pixels; \ } \ if (x) { \ uint32_t offset = \ tile_row + \ (sx >> tile_pixels) * tile_size + \ (sx & tile_mask) * cpp; \ memcpy(dst_row, (const char *)src + swizzle(offset), x); \ } \ } \ } #define swizzle_9(X) ((X) ^ (((X) >> 3) & 64)) memcpy_to_tiled_x(swizzle_9) memcpy_from_tiled_x(swizzle_9) #undef swizzle_9 #define swizzle_9_10(X) ((X) ^ ((((X) ^ ((X) >> 1)) >> 3) & 64)) memcpy_to_tiled_x(swizzle_9_10) memcpy_from_tiled_x(swizzle_9_10) #undef swizzle_9_10 #define swizzle_9_11(X) ((X) ^ ((((X) ^ ((X) >> 2)) >> 3) & 64)) memcpy_to_tiled_x(swizzle_9_11) memcpy_from_tiled_x(swizzle_9_11) #undef swizzle_9_11 #define swizzle_9_10_11(X) ((X) ^ ((((X) ^ ((X) >> 1) ^ ((X) >> 2)) >> 3) & 64)) memcpy_to_tiled_x(swizzle_9_10_11) memcpy_from_tiled_x(swizzle_9_10_11) #undef swizzle_9_10_11 static fast_memcpy void memcpy_to_tiled_x__gen2(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { const unsigned tile_width = 128; const unsigned tile_height = 16; const unsigned tile_size = 2048; const unsigned cpp = bpp / 8; const unsigned tile_pixels = tile_width / cpp; const unsigned tile_shift = ffs(tile_pixels) - 1; const unsigned tile_mask = tile_pixels - 1; DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); assert(src != dst); if (src_x | src_y) src = (const uint8_t *)src + src_y * src_stride + src_x * cpp; assert(src_stride >= width * cpp); src_stride -= width * cpp; while (height--) { unsigned w = width * cpp; uint8_t *tile_row = dst; tile_row += dst_y / tile_height * dst_stride * tile_height; tile_row += (dst_y & (tile_height-1)) * tile_width; if (dst_x) { tile_row += (dst_x >> tile_shift) * tile_size; if (dst_x & tile_mask) { const unsigned x = (dst_x & tile_mask) * cpp; const unsigned len = min(tile_width - x, w); memcpy(tile_row + x, src, len); tile_row += tile_size; src = (const uint8_t *)src + len; w -= len; } } while (w >= tile_width) { memcpy(tile_row, src, tile_width); tile_row += tile_size; src = (const uint8_t *)src + tile_width; w -= tile_width; } memcpy(tile_row, src, w); src = (const uint8_t *)src + src_stride + w; dst_y++; } } static fast_memcpy void memcpy_from_tiled_x__gen2(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { const unsigned tile_width = 128; const unsigned tile_height = 16; const unsigned tile_size = 2048; const unsigned cpp = bpp / 8; const unsigned tile_pixels = tile_width / cpp; const unsigned tile_shift = ffs(tile_pixels) - 1; const unsigned tile_mask = tile_pixels - 1; DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n", __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride)); assert(src != dst); if (dst_x | dst_y) dst = (uint8_t *)dst + dst_y * dst_stride + dst_x * cpp; assert(dst_stride >= width * cpp); dst_stride -= width * cpp; while (height--) { unsigned w = width * cpp; const uint8_t *tile_row = src; tile_row += src_y / tile_height * src_stride * tile_height; tile_row += (src_y & (tile_height-1)) * tile_width; if (src_x) { tile_row += (src_x >> tile_shift) * tile_size; if (src_x & tile_mask) { const unsigned x = (src_x & tile_mask) * cpp; const unsigned len = min(tile_width - x, w); memcpy(dst, tile_row + x, len); tile_row += tile_size; dst = (uint8_t *)dst + len; w -= len; } } while (w >= tile_width) { memcpy(dst, tile_row, tile_width); tile_row += tile_size; dst = (uint8_t *)dst + tile_width; w -= tile_width; } memcpy(dst, tile_row, w); dst = (uint8_t *)dst + dst_stride + w; src_y++; } } void choose_memcpy_tiled_x(struct kgem *kgem, int swizzling) { if (kgem->gen < 030) { if (swizzling == I915_BIT_6_SWIZZLE_NONE) { DBG(("%s: gen2, no swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__gen2; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__gen2; } else DBG(("%s: no detiling with swizzle functions for gen2\n", __FUNCTION__)); return; } switch (swizzling) { default: DBG(("%s: unknown swizzling, %d\n", __FUNCTION__, swizzling)); break; case I915_BIT_6_SWIZZLE_NONE: DBG(("%s: no swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__swizzle_0; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__swizzle_0; break; case I915_BIT_6_SWIZZLE_9: DBG(("%s: 6^9 swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__swizzle_9; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__swizzle_9; break; case I915_BIT_6_SWIZZLE_9_10: DBG(("%s: 6^9^10 swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__swizzle_9_10; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__swizzle_9_10; break; case I915_BIT_6_SWIZZLE_9_11: DBG(("%s: 6^9^11 swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__swizzle_9_11; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__swizzle_9_11; break; case I915_BIT_6_SWIZZLE_9_10_11: DBG(("%s: 6^9^10^11 swizzling\n", __FUNCTION__)); kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__swizzle_9_10_11; kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__swizzle_9_10_11; break; } } void memmove_box(const void *src, void *dst, int bpp, int32_t stride, const BoxRec *box, int dx, int dy) { #define FORCE_MEMMOVE 0 union { uint8_t u8; uint16_t u16; uint32_t u32; uint64_t u64; } tmp; const uint8_t *src_bytes; uint8_t *dst_bytes; int width, height; assert(src); assert(dst); assert(src != dst); assert(bpp >= 8); assert(box->x2 > box->x1); assert(box->y2 > box->y1); DBG(("%s: box=(%d, %d), (%d, %d), pitch=%d, bpp=%d, dx=%d, dy=%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp, dx, dy)); bpp /= 8; width = box->y1 * stride + box->x1 * bpp; src_bytes = (const uint8_t *)src + width; dst_bytes = (uint8_t *)dst + width; assert(dst_bytes != src_bytes); width = (box->x2 - box->x1) * bpp; height = (box->y2 - box->y1); assert(width <= stride); if (width == stride) { width *= height; height = 1; } if (dy >= 0) { switch (width) { case 1: do { *dst_bytes = tmp.u8 = *src_bytes; src_bytes += stride; dst_bytes += stride; } while (--height); break; case 2: do { *(uint16_t *)dst_bytes = tmp.u16 = *(const uint16_t *)src_bytes; src_bytes += stride; dst_bytes += stride; } while (--height); break; case 4: do { *(uint32_t *)dst_bytes = tmp.u32 = *(const uint32_t *)src_bytes; src_bytes += stride; dst_bytes += stride; } while (--height); break; case 8: do { *(uint64_t *)dst_bytes = tmp.u64 = *(const uint64_t *)src_bytes; src_bytes += stride; dst_bytes += stride; } while (--height); break; default: if (FORCE_MEMMOVE || (dst_bytes < src_bytes + width && src_bytes < dst_bytes + width)) { do { memmove(dst_bytes, src_bytes, width); src_bytes += stride; dst_bytes += stride; } while (--height); } else { do { memcpy(dst_bytes, src_bytes, width); src_bytes += stride; dst_bytes += stride; } while (--height); } break; } } else { src_bytes += (height-1) * stride; dst_bytes += (height-1) * stride; switch (width) { case 1: do { *dst_bytes = tmp.u8 = *src_bytes; src_bytes -= stride; dst_bytes -= stride; } while (--height); break; case 2: do { *(uint16_t *)dst_bytes = tmp.u16 = *(const uint16_t *)src_bytes; src_bytes -= stride; dst_bytes -= stride; } while (--height); break; case 4: do { *(uint32_t *)dst_bytes = tmp.u32 = *(const uint32_t *)src_bytes; src_bytes -= stride; dst_bytes -= stride; } while (--height); break; case 8: do { *(uint64_t *)dst_bytes = tmp.u64 = *(const uint64_t *)src_bytes; src_bytes -= stride; dst_bytes -= stride; } while (--height); break; default: if (FORCE_MEMMOVE || (dst_bytes < src_bytes + width && src_bytes < dst_bytes + width)) { do { memmove(dst_bytes, src_bytes, width); src_bytes -= stride; dst_bytes -= stride; } while (--height); } else { do { memcpy(dst_bytes, src_bytes, width); src_bytes -= stride; dst_bytes -= stride; } while (--height); } break; } } } void memcpy_xor(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height, uint32_t and, uint32_t or) { const uint8_t *src_bytes; uint8_t *dst_bytes; int i, w; assert(width && height); assert(bpp >= 8); assert(width*bpp <= 8*src_stride); assert(width*bpp <= 8*dst_stride); DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d, bpp=%d, and=%x, xor=%x\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride, bpp, and, or)); bpp /= 8; src_bytes = (const uint8_t *)src + src_stride * src_y + src_x * bpp; dst_bytes = (uint8_t *)dst + dst_stride * dst_y + dst_x * bpp; if (and == 0xffffffff) { switch (bpp) { case 1: if (width & 1) { do { for (i = 0; i < width; i++) dst_bytes[i] = src_bytes[i] | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; } else { width /= 2; or |= or << 8; } case 2: if (width & 1) { do { uint16_t *d = (uint16_t *)dst_bytes; const uint16_t *s = (const uint16_t *)src_bytes; for (i = 0; i < width; i++) d[i] = s[i] | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; } else { width /= 2; or |= or << 16; } case 4: w = width; if (w * 4 == dst_stride && dst_stride == src_stride) { w *= height; height = 1; } #if USE_SSE2 if (have_sse2()) { do { uint32_t *d = (uint32_t *)dst_bytes; const uint32_t *s = (const uint32_t *)src_bytes; __m128i mask = xmm_create_mask_32(or); i = w; while (i && (uintptr_t)d & 15) { *d++ = *s++ | or; i--; } while (i >= 16) { __m128i xmm1, xmm2, xmm3, xmm4; xmm1 = xmm_load_128u((const __m128i*)s + 0); xmm2 = xmm_load_128u((const __m128i*)s + 1); xmm3 = xmm_load_128u((const __m128i*)s + 2); xmm4 = xmm_load_128u((const __m128i*)s + 3); xmm_save_128((__m128i*)d + 0, _mm_or_si128(xmm1, mask)); xmm_save_128((__m128i*)d + 1, _mm_or_si128(xmm2, mask)); xmm_save_128((__m128i*)d + 2, _mm_or_si128(xmm3, mask)); xmm_save_128((__m128i*)d + 3, _mm_or_si128(xmm4, mask)); d += 16; s += 16; i -= 16; } if (i & 8) { __m128i xmm1, xmm2; xmm1 = xmm_load_128u((const __m128i*)s + 0); xmm2 = xmm_load_128u((const __m128i*)s + 1); xmm_save_128((__m128i*)d + 0, _mm_or_si128(xmm1, mask)); xmm_save_128((__m128i*)d + 1, _mm_or_si128(xmm2, mask)); d += 8; s += 8; i -= 8; } if (i & 4) { xmm_save_128((__m128i*)d, _mm_or_si128(xmm_load_128u((const __m128i*)s), mask)); d += 4; s += 4; i -= 4; } while (i) { *d++ = *s++ | or; i--; } src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); } else #else do { uint32_t *d = (uint32_t *)dst_bytes; uint32_t *s = (uint32_t *)src_bytes; for (i = 0; i < w; i++) d[i] = s[i] | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); #endif break; } } else { switch (bpp) { case 1: do { for (i = 0; i < width; i++) dst_bytes[i] = (src_bytes[i] & and) | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 2: do { uint16_t *d = (uint16_t *)dst_bytes; const uint16_t *s = (const uint16_t *)src_bytes; for (i = 0; i < width; i++) d[i] = (s[i] & and) | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; case 4: do { uint32_t *d = (uint32_t *)dst_bytes; const uint32_t *s = (const uint32_t *)src_bytes; for (i = 0; i < width; i++) d[i] = (s[i] & and) | or; src_bytes += src_stride; dst_bytes += dst_stride; } while (--height); break; } } } #define BILINEAR_INTERPOLATION_BITS 4 static inline int bilinear_weight(pixman_fixed_t x) { return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & ((1 << BILINEAR_INTERPOLATION_BITS) - 1); } #if BILINEAR_INTERPOLATION_BITS <= 4 /* Inspired by Filter_32_opaque from Skia */ static inline uint32_t bilinear_interpolation(uint32_t tl, uint32_t tr, uint32_t bl, uint32_t br, int distx, int disty) { int distxy, distxiy, distixy, distixiy; uint32_t lo, hi; distx <<= (4 - BILINEAR_INTERPOLATION_BITS); disty <<= (4 - BILINEAR_INTERPOLATION_BITS); distxy = distx * disty; distxiy = (distx << 4) - distxy; /* distx * (16 - disty) */ distixy = (disty << 4) - distxy; /* disty * (16 - distx) */ distixiy = 16 * 16 - (disty << 4) - (distx << 4) + distxy; /* (16 - distx) * (16 - disty) */ lo = (tl & 0xff00ff) * distixiy; hi = ((tl >> 8) & 0xff00ff) * distixiy; lo += (tr & 0xff00ff) * distxiy; hi += ((tr >> 8) & 0xff00ff) * distxiy; lo += (bl & 0xff00ff) * distixy; hi += ((bl >> 8) & 0xff00ff) * distixy; lo += (br & 0xff00ff) * distxy; hi += ((br >> 8) & 0xff00ff) * distxy; return ((lo >> 8) & 0xff00ff) | (hi & ~0xff00ff); } #elif SIZEOF_LONG > 4 static inline uint32_t bilinear_interpolation(uint32_t tl, uint32_t tr, uint32_t bl, uint32_t br, int distx, int disty) { uint64_t distxy, distxiy, distixy, distixiy; uint64_t tl64, tr64, bl64, br64; uint64_t f, r; distx <<= (8 - BILINEAR_INTERPOLATION_BITS); disty <<= (8 - BILINEAR_INTERPOLATION_BITS); distxy = distx * disty; distxiy = distx * (256 - disty); distixy = (256 - distx) * disty; distixiy = (256 - distx) * (256 - disty); /* Alpha and Blue */ tl64 = tl & 0xff0000ff; tr64 = tr & 0xff0000ff; bl64 = bl & 0xff0000ff; br64 = br & 0xff0000ff; f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; r = f & 0x0000ff0000ff0000ull; /* Red and Green */ tl64 = tl; tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); tr64 = tr; tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); bl64 = bl; bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); br64 = br; br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); return (uint32_t)(r >> 16); } #else static inline uint32_t bilinear_interpolation(uint32_t tl, uint32_t tr, uint32_t bl, uint32_t br, int distx, int disty) { int distxy, distxiy, distixy, distixiy; uint32_t f, r; distx <<= (8 - BILINEAR_INTERPOLATION_BITS); disty <<= (8 - BILINEAR_INTERPOLATION_BITS); distxy = distx * disty; distxiy = (distx << 8) - distxy; /* distx * (256 - disty) */ distixy = (disty << 8) - distxy; /* disty * (256 - distx) */ distixiy = 256 * 256 - (disty << 8) - (distx << 8) + distxy; /* (256 - distx) * (256 - disty) */ /* Blue */ r = ((tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy + (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy); /* Green */ f = ((tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy + (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy); r |= f & 0xff000000; tl >>= 16; tr >>= 16; bl >>= 16; br >>= 16; r >>= 16; /* Red */ f = ((tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy + (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy); r |= f & 0x00ff0000; /* Alpha */ f = ((tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy + (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy); r |= f & 0xff000000; return r; } #endif static inline uint32_t convert_pixel(const uint8_t *p, int x) { return ((uint32_t *)p)[x]; } fast void affine_blt(const void *src, void *dst, int bpp, int16_t src_x, int16_t src_y, int16_t src_width, int16_t src_height, int32_t src_stride, int16_t dst_x, int16_t dst_y, uint16_t dst_width, uint16_t dst_height, int32_t dst_stride, const struct pixman_f_transform *t) { static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; const pixman_fixed_t ux = pixman_double_to_fixed(t->m[0][0]); const pixman_fixed_t uy = pixman_double_to_fixed(t->m[1][0]); int i, j; assert(bpp == 32); for (j = 0; j < dst_height; j++) { pixman_fixed_t x, y; struct pixman_f_vector v; uint32_t *b; /* reference point is the center of the pixel */ v.v[0] = dst_x + 0.5; v.v[1] = dst_y + j + 0.5; v.v[2] = 1.0; pixman_f_transform_point_3d(t, &v); x = pixman_double_to_fixed(v.v[0]); x += pixman_int_to_fixed(src_x - dst_x); y = pixman_double_to_fixed(v.v[1]); y += pixman_int_to_fixed(src_y - dst_y); b = (uint32_t*)((uint8_t *)dst + (dst_y + j) * dst_stride + dst_x * bpp / 8); for (i = 0; i < dst_width; i++) { const uint8_t *row1; const uint8_t *row2; int x1, y1, x2, y2; uint32_t tl, tr, bl, br; int32_t fx, fy; x1 = x - pixman_fixed_1/2; y1 = y - pixman_fixed_1/2; fx = bilinear_weight(x1); fy = bilinear_weight(y1); x1 = pixman_fixed_to_int(x1); x2 = x1 + 1; y1 = pixman_fixed_to_int(y1); y2 = y1 + 1; if (x1 >= src_width || x2 < 0 || y1 >= src_height || y2 < 0) { b[i] = 0; goto next; } if (y2 == 0) { row1 = zero; } else { row1 = (uint8_t *)src + src_stride * y1; row1 += bpp / 8 * x1; } if (y1 == src_height - 1) { row2 = zero; } else { row2 = (uint8_t *)src + src_stride * y2; row2 += bpp / 8 * x1; } if (x2 == 0) { tl = 0; bl = 0; } else { tl = convert_pixel(row1, 0); bl = convert_pixel(row2, 0); } if (x1 == src_width - 1) { tr = 0; br = 0; } else { tr = convert_pixel(row1, 1); br = convert_pixel(row2, 1); } b[i] = bilinear_interpolation(tl, tr, bl, br, fx, fy); next: x += ux; y += uy; } } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/000077500000000000000000000000001267532330400224355ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/Makefile.am000066400000000000000000000032521267532330400244730ustar00rootroot00000000000000 # 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. noinst_LTLIBRARIES = libbrw.la noinst_PROGRAMS = brw_test AM_CFLAGS = \ @CWARNFLAGS@ \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/render_program \ @XORG_CFLAGS@ \ @UDEV_CFLAGS@ \ @DRM_CFLAGS@ \ $(NULL) if DEBUG AM_CFLAGS += @VALGRIND_CFLAGS@ endif libbrw_la_SOURCES = \ brw.h \ brw_disasm.c \ brw_eu.h \ brw_eu.c \ brw_eu_emit.c \ brw_sf.c \ brw_wm.c \ $(NULL) brw_test_SOURCES = \ brw_test.c \ brw_test.h \ brw_test_gen4.c \ brw_test_gen5.c \ brw_test_gen6.c \ brw_test_gen7.c \ $(NULL) brw_test_LDADD = \ libbrw.la \ $(NULL) AM_CFLAGS += @NOWARNFLAGS@ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw.h000066400000000000000000000016201267532330400233770ustar00rootroot00000000000000#include "brw_eu.h" bool brw_sf_kernel__nomask(struct brw_compile *p); bool brw_sf_kernel__mask(struct brw_compile *p); bool brw_wm_kernel__affine(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__affine_mask(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__projective(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__projective_mask(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch_width); bool brw_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch_width); xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_disasm.c000066400000000000000000000741261267532330400247450ustar00rootroot00000000000000/* * Copyright © 2008 Keith Packard * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include #include #include #include #include #include #include "brw_eu.h" static const struct { const char *name; int nsrc; int ndst; } opcode[128] = { [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_PLN] = { .name = "pln", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_MATH] = { .name = "math", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_SENDC] = { .name = "sendc", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 }, [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 2, .ndst = 1 }, [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 }, [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 }, [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 }, [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 }, [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 }, }; static const char *conditional_modifier[16] = { [BRW_CONDITIONAL_NONE] = "", [BRW_CONDITIONAL_Z] = ".e", [BRW_CONDITIONAL_NZ] = ".ne", [BRW_CONDITIONAL_G] = ".g", [BRW_CONDITIONAL_GE] = ".ge", [BRW_CONDITIONAL_L] = ".l", [BRW_CONDITIONAL_LE] = ".le", [BRW_CONDITIONAL_R] = ".r", [BRW_CONDITIONAL_O] = ".o", [BRW_CONDITIONAL_U] = ".u", }; static const char *negate[2] = { [0] = "", [1] = "-", }; static const char *_abs[2] = { [0] = "", [1] = "(abs)", }; static const char *vert_stride[16] = { [0] = "0", [1] = "1", [2] = "2", [3] = "4", [4] = "8", [5] = "16", [6] = "32", [15] = "VxH", }; static const char *width[8] = { [0] = "1", [1] = "2", [2] = "4", [3] = "8", [4] = "16", }; static const char *horiz_stride[4] = { [0] = "0", [1] = "1", [2] = "2", [3] = "4" }; static const char *chan_sel[4] = { [0] = "x", [1] = "y", [2] = "z", [3] = "w", }; #if 0 static const char *dest_condmod[16] = { }; static const char *imm_encoding[8] = { [0] = "UD", [1] = "D", [2] = "UW", [3] = "W", [5] = "VF", [6] = "V", [7] = "F" }; #endif static const char *debug_ctrl[2] = { [0] = "", [1] = ".breakpoint" }; static const char *saturate[2] = { [0] = "", [1] = ".sat" }; static const char *accwr[2] = { [0] = "", [1] = "AccWrEnable" }; static const char *wectrl[2] = { [0] = "WE_normal", [1] = "WE_all" }; static const char *exec_size[8] = { [0] = "1", [1] = "2", [2] = "4", [3] = "8", [4] = "16", [5] = "32" }; static const char *pred_inv[2] = { [0] = "+", [1] = "-" }; static const char *pred_ctrl_align16[16] = { [1] = "", [2] = ".x", [3] = ".y", [4] = ".z", [5] = ".w", [6] = ".any4h", [7] = ".all4h", }; static const char *pred_ctrl_align1[16] = { [1] = "", [2] = ".anyv", [3] = ".allv", [4] = ".any2h", [5] = ".all2h", [6] = ".any4h", [7] = ".all4h", [8] = ".any8h", [9] = ".all8h", [10] = ".any16h", [11] = ".all16h", }; static const char *thread_ctrl[4] = { [0] = "", [2] = "switch" }; static const char *compr_ctrl[4] = { [0] = "", [1] = "sechalf", [2] = "compr", [3] = "compr4", }; static const char *dep_ctrl[4] = { [0] = "", [1] = "NoDDClr", [2] = "NoDDChk", [3] = "NoDDClr,NoDDChk", }; static const char *mask_ctrl[4] = { [0] = "", [1] = "nomask", }; static const char *access_mode[2] = { [0] = "align1", [1] = "align16", }; static const char *reg_encoding[8] = { [0] = "UD", [1] = "D", [2] = "UW", [3] = "W", [4] = "UB", [5] = "B", [7] = "F" }; static const int reg_type_size[8] = { [0] = 4, [1] = 4, [2] = 2, [3] = 2, [4] = 1, [5] = 1, [7] = 4 }; static const char *reg_file[4] = { [0] = "A", [1] = "g", [2] = "m", [3] = "imm", }; static const char *writemask[16] = { [0x0] = ".", [0x1] = ".x", [0x2] = ".y", [0x3] = ".xy", [0x4] = ".z", [0x5] = ".xz", [0x6] = ".yz", [0x7] = ".xyz", [0x8] = ".w", [0x9] = ".xw", [0xa] = ".yw", [0xb] = ".xyw", [0xc] = ".zw", [0xd] = ".xzw", [0xe] = ".yzw", [0xf] = "", }; static const char *end_of_thread[2] = { [0] = "", [1] = "EOT" }; static const char *target_function[16] = { [BRW_SFID_NULL] = "null", [BRW_SFID_MATH] = "math", [BRW_SFID_SAMPLER] = "sampler", [BRW_SFID_MESSAGE_GATEWAY] = "gateway", [BRW_SFID_DATAPORT_READ] = "read", [BRW_SFID_DATAPORT_WRITE] = "write", [BRW_SFID_URB] = "urb", [BRW_SFID_THREAD_SPAWNER] = "thread_spawner" }; static const char *target_function_gen6[16] = { [BRW_SFID_NULL] = "null", [BRW_SFID_MATH] = "math", [BRW_SFID_SAMPLER] = "sampler", [BRW_SFID_MESSAGE_GATEWAY] = "gateway", [BRW_SFID_URB] = "urb", [BRW_SFID_THREAD_SPAWNER] = "thread_spawner", [GEN6_SFID_DATAPORT_SAMPLER_CACHE] = "sampler", [GEN6_SFID_DATAPORT_RENDER_CACHE] = "render", [GEN6_SFID_DATAPORT_CONSTANT_CACHE] = "const", [GEN7_SFID_DATAPORT_DATA_CACHE] = "data" }; static const char *dp_rc_msg_type_gen6[16] = { [BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ] = "OWORD block read", [GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ] = "RT UNORM read", [GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ] = "OWORD dual block read", [GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ] = "media block read", [GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ] = "OWORD unaligned block read", [GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ] = "DWORD scattered read", [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE] = "DWORD atomic write", [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE] = "OWORD block write", [GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE] = "OWORD dual block write", [GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE] = "media block write", [GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE] = "DWORD scattered write", [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE] = "RT write", [GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE] = "streamed VB write", [GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE] = "RT UNORMc write", }; static const char *math_function[16] = { [BRW_MATH_FUNCTION_INV] = "inv", [BRW_MATH_FUNCTION_LOG] = "log", [BRW_MATH_FUNCTION_EXP] = "exp", [BRW_MATH_FUNCTION_SQRT] = "sqrt", [BRW_MATH_FUNCTION_RSQ] = "rsq", [BRW_MATH_FUNCTION_SIN] = "sin", [BRW_MATH_FUNCTION_COS] = "cos", [BRW_MATH_FUNCTION_SINCOS] = "sincos", [BRW_MATH_FUNCTION_TAN] = "tan", [BRW_MATH_FUNCTION_POW] = "pow", [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod", [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intdiv", [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intmod", }; static const char *math_saturate[2] = { [0] = "", [1] = "sat" }; static const char *math_signed[2] = { [0] = "", [1] = "signed" }; static const char *math_scalar[2] = { [0] = "", [1] = "scalar" }; static const char *math_precision[2] = { [0] = "", [1] = "partial_precision" }; static const char *urb_opcode[2] = { [0] = "urb_write", [1] = "ff_sync", }; static const char *urb_swizzle[4] = { [BRW_URB_SWIZZLE_NONE] = "", [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave", [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose", }; static const char *urb_allocate[2] = { [0] = "", [1] = "allocate" }; static const char *urb_used[2] = { [0] = "", [1] = "used" }; static const char *urb_complete[2] = { [0] = "", [1] = "complete" }; static const char *sampler_target_format[4] = { [0] = "F", [2] = "UD", [3] = "D" }; static int column; static int string(FILE *file, const char *str) { fputs(str, file); column += strlen(str); return 0; } #if defined(__GNUC__) && (__GNUC__ > 2) __attribute__((format(printf, 2, 3))) #endif static int format(FILE *f, const char *fmt, ...) { char buf[1024]; va_list args; va_start(args, fmt); vsnprintf(buf, sizeof(buf) - 1, fmt, args); va_end(args); string(f, buf); return 0; } static void newline(FILE *f) { putc('\n', f); column = 0; } static void pad(FILE *f, int c) { do string(f, " "); while (column < c); } static void control(FILE *file, const char *name, const char *ctrl[], unsigned id, int *space) { if (!ctrl[id]) { fprintf(file, "*** invalid %s value %d ", name, id); assert(0); } if (ctrl[id][0]) { if (space && *space) string(file, " "); string(file, ctrl[id]); if (space) *space = 1; } } static void print_opcode(FILE *file, int id) { if (!opcode[id].name) { format(file, "*** invalid opcode value %d ", id); assert(0); } string(file, opcode[id].name); } static int reg(FILE *file, unsigned _reg_file, unsigned _reg_nr) { /* Clear the Compr4 instruction compression bit. */ if (_reg_file == BRW_MESSAGE_REGISTER_FILE) _reg_nr &= ~(1 << 7); if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) { switch (_reg_nr & 0xf0) { case BRW_ARF_NULL: string(file, "null"); return -1; case BRW_ARF_ADDRESS: format(file, "a%d", _reg_nr & 0x0f); break; case BRW_ARF_ACCUMULATOR: format(file, "acc%d", _reg_nr & 0x0f); break; case BRW_ARF_FLAG: format(file, "f%d", _reg_nr & 0x0f); break; case BRW_ARF_MASK: format(file, "mask%d", _reg_nr & 0x0f); break; case BRW_ARF_MASK_STACK: format(file, "msd%d", _reg_nr & 0x0f); break; case BRW_ARF_STATE: format(file, "sr%d", _reg_nr & 0x0f); break; case BRW_ARF_CONTROL: format(file, "cr%d", _reg_nr & 0x0f); break; case BRW_ARF_NOTIFICATION_COUNT: format(file, "n%d", _reg_nr & 0x0f); break; case BRW_ARF_IP: string(file, "ip"); return -1; default: format(file, "ARF%d", _reg_nr); break; } } else { control(file, "src reg file", reg_file, _reg_file, NULL); format(file, "%d", _reg_nr); } return 0; } static void dest(FILE *file, const struct brw_instruction *inst) { if (inst->header.access_mode == BRW_ALIGN_1) { if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT) { if (reg(file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr)) return; if (inst->bits1.da1.dest_subreg_nr) format(file, ".%d", inst->bits1.da1.dest_subreg_nr / reg_type_size[inst->bits1.da1.dest_reg_type]); format(file, "<%d>", inst->bits1.da1.dest_horiz_stride); control(file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL); } else { string(file, "g[a0"); if (inst->bits1.ia1.dest_subreg_nr) format(file, ".%d", inst->bits1.ia1.dest_subreg_nr / reg_type_size[inst->bits1.ia1.dest_reg_type]); if (inst->bits1.ia1.dest_indirect_offset) format(file, " %d", inst->bits1.ia1.dest_indirect_offset); string(file, "]"); format(file, "<%d>", inst->bits1.ia1.dest_horiz_stride); control(file, "dest reg encoding", reg_encoding, inst->bits1.ia1.dest_reg_type, NULL); } } else { if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT) { if (reg(file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr)) return; if (inst->bits1.da16.dest_subreg_nr) format(file, ".%d", inst->bits1.da16.dest_subreg_nr / reg_type_size[inst->bits1.da16.dest_reg_type]); string(file, "<1>"); control(file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL); control(file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL); } else { string(file, "Indirect align16 address mode not supported"); } } } static void src_align1_region(FILE *file, unsigned _vert_stride, unsigned _width, unsigned _horiz_stride) { string(file, "<"); control(file, "vert stride", vert_stride, _vert_stride, NULL); string(file, ","); control(file, "width", width, _width, NULL); string(file, ","); control(file, "horiz_stride", horiz_stride, _horiz_stride, NULL); string(file, ">"); } static void src_da1(FILE *file, unsigned type, unsigned _reg_file, unsigned _vert_stride, unsigned _width, unsigned _horiz_stride, unsigned reg_num, unsigned sub_reg_num, unsigned __abs, unsigned _negate) { control(file, "negate", negate, _negate, NULL); control(file, "abs", _abs, __abs, NULL); if (reg(file, _reg_file, reg_num)) return; if (sub_reg_num) format(file, ".%d", sub_reg_num / reg_type_size[type]); /* use formal style like spec */ src_align1_region(file, _vert_stride, _width, _horiz_stride); control(file, "src reg encoding", reg_encoding, type, NULL); } static void src_ia1(FILE *file, unsigned type, unsigned _reg_file, int _addr_imm, unsigned _addr_subreg_nr, unsigned _negate, unsigned __abs, unsigned _addr_mode, unsigned _horiz_stride, unsigned _width, unsigned _vert_stride) { control(file, "negate", negate, _negate, NULL); control(file, "abs", _abs, __abs, NULL); string(file, "g[a0"); if (_addr_subreg_nr) format(file, ".%d", _addr_subreg_nr); if (_addr_imm) format(file, " %d", _addr_imm); string(file, "]"); src_align1_region(file, _vert_stride, _width, _horiz_stride); control(file, "src reg encoding", reg_encoding, type, NULL); } static void src_da16(FILE *file, unsigned _reg_type, unsigned _reg_file, unsigned _vert_stride, unsigned _reg_nr, unsigned _subreg_nr, unsigned __abs, unsigned _negate, unsigned swz_x, unsigned swz_y, unsigned swz_z, unsigned swz_w) { control(file, "negate", negate, _negate, NULL); control(file, "abs", _abs, __abs, NULL); if (reg(file, _reg_file, _reg_nr)) return; if (_subreg_nr) /* bit4 for subreg number byte addressing. Make this same meaning as in da1 case, so output looks consistent. */ format(file, ".%d", 16 / reg_type_size[_reg_type]); string(file, "<"); control(file, "vert stride", vert_stride, _vert_stride, NULL); string(file, ",4,1>"); /* * Three kinds of swizzle display: * identity - nothing printed * 1->all - print the single channel * 1->1 - print the mapping */ if (swz_x == BRW_CHANNEL_X && swz_y == BRW_CHANNEL_Y && swz_z == BRW_CHANNEL_Z && swz_w == BRW_CHANNEL_W) { ; } else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w) { string(file, "."); control(file, "channel select", chan_sel, swz_x, NULL); } else { string(file, "."); control(file, "channel select", chan_sel, swz_x, NULL); control(file, "channel select", chan_sel, swz_y, NULL); control(file, "channel select", chan_sel, swz_z, NULL); control(file, "channel select", chan_sel, swz_w, NULL); } control(file, "src da16 reg type", reg_encoding, _reg_type, NULL); } static void imm(FILE *file, unsigned type, const struct brw_instruction *inst) { switch (type) { case BRW_REGISTER_TYPE_UD: format(file, "0x%08xUD", inst->bits3.ud); break; case BRW_REGISTER_TYPE_D: format(file, "%dD", inst->bits3.d); break; case BRW_REGISTER_TYPE_UW: format(file, "0x%04xUW", (uint16_t) inst->bits3.ud); break; case BRW_REGISTER_TYPE_W: format(file, "%dW", (int16_t) inst->bits3.d); break; case BRW_REGISTER_TYPE_UB: format(file, "0x%02xUB", (int8_t) inst->bits3.ud); break; case BRW_REGISTER_TYPE_VF: format(file, "Vector Float"); break; case BRW_REGISTER_TYPE_V: format(file, "0x%08xV", inst->bits3.ud); break; case BRW_REGISTER_TYPE_F: format(file, "%-gF", inst->bits3.f); } } static void src0(FILE *file, const struct brw_instruction *inst) { if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE) imm(file, inst->bits1.da1.src0_reg_type, inst); else if (inst->header.access_mode == BRW_ALIGN_1) { if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT) { src_da1(file, inst->bits1.da1.src0_reg_type, inst->bits1.da1.src0_reg_file, inst->bits2.da1.src0_vert_stride, inst->bits2.da1.src0_width, inst->bits2.da1.src0_horiz_stride, inst->bits2.da1.src0_reg_nr, inst->bits2.da1.src0_subreg_nr, inst->bits2.da1.src0_abs, inst->bits2.da1.src0_negate); } else { src_ia1(file, inst->bits1.ia1.src0_reg_type, inst->bits1.ia1.src0_reg_file, inst->bits2.ia1.src0_indirect_offset, inst->bits2.ia1.src0_subreg_nr, inst->bits2.ia1.src0_negate, inst->bits2.ia1.src0_abs, inst->bits2.ia1.src0_address_mode, inst->bits2.ia1.src0_horiz_stride, inst->bits2.ia1.src0_width, inst->bits2.ia1.src0_vert_stride); } } else { if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT) { src_da16(file, inst->bits1.da16.src0_reg_type, inst->bits1.da16.src0_reg_file, inst->bits2.da16.src0_vert_stride, inst->bits2.da16.src0_reg_nr, inst->bits2.da16.src0_subreg_nr, inst->bits2.da16.src0_abs, inst->bits2.da16.src0_negate, inst->bits2.da16.src0_swz_x, inst->bits2.da16.src0_swz_y, inst->bits2.da16.src0_swz_z, inst->bits2.da16.src0_swz_w); } else { string(file, "Indirect align16 address mode not supported"); } } } static void src1(FILE *file, const struct brw_instruction *inst) { if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE) imm(file, inst->bits1.da1.src1_reg_type, inst); else if (inst->header.access_mode == BRW_ALIGN_1) { if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT) { src_da1(file, inst->bits1.da1.src1_reg_type, inst->bits1.da1.src1_reg_file, inst->bits3.da1.src1_vert_stride, inst->bits3.da1.src1_width, inst->bits3.da1.src1_horiz_stride, inst->bits3.da1.src1_reg_nr, inst->bits3.da1.src1_subreg_nr, inst->bits3.da1.src1_abs, inst->bits3.da1.src1_negate); } else { src_ia1(file, inst->bits1.ia1.src1_reg_type, inst->bits1.ia1.src1_reg_file, inst->bits3.ia1.src1_indirect_offset, inst->bits3.ia1.src1_subreg_nr, inst->bits3.ia1.src1_negate, inst->bits3.ia1.src1_abs, inst->bits3.ia1.src1_address_mode, inst->bits3.ia1.src1_horiz_stride, inst->bits3.ia1.src1_width, inst->bits3.ia1.src1_vert_stride); } } else { if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT) { src_da16(file, inst->bits1.da16.src1_reg_type, inst->bits1.da16.src1_reg_file, inst->bits3.da16.src1_vert_stride, inst->bits3.da16.src1_reg_nr, inst->bits3.da16.src1_subreg_nr, inst->bits3.da16.src1_abs, inst->bits3.da16.src1_negate, inst->bits3.da16.src1_swz_x, inst->bits3.da16.src1_swz_y, inst->bits3.da16.src1_swz_z, inst->bits3.da16.src1_swz_w); } else { string(file, "Indirect align16 address mode not supported"); } } } static const int esize[6] = { [0] = 1, [1] = 2, [2] = 4, [3] = 8, [4] = 16, [5] = 32, }; static int qtr_ctrl(FILE *file, const struct brw_instruction *inst) { int qtr_ctl = inst->header.compression_control; int size = esize[inst->header.execution_size]; if (size == 8) { switch (qtr_ctl) { case 0: string(file, " 1Q"); break; case 1: string(file, " 2Q"); break; case 2: string(file, " 3Q"); break; case 3: string(file, " 4Q"); break; } } else if (size == 16){ if (qtr_ctl < 2) string(file, " 1H"); else string(file, " 2H"); } return 0; } void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen) { int space = 0; format(file, "%08x %08x %08x %08x\n", ((const uint32_t*)inst)[0], ((const uint32_t*)inst)[1], ((const uint32_t*)inst)[2], ((const uint32_t*)inst)[3]); if (inst->header.predicate_control) { string(file, "("); control(file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL); string(file, "f0"); if (inst->bits2.da1.flag_subreg_nr) format(file, ".%d", inst->bits2.da1.flag_subreg_nr); if (inst->header.access_mode == BRW_ALIGN_1) control(file, "predicate control align1", pred_ctrl_align1, inst->header.predicate_control, NULL); else control(file, "predicate control align16", pred_ctrl_align16, inst->header.predicate_control, NULL); string(file, ") "); } print_opcode(file, inst->header.opcode); control(file, "saturate", saturate, inst->header.saturate, NULL); control(file, "debug control", debug_ctrl, inst->header.debug_control, NULL); if (inst->header.opcode == BRW_OPCODE_MATH) { string(file, " "); control(file, "function", math_function, inst->header.destreg__conditionalmod, NULL); } else if (inst->header.opcode != BRW_OPCODE_SEND && inst->header.opcode != BRW_OPCODE_SENDC) control(file, "conditional modifier", conditional_modifier, inst->header.destreg__conditionalmod, NULL); if (inst->header.opcode != BRW_OPCODE_NOP) { string(file, "("); control(file, "execution size", exec_size, inst->header.execution_size, NULL); string(file, ")"); } if (inst->header.opcode == BRW_OPCODE_SEND && gen < 060) format(file, " %d", inst->header.destreg__conditionalmod); if (opcode[inst->header.opcode].ndst > 0) { pad(file, 16); dest(file, inst); } else if (gen >= 060 && (inst->header.opcode == BRW_OPCODE_IF || inst->header.opcode == BRW_OPCODE_ELSE || inst->header.opcode == BRW_OPCODE_ENDIF || inst->header.opcode == BRW_OPCODE_WHILE)) { format(file, " %d", inst->bits1.branch_gen6.jump_count); } if (opcode[inst->header.opcode].nsrc > 0) { pad(file, 32); src0(file, inst); } if (opcode[inst->header.opcode].nsrc > 1) { pad(file, 48); src1(file, inst); } if (inst->header.opcode == BRW_OPCODE_SEND || inst->header.opcode == BRW_OPCODE_SENDC) { enum brw_message_target target; if (gen >= 060) target = inst->header.destreg__conditionalmod; else if (gen >= 050) target = inst->bits2.send_gen5.sfid; else target = inst->bits3.generic.msg_target; newline (file); pad (file, 16); space = 0; if (gen >= 060) { control (file, "target function", target_function_gen6, target, &space); } else { control (file, "target function", target_function, target, &space); } switch (target) { case BRW_SFID_MATH: control (file, "math function", math_function, inst->bits3.math.function, &space); control (file, "math saturate", math_saturate, inst->bits3.math.saturate, &space); control (file, "math signed", math_signed, inst->bits3.math.int_type, &space); control (file, "math scalar", math_scalar, inst->bits3.math.data_type, &space); control (file, "math precision", math_precision, inst->bits3.math.precision, &space); break; case BRW_SFID_SAMPLER: if (gen >= 070) { format (file, " (%d, %d, %d, %d)", inst->bits3.sampler_gen7.binding_table_index, inst->bits3.sampler_gen7.sampler, inst->bits3.sampler_gen7.msg_type, inst->bits3.sampler_gen7.simd_mode); } else if (gen >= 050) { format (file, " (%d, %d, %d, %d)", inst->bits3.sampler_gen5.binding_table_index, inst->bits3.sampler_gen5.sampler, inst->bits3.sampler_gen5.msg_type, inst->bits3.sampler_gen5.simd_mode); } else if (gen >= 045) { format (file, " (%d, %d)", inst->bits3.sampler_g4x.binding_table_index, inst->bits3.sampler_g4x.sampler); } else { format (file, " (%d, %d, ", inst->bits3.sampler.binding_table_index, inst->bits3.sampler.sampler); control (file, "sampler target format", sampler_target_format, inst->bits3.sampler.return_format, NULL); string (file, ")"); } break; case BRW_SFID_DATAPORT_READ: if (gen >= 060) { format (file, " (%d, %d, %d, %d)", inst->bits3.gen6_dp.binding_table_index, inst->bits3.gen6_dp.msg_control, inst->bits3.gen6_dp.msg_type, inst->bits3.gen6_dp.send_commit_msg); } else if (gen >= 045) { format (file, " (%d, %d, %d)", inst->bits3.dp_read_gen5.binding_table_index, inst->bits3.dp_read_gen5.msg_control, inst->bits3.dp_read_gen5.msg_type); } else { format (file, " (%d, %d, %d)", inst->bits3.dp_read.binding_table_index, inst->bits3.dp_read.msg_control, inst->bits3.dp_read.msg_type); } break; case BRW_SFID_DATAPORT_WRITE: if (gen >= 070) { format (file, " ("); control (file, "DP rc message type", dp_rc_msg_type_gen6, inst->bits3.gen7_dp.msg_type, &space); format (file, ", %d, %d, %d)", inst->bits3.gen7_dp.binding_table_index, inst->bits3.gen7_dp.msg_control, inst->bits3.gen7_dp.msg_type); } else if (gen >= 060) { format (file, " ("); control (file, "DP rc message type", dp_rc_msg_type_gen6, inst->bits3.gen6_dp.msg_type, &space); format (file, ", %d, %d, %d, %d)", inst->bits3.gen6_dp.binding_table_index, inst->bits3.gen6_dp.msg_control, inst->bits3.gen6_dp.msg_type, inst->bits3.gen6_dp.send_commit_msg); } else { format (file, " (%d, %d, %d, %d)", inst->bits3.dp_write.binding_table_index, (inst->bits3.dp_write.last_render_target << 3) | inst->bits3.dp_write.msg_control, inst->bits3.dp_write.msg_type, inst->bits3.dp_write.send_commit_msg); } break; case BRW_SFID_URB: if (gen >= 050) { format (file, " %d", inst->bits3.urb_gen5.offset); } else { format (file, " %d", inst->bits3.urb.offset); } space = 1; if (gen >= 050) { control (file, "urb opcode", urb_opcode, inst->bits3.urb_gen5.opcode, &space); } control (file, "urb swizzle", urb_swizzle, inst->bits3.urb.swizzle_control, &space); control (file, "urb allocate", urb_allocate, inst->bits3.urb.allocate, &space); control (file, "urb used", urb_used, inst->bits3.urb.used, &space); control (file, "urb complete", urb_complete, inst->bits3.urb.complete, &space); break; case BRW_SFID_THREAD_SPAWNER: break; case GEN7_SFID_DATAPORT_DATA_CACHE: format (file, " (%d, %d, %d)", inst->bits3.gen7_dp.binding_table_index, inst->bits3.gen7_dp.msg_control, inst->bits3.gen7_dp.msg_type); break; default: format (file, "unsupported target %d", target); break; } if (space) string (file, " "); if (gen >= 050) { format (file, "mlen %d", inst->bits3.generic_gen5.msg_length); format (file, " rlen %d", inst->bits3.generic_gen5.response_length); } else { format (file, "mlen %d", inst->bits3.generic.msg_length); format (file, " rlen %d", inst->bits3.generic.response_length); } } pad(file, 64); if (inst->header.opcode != BRW_OPCODE_NOP) { string(file, "{"); space = 1; control(file, "access mode", access_mode, inst->header.access_mode, &space); if (gen >= 060) control(file, "write enable control", wectrl, inst->header.mask_control, &space); else control(file, "mask control", mask_ctrl, inst->header.mask_control, &space); control(file, "dependency control", dep_ctrl, inst->header.dependency_control, &space); if (gen >= 060) qtr_ctrl(file, inst); else { if (inst->header.compression_control == BRW_COMPRESSION_COMPRESSED && opcode[inst->header.opcode].ndst > 0 && inst->bits1.da1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE && inst->bits1.da1.dest_reg_nr & (1 << 7)) { format(file, " compr4"); } else { control(file, "compression control", compr_ctrl, inst->header.compression_control, &space); } } control(file, "thread control", thread_ctrl, inst->header.thread_control, &space); if (gen >= 060) control(file, "acc write control", accwr, inst->header.acc_wr_control, &space); if (inst->header.opcode == BRW_OPCODE_SEND || inst->header.opcode == BRW_OPCODE_SENDC) control(file, "end of thread", end_of_thread, inst->bits3.generic.end_of_thread, &space); if (space) string(file, " "); string(file, "}"); } string(file, ";"); newline(file); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_eu.c000066400000000000000000000106701267532330400240700ustar00rootroot00000000000000/* Copyright (C) Intel Corp. 2006. All Rights Reserved. Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to develop this 3D driver. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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: * Keith Whitwell */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "brw_eu.h" #include #include /* Returns the corresponding conditional mod for swapping src0 and * src1 in e.g. CMP. */ uint32_t brw_swap_cmod(uint32_t cmod) { switch (cmod) { case BRW_CONDITIONAL_Z: case BRW_CONDITIONAL_NZ: return cmod; case BRW_CONDITIONAL_G: return BRW_CONDITIONAL_LE; case BRW_CONDITIONAL_GE: return BRW_CONDITIONAL_L; case BRW_CONDITIONAL_L: return BRW_CONDITIONAL_GE; case BRW_CONDITIONAL_LE: return BRW_CONDITIONAL_G; default: return ~0; } } /* How does predicate control work when execution_size != 8? Do I * need to test/set for 0xffff when execution_size is 16? */ void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ) { p->current->header.predicate_control = BRW_PREDICATE_NONE; if (value != 0xff) { if (value != p->flag_value) { brw_MOV(p, brw_flag_reg(), brw_imm_uw(value)); p->flag_value = value; } p->current->header.predicate_control = BRW_PREDICATE_NORMAL; } } void brw_set_compression_control(struct brw_compile *p, enum brw_compression compression_control) { p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED); if (p->gen >= 060) { /* Since we don't use the 32-wide support in gen6, we translate * the pre-gen6 compression control here. */ switch (compression_control) { case BRW_COMPRESSION_NONE: /* This is the "use the first set of bits of dmask/vmask/arf * according to execsize" option. */ p->current->header.compression_control = GEN6_COMPRESSION_1Q; break; case BRW_COMPRESSION_2NDHALF: /* For 8-wide, this is "use the second set of 8 bits." */ p->current->header.compression_control = GEN6_COMPRESSION_2Q; break; case BRW_COMPRESSION_COMPRESSED: /* For 16-wide instruction compression, use the first set of 16 bits * since we don't do 32-wide dispatch. */ p->current->header.compression_control = GEN6_COMPRESSION_1H; break; default: assert(!"not reached"); p->current->header.compression_control = GEN6_COMPRESSION_1H; break; } } else { p->current->header.compression_control = compression_control; } } void brw_push_insn_state( struct brw_compile *p ) { assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]); memcpy(p->current+1, p->current, sizeof(struct brw_instruction)); p->compressed_stack[p->current - p->stack] = p->compressed; p->current++; } void brw_pop_insn_state( struct brw_compile *p ) { assert(p->current != p->stack); p->current--; p->compressed = p->compressed_stack[p->current - p->stack]; } void brw_compile_init(struct brw_compile *p, int gen, void *store) { assert(gen); p->gen = gen; p->store = store; p->nr_insn = 0; p->current = p->stack; p->compressed = false; memset(p->current, 0, sizeof(p->current[0])); /* Some defaults? */ brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */ brw_set_saturate(p, 0); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_predicate_control_flag_value(p, 0xff); p->if_stack_depth = 0; p->if_stack_array_size = 0; p->if_stack = NULL; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_eu.h000066400000000000000000001724251267532330400241040ustar00rootroot00000000000000/* Copyright (C) Intel Corp. 2006. All Rights Reserved. Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to develop this 3D driver. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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: * Keith Whitwell */ #ifndef BRW_EU_H #define BRW_EU_H #include #include #include #include #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6)) #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3) #define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3) #define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3) #define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0) #define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1) #define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2) #define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3) #define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1) #define WRITEMASK_X 0x1 #define WRITEMASK_Y 0x2 #define WRITEMASK_Z 0x4 #define WRITEMASK_W 0x8 #define WRITEMASK_XY (WRITEMASK_X | WRITEMASK_Y) #define WRITEMASK_XYZ (WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z) #define WRITEMASK_XYZW (WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z | WRITEMASK_W) /** Number of general purpose registers (VS, WM, etc) */ #define BRW_MAX_GRF 128 /** Number of message register file registers */ #define BRW_MAX_MRF 16 #define BRW_ALIGN_1 0 #define BRW_ALIGN_16 1 #define BRW_ADDRESS_DIRECT 0 #define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define BRW_CHANNEL_X 0 #define BRW_CHANNEL_Y 1 #define BRW_CHANNEL_Z 2 #define BRW_CHANNEL_W 3 enum brw_compression { BRW_COMPRESSION_NONE, BRW_COMPRESSION_2NDHALF, BRW_COMPRESSION_COMPRESSED, }; #define GEN6_COMPRESSION_1Q 0 #define GEN6_COMPRESSION_2Q 1 #define GEN6_COMPRESSION_3Q 2 #define GEN6_COMPRESSION_4Q 3 #define GEN6_COMPRESSION_1H 0 #define GEN6_COMPRESSION_2H 2 #define BRW_CONDITIONAL_NONE 0 #define BRW_CONDITIONAL_Z 1 #define BRW_CONDITIONAL_NZ 2 #define BRW_CONDITIONAL_EQ 1 /* Z */ #define BRW_CONDITIONAL_NEQ 2 /* NZ */ #define BRW_CONDITIONAL_G 3 #define BRW_CONDITIONAL_GE 4 #define BRW_CONDITIONAL_L 5 #define BRW_CONDITIONAL_LE 6 #define BRW_CONDITIONAL_R 7 #define BRW_CONDITIONAL_O 8 #define BRW_CONDITIONAL_U 9 #define BRW_DEBUG_NONE 0 #define BRW_DEBUG_BREAKPOINT 1 #define BRW_DEPENDENCY_NORMAL 0 #define BRW_DEPENDENCY_NOTCLEARED 1 #define BRW_DEPENDENCY_NOTCHECKED 2 #define BRW_DEPENDENCY_DISABLE 3 #define BRW_EXECUTE_1 0 #define BRW_EXECUTE_2 1 #define BRW_EXECUTE_4 2 #define BRW_EXECUTE_8 3 #define BRW_EXECUTE_16 4 #define BRW_EXECUTE_32 5 #define BRW_HORIZONTAL_STRIDE_0 0 #define BRW_HORIZONTAL_STRIDE_1 1 #define BRW_HORIZONTAL_STRIDE_2 2 #define BRW_HORIZONTAL_STRIDE_4 3 #define BRW_INSTRUCTION_NORMAL 0 #define BRW_INSTRUCTION_SATURATE 1 #define BRW_MASK_ENABLE 0 #define BRW_MASK_DISABLE 1 /** @{ * * Gen6 has replaced "mask enable/disable" with WECtrl, which is * effectively the same but much simpler to think about. Now, there * are two contributors ANDed together to whether channels are * executed: The predication on the instruction, and the channel write * enable. */ /** * This is the default value. It means that a channel's write enable is set * if the per-channel IP is pointing at this instruction. */ #define BRW_WE_NORMAL 0 /** * This is used like BRW_MASK_DISABLE, and causes all channels to have * their write enable set. Note that predication still contributes to * whether the channel actually gets written. */ #define BRW_WE_ALL 1 /** @} */ enum opcode { /* These are the actual hardware opcodes. */ BRW_OPCODE_MOV = 1, BRW_OPCODE_SEL = 2, BRW_OPCODE_NOT = 4, BRW_OPCODE_AND = 5, BRW_OPCODE_OR = 6, BRW_OPCODE_XOR = 7, BRW_OPCODE_SHR = 8, BRW_OPCODE_SHL = 9, BRW_OPCODE_RSR = 10, BRW_OPCODE_RSL = 11, BRW_OPCODE_ASR = 12, BRW_OPCODE_CMP = 16, BRW_OPCODE_CMPN = 17, BRW_OPCODE_JMPI = 32, BRW_OPCODE_IF = 34, BRW_OPCODE_IFF = 35, BRW_OPCODE_ELSE = 36, BRW_OPCODE_ENDIF = 37, BRW_OPCODE_DO = 38, BRW_OPCODE_WHILE = 39, BRW_OPCODE_BREAK = 40, BRW_OPCODE_CONTINUE = 41, BRW_OPCODE_HALT = 42, BRW_OPCODE_MSAVE = 44, BRW_OPCODE_MRESTORE = 45, BRW_OPCODE_PUSH = 46, BRW_OPCODE_POP = 47, BRW_OPCODE_WAIT = 48, BRW_OPCODE_SEND = 49, BRW_OPCODE_SENDC = 50, BRW_OPCODE_MATH = 56, BRW_OPCODE_ADD = 64, BRW_OPCODE_MUL = 65, BRW_OPCODE_AVG = 66, BRW_OPCODE_FRC = 67, BRW_OPCODE_RNDU = 68, BRW_OPCODE_RNDD = 69, BRW_OPCODE_RNDE = 70, BRW_OPCODE_RNDZ = 71, BRW_OPCODE_MAC = 72, BRW_OPCODE_MACH = 73, BRW_OPCODE_LZD = 74, BRW_OPCODE_SAD2 = 80, BRW_OPCODE_SADA2 = 81, BRW_OPCODE_DP4 = 84, BRW_OPCODE_DPH = 85, BRW_OPCODE_DP3 = 86, BRW_OPCODE_DP2 = 87, BRW_OPCODE_DPA2 = 88, BRW_OPCODE_LINE = 89, BRW_OPCODE_PLN = 90, BRW_OPCODE_NOP = 126, /* These are compiler backend opcodes that get translated into other * instructions. */ FS_OPCODE_FB_WRITE = 128, SHADER_OPCODE_RCP, SHADER_OPCODE_RSQ, SHADER_OPCODE_SQRT, SHADER_OPCODE_EXP2, SHADER_OPCODE_LOG2, SHADER_OPCODE_POW, SHADER_OPCODE_SIN, SHADER_OPCODE_COS, FS_OPCODE_DDX, FS_OPCODE_DDY, FS_OPCODE_PIXEL_X, FS_OPCODE_PIXEL_Y, FS_OPCODE_CINTERP, FS_OPCODE_LINTERP, FS_OPCODE_TEX, FS_OPCODE_TXB, FS_OPCODE_TXD, FS_OPCODE_TXF, FS_OPCODE_TXL, FS_OPCODE_TXS, FS_OPCODE_DISCARD, FS_OPCODE_SPILL, FS_OPCODE_UNSPILL, FS_OPCODE_PULL_CONSTANT_LOAD, VS_OPCODE_URB_WRITE, VS_OPCODE_SCRATCH_READ, VS_OPCODE_SCRATCH_WRITE, VS_OPCODE_PULL_CONSTANT_LOAD, }; #define BRW_PREDICATE_NONE 0 #define BRW_PREDICATE_NORMAL 1 #define BRW_PREDICATE_ALIGN1_ANYV 2 #define BRW_PREDICATE_ALIGN1_ALLV 3 #define BRW_PREDICATE_ALIGN1_ANY2H 4 #define BRW_PREDICATE_ALIGN1_ALL2H 5 #define BRW_PREDICATE_ALIGN1_ANY4H 6 #define BRW_PREDICATE_ALIGN1_ALL4H 7 #define BRW_PREDICATE_ALIGN1_ANY8H 8 #define BRW_PREDICATE_ALIGN1_ALL8H 9 #define BRW_PREDICATE_ALIGN1_ANY16H 10 #define BRW_PREDICATE_ALIGN1_ALL16H 11 #define BRW_PREDICATE_ALIGN16_REPLICATE_X 2 #define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3 #define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4 #define BRW_PREDICATE_ALIGN16_REPLICATE_W 5 #define BRW_PREDICATE_ALIGN16_ANY4H 6 #define BRW_PREDICATE_ALIGN16_ALL4H 7 #define BRW_ARCHITECTURE_REGISTER_FILE 0 #define BRW_GENERAL_REGISTER_FILE 1 #define BRW_MESSAGE_REGISTER_FILE 2 #define BRW_IMMEDIATE_VALUE 3 #define BRW_REGISTER_TYPE_UD 0 #define BRW_REGISTER_TYPE_D 1 #define BRW_REGISTER_TYPE_UW 2 #define BRW_REGISTER_TYPE_W 3 #define BRW_REGISTER_TYPE_UB 4 #define BRW_REGISTER_TYPE_B 5 #define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define BRW_REGISTER_TYPE_HF 6 #define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define BRW_REGISTER_TYPE_F 7 #define BRW_ARF_NULL 0x00 #define BRW_ARF_ADDRESS 0x10 #define BRW_ARF_ACCUMULATOR 0x20 #define BRW_ARF_FLAG 0x30 #define BRW_ARF_MASK 0x40 #define BRW_ARF_MASK_STACK 0x50 #define BRW_ARF_MASK_STACK_DEPTH 0x60 #define BRW_ARF_STATE 0x70 #define BRW_ARF_CONTROL 0x80 #define BRW_ARF_NOTIFICATION_COUNT 0x90 #define BRW_ARF_IP 0xA0 #define BRW_MRF_COMPR4 (1 << 7) #define BRW_AMASK 0 #define BRW_IMASK 1 #define BRW_LMASK 2 #define BRW_CMASK 3 #define BRW_THREAD_NORMAL 0 #define BRW_THREAD_ATOMIC 1 #define BRW_THREAD_SWITCH 2 #define BRW_VERTICAL_STRIDE_0 0 #define BRW_VERTICAL_STRIDE_1 1 #define BRW_VERTICAL_STRIDE_2 2 #define BRW_VERTICAL_STRIDE_4 3 #define BRW_VERTICAL_STRIDE_8 4 #define BRW_VERTICAL_STRIDE_16 5 #define BRW_VERTICAL_STRIDE_32 6 #define BRW_VERTICAL_STRIDE_64 7 #define BRW_VERTICAL_STRIDE_128 8 #define BRW_VERTICAL_STRIDE_256 9 #define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define BRW_WIDTH_1 0 #define BRW_WIDTH_2 1 #define BRW_WIDTH_4 2 #define BRW_WIDTH_8 3 #define BRW_WIDTH_16 4 #define BRW_STATELESS_BUFFER_BOUNDARY_1K 0 #define BRW_STATELESS_BUFFER_BOUNDARY_2K 1 #define BRW_STATELESS_BUFFER_BOUNDARY_4K 2 #define BRW_STATELESS_BUFFER_BOUNDARY_8K 3 #define BRW_STATELESS_BUFFER_BOUNDARY_16K 4 #define BRW_STATELESS_BUFFER_BOUNDARY_32K 5 #define BRW_STATELESS_BUFFER_BOUNDARY_64K 6 #define BRW_STATELESS_BUFFER_BOUNDARY_128K 7 #define BRW_STATELESS_BUFFER_BOUNDARY_256K 8 #define BRW_STATELESS_BUFFER_BOUNDARY_512K 9 #define BRW_STATELESS_BUFFER_BOUNDARY_1M 10 #define BRW_STATELESS_BUFFER_BOUNDARY_2M 11 #define BRW_POLYGON_FACING_FRONT 0 #define BRW_POLYGON_FACING_BACK 1 #define BRW_MESSAGE_TARGET_NULL 0 #define BRW_MESSAGE_TARGET_MATH 1 /* reserved on GEN6 */ #define BRW_MESSAGE_TARGET_SAMPLER 2 #define BRW_MESSAGE_TARGET_GATEWAY 3 #define BRW_MESSAGE_TARGET_DATAPORT_READ 4 #define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5 #define BRW_MESSAGE_TARGET_URB 6 #define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN6_MESSAGE_TARGET_DP_SAMPLER_CACHE 4 #define GEN6_MESSAGE_TARGET_DP_RENDER_CACHE 5 #define GEN6_MESSAGE_TARGET_DP_CONST_CACHE 9 #define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define BRW_SAMPLER_RETURN_FORMAT_UINT32 2 #define BRW_SAMPLER_RETURN_FORMAT_SINT32 3 #define BRW_SAMPLER_MESSAGE_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_COMPARE 0 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_COMPARE 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN5_SAMPLER_MESSAGE_SAMPLE 0 #define GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS 1 #define GEN5_SAMPLER_MESSAGE_SAMPLE_LOD 2 #define GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE 3 #define GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS 4 #define GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE 5 #define GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE 6 #define GEN5_SAMPLER_MESSAGE_SAMPLE_LD 7 #define GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO 10 /* for GEN5 only */ #define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0 #define BRW_SAMPLER_SIMD_MODE_SIMD8 1 #define BRW_SAMPLER_SIMD_MODE_SIMD16 2 #define BRW_SAMPLER_SIMD_MODE_SIMD32_64 3 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 /* This one stays the same across generations. */ #define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 /* GEN4 */ #define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define BRW_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 2 #define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 /* G45, GEN5 */ #define G45_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ 1 #define G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 2 #define G45_DATAPORT_READ_MESSAGE_AVC_LOOP_FILTER_READ 3 #define G45_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 4 #define G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 6 /* GEN6 */ #define GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ 1 #define GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 2 #define GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 4 #define GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ 5 #define GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 6 #define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0 #define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 /** * Message target: Shared Function ID for where to SEND a message. * * These are enumerated in the ISA reference under "send - Send Message". * In particular, see the following tables: * - G45 PRM, Volume 4, Table 14-15 "Message Descriptor Definition" * - Sandybridge PRM, Volume 4 Part 2, Table 8-16 "Extended Message Descriptor" * - BSpec, Volume 1a (GPU Overview) / Graphics Processing Engine (GPE) / * Overview / GPE Function IDs */ enum brw_message_target { BRW_SFID_NULL = 0, BRW_SFID_MATH = 1, /* Only valid on Gen4-5 */ BRW_SFID_SAMPLER = 2, BRW_SFID_MESSAGE_GATEWAY = 3, BRW_SFID_DATAPORT_READ = 4, BRW_SFID_DATAPORT_WRITE = 5, BRW_SFID_URB = 6, BRW_SFID_THREAD_SPAWNER = 7, GEN6_SFID_DATAPORT_SAMPLER_CACHE = 4, GEN6_SFID_DATAPORT_RENDER_CACHE = 5, GEN6_SFID_DATAPORT_CONSTANT_CACHE = 9, GEN7_SFID_DATAPORT_DATA_CACHE = 10, }; #define GEN7_MESSAGE_TARGET_DP_DATA_CACHE 10 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define BRW_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE 2 #define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 /* GEN6 */ #define GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE 7 #define GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 8 #define GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 9 #define GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE 10 #define GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 11 #define GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 12 #define GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE 13 #define GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE 14 #define BRW_MATH_FUNCTION_INV 1 #define BRW_MATH_FUNCTION_LOG 2 #define BRW_MATH_FUNCTION_EXP 3 #define BRW_MATH_FUNCTION_SQRT 4 #define BRW_MATH_FUNCTION_RSQ 5 #define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ #define BRW_MATH_FUNCTION_COS 7 /* was 8 */ #define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define BRW_MATH_FUNCTION_TAN 9 /* gen4 */ #define BRW_MATH_FUNCTION_FDIV 9 /* gen6+ */ #define BRW_MATH_FUNCTION_POW 10 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define BRW_MATH_INTEGER_UNSIGNED 0 #define BRW_MATH_INTEGER_SIGNED 1 #define BRW_MATH_PRECISION_FULL 0 #define BRW_MATH_PRECISION_PARTIAL 1 #define BRW_MATH_SATURATE_NONE 0 #define BRW_MATH_SATURATE_SATURATE 1 #define BRW_MATH_DATA_VECTOR 0 #define BRW_MATH_DATA_SCALAR 1 #define BRW_URB_OPCODE_WRITE 0 #define BRW_URB_SWIZZLE_NONE 0 #define BRW_URB_SWIZZLE_INTERLEAVE 1 #define BRW_URB_SWIZZLE_TRANSPOSE 2 #define BRW_SCRATCH_SPACE_SIZE_1K 0 #define BRW_SCRATCH_SPACE_SIZE_2K 1 #define BRW_SCRATCH_SPACE_SIZE_4K 2 #define BRW_SCRATCH_SPACE_SIZE_8K 3 #define BRW_SCRATCH_SPACE_SIZE_16K 4 #define BRW_SCRATCH_SPACE_SIZE_32K 5 #define BRW_SCRATCH_SPACE_SIZE_64K 6 #define BRW_SCRATCH_SPACE_SIZE_128K 7 #define BRW_SCRATCH_SPACE_SIZE_256K 8 #define BRW_SCRATCH_SPACE_SIZE_512K 9 #define BRW_SCRATCH_SPACE_SIZE_1M 10 #define BRW_SCRATCH_SPACE_SIZE_2M 11 #define REG_SIZE (8*4) struct brw_instruction { struct { unsigned opcode:7; unsigned pad:1; unsigned access_mode:1; unsigned mask_control:1; unsigned dependency_control:2; unsigned compression_control:2; /* gen6: quater control */ unsigned thread_control:2; unsigned predicate_control:4; unsigned predicate_inverse:1; unsigned execution_size:3; /** * Conditional Modifier for most instructions. On Gen6+, this is also * used for the SEND instruction's Message Target/SFID. */ unsigned destreg__conditionalmod:4; unsigned acc_wr_control:1; unsigned cmpt_control:1; unsigned debug_control:1; unsigned saturate:1; } header; union { struct { unsigned dest_reg_file:2; unsigned dest_reg_type:3; unsigned src0_reg_file:2; unsigned src0_reg_type:3; unsigned src1_reg_file:2; unsigned src1_reg_type:3; unsigned pad:1; unsigned dest_subreg_nr:5; unsigned dest_reg_nr:8; unsigned dest_horiz_stride:2; unsigned dest_address_mode:1; } da1; struct { unsigned dest_reg_file:2; unsigned dest_reg_type:3; unsigned src0_reg_file:2; unsigned src0_reg_type:3; unsigned src1_reg_file:2; /* 0x00000c00 */ unsigned src1_reg_type:3; /* 0x00007000 */ unsigned pad:1; int dest_indirect_offset:10; /* offset against the deref'd address reg */ unsigned dest_subreg_nr:3; /* subnr for the address reg a0.x */ unsigned dest_horiz_stride:2; unsigned dest_address_mode:1; } ia1; struct { unsigned dest_reg_file:2; unsigned dest_reg_type:3; unsigned src0_reg_file:2; unsigned src0_reg_type:3; unsigned src1_reg_file:2; unsigned src1_reg_type:3; unsigned pad:1; unsigned dest_writemask:4; unsigned dest_subreg_nr:1; unsigned dest_reg_nr:8; unsigned dest_horiz_stride:2; unsigned dest_address_mode:1; } da16; struct { unsigned dest_reg_file:2; unsigned dest_reg_type:3; unsigned src0_reg_file:2; unsigned src0_reg_type:3; unsigned pad0:6; unsigned dest_writemask:4; int dest_indirect_offset:6; unsigned dest_subreg_nr:3; unsigned dest_horiz_stride:2; unsigned dest_address_mode:1; } ia16; struct { unsigned dest_reg_file:2; unsigned dest_reg_type:3; unsigned src0_reg_file:2; unsigned src0_reg_type:3; unsigned src1_reg_file:2; unsigned src1_reg_type:3; unsigned pad:1; int jump_count:16; } branch_gen6; struct { unsigned dest_reg_file:1; unsigned flag_subreg_num:1; unsigned pad0:2; unsigned src0_abs:1; unsigned src0_negate:1; unsigned src1_abs:1; unsigned src1_negate:1; unsigned src2_abs:1; unsigned src2_negate:1; unsigned pad1:7; unsigned dest_writemask:4; unsigned dest_subreg_nr:3; unsigned dest_reg_nr:8; } da3src; } bits1; union { struct { unsigned src0_subreg_nr:5; unsigned src0_reg_nr:8; unsigned src0_abs:1; unsigned src0_negate:1; unsigned src0_address_mode:1; unsigned src0_horiz_stride:2; unsigned src0_width:3; unsigned src0_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad:5; } da1; struct { int src0_indirect_offset:10; unsigned src0_subreg_nr:3; unsigned src0_abs:1; unsigned src0_negate:1; unsigned src0_address_mode:1; unsigned src0_horiz_stride:2; unsigned src0_width:3; unsigned src0_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad:5; } ia1; struct { unsigned src0_swz_x:2; unsigned src0_swz_y:2; unsigned src0_subreg_nr:1; unsigned src0_reg_nr:8; unsigned src0_abs:1; unsigned src0_negate:1; unsigned src0_address_mode:1; unsigned src0_swz_z:2; unsigned src0_swz_w:2; unsigned pad0:1; unsigned src0_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad1:5; } da16; struct { unsigned src0_swz_x:2; unsigned src0_swz_y:2; int src0_indirect_offset:6; unsigned src0_subreg_nr:3; unsigned src0_abs:1; unsigned src0_negate:1; unsigned src0_address_mode:1; unsigned src0_swz_z:2; unsigned src0_swz_w:2; unsigned pad0:1; unsigned src0_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad1:5; } ia16; /* Extended Message Descriptor for Ironlake (Gen5) SEND instruction. * * Does not apply to Gen6+. The SFID/message target moved to bits * 27:24 of the header (destreg__conditionalmod); EOT is in bits3. */ struct { unsigned pad:26; unsigned end_of_thread:1; unsigned pad1:1; unsigned sfid:4; } send_gen5; /* for Ironlake only */ struct { unsigned src0_rep_ctrl:1; unsigned src0_swizzle:8; unsigned src0_subreg_nr:3; unsigned src0_reg_nr:8; unsigned pad0:1; unsigned src1_rep_ctrl:1; unsigned src1_swizzle:8; unsigned src1_subreg_nr_low:2; } da3src; } bits2; union { struct { unsigned src1_subreg_nr:5; unsigned src1_reg_nr:8; unsigned src1_abs:1; unsigned src1_negate:1; unsigned src1_address_mode:1; unsigned src1_horiz_stride:2; unsigned src1_width:3; unsigned src1_vert_stride:4; unsigned pad0:7; } da1; struct { unsigned src1_swz_x:2; unsigned src1_swz_y:2; unsigned src1_subreg_nr:1; unsigned src1_reg_nr:8; unsigned src1_abs:1; unsigned src1_negate:1; unsigned src1_address_mode:1; unsigned src1_swz_z:2; unsigned src1_swz_w:2; unsigned pad1:1; unsigned src1_vert_stride:4; unsigned pad2:7; } da16; struct { int src1_indirect_offset:10; unsigned src1_subreg_nr:3; unsigned src1_abs:1; unsigned src1_negate:1; unsigned src1_address_mode:1; unsigned src1_horiz_stride:2; unsigned src1_width:3; unsigned src1_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad1:5; } ia1; struct { unsigned src1_swz_x:2; unsigned src1_swz_y:2; int src1_indirect_offset:6; unsigned src1_subreg_nr:3; unsigned src1_abs:1; unsigned src1_negate:1; unsigned pad0:1; unsigned src1_swz_z:2; unsigned src1_swz_w:2; unsigned pad1:1; unsigned src1_vert_stride:4; unsigned flag_subreg_nr:1; unsigned flag_reg_nr:1; unsigned pad2:5; } ia16; struct { int jump_count:16; /* note: signed */ unsigned pop_count:4; unsigned pad0:12; } if_else; /* This is also used for gen7 IF/ELSE instructions */ struct { /* Signed jump distance to the ip to jump to if all channels * are disabled after the break or continue. It should point * to the end of the innermost control flow block, as that's * where some channel could get re-enabled. */ int jip:16; /* Signed jump distance to the location to resume execution * of this channel if it's enabled for the break or continue. */ int uip:16; } break_cont; /** * \defgroup SEND instructions / Message Descriptors * * @{ */ /** * Generic Message Descriptor for Gen4 SEND instructions. The structs * below expand function_control to something specific for their * message. Due to struct packing issues, they duplicate these bits. * * See the G45 PRM, Volume 4, Table 14-15. */ struct { unsigned function_control:16; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } generic; /** * Generic Message Descriptor for Gen5-7 SEND instructions. * * See the Sandybridge PRM, Volume 2 Part 2, Table 8-15. (Sadly, most * of the information on the SEND instruction is missing from the public * Ironlake PRM.) * * The table claims that bit 31 is reserved/MBZ on Gen6+, but it lies. * According to the SEND instruction description: * "The MSb of the message description, the EOT field, always comes from * bit 127 of the instruction word"...which is bit 31 of this field. */ struct { unsigned function_control:19; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } generic_gen5; /** G45 PRM, Volume 4, Section 6.1.1.1 */ struct { unsigned function:4; unsigned int_type:1; unsigned precision:1; unsigned saturate:1; unsigned data_type:1; unsigned pad0:8; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } math; /** Ironlake PRM, Volume 4 Part 1, Section 6.1.1.1 */ struct { unsigned function:4; unsigned int_type:1; unsigned precision:1; unsigned saturate:1; unsigned data_type:1; unsigned snapshot:1; unsigned pad0:10; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } math_gen5; /** G45 PRM, Volume 4, Section 4.8.1.1.1 [DevBW] and [DevCL] */ struct { unsigned binding_table_index:8; unsigned sampler:4; unsigned return_format:2; unsigned msg_type:2; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } sampler; /** G45 PRM, Volume 4, Section 4.8.1.1.2 [DevCTG] */ struct { unsigned binding_table_index:8; unsigned sampler:4; unsigned msg_type:4; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } sampler_g4x; /** Ironlake PRM, Volume 4 Part 1, Section 4.11.1.1.3 */ struct { unsigned binding_table_index:8; unsigned sampler:4; unsigned msg_type:4; unsigned simd_mode:2; unsigned pad0:1; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } sampler_gen5; struct { unsigned binding_table_index:8; unsigned sampler:4; unsigned msg_type:5; unsigned simd_mode:2; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } sampler_gen7; struct brw_urb_immediate { unsigned opcode:4; unsigned offset:6; unsigned swizzle_control:2; unsigned pad:1; unsigned allocate:1; unsigned used:1; unsigned complete:1; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } urb; struct { unsigned opcode:4; unsigned offset:6; unsigned swizzle_control:2; unsigned pad:1; unsigned allocate:1; unsigned used:1; unsigned complete:1; unsigned pad0:3; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } urb_gen5; struct { unsigned opcode:3; unsigned offset:11; unsigned swizzle_control:1; unsigned complete:1; unsigned per_slot_offset:1; unsigned pad0:2; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } urb_gen7; /** 965 PRM, Volume 4, Section 5.10.1.1: Message Descriptor */ struct { unsigned binding_table_index:8; unsigned msg_control:4; unsigned msg_type:2; unsigned target_cache:2; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } dp_read; /** G45 PRM, Volume 4, Section 5.10.1.1.2 */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned msg_type:3; unsigned target_cache:2; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } dp_read_g4x; /** Ironlake PRM, Volume 4 Part 1, Section 5.10.2.1.2. */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned msg_type:3; unsigned target_cache:2; unsigned pad0:3; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } dp_read_gen5; /** G45 PRM, Volume 4, Section 5.10.1.1.2. For both Gen4 and G45. */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned last_render_target:1; unsigned msg_type:3; unsigned send_commit_msg:1; unsigned response_length:4; unsigned msg_length:4; unsigned msg_target:4; unsigned pad1:3; unsigned end_of_thread:1; } dp_write; /** Ironlake PRM, Volume 4 Part 1, Section 5.10.2.1.2. */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned last_render_target:1; unsigned msg_type:3; unsigned send_commit_msg:1; unsigned pad0:3; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } dp_write_gen5; /** * Message for the Sandybridge Sampler Cache or Constant Cache Data Port. * * See the Sandybridge PRM, Volume 4 Part 1, Section 3.9.2.1.1. **/ struct { unsigned binding_table_index:8; unsigned msg_control:5; unsigned msg_type:3; unsigned pad0:3; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } gen6_dp_sampler_const_cache; /** * Message for the Sandybridge Render Cache Data Port. * * Most fields are defined in the Sandybridge PRM, Volume 4 Part 1, * Section 3.9.2.1.1: Message Descriptor. * * "Slot Group Select" and "Last Render Target" are part of the * 5-bit message control for Render Target Write messages. See * Section 3.9.9.2.1 of the same volume. */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned slot_group_select:1; unsigned last_render_target:1; unsigned msg_type:4; unsigned send_commit_msg:1; unsigned pad0:1; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad1:2; unsigned end_of_thread:1; } gen6_dp; /** * Message for any of the Gen7 Data Port caches. * * Most fields are defined in BSpec volume 5c.2 Data Port / Messages / * Data Port Messages / Message Descriptor. Once again, "Slot Group * Select" and "Last Render Target" are part of the 6-bit message * control for Render Target Writes. */ struct { unsigned binding_table_index:8; unsigned msg_control:3; unsigned slot_group_select:1; unsigned last_render_target:1; unsigned msg_control_pad:1; unsigned msg_type:4; unsigned pad1:1; unsigned header_present:1; unsigned response_length:5; unsigned msg_length:4; unsigned pad2:2; unsigned end_of_thread:1; } gen7_dp; /** @} */ struct { unsigned src1_subreg_nr_high:1; unsigned src1_reg_nr:8; unsigned pad0:1; unsigned src2_rep_ctrl:1; unsigned src2_swizzle:8; unsigned src2_subreg_nr:3; unsigned src2_reg_nr:8; unsigned pad1:2; } da3src; int d; unsigned ud; float f; } bits3; }; /* These aren't hardware structs, just something useful for us to pass around: * * Align1 operation has a lot of control over input ranges. Used in * WM programs to implement shaders decomposed into "channel serial" * or "structure of array" form: */ struct brw_reg { unsigned type:4; unsigned file:2; unsigned nr:8; unsigned subnr:5; /* :1 in align16 */ unsigned negate:1; /* source only */ unsigned abs:1; /* source only */ unsigned vstride:4; /* source only */ unsigned width:3; /* src only, align1 only */ unsigned hstride:2; /* align1 only */ unsigned address_mode:1; /* relative addressing, hopefully! */ unsigned pad0:1; union { struct { unsigned swizzle:8; /* src only, align16 only */ unsigned writemask:4; /* dest only, align16 only */ int indirect_offset:10; /* relative addressing offset */ unsigned pad1:10; /* two dwords total */ } bits; float f; int d; unsigned ud; } dw1; }; struct brw_indirect { unsigned addr_subnr:4; int addr_offset:10; unsigned pad:18; }; #define BRW_EU_MAX_INSN_STACK 5 #define BRW_EU_MAX_INSN 10000 struct brw_compile { struct brw_instruction *store; unsigned nr_insn; int gen; /* Allow clients to push/pop instruction state: */ struct brw_instruction stack[BRW_EU_MAX_INSN_STACK]; bool compressed_stack[BRW_EU_MAX_INSN_STACK]; struct brw_instruction *current; unsigned flag_value; bool single_program_flow; bool compressed; /* Control flow stacks: * - if_stack contains IF and ELSE instructions which must be patched * (and popped) once the matching ENDIF instruction is encountered. */ struct brw_instruction **if_stack; int if_stack_depth; int if_stack_array_size; }; static inline int type_sz(unsigned type) { switch (type) { case BRW_REGISTER_TYPE_UD: case BRW_REGISTER_TYPE_D: case BRW_REGISTER_TYPE_F: return 4; case BRW_REGISTER_TYPE_HF: case BRW_REGISTER_TYPE_UW: case BRW_REGISTER_TYPE_W: return 2; case BRW_REGISTER_TYPE_UB: case BRW_REGISTER_TYPE_B: return 1; default: return 0; } } /** * Construct a brw_reg. * \param file one of the BRW_x_REGISTER_FILE values * \param nr register number/index * \param subnr register sub number * \param type one of BRW_REGISTER_TYPE_x * \param vstride one of BRW_VERTICAL_STRIDE_x * \param width one of BRW_WIDTH_x * \param hstride one of BRW_HORIZONTAL_STRIDE_x * \param swizzle one of BRW_SWIZZLE_x * \param writemask WRITEMASK_X/Y/Z/W bitfield */ static inline struct brw_reg brw_reg(unsigned file, unsigned nr, unsigned subnr, unsigned type, unsigned vstride, unsigned width, unsigned hstride, unsigned swizzle, unsigned writemask) { struct brw_reg reg; if (file == BRW_GENERAL_REGISTER_FILE) assert(nr < BRW_MAX_GRF); else if (file == BRW_MESSAGE_REGISTER_FILE) assert((nr & ~(1 << 7)) < BRW_MAX_MRF); else if (file == BRW_ARCHITECTURE_REGISTER_FILE) assert(nr <= BRW_ARF_IP); reg.type = type; reg.file = file; reg.nr = nr; reg.subnr = subnr * type_sz(type); reg.negate = 0; reg.abs = 0; reg.vstride = vstride; reg.width = width; reg.hstride = hstride; reg.address_mode = BRW_ADDRESS_DIRECT; reg.pad0 = 0; /* Could do better: If the reg is r5.3<0;1,0>, we probably want to * set swizzle and writemask to W, as the lower bits of subnr will * be lost when converted to align16. This is probably too much to * keep track of as you'd want it adjusted by suboffset(), etc. * Perhaps fix up when converting to align16? */ reg.dw1.bits.swizzle = swizzle; reg.dw1.bits.writemask = writemask; reg.dw1.bits.indirect_offset = 0; reg.dw1.bits.pad1 = 0; return reg; } /** Construct float[16] register */ static inline struct brw_reg brw_vec16_reg(unsigned file, unsigned nr, unsigned subnr) { return brw_reg(file, nr, subnr, BRW_REGISTER_TYPE_F, BRW_VERTICAL_STRIDE_16, BRW_WIDTH_16, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } /** Construct float[8] register */ static inline struct brw_reg brw_vec8_reg(unsigned file, unsigned nr, unsigned subnr) { return brw_reg(file, nr, subnr, BRW_REGISTER_TYPE_F, BRW_VERTICAL_STRIDE_8, BRW_WIDTH_8, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } /** Construct float[4] register */ static inline struct brw_reg brw_vec4_reg(unsigned file, unsigned nr, unsigned subnr) { return brw_reg(file, nr, subnr, BRW_REGISTER_TYPE_F, BRW_VERTICAL_STRIDE_4, BRW_WIDTH_4, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } /** Construct float[2] register */ static inline struct brw_reg brw_vec2_reg(unsigned file, unsigned nr, unsigned subnr) { return brw_reg(file, nr, subnr, BRW_REGISTER_TYPE_F, BRW_VERTICAL_STRIDE_2, BRW_WIDTH_2, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYXY, WRITEMASK_XY); } /** Construct float[1] register */ static inline struct brw_reg brw_vec1_reg(unsigned file, unsigned nr, unsigned subnr) { return brw_reg(file, nr, subnr, BRW_REGISTER_TYPE_F, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, BRW_HORIZONTAL_STRIDE_0, BRW_SWIZZLE_XXXX, WRITEMASK_X); } static inline struct brw_reg __retype(struct brw_reg reg, unsigned type) { reg.type = type; return reg; } static inline struct brw_reg __retype_d(struct brw_reg reg) { return __retype(reg, BRW_REGISTER_TYPE_D); } static inline struct brw_reg __retype_ud(struct brw_reg reg) { return __retype(reg, BRW_REGISTER_TYPE_UD); } static inline struct brw_reg __retype_uw(struct brw_reg reg) { return __retype(reg, BRW_REGISTER_TYPE_UW); } static inline struct brw_reg __sechalf(struct brw_reg reg) { if (reg.vstride) reg.nr++; return reg; } static inline struct brw_reg __suboffset(struct brw_reg reg, unsigned delta) { reg.subnr += delta * type_sz(reg.type); return reg; } static inline struct brw_reg __offset(struct brw_reg reg, unsigned delta) { reg.nr += delta; return reg; } static inline struct brw_reg byte_offset(struct brw_reg reg, unsigned bytes) { unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes; reg.nr = newoffset / REG_SIZE; reg.subnr = newoffset % REG_SIZE; return reg; } /** Construct unsigned word[16] register */ static inline struct brw_reg brw_uw16_reg(unsigned file, unsigned nr, unsigned subnr) { return __suboffset(__retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); } /** Construct unsigned word[8] register */ static inline struct brw_reg brw_uw8_reg(unsigned file, unsigned nr, unsigned subnr) { return __suboffset(__retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); } /** Construct unsigned word[1] register */ static inline struct brw_reg brw_uw1_reg(unsigned file, unsigned nr, unsigned subnr) { return __suboffset(__retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); } static inline struct brw_reg brw_imm_reg(unsigned type) { return brw_reg( BRW_IMMEDIATE_VALUE, 0, 0, type, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, BRW_HORIZONTAL_STRIDE_0, 0, 0); } /** Construct float immediate register */ static inline struct brw_reg brw_imm_f(float f) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F); imm.dw1.f = f; return imm; } /** Construct integer immediate register */ static inline struct brw_reg brw_imm_d(int d) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D); imm.dw1.d = d; return imm; } /** Construct uint immediate register */ static inline struct brw_reg brw_imm_ud(unsigned ud) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD); imm.dw1.ud = ud; return imm; } /** Construct ushort immediate register */ static inline struct brw_reg brw_imm_uw(uint16_t uw) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW); imm.dw1.ud = uw | (uw << 16); return imm; } /** Construct short immediate register */ static inline struct brw_reg brw_imm_w(int16_t w) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W); imm.dw1.d = w | (w << 16); return imm; } /* brw_imm_b and brw_imm_ub aren't supported by hardware - the type * numbers alias with _V and _VF below: */ /** Construct vector of eight signed half-byte values */ static inline struct brw_reg brw_imm_v(unsigned v) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V); imm.vstride = BRW_VERTICAL_STRIDE_0; imm.width = BRW_WIDTH_8; imm.hstride = BRW_HORIZONTAL_STRIDE_1; imm.dw1.ud = v; return imm; } /** Construct vector of four 8-bit float values */ static inline struct brw_reg brw_imm_vf(unsigned v) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); imm.vstride = BRW_VERTICAL_STRIDE_0; imm.width = BRW_WIDTH_4; imm.hstride = BRW_HORIZONTAL_STRIDE_1; imm.dw1.ud = v; return imm; } #define VF_ZERO 0x0 #define VF_ONE 0x30 #define VF_NEG (1<<7) static inline struct brw_reg brw_imm_vf4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) { struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); imm.vstride = BRW_VERTICAL_STRIDE_0; imm.width = BRW_WIDTH_4; imm.hstride = BRW_HORIZONTAL_STRIDE_1; imm.dw1.ud = ((v0 << 0) | (v1 << 8) | (v2 << 16) | (v3 << 24)); return imm; } static inline struct brw_reg brw_address(struct brw_reg reg) { return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr); } /** Construct float[1] general-purpose register */ static inline struct brw_reg brw_vec1_grf(unsigned nr, unsigned subnr) { return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } /** Construct float[2] general-purpose register */ static inline struct brw_reg brw_vec2_grf(unsigned nr, unsigned subnr) { return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } /** Construct float[4] general-purpose register */ static inline struct brw_reg brw_vec4_grf(unsigned nr, unsigned subnr) { return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } /** Construct float[8] general-purpose register */ static inline struct brw_reg brw_vec8_grf(unsigned nr, unsigned subnr) { return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } static inline struct brw_reg brw_uw8_grf(unsigned nr, unsigned subnr) { return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } static inline struct brw_reg brw_uw16_grf(unsigned nr, unsigned subnr) { return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); } /** Construct null register (usually used for setting condition codes) */ static inline struct brw_reg brw_null_reg(void) { return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0); } static inline struct brw_reg brw_address_reg(unsigned subnr) { return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ADDRESS, subnr); } /* If/else instructions break in align16 mode if writemask & swizzle * aren't xyzw. This goes against the convention for other scalar * regs: */ static inline struct brw_reg brw_ip_reg(void) { return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_IP, 0, BRW_REGISTER_TYPE_UD, BRW_VERTICAL_STRIDE_4, /* ? */ BRW_WIDTH_1, BRW_HORIZONTAL_STRIDE_0, BRW_SWIZZLE_XYZW, /* NOTE! */ WRITEMASK_XYZW); /* NOTE! */ } static inline struct brw_reg brw_acc_reg(void) { return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_ACCUMULATOR, 0); } static inline struct brw_reg brw_notification_1_reg(void) { return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NOTIFICATION_COUNT, 1, BRW_REGISTER_TYPE_UD, BRW_VERTICAL_STRIDE_0, BRW_WIDTH_1, BRW_HORIZONTAL_STRIDE_0, BRW_SWIZZLE_XXXX, WRITEMASK_X); } static inline struct brw_reg brw_flag_reg(void) { return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_FLAG, 0); } static inline struct brw_reg brw_mask_reg(unsigned subnr) { return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_MASK, subnr); } static inline struct brw_reg brw_message_reg(unsigned nr) { assert((nr & ~(1 << 7)) < BRW_MAX_MRF); return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0); } static inline struct brw_reg brw_message4_reg(unsigned nr, int subnr) { assert((nr & ~(1 << 7)) < BRW_MAX_MRF); return brw_vec4_reg(BRW_MESSAGE_REGISTER_FILE, nr, subnr); } /* This is almost always called with a numeric constant argument, so * make things easy to evaluate at compile time: */ static inline unsigned cvt(unsigned val) { switch (val) { case 0: return 0; case 1: return 1; case 2: return 2; case 4: return 3; case 8: return 4; case 16: return 5; case 32: return 6; } return 0; } static inline struct brw_reg __stride(struct brw_reg reg, unsigned vstride, unsigned width, unsigned hstride) { reg.vstride = cvt(vstride); reg.width = cvt(width) - 1; reg.hstride = cvt(hstride); return reg; } static inline struct brw_reg vec16(struct brw_reg reg) { return __stride(reg, 16,16,1); } static inline struct brw_reg vec8(struct brw_reg reg) { return __stride(reg, 8,8,1); } static inline struct brw_reg vec4(struct brw_reg reg) { return __stride(reg, 4,4,1); } static inline struct brw_reg vec2(struct brw_reg reg) { return __stride(reg, 2,2,1); } static inline struct brw_reg vec1(struct brw_reg reg) { return __stride(reg, 0,1,0); } static inline struct brw_reg get_element(struct brw_reg reg, unsigned elt) { return vec1(__suboffset(reg, elt)); } static inline struct brw_reg get_element_ud(struct brw_reg reg, unsigned elt) { return vec1(__suboffset(__retype(reg, BRW_REGISTER_TYPE_UD), elt)); } static inline struct brw_reg brw_swizzle(struct brw_reg reg, unsigned x, unsigned y, unsigned z, unsigned w) { assert(reg.file != BRW_IMMEDIATE_VALUE); reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x), BRW_GET_SWZ(reg.dw1.bits.swizzle, y), BRW_GET_SWZ(reg.dw1.bits.swizzle, z), BRW_GET_SWZ(reg.dw1.bits.swizzle, w)); return reg; } static inline struct brw_reg brw_swizzle1(struct brw_reg reg, unsigned x) { return brw_swizzle(reg, x, x, x, x); } static inline struct brw_reg brw_writemask(struct brw_reg reg, unsigned mask) { assert(reg.file != BRW_IMMEDIATE_VALUE); reg.dw1.bits.writemask &= mask; return reg; } static inline struct brw_reg brw_set_writemask(struct brw_reg reg, unsigned mask) { assert(reg.file != BRW_IMMEDIATE_VALUE); reg.dw1.bits.writemask = mask; return reg; } static inline struct brw_reg brw_negate(struct brw_reg reg) { reg.negate ^= 1; return reg; } static inline struct brw_reg brw_abs(struct brw_reg reg) { reg.abs = 1; return reg; } /*********************************************************************** */ static inline struct brw_reg brw_vec4_indirect(unsigned subnr, int offset) { struct brw_reg reg = brw_vec4_grf(0, 0); reg.subnr = subnr; reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; reg.dw1.bits.indirect_offset = offset; return reg; } static inline struct brw_reg brw_vec1_indirect(unsigned subnr, int offset) { struct brw_reg reg = brw_vec1_grf(0, 0); reg.subnr = subnr; reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; reg.dw1.bits.indirect_offset = offset; return reg; } static inline struct brw_reg deref_4f(struct brw_indirect ptr, int offset) { return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset); } static inline struct brw_reg deref_1f(struct brw_indirect ptr, int offset) { return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset); } static inline struct brw_reg deref_4b(struct brw_indirect ptr, int offset) { return __retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B); } static inline struct brw_reg deref_1uw(struct brw_indirect ptr, int offset) { return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); } static inline struct brw_reg deref_1d(struct brw_indirect ptr, int offset) { return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D); } static inline struct brw_reg deref_1ud(struct brw_indirect ptr, int offset) { return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); } static inline struct brw_reg get_addr_reg(struct brw_indirect ptr) { return brw_address_reg(ptr.addr_subnr); } static inline struct brw_indirect brw_indirect_offset(struct brw_indirect ptr, int offset) { ptr.addr_offset += offset; return ptr; } static inline struct brw_indirect brw_indirect(unsigned addr_subnr, int offset) { struct brw_indirect ptr; ptr.addr_subnr = addr_subnr; ptr.addr_offset = offset; ptr.pad = 0; return ptr; } /** Do two brw_regs refer to the same register? */ static inline bool brw_same_reg(struct brw_reg r1, struct brw_reg r2) { return r1.file == r2.file && r1.nr == r2.nr; } static inline struct brw_instruction *current_insn( struct brw_compile *p) { return &p->store[p->nr_insn]; } static inline void brw_set_predicate_control( struct brw_compile *p, unsigned pc ) { p->current->header.predicate_control = pc; } static inline void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse) { p->current->header.predicate_inverse = predicate_inverse; } static inline void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional ) { p->current->header.destreg__conditionalmod = conditional; } static inline void brw_set_access_mode(struct brw_compile *p, unsigned access_mode) { p->current->header.access_mode = access_mode; } static inline void brw_set_mask_control(struct brw_compile *p, unsigned value) { p->current->header.mask_control = value; } static inline void brw_set_saturate(struct brw_compile *p, unsigned value) { p->current->header.saturate = value; } static inline void brw_set_acc_write_control(struct brw_compile *p, unsigned value) { if (p->gen >= 060) p->current->header.acc_wr_control = value; } void brw_pop_insn_state(struct brw_compile *p); void brw_push_insn_state(struct brw_compile *p); void brw_set_compression_control(struct brw_compile *p, enum brw_compression control); void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ); void brw_compile_init(struct brw_compile *p, int gen, void *store); void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg dest); void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg reg); void brw_set_src1(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg reg); void gen6_resolve_implied_move(struct brw_compile *p, struct brw_reg *src, unsigned msg_reg_nr); static inline struct brw_instruction * brw_next_insn(struct brw_compile *p, unsigned opcode) { struct brw_instruction *insn; assert(p->nr_insn + 1 < BRW_EU_MAX_INSN); insn = &p->store[p->nr_insn++]; *insn = *p->current; if (p->current->header.destreg__conditionalmod) { p->current->header.destreg__conditionalmod = 0; p->current->header.predicate_control = BRW_PREDICATE_NORMAL; } insn->header.opcode = opcode; return insn; } /* Helpers for regular instructions: */ #define ALU1(OP) \ static inline struct brw_instruction *brw_##OP(struct brw_compile *p, \ struct brw_reg dest, \ struct brw_reg src0) \ { \ return brw_alu1(p, BRW_OPCODE_##OP, dest, src0); \ } #define ALU2(OP) \ static inline struct brw_instruction *brw_##OP(struct brw_compile *p, \ struct brw_reg dest, \ struct brw_reg src0, \ struct brw_reg src1) \ { \ return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \ } /* Rounding operations (other than RNDD) require two instructions - the first * stores a rounded value (possibly the wrong way) in the dest register, but * also sets a per-channel "increment bit" in the flag register. A predicated * add of 1.0 fixes dest to contain the desired result. * * Sandybridge and later appear to round correctly without an ADD. */ #define ROUND(OP) \ static inline void brw_##OP(struct brw_compile *p, \ struct brw_reg dest, \ struct brw_reg src) \ { \ struct brw_instruction *rnd, *add; \ rnd = brw_next_insn(p, BRW_OPCODE_##OP); \ brw_set_dest(p, rnd, dest); \ brw_set_src0(p, rnd, src); \ if (p->gen < 060) { \ /* turn on round-increments */ \ rnd->header.destreg__conditionalmod = BRW_CONDITIONAL_R; \ add = brw_ADD(p, dest, dest, brw_imm_f(1.0f)); \ add->header.predicate_control = BRW_PREDICATE_NORMAL; \ } \ } static inline struct brw_instruction *brw_alu1(struct brw_compile *p, unsigned opcode, struct brw_reg dest, struct brw_reg src) { struct brw_instruction *insn = brw_next_insn(p, opcode); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); return insn; } static inline struct brw_instruction *brw_alu2(struct brw_compile *p, unsigned opcode, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1 ) { struct brw_instruction *insn = brw_next_insn(p, opcode); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_src1(p, insn, src1); return insn; } static inline struct brw_instruction *brw_ADD(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1) { /* 6.2.2: add */ if (src0.type == BRW_REGISTER_TYPE_F || (src0.file == BRW_IMMEDIATE_VALUE && src0.type == BRW_REGISTER_TYPE_VF)) { assert(src1.type != BRW_REGISTER_TYPE_UD); assert(src1.type != BRW_REGISTER_TYPE_D); } if (src1.type == BRW_REGISTER_TYPE_F || (src1.file == BRW_IMMEDIATE_VALUE && src1.type == BRW_REGISTER_TYPE_VF)) { assert(src0.type != BRW_REGISTER_TYPE_UD); assert(src0.type != BRW_REGISTER_TYPE_D); } return brw_alu2(p, BRW_OPCODE_ADD, dest, src0, src1); } static inline struct brw_instruction *brw_MUL(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1) { /* 6.32.38: mul */ if (src0.type == BRW_REGISTER_TYPE_D || src0.type == BRW_REGISTER_TYPE_UD || src1.type == BRW_REGISTER_TYPE_D || src1.type == BRW_REGISTER_TYPE_UD) { assert(dest.type != BRW_REGISTER_TYPE_F); } if (src0.type == BRW_REGISTER_TYPE_F || (src0.file == BRW_IMMEDIATE_VALUE && src0.type == BRW_REGISTER_TYPE_VF)) { assert(src1.type != BRW_REGISTER_TYPE_UD); assert(src1.type != BRW_REGISTER_TYPE_D); } if (src1.type == BRW_REGISTER_TYPE_F || (src1.file == BRW_IMMEDIATE_VALUE && src1.type == BRW_REGISTER_TYPE_VF)) { assert(src0.type != BRW_REGISTER_TYPE_UD); assert(src0.type != BRW_REGISTER_TYPE_D); } assert(src0.file != BRW_ARCHITECTURE_REGISTER_FILE || src0.nr != BRW_ARF_ACCUMULATOR); assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE || src1.nr != BRW_ARF_ACCUMULATOR); return brw_alu2(p, BRW_OPCODE_MUL, dest, src0, src1); } static inline struct brw_instruction *brw_JMPI(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1) { struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1); insn->header.execution_size = 1; insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.mask_control = BRW_MASK_DISABLE; p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn; } ALU1(MOV); ALU2(SEL); ALU1(NOT); ALU2(AND); ALU2(OR); ALU2(XOR); ALU2(SHR); ALU2(SHL); ALU2(RSR); ALU2(RSL); ALU2(ASR); ALU1(FRC); ALU1(RNDD); ALU2(MAC); ALU2(MACH); ALU1(LZD); ALU2(DP4); ALU2(DPH); ALU2(DP3); ALU2(DP2); ALU2(LINE); ALU2(PLN); ROUND(RNDZ); ROUND(RNDE); #undef ALU1 #undef ALU2 #undef ROUND /* Helpers for SEND instruction */ void brw_set_dp_read_message(struct brw_compile *p, struct brw_instruction *insn, unsigned binding_table_index, unsigned msg_control, unsigned msg_type, unsigned target_cache, unsigned msg_length, unsigned response_length); void brw_set_dp_write_message(struct brw_compile *p, struct brw_instruction *insn, unsigned binding_table_index, unsigned msg_control, unsigned msg_type, unsigned msg_length, bool header_present, bool last_render_target, unsigned response_length, bool end_of_thread, bool send_commit_msg); void brw_urb_WRITE(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, bool allocate, bool used, unsigned msg_length, unsigned response_length, bool eot, bool writes_complete, unsigned offset, unsigned swizzle); void brw_ff_sync(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, bool allocate, unsigned response_length, bool eot); void brw_fb_WRITE(struct brw_compile *p, int dispatch_width, unsigned msg_reg_nr, struct brw_reg src0, unsigned msg_control, unsigned binding_table_index, unsigned msg_length, unsigned response_length, bool eot, bool header_present); void brw_SAMPLE(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, unsigned binding_table_index, unsigned sampler, unsigned writemask, unsigned msg_type, unsigned response_length, unsigned msg_length, bool header_present, unsigned simd_mode); void brw_math_16(struct brw_compile *p, struct brw_reg dest, unsigned function, unsigned saturate, unsigned msg_reg_nr, struct brw_reg src, unsigned precision); void brw_math(struct brw_compile *p, struct brw_reg dest, unsigned function, unsigned saturate, unsigned msg_reg_nr, struct brw_reg src, unsigned data_type, unsigned precision); void brw_math2(struct brw_compile *p, struct brw_reg dest, unsigned function, struct brw_reg src0, struct brw_reg src1); void brw_oword_block_read(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, uint32_t offset, uint32_t bind_table_index); void brw_oword_block_read_scratch(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, int num_regs, unsigned offset); void brw_oword_block_write_scratch(struct brw_compile *p, struct brw_reg mrf, int num_regs, unsigned offset); void brw_dword_scattered_read(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, uint32_t bind_table_index); void brw_dp_READ_4_vs(struct brw_compile *p, struct brw_reg dest, unsigned location, unsigned bind_table_index); void brw_dp_READ_4_vs_relative(struct brw_compile *p, struct brw_reg dest, struct brw_reg addrReg, unsigned offset, unsigned bind_table_index); /* If/else/endif. Works by manipulating the execution flags on each * channel. */ struct brw_instruction *brw_IF(struct brw_compile *p, unsigned execute_size); struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional, struct brw_reg src0, struct brw_reg src1); void brw_ELSE(struct brw_compile *p); void brw_ENDIF(struct brw_compile *p); /* DO/WHILE loops: */ struct brw_instruction *brw_DO(struct brw_compile *p, unsigned execute_size); struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *patch_insn); struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count); struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count); struct brw_instruction *gen6_CONT(struct brw_compile *p, struct brw_instruction *do_insn); /* Forward jumps: */ void brw_land_fwd_jump(struct brw_compile *p, struct brw_instruction *jmp_insn); void brw_NOP(struct brw_compile *p); void brw_WAIT(struct brw_compile *p); /* Special case: there is never a destination, execution size will be * taken from src0: */ void brw_CMP(struct brw_compile *p, struct brw_reg dest, unsigned conditional, struct brw_reg src0, struct brw_reg src1); static inline void brw_math_invert(struct brw_compile *p, struct brw_reg dst, struct brw_reg src) { brw_math(p, dst, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 0, src, BRW_MATH_PRECISION_FULL, BRW_MATH_DATA_VECTOR); } void brw_set_uip_jip(struct brw_compile *p); uint32_t brw_swap_cmod(uint32_t cmod); void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen); #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_eu_emit.c000066400000000000000000001653571267532330400251230ustar00rootroot00000000000000/* Copyright (C) Intel Corp. 2006. All Rights Reserved. Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to develop this 3D driver. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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: * Keith Whitwell */ #include "brw_eu.h" #include #include #define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0])) /*********************************************************************** * Internal helper for constructing instructions */ static void guess_execution_size(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg reg) { if (reg.width == BRW_WIDTH_8 && p->compressed) insn->header.execution_size = BRW_EXECUTE_16; else insn->header.execution_size = reg.width; } /** * Prior to Sandybridge, the SEND instruction accepted non-MRF source * registers, implicitly moving the operand to a message register. * * On Sandybridge, this is no longer the case. This function performs the * explicit move; it should be called before emitting a SEND instruction. */ void gen6_resolve_implied_move(struct brw_compile *p, struct brw_reg *src, unsigned msg_reg_nr) { if (p->gen < 060) return; if (src->file == BRW_MESSAGE_REGISTER_FILE) return; if (src->file != BRW_ARCHITECTURE_REGISTER_FILE || src->nr != BRW_ARF_NULL) { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, __retype_ud(brw_message_reg(msg_reg_nr)), __retype_ud(*src)); brw_pop_insn_state(p); } *src = brw_message_reg(msg_reg_nr); } static void gen7_convert_mrf_to_grf(struct brw_compile *p, struct brw_reg *reg) { /* From the BSpec / ISA Reference / send - [DevIVB+]: * "The send with EOT should use register space R112-R127 for . This is * to enable loading of a new thread into the same slot while the message * with EOT for current thread is pending dispatch." * * Since we're pretending to have 16 MRFs anyway, we may as well use the * registers required for messages with EOT. */ if (p->gen >= 070 && reg->file == BRW_MESSAGE_REGISTER_FILE) { reg->file = BRW_GENERAL_REGISTER_FILE; reg->nr += 111; } } void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg dest) { if (dest.file != BRW_ARCHITECTURE_REGISTER_FILE && dest.file != BRW_MESSAGE_REGISTER_FILE) assert(dest.nr < 128); gen7_convert_mrf_to_grf(p, &dest); insn->bits1.da1.dest_reg_file = dest.file; insn->bits1.da1.dest_reg_type = dest.type; insn->bits1.da1.dest_address_mode = dest.address_mode; if (dest.address_mode == BRW_ADDRESS_DIRECT) { insn->bits1.da1.dest_reg_nr = dest.nr; if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits1.da1.dest_subreg_nr = dest.subnr; if (dest.hstride == BRW_HORIZONTAL_STRIDE_0) dest.hstride = BRW_HORIZONTAL_STRIDE_1; insn->bits1.da1.dest_horiz_stride = dest.hstride; } else { insn->bits1.da16.dest_subreg_nr = dest.subnr / 16; insn->bits1.da16.dest_writemask = dest.dw1.bits.writemask; /* even ignored in da16, still need to set as '01' */ insn->bits1.da16.dest_horiz_stride = 1; } } else { insn->bits1.ia1.dest_subreg_nr = dest.subnr; /* These are different sizes in align1 vs align16: */ if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits1.ia1.dest_indirect_offset = dest.dw1.bits.indirect_offset; if (dest.hstride == BRW_HORIZONTAL_STRIDE_0) dest.hstride = BRW_HORIZONTAL_STRIDE_1; insn->bits1.ia1.dest_horiz_stride = dest.hstride; } else { insn->bits1.ia16.dest_indirect_offset = dest.dw1.bits.indirect_offset; /* even ignored in da16, still need to set as '01' */ insn->bits1.ia16.dest_horiz_stride = 1; } } guess_execution_size(p, insn, dest); } static const int reg_type_size[8] = { [0] = 4, [1] = 4, [2] = 2, [3] = 2, [4] = 1, [5] = 1, [7] = 4 }; static void validate_reg(struct brw_instruction *insn, struct brw_reg reg) { int hstride_for_reg[] = {0, 1, 2, 4}; int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256}; int width_for_reg[] = {1, 2, 4, 8, 16}; int execsize_for_reg[] = {1, 2, 4, 8, 16}; int width, hstride, vstride, execsize; if (reg.file == BRW_IMMEDIATE_VALUE) { /* 3.3.6: Region Parameters. Restriction: Immediate vectors * mean the destination has to be 128-bit aligned and the * destination horiz stride has to be a word. */ if (reg.type == BRW_REGISTER_TYPE_V) { assert(hstride_for_reg[insn->bits1.da1.dest_horiz_stride] * reg_type_size[insn->bits1.da1.dest_reg_type] == 2); } return; } if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE && reg.file == BRW_ARF_NULL) return; assert(reg.hstride >= 0 && reg.hstride < ARRAY_SIZE(hstride_for_reg)); assert(reg.vstride >= 0 && reg.vstride < ARRAY_SIZE(vstride_for_reg)); assert(reg.width >= 0 && reg.width < ARRAY_SIZE(width_for_reg)); assert(insn->header.execution_size >= 0 && insn->header.execution_size < ARRAY_SIZE(execsize_for_reg)); hstride = hstride_for_reg[reg.hstride]; if (reg.vstride == 0xf) { vstride = -1; } else { vstride = vstride_for_reg[reg.vstride]; } width = width_for_reg[reg.width]; execsize = execsize_for_reg[insn->header.execution_size]; /* Restrictions from 3.3.10: Register Region Restrictions. */ /* 3. */ assert(execsize >= width); /* 4. */ if (execsize == width && hstride != 0) { assert(vstride == -1 || vstride == width * hstride); } /* 5. */ if (execsize == width && hstride == 0) { /* no restriction on vstride. */ } /* 6. */ if (width == 1) { assert(hstride == 0); } /* 7. */ if (execsize == 1 && width == 1) { assert(hstride == 0); assert(vstride == 0); } /* 8. */ if (vstride == 0 && hstride == 0) { assert(width == 1); } /* 10. Check destination issues. */ } void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg reg) { if (reg.type != BRW_ARCHITECTURE_REGISTER_FILE) assert(reg.nr < 128); gen7_convert_mrf_to_grf(p, ®); validate_reg(insn, reg); insn->bits1.da1.src0_reg_file = reg.file; insn->bits1.da1.src0_reg_type = reg.type; insn->bits2.da1.src0_abs = reg.abs; insn->bits2.da1.src0_negate = reg.negate; insn->bits2.da1.src0_address_mode = reg.address_mode; if (reg.file == BRW_IMMEDIATE_VALUE) { insn->bits3.ud = reg.dw1.ud; /* Required to set some fields in src1 as well: */ insn->bits1.da1.src1_reg_file = 0; /* arf */ insn->bits1.da1.src1_reg_type = reg.type; } else { if (reg.address_mode == BRW_ADDRESS_DIRECT) { if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits2.da1.src0_subreg_nr = reg.subnr; insn->bits2.da1.src0_reg_nr = reg.nr; } else { insn->bits2.da16.src0_subreg_nr = reg.subnr / 16; insn->bits2.da16.src0_reg_nr = reg.nr; } } else { insn->bits2.ia1.src0_subreg_nr = reg.subnr; if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits2.ia1.src0_indirect_offset = reg.dw1.bits.indirect_offset; } else { insn->bits2.ia16.src0_subreg_nr = reg.dw1.bits.indirect_offset; } } if (insn->header.access_mode == BRW_ALIGN_1) { if (reg.width == BRW_WIDTH_1 && insn->header.execution_size == BRW_EXECUTE_1) { insn->bits2.da1.src0_horiz_stride = BRW_HORIZONTAL_STRIDE_0; insn->bits2.da1.src0_width = BRW_WIDTH_1; insn->bits2.da1.src0_vert_stride = BRW_VERTICAL_STRIDE_0; } else { insn->bits2.da1.src0_horiz_stride = reg.hstride; insn->bits2.da1.src0_width = reg.width; insn->bits2.da1.src0_vert_stride = reg.vstride; } } else { insn->bits2.da16.src0_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X); insn->bits2.da16.src0_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y); insn->bits2.da16.src0_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z); insn->bits2.da16.src0_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W); /* This is an oddity of the fact we're using the same * descriptions for registers in align_16 as align_1: */ if (reg.vstride == BRW_VERTICAL_STRIDE_8) insn->bits2.da16.src0_vert_stride = BRW_VERTICAL_STRIDE_4; else insn->bits2.da16.src0_vert_stride = reg.vstride; } } } void brw_set_src1(struct brw_compile *p, struct brw_instruction *insn, struct brw_reg reg) { assert(reg.file != BRW_MESSAGE_REGISTER_FILE); assert(reg.nr < 128); gen7_convert_mrf_to_grf(p, ®); validate_reg(insn, reg); insn->bits1.da1.src1_reg_file = reg.file; insn->bits1.da1.src1_reg_type = reg.type; insn->bits3.da1.src1_abs = reg.abs; insn->bits3.da1.src1_negate = reg.negate; /* Only src1 can be immediate in two-argument instructions. */ assert(insn->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE); if (reg.file == BRW_IMMEDIATE_VALUE) { insn->bits3.ud = reg.dw1.ud; } else { /* This is a hardware restriction, which may or may not be lifted * in the future: */ assert (reg.address_mode == BRW_ADDRESS_DIRECT); /* assert (reg.file == BRW_GENERAL_REGISTER_FILE); */ if (insn->header.access_mode == BRW_ALIGN_1) { insn->bits3.da1.src1_subreg_nr = reg.subnr; insn->bits3.da1.src1_reg_nr = reg.nr; } else { insn->bits3.da16.src1_subreg_nr = reg.subnr / 16; insn->bits3.da16.src1_reg_nr = reg.nr; } if (insn->header.access_mode == BRW_ALIGN_1) { if (reg.width == BRW_WIDTH_1 && insn->header.execution_size == BRW_EXECUTE_1) { insn->bits3.da1.src1_horiz_stride = BRW_HORIZONTAL_STRIDE_0; insn->bits3.da1.src1_width = BRW_WIDTH_1; insn->bits3.da1.src1_vert_stride = BRW_VERTICAL_STRIDE_0; } else { insn->bits3.da1.src1_horiz_stride = reg.hstride; insn->bits3.da1.src1_width = reg.width; insn->bits3.da1.src1_vert_stride = reg.vstride; } } else { insn->bits3.da16.src1_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X); insn->bits3.da16.src1_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y); insn->bits3.da16.src1_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z); insn->bits3.da16.src1_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W); /* This is an oddity of the fact we're using the same * descriptions for registers in align_16 as align_1: */ if (reg.vstride == BRW_VERTICAL_STRIDE_8) insn->bits3.da16.src1_vert_stride = BRW_VERTICAL_STRIDE_4; else insn->bits3.da16.src1_vert_stride = reg.vstride; } } } /** * Set the Message Descriptor and Extended Message Descriptor fields * for SEND messages. * * \note This zeroes out the Function Control bits, so it must be called * \b before filling out any message-specific data. Callers can * choose not to fill in irrelevant bits; they will be zero. */ static void brw_set_message_descriptor(struct brw_compile *p, struct brw_instruction *inst, enum brw_message_target sfid, unsigned msg_length, unsigned response_length, bool header_present, bool end_of_thread) { brw_set_src1(p, inst, brw_imm_d(0)); if (p->gen >= 050) { inst->bits3.generic_gen5.header_present = header_present; inst->bits3.generic_gen5.response_length = response_length; inst->bits3.generic_gen5.msg_length = msg_length; inst->bits3.generic_gen5.end_of_thread = end_of_thread; if (p->gen >= 060) { /* On Gen6+ Message target/SFID goes in bits 27:24 of the header */ inst->header.destreg__conditionalmod = sfid; } else { /* Set Extended Message Descriptor (ex_desc) */ inst->bits2.send_gen5.sfid = sfid; inst->bits2.send_gen5.end_of_thread = end_of_thread; } } else { inst->bits3.generic.response_length = response_length; inst->bits3.generic.msg_length = msg_length; inst->bits3.generic.msg_target = sfid; inst->bits3.generic.end_of_thread = end_of_thread; } } static void brw_set_math_message(struct brw_compile *p, struct brw_instruction *insn, unsigned function, unsigned integer_type, bool low_precision, bool saturate, unsigned dataType) { unsigned msg_length; unsigned response_length; /* Infer message length from the function */ switch (function) { case BRW_MATH_FUNCTION_POW: case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT: case BRW_MATH_FUNCTION_INT_DIV_REMAINDER: case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER: msg_length = 2; break; default: msg_length = 1; break; } /* Infer response length from the function */ switch (function) { case BRW_MATH_FUNCTION_SINCOS: case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER: response_length = 2; break; default: response_length = 1; break; } brw_set_message_descriptor(p, insn, BRW_SFID_MATH, msg_length, response_length, false, false); if (p->gen == 050) { insn->bits3.math_gen5.function = function; insn->bits3.math_gen5.int_type = integer_type; insn->bits3.math_gen5.precision = low_precision; insn->bits3.math_gen5.saturate = saturate; insn->bits3.math_gen5.data_type = dataType; insn->bits3.math_gen5.snapshot = 0; } else { insn->bits3.math.function = function; insn->bits3.math.int_type = integer_type; insn->bits3.math.precision = low_precision; insn->bits3.math.saturate = saturate; insn->bits3.math.data_type = dataType; } } static void brw_set_ff_sync_message(struct brw_compile *p, struct brw_instruction *insn, bool allocate, unsigned response_length, bool end_of_thread) { brw_set_message_descriptor(p, insn, BRW_SFID_URB, 1, response_length, true, end_of_thread); insn->bits3.urb_gen5.opcode = 1; /* FF_SYNC */ insn->bits3.urb_gen5.offset = 0; /* Not used by FF_SYNC */ insn->bits3.urb_gen5.swizzle_control = 0; /* Not used by FF_SYNC */ insn->bits3.urb_gen5.allocate = allocate; insn->bits3.urb_gen5.used = 0; /* Not used by FF_SYNC */ insn->bits3.urb_gen5.complete = 0; /* Not used by FF_SYNC */ } static void brw_set_urb_message(struct brw_compile *p, struct brw_instruction *insn, bool allocate, bool used, unsigned msg_length, unsigned response_length, bool end_of_thread, bool complete, unsigned offset, unsigned swizzle_control) { brw_set_message_descriptor(p, insn, BRW_SFID_URB, msg_length, response_length, true, end_of_thread); if (p->gen >= 070) { insn->bits3.urb_gen7.opcode = 0; /* URB_WRITE_HWORD */ insn->bits3.urb_gen7.offset = offset; assert(swizzle_control != BRW_URB_SWIZZLE_TRANSPOSE); insn->bits3.urb_gen7.swizzle_control = swizzle_control; /* per_slot_offset = 0 makes it ignore offsets in message header */ insn->bits3.urb_gen7.per_slot_offset = 0; insn->bits3.urb_gen7.complete = complete; } else if (p->gen >= 050) { insn->bits3.urb_gen5.opcode = 0; /* URB_WRITE */ insn->bits3.urb_gen5.offset = offset; insn->bits3.urb_gen5.swizzle_control = swizzle_control; insn->bits3.urb_gen5.allocate = allocate; insn->bits3.urb_gen5.used = used; /* ? */ insn->bits3.urb_gen5.complete = complete; } else { insn->bits3.urb.opcode = 0; /* ? */ insn->bits3.urb.offset = offset; insn->bits3.urb.swizzle_control = swizzle_control; insn->bits3.urb.allocate = allocate; insn->bits3.urb.used = used; /* ? */ insn->bits3.urb.complete = complete; } } void brw_set_dp_write_message(struct brw_compile *p, struct brw_instruction *insn, unsigned binding_table_index, unsigned msg_control, unsigned msg_type, unsigned msg_length, bool header_present, bool last_render_target, unsigned response_length, bool end_of_thread, bool send_commit_msg) { unsigned sfid; if (p->gen >= 070) { /* Use the Render Cache for RT writes; otherwise use the Data Cache */ if (msg_type == GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE) sfid = GEN6_SFID_DATAPORT_RENDER_CACHE; else sfid = GEN7_SFID_DATAPORT_DATA_CACHE; } else if (p->gen >= 060) { /* Use the render cache for all write messages. */ sfid = GEN6_SFID_DATAPORT_RENDER_CACHE; } else { sfid = BRW_SFID_DATAPORT_WRITE; } brw_set_message_descriptor(p, insn, sfid, msg_length, response_length, header_present, end_of_thread); if (p->gen >= 070) { insn->bits3.gen7_dp.binding_table_index = binding_table_index; insn->bits3.gen7_dp.msg_control = msg_control; insn->bits3.gen7_dp.last_render_target = last_render_target; insn->bits3.gen7_dp.msg_type = msg_type; } else if (p->gen >= 060) { insn->bits3.gen6_dp.binding_table_index = binding_table_index; insn->bits3.gen6_dp.msg_control = msg_control; insn->bits3.gen6_dp.last_render_target = last_render_target; insn->bits3.gen6_dp.msg_type = msg_type; insn->bits3.gen6_dp.send_commit_msg = send_commit_msg; } else if (p->gen >= 050) { insn->bits3.dp_write_gen5.binding_table_index = binding_table_index; insn->bits3.dp_write_gen5.msg_control = msg_control; insn->bits3.dp_write_gen5.last_render_target = last_render_target; insn->bits3.dp_write_gen5.msg_type = msg_type; insn->bits3.dp_write_gen5.send_commit_msg = send_commit_msg; } else { insn->bits3.dp_write.binding_table_index = binding_table_index; insn->bits3.dp_write.msg_control = msg_control; insn->bits3.dp_write.last_render_target = last_render_target; insn->bits3.dp_write.msg_type = msg_type; insn->bits3.dp_write.send_commit_msg = send_commit_msg; } } void brw_set_dp_read_message(struct brw_compile *p, struct brw_instruction *insn, unsigned binding_table_index, unsigned msg_control, unsigned msg_type, unsigned target_cache, unsigned msg_length, unsigned response_length) { unsigned sfid; if (p->gen >= 070) { sfid = GEN7_SFID_DATAPORT_DATA_CACHE; } else if (p->gen >= 060) { if (target_cache == BRW_DATAPORT_READ_TARGET_RENDER_CACHE) sfid = GEN6_SFID_DATAPORT_RENDER_CACHE; else sfid = GEN6_SFID_DATAPORT_SAMPLER_CACHE; } else { sfid = BRW_SFID_DATAPORT_READ; } brw_set_message_descriptor(p, insn, sfid, msg_length, response_length, true, false); if (p->gen >= 070) { insn->bits3.gen7_dp.binding_table_index = binding_table_index; insn->bits3.gen7_dp.msg_control = msg_control; insn->bits3.gen7_dp.last_render_target = 0; insn->bits3.gen7_dp.msg_type = msg_type; } else if (p->gen >= 060) { insn->bits3.gen6_dp.binding_table_index = binding_table_index; insn->bits3.gen6_dp.msg_control = msg_control; insn->bits3.gen6_dp.last_render_target = 0; insn->bits3.gen6_dp.msg_type = msg_type; insn->bits3.gen6_dp.send_commit_msg = 0; } else if (p->gen >= 050) { insn->bits3.dp_read_gen5.binding_table_index = binding_table_index; insn->bits3.dp_read_gen5.msg_control = msg_control; insn->bits3.dp_read_gen5.msg_type = msg_type; insn->bits3.dp_read_gen5.target_cache = target_cache; } else if (p->gen >= 045) { insn->bits3.dp_read_g4x.binding_table_index = binding_table_index; /*0:7*/ insn->bits3.dp_read_g4x.msg_control = msg_control; /*8:10*/ insn->bits3.dp_read_g4x.msg_type = msg_type; /*11:13*/ insn->bits3.dp_read_g4x.target_cache = target_cache; /*14:15*/ } else { insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/ insn->bits3.dp_read.msg_control = msg_control; /*8:11*/ insn->bits3.dp_read.msg_type = msg_type; /*12:13*/ insn->bits3.dp_read.target_cache = target_cache; /*14:15*/ } } static void brw_set_sampler_message(struct brw_compile *p, struct brw_instruction *insn, unsigned binding_table_index, unsigned sampler, unsigned msg_type, unsigned response_length, unsigned msg_length, bool header_present, unsigned simd_mode) { brw_set_message_descriptor(p, insn, BRW_SFID_SAMPLER, msg_length, response_length, header_present, false); if (p->gen >= 070) { insn->bits3.sampler_gen7.binding_table_index = binding_table_index; insn->bits3.sampler_gen7.sampler = sampler; insn->bits3.sampler_gen7.msg_type = msg_type; insn->bits3.sampler_gen7.simd_mode = simd_mode; } else if (p->gen >= 050) { insn->bits3.sampler_gen5.binding_table_index = binding_table_index; insn->bits3.sampler_gen5.sampler = sampler; insn->bits3.sampler_gen5.msg_type = msg_type; insn->bits3.sampler_gen5.simd_mode = simd_mode; } else if (p->gen >= 045) { insn->bits3.sampler_g4x.binding_table_index = binding_table_index; insn->bits3.sampler_g4x.sampler = sampler; insn->bits3.sampler_g4x.msg_type = msg_type; } else { insn->bits3.sampler.binding_table_index = binding_table_index; insn->bits3.sampler.sampler = sampler; insn->bits3.sampler.msg_type = msg_type; insn->bits3.sampler.return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32; } } void brw_NOP(struct brw_compile *p) { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_NOP); brw_set_dest(p, insn, __retype_ud(brw_vec4_grf(0,0))); brw_set_src0(p, insn, __retype_ud(brw_vec4_grf(0,0))); brw_set_src1(p, insn, brw_imm_ud(0x0)); } /*********************************************************************** * Comparisons, if/else/endif */ static void push_if_stack(struct brw_compile *p, struct brw_instruction *inst) { p->if_stack[p->if_stack_depth] = inst; p->if_stack_depth++; if (p->if_stack_array_size <= p->if_stack_depth) { p->if_stack_array_size *= 2; p->if_stack = realloc(p->if_stack, sizeof(struct brw_instruction *)*p->if_stack_array_size); } } /* EU takes the value from the flag register and pushes it onto some * sort of a stack (presumably merging with any flag value already on * the stack). Within an if block, the flags at the top of the stack * control execution on each channel of the unit, eg. on each of the * 16 pixel values in our wm programs. * * When the matching 'else' instruction is reached (presumably by * countdown of the instruction count patched in by our ELSE/ENDIF * functions), the relevant flags are inverted. * * When the matching 'endif' instruction is reached, the flags are * popped off. If the stack is now empty, normal execution resumes. */ struct brw_instruction * brw_IF(struct brw_compile *p, unsigned execute_size) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_IF); /* Override the defaults for this instruction: */ if (p->gen < 060) { brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); } else if (p->gen < 070) { brw_set_dest(p, insn, brw_imm_w(0)); insn->bits1.branch_gen6.jump_count = 0; brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, __retype_d(brw_null_reg())); } else { brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, brw_imm_ud(0)); insn->bits3.break_cont.jip = 0; insn->bits3.break_cont.uip = 0; } insn->header.execution_size = execute_size; insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.predicate_control = BRW_PREDICATE_NORMAL; insn->header.mask_control = BRW_MASK_ENABLE; if (!p->single_program_flow) insn->header.thread_control = BRW_THREAD_SWITCH; p->current->header.predicate_control = BRW_PREDICATE_NONE; push_if_stack(p, insn); return insn; } /* This function is only used for gen6-style IF instructions with an * embedded comparison (conditional modifier). It is not used on gen7. */ struct brw_instruction * gen6_IF(struct brw_compile *p, uint32_t conditional, struct brw_reg src0, struct brw_reg src1) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_IF); brw_set_dest(p, insn, brw_imm_w(0)); if (p->compressed) { insn->header.execution_size = BRW_EXECUTE_16; } else { insn->header.execution_size = BRW_EXECUTE_8; } insn->bits1.branch_gen6.jump_count = 0; brw_set_src0(p, insn, src0); brw_set_src1(p, insn, src1); assert(insn->header.compression_control == BRW_COMPRESSION_NONE); assert(insn->header.predicate_control == BRW_PREDICATE_NONE); insn->header.destreg__conditionalmod = conditional; if (!p->single_program_flow) insn->header.thread_control = BRW_THREAD_SWITCH; push_if_stack(p, insn); return insn; } /** * In single-program-flow (SPF) mode, convert IF and ELSE into ADDs. */ static void convert_IF_ELSE_to_ADD(struct brw_compile *p, struct brw_instruction *if_inst, struct brw_instruction *else_inst) { /* The next instruction (where the ENDIF would be, if it existed) */ struct brw_instruction *next_inst = &p->store[p->nr_insn]; assert(p->single_program_flow); assert(if_inst != NULL && if_inst->header.opcode == BRW_OPCODE_IF); assert(else_inst == NULL || else_inst->header.opcode == BRW_OPCODE_ELSE); assert(if_inst->header.execution_size == BRW_EXECUTE_1); /* Convert IF to an ADD instruction that moves the instruction pointer * to the first instruction of the ELSE block. If there is no ELSE * block, point to where ENDIF would be. Reverse the predicate. * * There's no need to execute an ENDIF since we don't need to do any * stack operations, and if we're currently executing, we just want to * continue normally. */ if_inst->header.opcode = BRW_OPCODE_ADD; if_inst->header.predicate_inverse = 1; if (else_inst != NULL) { /* Convert ELSE to an ADD instruction that points where the ENDIF * would be. */ else_inst->header.opcode = BRW_OPCODE_ADD; if_inst->bits3.ud = (else_inst - if_inst + 1) * 16; else_inst->bits3.ud = (next_inst - else_inst) * 16; } else { if_inst->bits3.ud = (next_inst - if_inst) * 16; } } /** * Patch IF and ELSE instructions with appropriate jump targets. */ static void patch_IF_ELSE(struct brw_compile *p, struct brw_instruction *if_inst, struct brw_instruction *else_inst, struct brw_instruction *endif_inst) { unsigned br = 1; assert(!p->single_program_flow); assert(if_inst != NULL && if_inst->header.opcode == BRW_OPCODE_IF); assert(endif_inst != NULL); assert(else_inst == NULL || else_inst->header.opcode == BRW_OPCODE_ELSE); /* Jump count is for 64bit data chunk each, so one 128bit instruction * requires 2 chunks. */ if (p->gen >= 050) br = 2; assert(endif_inst->header.opcode == BRW_OPCODE_ENDIF); endif_inst->header.execution_size = if_inst->header.execution_size; if (else_inst == NULL) { /* Patch IF -> ENDIF */ if (p->gen < 060) { /* Turn it into an IFF, which means no mask stack operations for * all-false and jumping past the ENDIF. */ if_inst->header.opcode = BRW_OPCODE_IFF; if_inst->bits3.if_else.jump_count = br * (endif_inst - if_inst + 1); if_inst->bits3.if_else.pop_count = 0; if_inst->bits3.if_else.pad0 = 0; } else if (p->gen < 070) { /* As of gen6, there is no IFF and IF must point to the ENDIF. */ if_inst->bits1.branch_gen6.jump_count = br * (endif_inst - if_inst); } else { if_inst->bits3.break_cont.uip = br * (endif_inst - if_inst); if_inst->bits3.break_cont.jip = br * (endif_inst - if_inst); } } else { else_inst->header.execution_size = if_inst->header.execution_size; /* Patch IF -> ELSE */ if (p->gen < 060) { if_inst->bits3.if_else.jump_count = br * (else_inst - if_inst); if_inst->bits3.if_else.pop_count = 0; if_inst->bits3.if_else.pad0 = 0; } else if (p->gen <= 070) { if_inst->bits1.branch_gen6.jump_count = br * (else_inst - if_inst + 1); } /* Patch ELSE -> ENDIF */ if (p->gen < 060) { /* BRW_OPCODE_ELSE pre-gen6 should point just past the * matching ENDIF. */ else_inst->bits3.if_else.jump_count = br*(endif_inst - else_inst + 1); else_inst->bits3.if_else.pop_count = 1; else_inst->bits3.if_else.pad0 = 0; } else if (p->gen < 070) { /* BRW_OPCODE_ELSE on gen6 should point to the matching ENDIF. */ else_inst->bits1.branch_gen6.jump_count = br*(endif_inst - else_inst); } else { /* The IF instruction's JIP should point just past the ELSE */ if_inst->bits3.break_cont.jip = br * (else_inst - if_inst + 1); /* The IF instruction's UIP and ELSE's JIP should point to ENDIF */ if_inst->bits3.break_cont.uip = br * (endif_inst - if_inst); else_inst->bits3.break_cont.jip = br * (endif_inst - else_inst); } } } void brw_ELSE(struct brw_compile *p) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_ELSE); if (p->gen < 060) { brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); } else if (p->gen < 070) { brw_set_dest(p, insn, brw_imm_w(0)); insn->bits1.branch_gen6.jump_count = 0; brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, __retype_d(brw_null_reg())); } else { brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, brw_imm_ud(0)); insn->bits3.break_cont.jip = 0; insn->bits3.break_cont.uip = 0; } insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.mask_control = BRW_MASK_ENABLE; if (!p->single_program_flow) insn->header.thread_control = BRW_THREAD_SWITCH; push_if_stack(p, insn); } void brw_ENDIF(struct brw_compile *p) { struct brw_instruction *insn; struct brw_instruction *else_inst = NULL; struct brw_instruction *if_inst = NULL; /* Pop the IF and (optional) ELSE instructions from the stack */ p->if_stack_depth--; if (p->if_stack[p->if_stack_depth]->header.opcode == BRW_OPCODE_ELSE) { else_inst = p->if_stack[p->if_stack_depth]; p->if_stack_depth--; } if_inst = p->if_stack[p->if_stack_depth]; if (p->single_program_flow) { /* ENDIF is useless; don't bother emitting it. */ convert_IF_ELSE_to_ADD(p, if_inst, else_inst); return; } insn = brw_next_insn(p, BRW_OPCODE_ENDIF); if (p->gen < 060) { brw_set_dest(p, insn, __retype_ud(brw_vec4_grf(0,0))); brw_set_src0(p, insn, __retype_ud(brw_vec4_grf(0,0))); brw_set_src1(p, insn, brw_imm_d(0x0)); } else if (p->gen < 070) { brw_set_dest(p, insn, brw_imm_w(0)); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, __retype_d(brw_null_reg())); } else { brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, brw_imm_ud(0)); } insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.mask_control = BRW_MASK_ENABLE; insn->header.thread_control = BRW_THREAD_SWITCH; /* Also pop item off the stack in the endif instruction: */ if (p->gen < 060) { insn->bits3.if_else.jump_count = 0; insn->bits3.if_else.pop_count = 1; insn->bits3.if_else.pad0 = 0; } else if (p->gen < 070) { insn->bits1.branch_gen6.jump_count = 2; } else { insn->bits3.break_cont.jip = 2; } patch_IF_ELSE(p, if_inst, else_inst, insn); } struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_BREAK); if (p->gen >= 060) { brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, brw_imm_d(0x0)); } else { brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); insn->bits3.if_else.pad0 = 0; insn->bits3.if_else.pop_count = pop_count; } insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = BRW_EXECUTE_8; return insn; } struct brw_instruction *gen6_CONT(struct brw_compile *p, struct brw_instruction *do_insn) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_CONTINUE); brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = BRW_EXECUTE_8; return insn; } struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count) { struct brw_instruction *insn; insn = brw_next_insn(p, BRW_OPCODE_CONTINUE); brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = BRW_EXECUTE_8; /* insn->header.mask_control = BRW_MASK_DISABLE; */ insn->bits3.if_else.pad0 = 0; insn->bits3.if_else.pop_count = pop_count; return insn; } /* DO/WHILE loop: * * The DO/WHILE is just an unterminated loop -- break or continue are * used for control within the loop. We have a few ways they can be * done. * * For uniform control flow, the WHILE is just a jump, so ADD ip, ip, * jip and no DO instruction. * * For non-uniform control flow pre-gen6, there's a DO instruction to * push the mask, and a WHILE to jump back, and BREAK to get out and * pop the mask. * * For gen6, there's no more mask stack, so no need for DO. WHILE * just points back to the first instruction of the loop. */ struct brw_instruction *brw_DO(struct brw_compile *p, unsigned execute_size) { if (p->gen >= 060 || p->single_program_flow) { return &p->store[p->nr_insn]; } else { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_DO); /* Override the defaults for this instruction: */ brw_set_dest(p, insn, brw_null_reg()); brw_set_src0(p, insn, brw_null_reg()); brw_set_src1(p, insn, brw_null_reg()); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = execute_size; insn->header.predicate_control = BRW_PREDICATE_NONE; /* insn->header.mask_control = BRW_MASK_ENABLE; */ /* insn->header.mask_control = BRW_MASK_DISABLE; */ return insn; } } struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn) { struct brw_instruction *insn; unsigned br = 1; if (p->gen >= 050) br = 2; if (p->gen >= 070) { insn = brw_next_insn(p, BRW_OPCODE_WHILE); brw_set_dest(p, insn, __retype_d(brw_null_reg())); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, brw_imm_ud(0)); insn->bits3.break_cont.jip = br * (do_insn - insn); insn->header.execution_size = BRW_EXECUTE_8; } else if (p->gen >= 060) { insn = brw_next_insn(p, BRW_OPCODE_WHILE); brw_set_dest(p, insn, brw_imm_w(0)); insn->bits1.branch_gen6.jump_count = br * (do_insn - insn); brw_set_src0(p, insn, __retype_d(brw_null_reg())); brw_set_src1(p, insn, __retype_d(brw_null_reg())); insn->header.execution_size = BRW_EXECUTE_8; } else { if (p->single_program_flow) { insn = brw_next_insn(p, BRW_OPCODE_ADD); brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d((do_insn - insn) * 16)); insn->header.execution_size = BRW_EXECUTE_1; } else { insn = brw_next_insn(p, BRW_OPCODE_WHILE); assert(do_insn->header.opcode == BRW_OPCODE_DO); brw_set_dest(p, insn, brw_ip_reg()); brw_set_src0(p, insn, brw_ip_reg()); brw_set_src1(p, insn, brw_imm_d(0)); insn->header.execution_size = do_insn->header.execution_size; insn->bits3.if_else.jump_count = br * (do_insn - insn + 1); insn->bits3.if_else.pop_count = 0; insn->bits3.if_else.pad0 = 0; } } insn->header.compression_control = BRW_COMPRESSION_NONE; p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn; } /* FORWARD JUMPS: */ void brw_land_fwd_jump(struct brw_compile *p, struct brw_instruction *jmp_insn) { struct brw_instruction *landing = &p->store[p->nr_insn]; unsigned jmpi = 1; if (p->gen >= 050) jmpi = 2; assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI); assert(jmp_insn->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE); jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1); } /* To integrate with the above, it makes sense that the comparison * instruction should populate the flag register. It might be simpler * just to use the flag reg for most WM tasks? */ void brw_CMP(struct brw_compile *p, struct brw_reg dest, unsigned conditional, struct brw_reg src0, struct brw_reg src1) { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_CMP); insn->header.destreg__conditionalmod = conditional; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_src1(p, insn, src1); /* Make it so that future instructions will use the computed flag * value until brw_set_predicate_control_flag_value() is called * again. */ if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE && dest.nr == 0) { p->current->header.predicate_control = BRW_PREDICATE_NORMAL; p->flag_value = 0xff; } } /* Issue 'wait' instruction for n1, host could program MMIO to wake up thread. */ void brw_WAIT(struct brw_compile *p) { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_WAIT); struct brw_reg src = brw_notification_1_reg(); brw_set_dest(p, insn, src); brw_set_src0(p, insn, src); brw_set_src1(p, insn, brw_null_reg()); insn->header.execution_size = 0; /* must */ insn->header.predicate_control = 0; insn->header.compression_control = 0; } /*********************************************************************** * Helpers for the various SEND message types: */ /** Extended math function, float[8]. */ void brw_math(struct brw_compile *p, struct brw_reg dest, unsigned function, unsigned saturate, unsigned msg_reg_nr, struct brw_reg src, unsigned data_type, unsigned precision) { if (p->gen >= 060) { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_MATH); assert(dest.file == BRW_GENERAL_REGISTER_FILE); assert(src.file == BRW_GENERAL_REGISTER_FILE); assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1); assert(src.hstride == BRW_HORIZONTAL_STRIDE_1); /* Source modifiers are ignored for extended math instructions. */ assert(!src.negate); assert(!src.abs); if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT && function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) { assert(src.type == BRW_REGISTER_TYPE_F); } /* Math is the same ISA format as other opcodes, except that CondModifier * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. */ insn->header.destreg__conditionalmod = function; insn->header.saturate = saturate; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); brw_set_src1(p, insn, brw_null_reg()); } else { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_SEND); /* Example code doesn't set predicate_control for send * instructions. */ insn->header.predicate_control = 0; insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); brw_set_math_message(p, insn, function, src.type == BRW_REGISTER_TYPE_D, precision, saturate, data_type); } } /** Extended math function, float[8]. */ void brw_math2(struct brw_compile *p, struct brw_reg dest, unsigned function, struct brw_reg src0, struct brw_reg src1) { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_MATH); assert(dest.file == BRW_GENERAL_REGISTER_FILE); assert(src0.file == BRW_GENERAL_REGISTER_FILE); assert(src1.file == BRW_GENERAL_REGISTER_FILE); assert(dest.hstride == BRW_HORIZONTAL_STRIDE_1); assert(src0.hstride == BRW_HORIZONTAL_STRIDE_1); assert(src1.hstride == BRW_HORIZONTAL_STRIDE_1); if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT && function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) { assert(src0.type == BRW_REGISTER_TYPE_F); assert(src1.type == BRW_REGISTER_TYPE_F); } /* Source modifiers are ignored for extended math instructions. */ assert(!src0.negate); assert(!src0.abs); assert(!src1.negate); assert(!src1.abs); /* Math is the same ISA format as other opcodes, except that CondModifier * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. */ insn->header.destreg__conditionalmod = function; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_src1(p, insn, src1); } /** * Extended math function, float[16]. * Use 2 send instructions. */ void brw_math_16(struct brw_compile *p, struct brw_reg dest, unsigned function, unsigned saturate, unsigned msg_reg_nr, struct brw_reg src, unsigned precision) { struct brw_instruction *insn; if (p->gen >= 060) { insn = brw_next_insn(p, BRW_OPCODE_MATH); /* Math is the same ISA format as other opcodes, except that CondModifier * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. */ insn->header.destreg__conditionalmod = function; insn->header.saturate = saturate; /* Source modifiers are ignored for extended math instructions. */ assert(!src.negate); assert(!src.abs); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); brw_set_src1(p, insn, brw_null_reg()); return; } /* First instruction: */ brw_push_insn_state(p); brw_set_predicate_control_flag_value(p, 0xff); brw_set_compression_control(p, BRW_COMPRESSION_NONE); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); brw_set_math_message(p, insn, function, BRW_MATH_INTEGER_UNSIGNED, precision, saturate, BRW_MATH_DATA_VECTOR); /* Second instruction: */ insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.compression_control = BRW_COMPRESSION_2NDHALF; insn->header.destreg__conditionalmod = msg_reg_nr+1; brw_set_dest(p, insn, __offset(dest,1)); brw_set_src0(p, insn, src); brw_set_math_message(p, insn, function, BRW_MATH_INTEGER_UNSIGNED, precision, saturate, BRW_MATH_DATA_VECTOR); brw_pop_insn_state(p); } /** * Write a block of OWORDs (half a GRF each) from the scratch buffer, * using a constant offset per channel. * * The offset must be aligned to oword size (16 bytes). Used for * register spilling. */ void brw_oword_block_write_scratch(struct brw_compile *p, struct brw_reg mrf, int num_regs, unsigned offset) { uint32_t msg_control, msg_type; int mlen; if (p->gen >= 060) offset /= 16; mrf = __retype_ud(mrf); if (num_regs == 1) { msg_control = BRW_DATAPORT_OWORD_BLOCK_2_OWORDS; mlen = 2; } else { msg_control = BRW_DATAPORT_OWORD_BLOCK_4_OWORDS; mlen = 3; } /* Set up the message header. This is g0, with g0.2 filled with * the offset. We don't want to leave our offset around in g0 or * it'll screw up texture samples, so set it up inside the message * reg. */ { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, mrf, __retype_ud(brw_vec8_grf(0, 0))); /* set message header global offset field (reg 0, element 2) */ brw_MOV(p, __retype_ud(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, mrf.nr, 2)), brw_imm_ud(offset)); brw_pop_insn_state(p); } { struct brw_reg dest; struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_SEND); int send_commit_msg; struct brw_reg src_header = __retype_uw(brw_vec8_grf(0, 0)); if (insn->header.compression_control != BRW_COMPRESSION_NONE) { insn->header.compression_control = BRW_COMPRESSION_NONE; src_header = vec16(src_header); } assert(insn->header.predicate_control == BRW_PREDICATE_NONE); insn->header.destreg__conditionalmod = mrf.nr; /* Until gen6, writes followed by reads from the same location * are not guaranteed to be ordered unless write_commit is set. * If set, then a no-op write is issued to the destination * register to set a dependency, and a read from the destination * can be used to ensure the ordering. * * For gen6, only writes between different threads need ordering * protection. Our use of DP writes is all about register * spilling within a thread. */ if (p->gen >= 060) { dest = __retype_uw(vec16(brw_null_reg())); send_commit_msg = 0; } else { dest = src_header; send_commit_msg = 1; } brw_set_dest(p, insn, dest); if (p->gen >= 060) { brw_set_src0(p, insn, mrf); } else { brw_set_src0(p, insn, brw_null_reg()); } if (p->gen >= 060) msg_type = GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE; else msg_type = BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE; brw_set_dp_write_message(p, insn, 255, /* binding table index (255=stateless) */ msg_control, msg_type, mlen, true, /* header_present */ 0, /* pixel scoreboard */ send_commit_msg, /* response_length */ 0, /* eot */ send_commit_msg); } } /** * Read a block of owords (half a GRF each) from the scratch buffer * using a constant index per channel. * * Offset must be aligned to oword size (16 bytes). Used for register * spilling. */ void brw_oword_block_read_scratch(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, int num_regs, unsigned offset) { uint32_t msg_control; int rlen; if (p->gen >= 060) offset /= 16; mrf = __retype_ud(mrf); dest = __retype_uw(dest); if (num_regs == 1) { msg_control = BRW_DATAPORT_OWORD_BLOCK_2_OWORDS; rlen = 1; } else { msg_control = BRW_DATAPORT_OWORD_BLOCK_4_OWORDS; rlen = 2; } { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, mrf, __retype_ud(brw_vec8_grf(0, 0))); /* set message header global offset field (reg 0, element 2) */ brw_MOV(p, __retype_ud(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, mrf.nr, 2)), brw_imm_ud(offset)); brw_pop_insn_state(p); } { struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_SEND); assert(insn->header.predicate_control == 0); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.destreg__conditionalmod = mrf.nr; brw_set_dest(p, insn, dest); /* UW? */ if (p->gen >= 060) { brw_set_src0(p, insn, mrf); } else { brw_set_src0(p, insn, brw_null_reg()); } brw_set_dp_read_message(p, insn, 255, /* binding table index (255=stateless) */ msg_control, BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ BRW_DATAPORT_READ_TARGET_RENDER_CACHE, 1, /* msg_length */ rlen); } } /** * Read a float[4] vector from the data port Data Cache (const buffer). * Location (in buffer) should be a multiple of 16. * Used for fetching shader constants. */ void brw_oword_block_read(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, uint32_t offset, uint32_t bind_table_index) { struct brw_instruction *insn; /* On newer hardware, offset is in units of owords. */ if (p->gen >= 060) offset /= 16; mrf = __retype_ud(mrf); brw_push_insn_state(p); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, mrf, __retype_ud(brw_vec8_grf(0, 0))); /* set message header global offset field (reg 0, element 2) */ brw_MOV(p, __retype_ud(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, mrf.nr, 2)), brw_imm_ud(offset)); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.destreg__conditionalmod = mrf.nr; /* cast dest to a uword[8] vector */ dest = __retype_uw(vec8(dest)); brw_set_dest(p, insn, dest); if (p->gen >= 060) { brw_set_src0(p, insn, mrf); } else { brw_set_src0(p, insn, brw_null_reg()); } brw_set_dp_read_message(p, insn, bind_table_index, BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW, BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, BRW_DATAPORT_READ_TARGET_DATA_CACHE, 1, /* msg_length */ 1); /* response_length (1 reg, 2 owords!) */ brw_pop_insn_state(p); } /** * Read a set of dwords from the data port Data Cache (const buffer). * * Location (in buffer) appears as UD offsets in the register after * the provided mrf header reg. */ void brw_dword_scattered_read(struct brw_compile *p, struct brw_reg dest, struct brw_reg mrf, uint32_t bind_table_index) { struct brw_instruction *insn; mrf = __retype_ud(mrf); brw_push_insn_state(p); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, mrf, __retype_ud(brw_vec8_grf(0, 0))); brw_pop_insn_state(p); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.destreg__conditionalmod = mrf.nr; /* cast dest to a uword[8] vector */ dest = __retype_uw(vec8(dest)); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, brw_null_reg()); brw_set_dp_read_message(p, insn, bind_table_index, BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS, BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ, BRW_DATAPORT_READ_TARGET_DATA_CACHE, 2, /* msg_length */ 1); /* response_length */ } /** * Read float[4] constant(s) from VS constant buffer. * For relative addressing, two float[4] constants will be read into 'dest'. * Otherwise, one float[4] constant will be read into the lower half of 'dest'. */ void brw_dp_READ_4_vs(struct brw_compile *p, struct brw_reg dest, unsigned location, unsigned bind_table_index) { struct brw_instruction *insn; unsigned msg_reg_nr = 1; if (p->gen >= 060) location /= 16; /* Setup MRF[1] with location/offset into const buffer */ brw_push_insn_state(p); brw_set_access_mode(p, BRW_ALIGN_1); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_predicate_control(p, BRW_PREDICATE_NONE); brw_MOV(p, __retype_ud(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, msg_reg_nr, 2)), brw_imm_ud(location)); brw_pop_insn_state(p); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.predicate_control = BRW_PREDICATE_NONE; insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.destreg__conditionalmod = msg_reg_nr; insn->header.mask_control = BRW_MASK_DISABLE; brw_set_dest(p, insn, dest); if (p->gen >= 060) { brw_set_src0(p, insn, brw_message_reg(msg_reg_nr)); } else { brw_set_src0(p, insn, brw_null_reg()); } brw_set_dp_read_message(p, insn, bind_table_index, 0, BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ BRW_DATAPORT_READ_TARGET_DATA_CACHE, 1, /* msg_length */ 1); /* response_length (1 Oword) */ } /** * Read a float[4] constant per vertex from VS constant buffer, with * relative addressing. */ void brw_dp_READ_4_vs_relative(struct brw_compile *p, struct brw_reg dest, struct brw_reg addr_reg, unsigned offset, unsigned bind_table_index) { struct brw_reg src = brw_vec8_grf(0, 0); struct brw_instruction *insn; int msg_type; /* Setup MRF[1] with offset into const buffer */ brw_push_insn_state(p); brw_set_access_mode(p, BRW_ALIGN_1); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_predicate_control(p, BRW_PREDICATE_NONE); /* M1.0 is block offset 0, M1.4 is block offset 1, all other * fields ignored. */ brw_ADD(p, __retype_d(brw_message_reg(1)), addr_reg, brw_imm_d(offset)); brw_pop_insn_state(p); gen6_resolve_implied_move(p, &src, 0); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.predicate_control = BRW_PREDICATE_NONE; insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.destreg__conditionalmod = 0; insn->header.mask_control = BRW_MASK_DISABLE; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src); if (p->gen >= 060) msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ; else if (p->gen >= 045) msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ; else msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ; brw_set_dp_read_message(p, insn, bind_table_index, BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD, msg_type, BRW_DATAPORT_READ_TARGET_DATA_CACHE, 2, /* msg_length */ 1); /* response_length */ } void brw_fb_WRITE(struct brw_compile *p, int dispatch_width, unsigned msg_reg_nr, struct brw_reg src0, unsigned msg_control, unsigned binding_table_index, unsigned msg_length, unsigned response_length, bool eot, bool header_present) { struct brw_instruction *insn; unsigned msg_type; struct brw_reg dest; if (dispatch_width == 16) dest = __retype_uw(vec16(brw_null_reg())); else dest = __retype_uw(vec8(brw_null_reg())); if (p->gen >= 060 && binding_table_index == 0) { insn = brw_next_insn(p, BRW_OPCODE_SENDC); } else { insn = brw_next_insn(p, BRW_OPCODE_SEND); } /* The execution mask is ignored for render target writes. */ insn->header.predicate_control = 0; insn->header.compression_control = BRW_COMPRESSION_NONE; if (p->gen >= 060) { /* headerless version, just submit color payload */ src0 = brw_message_reg(msg_reg_nr); msg_type = GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE; } else { insn->header.destreg__conditionalmod = msg_reg_nr; msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE; } brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_dp_write_message(p, insn, binding_table_index, msg_control, msg_type, msg_length, header_present, eot, response_length, eot, 0 /* send_commit_msg */); } /** * Texture sample instruction. * Note: the msg_type plus msg_length values determine exactly what kind * of sampling operation is performed. See volume 4, page 161 of docs. */ void brw_SAMPLE(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, unsigned binding_table_index, unsigned sampler, unsigned writemask, unsigned msg_type, unsigned response_length, unsigned msg_length, bool header_present, unsigned simd_mode) { assert(writemask); if (p->gen < 050 || writemask != WRITEMASK_XYZW) { struct brw_reg m1 = brw_message_reg(msg_reg_nr); writemask = ~writemask & WRITEMASK_XYZW; brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, __retype_ud(m1), __retype_ud(brw_vec8_grf(0,0))); brw_MOV(p, get_element_ud(m1, 2), brw_imm_ud(writemask << 12)); brw_pop_insn_state(p); src0 = __retype_uw(brw_null_reg()); } { struct brw_instruction *insn; gen6_resolve_implied_move(p, &src0, msg_reg_nr); insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.predicate_control = 0; /* XXX */ insn->header.compression_control = BRW_COMPRESSION_NONE; if (p->gen < 060) insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_sampler_message(p, insn, binding_table_index, sampler, msg_type, response_length, msg_length, header_present, simd_mode); } } /* All these variables are pretty confusing - we might be better off * using bitmasks and macros for this, in the old style. Or perhaps * just having the caller instantiate the fields in dword3 itself. */ void brw_urb_WRITE(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, bool allocate, bool used, unsigned msg_length, unsigned response_length, bool eot, bool writes_complete, unsigned offset, unsigned swizzle) { struct brw_instruction *insn; gen6_resolve_implied_move(p, &src0, msg_reg_nr); if (p->gen >= 070) { /* Enable Channel Masks in the URB_WRITE_HWORD message header */ brw_push_insn_state(p); brw_set_access_mode(p, BRW_ALIGN_1); brw_OR(p, __retype_ud(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE, msg_reg_nr, 5)), __retype_ud(brw_vec1_grf(0, 5)), brw_imm_ud(0xff00)); brw_pop_insn_state(p); } insn = brw_next_insn(p, BRW_OPCODE_SEND); assert(msg_length < BRW_MAX_MRF); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_src1(p, insn, brw_imm_d(0)); if (p->gen <= 060) insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_urb_message(p, insn, allocate, used, msg_length, response_length, eot, writes_complete, offset, swizzle); } static int brw_find_next_block_end(struct brw_compile *p, int start) { int ip; for (ip = start + 1; ip < p->nr_insn; ip++) { struct brw_instruction *insn = &p->store[ip]; switch (insn->header.opcode) { case BRW_OPCODE_ENDIF: case BRW_OPCODE_ELSE: case BRW_OPCODE_WHILE: return ip; } } assert(!"not reached"); return start + 1; } /* There is no DO instruction on gen6, so to find the end of the loop * we have to see if the loop is jumping back before our start * instruction. */ static int brw_find_loop_end(struct brw_compile *p, int start) { int ip; int br = 2; for (ip = start + 1; ip < p->nr_insn; ip++) { struct brw_instruction *insn = &p->store[ip]; if (insn->header.opcode == BRW_OPCODE_WHILE) { int jip = p->gen <= 070 ? insn->bits1.branch_gen6.jump_count : insn->bits3.break_cont.jip; if (ip + jip / br <= start) return ip; } } assert(!"not reached"); return start + 1; } /* After program generation, go back and update the UIP and JIP of * BREAK and CONT instructions to their correct locations. */ void brw_set_uip_jip(struct brw_compile *p) { int ip; int br = 2; if (p->gen <= 060) return; for (ip = 0; ip < p->nr_insn; ip++) { struct brw_instruction *insn = &p->store[ip]; switch (insn->header.opcode) { case BRW_OPCODE_BREAK: insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip); /* Gen7 UIP points to WHILE; Gen6 points just after it */ insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip + (p->gen <= 070 ? 1 : 0)); break; case BRW_OPCODE_CONTINUE: insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip); insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip); assert(insn->bits3.break_cont.uip != 0); assert(insn->bits3.break_cont.jip != 0); break; } } } void brw_ff_sync(struct brw_compile *p, struct brw_reg dest, unsigned msg_reg_nr, struct brw_reg src0, bool allocate, unsigned response_length, bool eot) { struct brw_instruction *insn; gen6_resolve_implied_move(p, &src0, msg_reg_nr); insn = brw_next_insn(p, BRW_OPCODE_SEND); brw_set_dest(p, insn, dest); brw_set_src0(p, insn, src0); brw_set_src1(p, insn, brw_imm_d(0)); if (p->gen < 060) insn->header.destreg__conditionalmod = msg_reg_nr; brw_set_ff_sync_message(p, insn, allocate, response_length, eot); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_sf.c000066400000000000000000000025251267532330400240670ustar00rootroot00000000000000#include "brw.h" bool brw_sf_kernel__nomask(struct brw_compile *p) { struct brw_reg inv, v0, v1, v2, delta; v0 = brw_vec4_grf(3, 0); v1 = brw_vec4_grf(4, 0); v2 = brw_vec4_grf(5, 0); delta = brw_vec8_grf(7, 0); inv = brw_vec4_grf(6, 0); brw_math_invert(p, inv, brw_vec4_grf(1, 11)); brw_MOV(p, brw_message_reg(3), v0); brw_ADD(p, delta, v1, brw_negate(v2)); brw_MUL(p, brw_message_reg(1), delta, brw_vec1_grf(6,0)); brw_ADD(p, delta, v2, brw_negate(v0)); brw_MUL(p, brw_message_reg(2), delta, brw_vec1_grf(6,2)); brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0 ,0), false, true, 4, 0, true, true, 0, BRW_URB_SWIZZLE_TRANSPOSE); return true; } bool brw_sf_kernel__mask(struct brw_compile *p) { struct brw_reg inv, v0, v1, v2; v0 = brw_vec8_grf(3, 0); v1 = brw_vec8_grf(4, 0); v2 = brw_vec8_grf(5, 0); inv = brw_vec4_grf(6, 0); brw_math_invert(p, inv, brw_vec4_grf(1, 11)); brw_MOV(p, brw_message_reg(3), v0); brw_ADD(p, brw_vec8_grf(7, 0), v1, brw_negate(v2)); brw_MUL(p, brw_message_reg(1), brw_vec8_grf(7, 0), brw_vec1_grf(6,0)); brw_ADD(p, brw_vec8_grf(7, 0), v2, brw_negate(v0)); brw_MUL(p, brw_message_reg(2), brw_vec8_grf(7, 0), brw_vec1_grf(6,2)); brw_urb_WRITE(p, brw_null_reg(), 0, brw_vec8_grf(0 ,0), false, true, 4, 0, true, true, 0, BRW_URB_SWIZZLE_TRANSPOSE); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test.c000066400000000000000000000036551267532330400244430ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "brw_test.h" #include void brw_test_compare(const char *function, int gen, const struct brw_instruction *new, int num_new, const struct brw_instruction *old, int num_old) { int n; if (num_new != num_old || memcmp(new, old, num_new * sizeof(struct brw_instruction))) { printf ("%s: new\n", function); for (n = 0; n < num_new; n++) brw_disasm(stdout, &new[n], gen); printf ("%s: old\n", function); for (n = 0; n < num_old; n++) brw_disasm(stdout, &old[n], gen); printf ("\n"); } } /* Check that we can recreate all the existing programs using the assembler */ int main(int argc, char **argv) { brw_test_gen4(); brw_test_gen5(); brw_test_gen6(); brw_test_gen7(); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test.h000066400000000000000000000031611267532330400244400ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef BRW_TEST_H #define BRW_TEST_H #include "brw.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) #endif void brw_test_compare(const char *function, int gen, const struct brw_instruction *new, int num_new, const struct brw_instruction *old, int num_old); void brw_test_gen4(void); void brw_test_gen5(void); void brw_test_gen6(void); void brw_test_gen7(void); #endif /* BRW_TEST_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test_gen4.c000066400000000000000000000122141267532330400253470ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "brw_test.h" #include static const uint32_t sf_kernel[][4] = { #include "exa_sf.g4b" }; static const uint32_t sf_kernel_mask[][4] = { #include "exa_sf_mask.g4b" }; static const uint32_t ps_kernel_nomask_affine[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_nomask_projective[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_affine[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_projective[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_a.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca_srcalpha.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_a.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca_srcalpha.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_masknoca_affine[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_a.g4b" #include "exa_wm_noca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_masknoca_projective[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_a.g4b" #include "exa_wm_noca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_planar.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; #define GEN 040 #define compare(old) brw_test_compare(__FUNCTION__, p.gen, p.store, p.nr_insn, (struct brw_instruction *)old, ARRAY_SIZE(old)-8) static void gen4_sf__nomask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_sf_kernel__nomask(&p); compare(sf_kernel); } static void gen4_sf__mask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_sf_kernel__mask(&p); compare(sf_kernel_mask); } static void gen4_wm_kernel__affine_nomask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine(&p, 16); compare(ps_kernel_nomask_affine); } static void gen4_wm_kernel__affine_mask_noca(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask(&p, 16); compare(ps_kernel_masknoca_affine); } static void gen4_wm_kernel__projective_nomask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__projective(&p, 16); compare(ps_kernel_nomask_projective); } void brw_test_gen4(void) { gen4_sf__nomask(); gen4_sf__mask(); gen4_wm_kernel__affine_nomask(); gen4_wm_kernel__affine_mask_noca(); gen4_wm_kernel__projective_nomask(); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test_gen5.c000066400000000000000000000124561267532330400253600ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "brw_test.h" #include static const uint32_t sf_kernel[][4] = { #include "exa_sf.g5b" }; static const uint32_t sf_kernel_mask[][4] = { #include "exa_sf_mask.g5b" }; static const uint32_t ps_kernel_nomask_affine[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_nomask_projective[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_projective.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_maskca_affine[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_mask_affine.g5b" #include "exa_wm_mask_sample_argb.g5b" #include "exa_wm_ca.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_maskca_projective[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_projective.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_mask_projective.g5b" #include "exa_wm_mask_sample_argb.g5b" #include "exa_wm_ca.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_a.g5b" #include "exa_wm_mask_affine.g5b" #include "exa_wm_mask_sample_argb.g5b" #include "exa_wm_ca_srcalpha.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_projective.g5b" #include "exa_wm_src_sample_a.g5b" #include "exa_wm_mask_projective.g5b" #include "exa_wm_mask_sample_argb.g5b" #include "exa_wm_ca_srcalpha.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_masknoca_affine[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_mask_affine.g5b" #include "exa_wm_mask_sample_a.g5b" #include "exa_wm_noca.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_masknoca_projective[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_projective.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_mask_projective.g5b" #include "exa_wm_mask_sample_a.g5b" #include "exa_wm_noca.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_yuv_rgb.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_planar.g5b" #include "exa_wm_yuv_rgb.g5b" #include "exa_wm_write.g5b" }; #define compare(old) brw_test_compare(__FUNCTION__, p.gen, p.store, p.nr_insn, (struct brw_instruction *)old, ARRAY_SIZE(old)) #define GEN 050 static void gen5_sf(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_sf_kernel__nomask(&p); compare(sf_kernel); } static void gen5_sf_mask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_sf_kernel__mask(&p); compare(sf_kernel_mask); } static void gen5_wm_affine_nomask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine(&p, 16); compare(ps_kernel_nomask_affine); } static void gen5_wm_affine_mask_noca(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask(&p, 16); compare(ps_kernel_masknoca_affine); } static void gen5_wm_affine_mask_ca(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask_ca(&p, 16); compare(ps_kernel_maskca_affine); } static void gen5_wm_projective_nomask(void) { uint32_t store[128]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__projective(&p, 16); compare(ps_kernel_nomask_projective); } void brw_test_gen5(void) { gen5_sf(); gen5_sf_mask(); gen5_wm_affine_nomask(); gen5_wm_affine_mask_noca(); gen5_wm_affine_mask_ca(); gen5_wm_projective_nomask(); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test_gen6.c000066400000000000000000000131611267532330400253530ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "brw_test.h" #include static const uint32_t ps_kernel_nomask_affine[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_nomask_projective[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_affine[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_projective[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_a.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_a.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_masknoca_affine[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_a.g6b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_masknoca_projective[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_a.g6b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_packed[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_planar[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_planar.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; #define compare(old) brw_test_compare(__FUNCTION__, p.gen, p.store, p.nr_insn, (struct brw_instruction *)old, ARRAY_SIZE(old)) #if 0 static void wm_src_affine(struct brw_compile *p) { brw_PLN(p, brw_message_reg(2), brw_vec1_grf(6,0), brw_vec8_grf(2,0)); brw_PLN(p, brw_message_reg(3), brw_vec1_grf(6,0), brw_vec8_grf(4,0)); brw_PLN(p, brw_message_reg(4), brw_vec1_grf(6,4), brw_vec8_grf(2,0)); brw_PLN(p, brw_message_reg(5), brw_vec1_grf(6,4), brw_vec8_grf(4,0)); } static void wm_src_sample_argb(struct brw_compile *p) { static const uint32_t fragment[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_write.g6b" }; int n; brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, retype(brw_vec1_grf(0,2), BRW_REGISTER_TYPE_UD), brw_imm_ud(0)); brw_pop_insn_state(p); brw_SAMPLE(p, retype(vec16(brw_vec8_grf(14, 0)), BRW_REGISTER_TYPE_UW), 1, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD), 1, 0, WRITEMASK_XYZW, GEN5_SAMPLER_MESSAGE_SAMPLE, 8, 5, true, BRW_SAMPLER_SIMD_MODE_SIMD16); for (n = 0; n < p->nr_insn; n++) { brw_disasm(stdout, &p->store[n], 60); } printf("\n\n"); for (n = 0; n < ARRAY_SIZE(fragment); n++) { brw_disasm(stdout, (const struct brw_instruction *)&fragment[n][0], 60); } } static void wm_write(struct brw_compile *p) { } #endif static void gen6_ps_nomask_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, 060, store); brw_wm_kernel__affine(&p, 16); compare(ps_kernel_nomask_affine); } static void gen6_ps_mask_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, 060, store); brw_wm_kernel__affine_mask(&p, 16); compare(ps_kernel_masknoca_affine); } static void gen6_ps_nomask_projective(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, 060, store); brw_wm_kernel__projective(&p, 16); compare(ps_kernel_nomask_projective); } void brw_test_gen6(void) { gen6_ps_nomask_affine(); gen6_ps_mask_affine(); gen6_ps_nomask_projective(); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_test_gen7.c000066400000000000000000000117461267532330400253630ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "brw_test.h" #include static const uint32_t ps_kernel_nomask_affine[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_nomask_projective[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_affine[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_projective[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_a.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_a.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_masknoca_affine[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_a.g7b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_masknoca_projective[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_a.g7b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_packed[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_planar[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_planar.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; #define compare(old) brw_test_compare(__FUNCTION__, p.gen, p.store, p.nr_insn, (struct brw_instruction *)old, ARRAY_SIZE(old)) #define GEN 070 static void gen7_ps_nomask_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine(&p, 8); compare(ps_kernel_nomask_affine); } static void gen7_ps_mask_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask(&p, 8); compare(ps_kernel_masknoca_affine); } static void gen7_ps_maskca_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask_ca(&p, 8); compare(ps_kernel_maskca_affine); } static void gen7_ps_masksa_affine(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_mask_sa(&p, 8); compare(ps_kernel_maskca_srcalpha_affine); } static void gen7_ps_nomask_projective(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__projective(&p, 8); compare(ps_kernel_nomask_projective); } static void gen7_ps_opacity(void) { uint32_t store[1024]; struct brw_compile p; brw_compile_init(&p, GEN, store); brw_wm_kernel__affine_opacity(&p, 16); compare(ps_kernel_nomask_affine); } void brw_test_gen7(void) { gen7_ps_nomask_affine(); gen7_ps_mask_affine(); gen7_ps_maskca_affine(); gen7_ps_masksa_affine(); gen7_ps_nomask_projective(); gen7_ps_opacity(); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/brw/brw_wm.c000066400000000000000000000374371267532330400241140ustar00rootroot00000000000000#include "brw.h" #define X16 8 #define Y16 10 static void brw_wm_xy(struct brw_compile *p, int dw) { struct brw_reg r1 = brw_vec1_grf(1, 0); struct brw_reg r1_uw = __retype_uw(r1); struct brw_reg x_uw, y_uw; brw_set_compression_control(p, BRW_COMPRESSION_NONE); if (dw == 16) { x_uw = brw_uw16_grf(30, 0); y_uw = brw_uw16_grf(28, 0); } else { x_uw = brw_uw8_grf(30, 0); y_uw = brw_uw8_grf(28, 0); } brw_ADD(p, x_uw, __stride(__suboffset(r1_uw, 4), 2, 4, 0), brw_imm_v(0x10101010)); brw_ADD(p, y_uw, __stride(__suboffset(r1_uw, 5), 2, 4, 0), brw_imm_v(0x11001100)); brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); brw_ADD(p, brw_vec8_grf(X16, 0), vec8(x_uw), brw_negate(r1)); brw_ADD(p, brw_vec8_grf(Y16, 0), vec8(y_uw), brw_negate(__suboffset(r1, 1))); } static void brw_wm_affine_st(struct brw_compile *p, int dw, int channel, int msg) { int uv; if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); uv = p->gen >= 060 ? 6 : 3; } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); uv = p->gen >= 060 ? 4 : 3; } uv += 2*channel; msg++; if (p->gen >= 060) { brw_PLN(p, brw_message_reg(msg), brw_vec1_grf(uv, 0), brw_vec8_grf(2, 0)); msg += dw/8; brw_PLN(p, brw_message_reg(msg), brw_vec1_grf(uv, 4), brw_vec8_grf(2, 0)); } else { struct brw_reg r = brw_vec1_grf(uv, 0); brw_LINE(p, brw_null_reg(), __suboffset(r, 0), brw_vec8_grf(X16, 0)); brw_MAC(p, brw_message_reg(msg), __suboffset(r, 1), brw_vec8_grf(Y16, 0)); msg += dw/8; brw_LINE(p, brw_null_reg(), __suboffset(r, 4), brw_vec8_grf(X16, 0)); brw_MAC(p, brw_message_reg(msg), __suboffset(r, 5), brw_vec8_grf(Y16, 0)); } } static inline unsigned simd(int dw) { return dw == 16 ? BRW_SAMPLER_SIMD_MODE_SIMD16 : BRW_SAMPLER_SIMD_MODE_SIMD8; } static inline struct brw_reg sample_result(int dw, int result) { return brw_reg(BRW_GENERAL_REGISTER_FILE, result, 0, BRW_REGISTER_TYPE_UW, dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } static int brw_wm_sample(struct brw_compile *p, int dw, int channel, int msg, int result) { struct brw_reg src0; bool header; int len; len = dw == 16 ? 4 : 2; if (p->gen >= 060) { header = false; src0 = brw_message_reg(++msg); } else { header = true; src0 = brw_vec8_grf(0, 0); } brw_SAMPLE(p, sample_result(dw, result), msg, src0, channel+1, channel, WRITEMASK_XYZW, 0, 2*len, len+header, header, simd(dw)); return result; } static int brw_wm_sample__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { struct brw_reg src0; int mlen, rlen; if (dw == 8) { /* SIMD8 sample return is not masked */ mlen = 3; rlen = 4; } else { mlen = 5; rlen = 2; } if (p->gen >= 060) src0 = brw_message_reg(msg); else src0 = brw_vec8_grf(0, 0); brw_SAMPLE(p, sample_result(dw, result), msg, src0, channel+1, channel, WRITEMASK_W, 0, rlen, mlen, true, simd(dw)); if (dw == 8) result += 3; return result; } static int brw_wm_affine(struct brw_compile *p, int dw, int channel, int msg, int result) { brw_wm_affine_st(p, dw, channel, msg); return brw_wm_sample(p, dw, channel, msg, result); } static int brw_wm_affine__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { brw_wm_affine_st(p, dw, channel, msg); return brw_wm_sample__alpha(p, dw, channel, msg, result); } static inline struct brw_reg null_result(int dw) { return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0, BRW_REGISTER_TYPE_UW, dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } static void brw_fb_write(struct brw_compile *p, int dw) { struct brw_instruction *insn; unsigned msg_control, msg_type, msg_len; struct brw_reg src0; bool header; if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; msg_len = 8; } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; msg_len = 4; } if (p->gen < 060) { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_mask_control(p, BRW_MASK_DISABLE); brw_MOV(p, brw_message_reg(1), brw_vec8_grf(1, 0)); brw_pop_insn_state(p); msg_len += 2; } /* The execution mask is ignored for render target writes. */ insn = brw_next_insn(p, BRW_OPCODE_SEND); insn->header.predicate_control = 0; insn->header.compression_control = BRW_COMPRESSION_NONE; if (p->gen >= 060) { msg_type = GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE; src0 = brw_message_reg(2); header = false; } else { insn->header.destreg__conditionalmod = 0; msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE; src0 = __retype_uw(brw_vec8_grf(0, 0)); header = true; } brw_set_dest(p, insn, null_result(dw)); brw_set_src0(p, insn, src0); brw_set_dp_write_message(p, insn, 0, msg_control, msg_type, msg_len, header, true, 0, true, false); } static void brw_wm_write(struct brw_compile *p, int dw, int src) { int n; if (dw == 8 && p->gen >= 060) { /* XXX pixel execution mask? */ brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(2), brw_vec8_grf(src+0, 0)); brw_MOV(p, brw_message_reg(3), brw_vec8_grf(src+1, 0)); brw_MOV(p, brw_message_reg(4), brw_vec8_grf(src+2, 0)); brw_MOV(p, brw_message_reg(5), brw_vec8_grf(src+3, 0)); goto done; } brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) { if (p->gen >= 060) { brw_MOV(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0)); } else if (p->gen >= 045 && dw == 16) { brw_MOV(p, brw_message_reg(2 + n + BRW_MRF_COMPR4), brw_vec8_grf(src + 2*n, 0)); } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(2 + n), brw_vec8_grf(src + 2*n, 0)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MOV(p, brw_message_reg(2 + n + 4), brw_vec8_grf(src + 2*n+1, 0)); } } } done: brw_fb_write(p, dw); } static void brw_wm_write__mask(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8 && p->gen >= 060) { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2), brw_vec8_grf(src+0, 0), brw_vec8_grf(mask, 0)); brw_MUL(p, brw_message_reg(3), brw_vec8_grf(src+1, 0), brw_vec8_grf(mask, 0)); brw_MUL(p, brw_message_reg(4), brw_vec8_grf(src+2, 0), brw_vec8_grf(mask, 0)); brw_MUL(p, brw_message_reg(5), brw_vec8_grf(src+3, 0), brw_vec8_grf(mask, 0)); goto done; } brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) { if (p->gen >= 060) { brw_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask, 0)); } else if (p->gen >= 045 && dw == 16) { brw_MUL(p, brw_message_reg(2 + n + BRW_MRF_COMPR4), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask, 0)); } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask, 0)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MUL(p, brw_message_reg(2 + n + 4), brw_vec8_grf(src + 2*n+1, 0), brw_vec8_grf(mask+1, 0)); } } } done: brw_fb_write(p, dw); } static void brw_wm_write__opacity(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8 && p->gen >= 060) { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2), brw_vec8_grf(src+0, 0), brw_vec1_grf(mask, 3)); brw_MUL(p, brw_message_reg(3), brw_vec8_grf(src+1, 0), brw_vec1_grf(mask, 3)); brw_MUL(p, brw_message_reg(4), brw_vec8_grf(src+2, 0), brw_vec1_grf(mask, 3)); brw_MUL(p, brw_message_reg(5), brw_vec8_grf(src+3, 0), brw_vec1_grf(mask, 3)); goto done; } brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) { if (p->gen >= 060) { brw_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec1_grf(mask, 3)); } else if (p->gen >= 045 && dw == 16) { brw_MUL(p, brw_message_reg(2 + n + BRW_MRF_COMPR4), brw_vec8_grf(src + 2*n, 0), brw_vec1_grf(mask, 3)); } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + 2*n, 0), brw_vec1_grf(mask, 3)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MUL(p, brw_message_reg(2 + n + 4), brw_vec8_grf(src + 2*n+1, 0), brw_vec1_grf(mask, 3)); } } } done: brw_fb_write(p, dw); } static void brw_wm_write__mask_ca(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8 && p->gen >= 060) { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2), brw_vec8_grf(src + 0, 0), brw_vec8_grf(mask + 0, 0)); brw_MUL(p, brw_message_reg(3), brw_vec8_grf(src + 1, 0), brw_vec8_grf(mask + 1, 0)); brw_MUL(p, brw_message_reg(4), brw_vec8_grf(src + 2, 0), brw_vec8_grf(mask + 2, 0)); brw_MUL(p, brw_message_reg(5), brw_vec8_grf(src + 3, 0), brw_vec8_grf(mask + 3, 0)); goto done; } brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) { if (p->gen >= 060) { brw_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask + 2*n, 0)); } else if (p->gen >= 045 && dw == 16) { brw_MUL(p, brw_message_reg(2 + n + BRW_MRF_COMPR4), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask + 2*n, 0)); } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask + 2*n, 0)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MUL(p, brw_message_reg(2 + n + 4), brw_vec8_grf(src + 2*n + 1, 0), brw_vec8_grf(mask + 2*n + 1, 0)); } } } done: brw_fb_write(p, dw); } bool brw_wm_kernel__affine(struct brw_compile *p, int dispatch) { if (p->gen < 060) brw_wm_xy(p, dispatch); brw_wm_write(p, dispatch, brw_wm_affine(p, dispatch, 0, 1, 12)); return true; } bool brw_wm_kernel__affine_mask(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_affine(p, dispatch, 0, 1, 12); mask = brw_wm_affine__alpha(p, dispatch, 1, 6, 20); brw_wm_write__mask(p, dispatch, src, mask); return true; } bool brw_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_affine(p, dispatch, 0, 1, 12); mask = brw_wm_affine(p, dispatch, 1, 6, 20); brw_wm_write__mask_ca(p, dispatch, src, mask); return true; } bool brw_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_affine__alpha(p, dispatch, 0, 1, 12); mask = brw_wm_affine(p, dispatch, 1, 6, 16); brw_wm_write__mask(p, dispatch, mask, src); return true; } /* Projective variants */ static void brw_wm_projective_st(struct brw_compile *p, int dw, int channel, int msg) { int uv; if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); uv = p->gen >= 060 ? 6 : 3; } else { brw_set_compression_control(p, BRW_COMPRESSION_NONE); uv = p->gen >= 060 ? 4 : 3; } uv += 2*channel; msg++; if (p->gen >= 060) { /* First compute 1/z */ brw_PLN(p, brw_vec8_grf(30, 0), brw_vec1_grf(uv+1, 0), brw_vec8_grf(2, 0)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); brw_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0)); brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); } else brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); brw_PLN(p, brw_vec8_grf(26, 0), brw_vec1_grf(uv, 0), brw_vec8_grf(2, 0)); brw_PLN(p, brw_vec8_grf(28, 0), brw_vec1_grf(uv, 4), brw_vec8_grf(2, 0)); brw_MUL(p, brw_message_reg(msg), brw_vec8_grf(26, 0), brw_vec8_grf(30, 0)); brw_MUL(p, brw_message_reg(msg + dw/8), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0)); } else { struct brw_reg r = brw_vec1_grf(uv, 0); /* First compute 1/z */ brw_LINE(p, brw_null_reg(), brw_vec1_grf(uv+1, 0), brw_vec8_grf(X16, 0)); brw_MAC(p, brw_vec8_grf(30, 0), brw_vec1_grf(uv+1, 1), brw_vec8_grf(Y16, 0)); if (dw == 16) { brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); brw_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0)); brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); } else brw_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); /* Now compute the output s,t values */ brw_LINE(p, brw_null_reg(), __suboffset(r, 0), brw_vec8_grf(X16, 0)); brw_MAC(p, brw_vec8_grf(28, 0), __suboffset(r, 1), brw_vec8_grf(Y16, 0)); brw_MUL(p, brw_message_reg(msg), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0)); msg += dw/8; brw_LINE(p, brw_null_reg(), __suboffset(r, 4), brw_vec8_grf(X16, 0)); brw_MAC(p, brw_vec8_grf(28, 0), __suboffset(r, 5), brw_vec8_grf(Y16, 0)); brw_MUL(p, brw_message_reg(msg), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0)); } } static int brw_wm_projective(struct brw_compile *p, int dw, int channel, int msg, int result) { brw_wm_projective_st(p, dw, channel, msg); return brw_wm_sample(p, dw, channel, msg, result); } static int brw_wm_projective__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { brw_wm_projective_st(p, dw, channel, msg); return brw_wm_sample__alpha(p, dw, channel, msg, result); } bool brw_wm_kernel__projective(struct brw_compile *p, int dispatch) { if (p->gen < 060) brw_wm_xy(p, dispatch); brw_wm_write(p, dispatch, brw_wm_projective(p, dispatch, 0, 1, 12)); return true; } bool brw_wm_kernel__projective_mask(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_projective(p, dispatch, 0, 1, 12); mask = brw_wm_projective__alpha(p, dispatch, 1, 6, 20); brw_wm_write__mask(p, dispatch, src, mask); return true; } bool brw_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_projective(p, dispatch, 0, 1, 12); mask = brw_wm_projective(p, dispatch, 1, 6, 20); brw_wm_write__mask_ca(p, dispatch, src, mask); return true; } bool brw_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) brw_wm_xy(p, dispatch); src = brw_wm_projective__alpha(p, dispatch, 0, 1, 12); mask = brw_wm_projective(p, dispatch, 1, 6, 16); brw_wm_write__mask(p, dispatch, mask, src); return true; } bool brw_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) { brw_wm_xy(p, dispatch); mask = 5; } else mask = dispatch == 16 ? 8 : 6; src = brw_wm_affine(p, dispatch, 0, 1, 12); brw_wm_write__opacity(p, dispatch, src, mask); return true; } bool brw_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch) { int src, mask; if (p->gen < 060) { brw_wm_xy(p, dispatch); mask = 5; } else mask = dispatch == 16 ? 8 : 6; src = brw_wm_projective(p, dispatch, 0, 1, 12); brw_wm_write__opacity(p, dispatch, src, mask); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/compiler.h000066400000000000000000000057151267532330400236360ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef _SNA_COMPILER_H_ #define _SNA_COMPILER_H_ #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) #define likely(expr) (__builtin_expect (!!(expr), 1)) #define unlikely(expr) (__builtin_expect (!!(expr), 0)) #define noinline __attribute__((noinline)) #define force_inline inline __attribute__((always_inline)) #define fastcall __attribute__((regparm(3))) #define must_check __attribute__((warn_unused_result)) #define constant __attribute__((const)) #define pure __attribute__((pure)) #define tightly_packed __attribute__((__packed__)) #define flatten __attribute__((flatten)) #define nonnull __attribute__((nonnull)) #define page_aligned __attribute__((aligned(4096))) #else #define likely(expr) (expr) #define unlikely(expr) (expr) #define noinline #define force_inline inline #define fastcall #define must_check #define constant #define pure #define tighly_packed #define flatten #define nonnull #define page_aligned #endif #define HAS_GCC(major, minor) defined(__GNUC__) && (__GNUC__ > (major) || __GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) #if HAS_GCC(4, 5) #define sse2 __attribute__((target("sse2,fpmath=sse"))) #define sse4_2 __attribute__((target("sse4.2,sse2,fpmath=sse"))) #endif #if HAS_GCC(4, 6) && defined(__OPTIMIZE__) #define fast __attribute__((optimize("Ofast"))) #else #define fast #endif #if HAS_GCC(4, 7) #define avx2 fast __attribute__((target("avx2,avx,sse4.2,sse2,fpmath=sse"))) #endif #if HAS_GCC(4, 5) && defined(__OPTIMIZE__) #define fast_memcpy fast __attribute__((target("inline-all-stringops"))) #else #define fast_memcpy #endif #ifdef HAVE_VALGRIND #define VG(x) x #else #define VG(x) #endif #define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s))) #define COMPILE_TIME_ASSERT(E) ((void)sizeof(char[1 - 2*!(E)])) #endif /* _SNA_COMPILER_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/debug.h000066400000000000000000000027171267532330400231110ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef _SNA_DEBUG_H_ #define _SNA_DEBUG_H_ #if HAS_DEBUG_FULL void LogF(const char *f, ...); #define DBG(x) LogF x #else #define DBG(x) #endif #if HAS_DEBUG_FULL || !defined(NDEBUG) #define ERR(x) ErrorF x #else #define ERR(x) #endif #endif /* _SNA_DEBUG_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/000077500000000000000000000000001267532330400222325ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/Makefile.am000066400000000000000000000010441267532330400242650ustar00rootroot00000000000000noinst_LTLIBRARIES = libfb.la libfb_la_CFLAGS = @CWARNFLAGS@ @XORG_CFLAGS@ @NOWARNFLAGS@ libfb_la_LIBADD = $(PIXMAN_LIBS) libfb_la_SOURCES = \ fb.h \ sfb.h \ fbarc.c \ fbarcbits.h \ fbbitmap.c \ fbblt.c \ fbbltone.c \ fbclip.c \ fbclip.h \ fbcopy.c \ fbfill.c \ fbgc.c \ fbglyph.c \ fbglyphbits.h \ fbimage.c \ fbline.c \ fblinebits.h \ fbpict.c \ fbpict.h \ fbpoint.c \ fbpointbits.h \ fbpush.c \ fbrop.h \ fbseg.c \ fbsegbits.h \ fbspan.c \ fbstipple.c \ fbtile.c \ fbutil.c \ $(NULL) EXTRA_DIST = README xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/README000066400000000000000000000001031267532330400231040ustar00rootroot00000000000000Note this code is intended to live inside pixman in the long term. xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fb.h000066400000000000000000000411451267532330400227770ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef FB_H #define FB_H #include #include #include #include #include #include #include #include #include "sfb.h" #include "../../compat-api.h" #include "../debug.h" #define WRITE(ptr, val) (*(ptr) = (val)) #define READ(ptr) (*(ptr)) /* * This single define controls the basic size of data manipulated * by this software; it must be log2(sizeof (FbBits) * 8) */ #define FB_SHIFT LOG2_BITMAP_PAD #define FB_UNIT (1 << FB_SHIFT) #define FB_HALFUNIT (1 << (FB_SHIFT-1)) #define FB_MASK (FB_UNIT - 1) #define FB_ALLONES ((FbBits) -1) #if IMAGE_BYTE_ORDER != LSBFirst #error "IMAGE_BYTE_ORDER must be LSBFirst" #endif #if GLYPHPADBYTES != 4 #error "GLYPHPADBYTES must be 4" #endif #if FB_SHIFT != 5 #error "FB_SHIFT ala LOG2_BITMAP_PAD must be 5" #endif #define FB_STIP_SHIFT LOG2_BITMAP_PAD #define FB_STIP_UNIT (1 << FB_STIP_SHIFT) #define FB_STIP_MASK (FB_STIP_UNIT - 1) #define FB_STIP_ALLONES ((FbStip) -1) #define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) typedef uint32_t FbBits; typedef FbBits FbStip; typedef int FbStride; #include "fbrop.h" #define FbScrLeft(x,n) ((x) >> (n)) #define FbScrRight(x,n) ((x) << (n)) /* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ #define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) #define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) #define FbPatternOffsetBits 0 #define FbStipLeft(x,n) FbScrLeft(x,n) #define FbStipRight(x,n) FbScrRight(x,n) #define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) #define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) #define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) #define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) #define FbLeftMask(x) ( ((x) & FB_MASK) ? \ FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) #define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) #define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) #define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) #define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) #define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) #define FbMaskBits(x,w,l,n,r) { \ n = (w); \ r = FbRightMask((x)+n); \ l = FbLeftMask(x); \ if (l) { \ n -= FB_UNIT - ((x) & FB_MASK); \ if (n < 0) { \ n = 0; \ l &= r; \ r = 0; \ } \ } \ n >>= FB_SHIFT; \ } #define FbByteMaskInvalid 0x10 #define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) #define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) #define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) #define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ FbSelectPart(xor,off,t))) #ifndef FbSelectPart #define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) #endif #define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ n = (w); \ lb = 0; \ rb = 0; \ r = FbRightMask((x)+n); \ if (r) { \ /* compute right byte length */ \ if ((copy) && (((x) + n) & 7) == 0) { \ rb = (((x) + n) & FB_MASK) >> 3; \ } else { \ rb = FbByteMaskInvalid; \ } \ } \ l = FbLeftMask(x); \ if (l) { \ /* compute left byte length */ \ if ((copy) && ((x) & 7) == 0) { \ lb = ((x) & FB_MASK) >> 3; \ } else { \ lb = FbByteMaskInvalid; \ } \ /* subtract out the portion painted by leftMask */ \ n -= FB_UNIT - ((x) & FB_MASK); \ if (n < 0) { \ if (lb != FbByteMaskInvalid) { \ if (rb == FbByteMaskInvalid) { \ lb = FbByteMaskInvalid; \ } else if (rb) { \ lb |= (rb - lb) << (FB_SHIFT - 3); \ rb = 0; \ } \ } \ n = 0; \ l &= r; \ r = 0; \ }\ } \ n >>= FB_SHIFT; \ } #define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ switch (lb) { \ case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ break; \ case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ break; \ case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ break; \ case sizeof (FbBits) - 3: \ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ case sizeof (FbBits) - 2: \ FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ break; \ case sizeof (FbBits) - 1: \ FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ break; \ default: \ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ break; \ } \ } #define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ switch (rb) { \ case 1: \ FbStorePart(dst,0,CARD8,xor); \ break; \ case 2: \ FbStorePart(dst,0,CARD16,xor); \ break; \ case 3: \ FbStorePart(dst,0,CARD16,xor); \ FbStorePart(dst,2,CARD8,xor); \ break; \ default: \ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ } \ } #define FbMaskStip(x,w,l,n,r) { \ n = (w); \ r = FbRightStipMask((x)+n); \ l = FbLeftStipMask(x); \ if (l) { \ n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ if (n < 0) { \ n = 0; \ l &= r; \ r = 0; \ } \ } \ n >>= FB_STIP_SHIFT; \ } /* * These macros are used to transparently stipple * in copy mode; the expected usage is with 'n' constant * so all of the conditional parts collapse into a minimal * sequence of partial word writes * * 'n' is the bytemask of which bytes to store, 'a' is the address * of the FbBits base unit, 'o' is the offset within that unit * * The term "lane" comes from the hardware term "byte-lane" which */ #define FbLaneCase1(n,a,o) \ if ((n) == 0x01) { \ WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ } #define FbLaneCase2(n,a,o) \ if ((n) == 0x03) { \ WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ } else { \ FbLaneCase1((n)&1,a,o) \ FbLaneCase1((n)>>1,a,(o)+1) \ } #define FbLaneCase4(n,a,o) \ if ((n) == 0x0f) { \ WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ } else { \ FbLaneCase2((n)&3,a,o) \ FbLaneCase2((n)>>2,a,(o)+2) \ } #define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) typedef struct { long changes; long serial; GCFuncs *old_funcs; void *priv; FbBits and, xor; /* reduced rop values */ FbBits bgand, bgxor; /* for stipples */ FbBits fg, bg, pm; /* expanded and filled */ unsigned int dashLength; /* total of all dash elements */ unsigned char evenStipple; /* stipple is even */ unsigned char bpp; /* current drawable bpp */ } FbGCPrivate, *FbGCPrivPtr; extern DevPrivateKeyRec sna_gc_key; extern DevPrivateKeyRec sna_window_key; static inline FbGCPrivate *fb_gc(GCPtr gc) { return (FbGCPrivate *)__get_private(gc, sna_gc_key); } static inline PixmapPtr fbGetWindowPixmap(WindowPtr window) { return *(PixmapPtr *)__get_private(window, sna_window_key); } #ifdef ROOTLESS #define __fbPixDrawableX(p) ((p)->drawable.x) #define __fbPixDrawableY(p) ((p)->drawable.y) #else #define __fbPixDrawableX(p) 0 #define __fbPixDrawableY(p) 0 #endif #ifdef COMPOSITE #define __fbPixOffXWin(p) (__fbPixDrawableX(p) - (p)->screen_x) #define __fbPixOffYWin(p) (__fbPixDrawableY(p) - (p)->screen_y) #else #define __fbPixOffXWin(p) (__fbPixDrawableX(p)) #define __fbPixOffYWin(p) (__fbPixDrawableY(p)) #endif #define __fbPixOffXPix(p) (__fbPixDrawableX(p)) #define __fbPixOffYPix(p) (__fbPixDrawableY(p)) #define fbGetDrawablePixmap(drawable, pixmap, xoff, yoff) { \ if ((drawable)->type != DRAWABLE_PIXMAP) { \ (pixmap) = fbGetWindowPixmap((WindowPtr)drawable); \ (xoff) = __fbPixOffXWin(pixmap); \ (yoff) = __fbPixOffYWin(pixmap); \ } else { \ (pixmap) = (PixmapPtr) (drawable); \ (xoff) = __fbPixOffXPix(pixmap); \ (yoff) = __fbPixOffYPix(pixmap); \ } \ } #define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);\ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ } #define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);\ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ } #define fbGetDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ PixmapPtr _pPix; \ fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ } #define fbGetStipDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \ PixmapPtr _pPix; \ fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \ fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ } /* * XFree86 empties the root BorderClip when the VT is inactive, * here's a macro which uses that to disable GetImage and GetSpans */ #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0) #define fbWindowEnabled(pWin) \ RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip) #else #define fbWindowEnabled(pWin) \ RegionNotEmpty(&WindowTable[(pWin)->drawable.pScreen->myNum]->borderClip) #endif #define fbDrawableEnabled(drawable) \ ((drawable)->type == DRAWABLE_PIXMAP ? \ TRUE : fbWindowEnabled((WindowPtr) drawable)) #define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) /* * Accelerated tiles are power of 2 width <= FB_UNIT */ #define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) /* * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp * with dstBpp a power of 2 as well */ #define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) inline static int16_t fbBound(int16_t a, uint16_t b) { int v = (int)a + (int)b; if (v > MAXSHORT) return MAXSHORT; return v; } extern void fbPolyArc(DrawablePtr drawable, GCPtr gc, int narcs, xArc * parcs); extern void fbBlt(FbBits *src, FbStride srcStride, int srcX, FbBits *dst, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown); #if FB_STIP_SHIFT == FB_SHIFT static inline void fbBltStip(FbStip *src, FbStride srcStride, int srcX, FbStip *dst, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp) { fbBlt((FbBits *)src, srcStride, srcX, (FbBits *)dst, dstStride, dstX, width, height, alu, pm, bpp, FALSE, FALSE); } #else #error FB_STIP_SHIFT must equal FB_SHIFT #endif extern void fbBltOne(FbStip *src, FbStride srcStride, int srcX, FbBits *dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor); extern void fbBltPlane(FbBits *src, FbStride srcStride, int srcX, int srcBpp, FbStip *dst, FbStride dstStride, int dstX, int width, int height, FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask); extern void fbCopyNtoN(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern void fbCopy1toN(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern void fbCopyNto1(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); extern RegionPtr fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, int width, int height, int dx, int dy); extern RegionPtr fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, int width, int height, int dx, int dy, unsigned long bitplane); extern void fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height); extern void fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc, int x1, int y1, int x2, int y2); extern void fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *rec); extern void fbFillSpans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int fSorted); extern void fbPadPixmap(PixmapPtr pPixmap); extern void fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable); extern void fbGetSpans(DrawablePtr drawable, int wMax, DDXPointPtr pt, int *width, int n, char *dst); extern void fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int n, CharInfoPtr *info, pointer glyphs); extern void fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int n, CharInfoPtr *info, pointer glyphs); extern void fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *image); extern void fbPutXYImage(DrawablePtr drawable, GCPtr gc, FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, int x, int y, int width, int height, FbStip * src, FbStride srcStride, int srcX); extern void fbGetImage(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); extern void fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt); extern void fbFixCoordModePrevious(int n, DDXPointPtr pt); extern void fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg); extern RegionPtr fbBitmapToRegion(PixmapPtr pixmap); extern void fbPolyPoint(DrawablePtr drawable, GCPtr gc, int mode, int n, xPoint *pt, unsigned flags); extern void fbPushImage(DrawablePtr drawable, GCPtr gc, FbStip *src, FbStride srcStride, int srcX, int x, int y, int width, int height); extern void fbPushPixels(GCPtr gc, PixmapPtr pBitmap, DrawablePtr drawable, int dx, int dy, int xOrg, int yOrg); extern void fbSetSpans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr pt, int *width, int n, int fSorted); extern void fbSegment(DrawablePtr drawable, GCPtr gc, int xa, int ya, int xb, int yb, bool drawLast, int *dashOffset); extern void fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *clip, int xa, int ya, int xb, int yb, bool drawLast, int *dashOffset); extern void fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n); extern void fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbStip *stip, FbStride stipStride, int stipWidth, int stipHeight, Bool even, FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot); extern void fbTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot); extern FbBits fbReplicatePixel(Pixel p, int bpp); #endif /* FB_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbarc.c000066400000000000000000000073511267532330400234610ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include #include #include #define ARC fbArc8 #define BITS BYTE #define BITS2 CARD16 #define BITS4 CARD32 #include "fbarcbits.h" #undef BITS #undef BITS2 #undef BITS4 #undef ARC #define ARC fbArc16 #define BITS CARD16 #define BITS2 CARD32 #include "fbarcbits.h" #undef BITS #undef BITS2 #undef ARC #define ARC fbArc32 #define BITS CARD32 #include "fbarcbits.h" #undef BITS #undef ARC void fbPolyArc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc) { DBG(("%s x %d, width=%d, fill=%d, line=%d\n", __FUNCTION__, n, gc->lineWidth, gc->lineStyle, gc->fillStyle)); if (gc->lineWidth == 0) { void (*raster)(FbBits *dst, FbStride dstStride, int dstBpp, xArc *arc, int dx, int dy, FbBits and, FbBits xor); raster = 0; if (gc->lineStyle == LineSolid && gc->fillStyle == FillSolid) { switch (drawable->bitsPerPixel) { case 8: raster = fbArc8; break; case 16: raster = fbArc16; break; case 32: raster = fbArc32; break; } } if (raster) { FbGCPrivPtr pgc = fb_gc(gc); FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; BoxRec box; int x2, y2; fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (n--) { if (miCanZeroArc(arc)) { box.x1 = arc->x + drawable->x; box.y1 = arc->y + drawable->y; /* * Because box.x2 and box.y2 get truncated to 16 bits, and the * RECT_IN_REGION test treats the resulting number as a signed * integer, the RECT_IN_REGION test alone can go the wrong way. * This can result in a server crash because the rendering * routines in this file deal directly with cpu addresses * of pixels to be stored, and do not clip or otherwise check * that all such addresses are within their respective pixmaps. * So we only allow the RECT_IN_REGION test to be used for * values that can be expressed correctly in a signed short. */ x2 = box.x1 + (int) arc->width + 1; box.x2 = x2; y2 = box.y1 + (int) arc->height + 1; box.y2 = y2; if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && (RegionContainsRect(gc->pCompositeClip, &box) == rgnIN)) { raster(dst, dstStride, dstBpp, arc, drawable->x + dstXoff, drawable->y + dstYoff, pgc->and, pgc->xor); } else miZeroPolyArc(drawable, gc, 1, arc); } else miPolyArc(drawable, gc, 1, arc); arc++; } } else miZeroPolyArc(drawable, gc, n, arc); } else miPolyArc(drawable, gc, n, arc); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbarcbits.h000066400000000000000000000135031267532330400243440ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) #define ARCCOPY(d) WRITE(d,xorBits) #define ARCRROP(d) RROP(d,andBits,xorBits) static void ARC(FbBits * dst, FbStride dstStride, int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor) { BITS *bits; FbStride bitsStride; miZeroArcRec info; Bool do360; int x; BITS *yorgp, *yorgop; BITS andBits, xorBits; int yoffset, dyoffset; int y, a, b, d, mask; int k1, k3, dx, dy; bits = (BITS *) dst; bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); andBits = (BITS) and; xorBits = (BITS) xor; do360 = miZeroArcSetup(arc, &info, TRUE); yorgp = bits + ((info.yorg + drawY) * bitsStride); yorgop = bits + ((info.yorgo + drawY) * bitsStride); info.xorg = (info.xorg + drawX); info.xorgo = (info.xorgo + drawX); MIARCSETUP(); yoffset = y ? bitsStride : 0; dyoffset = 0; mask = info.initialMask; if (!(arc->width & 1)) { if (andBits == 0) { if (mask & 2) ARCCOPY(yorgp + info.xorgo); if (mask & 8) ARCCOPY(yorgop + info.xorgo); } else { if (mask & 2) ARCRROP(yorgp + info.xorgo); if (mask & 8) ARCRROP(yorgop + info.xorgo); } } if (!info.end.x || !info.end.y) { mask = info.end.mask; info.end = info.altend; } if (do360 && (arc->width == arc->height) && !(arc->width & 1)) { int xoffset = bitsStride; BITS *yorghb = yorgp + (info.h * bitsStride) + info.xorg; BITS *yorgohb = yorghb - info.h; yorgp += info.xorg; yorgop += info.xorg; yorghb += info.h; while (1) { if (andBits == 0) { ARCCOPY(yorgp + yoffset + x); ARCCOPY(yorgp + yoffset - x); ARCCOPY(yorgop - yoffset - x); ARCCOPY(yorgop - yoffset + x); } else { ARCRROP(yorgp + yoffset + x); ARCRROP(yorgp + yoffset - x); ARCRROP(yorgop - yoffset - x); ARCRROP(yorgop - yoffset + x); } if (a < 0) break; if (andBits == 0) { ARCCOPY(yorghb - xoffset - y); ARCCOPY(yorgohb - xoffset + y); ARCCOPY(yorgohb + xoffset + y); ARCCOPY(yorghb + xoffset - y); } else { ARCRROP(yorghb - xoffset - y); ARCRROP(yorgohb - xoffset + y); ARCRROP(yorgohb + xoffset + y); ARCRROP(yorghb + xoffset - y); } xoffset += bitsStride; MIARCCIRCLESTEP(yoffset += bitsStride; ); } yorgp -= info.xorg; yorgop -= info.xorg; x = info.w; yoffset = info.h * bitsStride; } else if (do360) { while (y < info.h || x < info.w) { MIARCOCTANTSHIFT(dyoffset = bitsStride; ); if (andBits == 0) { ARCCOPY(yorgp + yoffset + info.xorg + x); ARCCOPY(yorgp + yoffset + info.xorgo - x); ARCCOPY(yorgop - yoffset + info.xorgo - x); ARCCOPY(yorgop - yoffset + info.xorg + x); } else { ARCRROP(yorgp + yoffset + info.xorg + x); ARCRROP(yorgp + yoffset + info.xorgo - x); ARCRROP(yorgop - yoffset + info.xorgo - x); ARCRROP(yorgop - yoffset + info.xorg + x); } MIARCSTEP(yoffset += dyoffset; , yoffset += bitsStride; ); } } else { while (y < info.h || x < info.w) { MIARCOCTANTSHIFT(dyoffset = bitsStride; ); if ((x == info.start.x) || (y == info.start.y)) { mask = info.start.mask; info.start = info.altstart; } if (andBits == 0) { if (mask & 1) ARCCOPY(yorgp + yoffset + info.xorg + x); if (mask & 2) ARCCOPY(yorgp + yoffset + info.xorgo - x); if (mask & 4) ARCCOPY(yorgop - yoffset + info.xorgo - x); if (mask & 8) ARCCOPY(yorgop - yoffset + info.xorg + x); } else { if (mask & 1) ARCRROP(yorgp + yoffset + info.xorg + x); if (mask & 2) ARCRROP(yorgp + yoffset + info.xorgo - x); if (mask & 4) ARCRROP(yorgop - yoffset + info.xorgo - x); if (mask & 8) ARCRROP(yorgop - yoffset + info.xorg + x); } if ((x == info.end.x) || (y == info.end.y)) { mask = info.end.mask; info.end = info.altend; } MIARCSTEP(yoffset += dyoffset; , yoffset += bitsStride; ); } } if ((x == info.start.x) || (y == info.start.y)) mask = info.start.mask; if (andBits == 0) { if (mask & 1) ARCCOPY(yorgp + yoffset + info.xorg + x); if (mask & 4) ARCCOPY(yorgop - yoffset + info.xorgo - x); if (arc->height & 1) { if (mask & 2) ARCCOPY(yorgp + yoffset + info.xorgo - x); if (mask & 8) ARCCOPY(yorgop - yoffset + info.xorg + x); } } else { if (mask & 1) ARCRROP(yorgp + yoffset + info.xorg + x); if (mask & 4) ARCRROP(yorgop - yoffset + info.xorgo - x); if (arc->height & 1) { if (mask & 2) ARCRROP(yorgp + yoffset + info.xorgo - x); if (mask & 8) ARCRROP(yorgop - yoffset + info.xorg + x); } } } #undef ARCCOPY #undef ARCRROP #undef RROP #undef isClipped xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbbitmap.c000066400000000000000000000117241267532330400241670ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" static Bool region_grow(RegionPtr region) { RegDataPtr data; int n; n = 16; if (!region->data) { region->data = malloc(RegionSizeof(n)); if (!region->data) return RegionBreak(region); region->data->numRects = 1; *RegionBoxptr(region) = region->extents; } else if (!region->data->size) { region->data = malloc(RegionSizeof(n)); if (!region->data) return RegionBreak(region); region->data->numRects = 0; } else { n = 2 * region->data->numRects; data = (RegDataPtr) realloc(region->data, RegionSizeof(n)); if (!data) return RegionBreak(region); region->data = data; } region->data->size = n; return TRUE; } static inline void add(RegionPtr region, int16_t x1, int16_t y1, int16_t x2, int16_t y2) { BoxPtr r; if (region->data->numRects == region->data->size && !region_grow(region)) return; r = RegionBoxptr(region) + region->data->numRects++; r->x1 = x1; r->y1 = y1; r->x2 = x2; r->y2 = y2; DBG(("%s[%ld/%ld]: (%d, %d), (%d, %d)\n", __FUNCTION__, (long)region->data->numRects, (long)region->data->size, x1, y1, x2, y2)); if (x1 < region->extents.x1) region->extents.x1 = x1; if (x2 > region->extents.x2) region->extents.x2 = x2; } #define MASK_0 (FB_ALLONES & ~FbScrRight(FB_ALLONES, 1)) /* Convert bitmap clip mask into clipping region. * First, goes through each line and makes boxes by noting the transitions * from 0 to 1 and 1 to 0. * Then it coalesces the current line with the previous if they have boxes * at the same X coordinates. */ RegionPtr fbBitmapToRegion(PixmapPtr pixmap) { FbBits maskw; register RegionPtr region; const FbBits *bits, *line, *end; int width, y1, y2, base, x1; int stride, i; DBG(("%s bitmap=%dx%d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); region = RegionCreate(NULL, 1); if (!region) return NullRegion; line = (FbBits *) pixmap->devPrivate.ptr; stride = pixmap->devKind >> (FB_SHIFT - 3); width = pixmap->drawable.width; maskw = 0; if (width & 7) maskw = FB_ALLONES & ~FbScrRight(FB_ALLONES, width & FB_MASK); region->extents.x1 = width; region->extents.x2 = 0; y2 = 0; while (y2 < pixmap->drawable.height) { y1 = y2++; bits = line; line += stride; while (y2 < pixmap->drawable.height && memcmp(bits, line, width >> 3) == 0 && (maskw == 0 || (bits[width >> FB_SHIFT] & maskw) == (line[width >> FB_SHIFT] & maskw))) line += stride, y2++; if (READ(bits) & MASK_0) x1 = 0; else x1 = -1; /* Process all words which are fully in the pixmap */ end = bits + (width >> FB_SHIFT); for (base = 0; bits < end; base += FB_UNIT) { FbBits w = READ(bits++); if (x1 < 0) { if (!w) continue; } else { if (!~w) continue; } for (i = 0; i < FB_UNIT; i++) { if (w & MASK_0) { if (x1 < 0) x1 = base + i; } else { if (x1 >= 0) { add(region, x1, y1, base + i, y2); x1 = -1; } } w = FbScrLeft(w, 1); } } if (width & FB_MASK) { FbBits w = READ(bits++); for (i = 0; i < (width & FB_MASK); i++) { if (w & MASK_0) { if (x1 < 0) x1 = base + i; } else { if (x1 >= 0) { add(region, x1, y1, base + i, y2); x1 = -1; } } w = FbScrLeft(w, 1); } } if (x1 >= 0) add(region, x1, y1, width, y2); } if (region->data->numRects) { region->extents.y1 = RegionBoxptr(region)->y1; region->extents.y2 = RegionEnd(region)->y2; if (region->data->numRects == 1) { free(region->data); region->data = NULL; } } else region->extents.x1 = region->extents.x2 = 0; DBG(("%s: region extents=(%d, %d), (%d, %d) x %d\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region))); return region; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbblt.c000066400000000000000000000217311267532330400234730ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" typedef struct _mergeRopBits { FbBits ca1, cx1, ca2, cx2; } FbMergeRopRec, *FbMergeRopPtr; #define O 0 #define I FB_ALLONES static const FbMergeRopRec FbMergeRopBits[16] = { {O, O, O, O}, /* clear 0x0 0 */ {I, O, O, O}, /* and 0x1 src AND dst */ {I, O, I, O}, /* andReverse 0x2 src AND NOT dst */ {O, O, I, O}, /* copy 0x3 src */ {I, I, O, O}, /* andInverted 0x4 NOT src AND dst */ {O, I, O, O}, /* noop 0x5 dst */ {O, I, I, O}, /* xor 0x6 src XOR dst */ {I, I, I, O}, /* or 0x7 src OR dst */ {I, I, I, I}, /* nor 0x8 NOT src AND NOT dst */ {O, I, I, I}, /* equiv 0x9 NOT src XOR dst */ {O, I, O, I}, /* invert 0xa NOT dst */ {I, I, O, I}, /* orReverse 0xb src OR NOT dst */ {O, O, I, I}, /* copyInverted 0xc NOT src */ {I, O, I, I}, /* orInverted 0xd NOT src OR dst */ {I, O, O, I}, /* nand 0xe NOT src OR NOT dst */ {O, O, O, I}, /* set 0xf 1 */ }; #undef O #undef I #define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2; #define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx; #define FbInitializeMergeRop(alu,pm) {\ const FbMergeRopRec *_bits; \ _bits = &FbMergeRopBits[alu]; \ _ca1 = _bits->ca1 & pm; \ _cx1 = _bits->cx1 | ~pm; \ _ca2 = _bits->ca2 & pm; \ _cx2 = _bits->cx2 & pm; \ } #define InitializeShifts(sx,dx,ls,rs) { \ if (sx != dx) { \ if (sx > dx) { \ ls = sx - dx; \ rs = FB_UNIT - ls; \ } else { \ rs = dx - sx; \ ls = FB_UNIT - rs; \ } \ } \ } static void fbBlt__rop(FbBits *srcLine, FbStride srcStride, int srcX, FbBits *dstLine, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown) { FbBits *src, *dst; int leftShift, rightShift; FbBits startmask, endmask; FbBits bits, bits1; int n, nmiddle; Bool destInvarient; int startbyte, endbyte; FbDeclareMergeRop(); FbInitializeMergeRop(alu, pm); destInvarient = FbDestInvarientMergeRop(); if (upsidedown) { srcLine += (height - 1) * (srcStride); dstLine += (height - 1) * (dstStride); srcStride = -srcStride; dstStride = -dstStride; } FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte, nmiddle, endmask, endbyte); if (reverse) { srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; srcX = (srcX + width - 1) & FB_MASK; dstX = (dstX + width - 1) & FB_MASK; } else { srcLine += srcX >> FB_SHIFT; dstLine += dstX >> FB_SHIFT; srcX &= FB_MASK; dstX &= FB_MASK; } if (srcX == dstX) { while (height--) { src = srcLine; srcLine += srcStride; dst = dstLine; dstLine += dstStride; if (reverse) { if (endmask) { bits = READ(--src); --dst; FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } n = nmiddle; if (destInvarient) { while (n--) WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); } else { while (n--) { bits = READ(--src); --dst; WRITE(dst, FbDoMergeRop(bits, READ(dst))); } } if (startmask) { bits = READ(--src); --dst; FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); } } else { if (startmask) { bits = READ(src++); FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); dst++; } n = nmiddle; if (destInvarient) { while (n--) WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); } else { while (n--) { bits = READ(src++); WRITE(dst, FbDoMergeRop(bits, READ(dst))); dst++; } } if (endmask) { bits = READ(src); FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } } } } else { if (srcX > dstX) { leftShift = srcX - dstX; rightShift = FB_UNIT - leftShift; } else { rightShift = dstX - srcX; leftShift = FB_UNIT - rightShift; } while (height--) { src = srcLine; srcLine += srcStride; dst = dstLine; dstLine += dstStride; bits1 = 0; if (reverse) { if (srcX < dstX) bits1 = READ(--src); if (endmask) { bits = FbScrRight(bits1, rightShift); if (FbScrRight(endmask, leftShift)) { bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); } --dst; FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } n = nmiddle; if (destInvarient) { while (n--) { bits = FbScrRight(bits1, rightShift); bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); --dst; WRITE(dst, FbDoDestInvarientMergeRop(bits)); } } else { while (n--) { bits = FbScrRight(bits1, rightShift); bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); --dst; WRITE(dst, FbDoMergeRop(bits, READ(dst))); } } if (startmask) { bits = FbScrRight(bits1, rightShift); if (FbScrRight(startmask, leftShift)) { bits1 = READ(--src); bits |= FbScrLeft(bits1, leftShift); } --dst; FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); } } else { if (srcX > dstX) bits1 = READ(src++); if (startmask) { bits = FbScrLeft(bits1, leftShift); if (FbScrLeft(startmask, rightShift)) { bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); } FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); dst++; } n = nmiddle; if (destInvarient) { while (n--) { bits = FbScrLeft(bits1, leftShift); bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); WRITE(dst, FbDoDestInvarientMergeRop(bits)); dst++; } } else { while (n--) { bits = FbScrLeft(bits1, leftShift); bits1 = READ(src++); bits |= FbScrRight(bits1, rightShift); WRITE(dst, FbDoMergeRop(bits, READ(dst))); dst++; } } if (endmask) { bits = FbScrLeft(bits1, leftShift); if (FbScrLeft(endmask, rightShift)) { bits1 = READ(src); bits |= FbScrRight(bits1, rightShift); } FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); } } } } } void fbBlt(FbBits *srcLine, FbStride srcStride, int srcX, FbBits *dstLine, FbStride dstStride, int dstX, int width, int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown) { DBG(("%s %dx%d, alu=%d, pm=%x, bpp=%d (reverse=%d, upsidedown=%d)\n", __FUNCTION__, width, height, alu, pm, bpp, reverse, upsidedown)); if (alu == GXcopy && pm == FB_ALLONES && ((srcX|dstX|width) & 7) == 0) { CARD8 *s = (CARD8 *) srcLine; CARD8 *d = (CARD8 *) dstLine; void *(*func)(void *, const void *, size_t); int i; srcStride *= sizeof(FbBits); dstStride *= sizeof(FbBits); width >>= 3; s += srcX >> 3; d += dstX >> 3; DBG(("%s fast blt, src_stride=%d, dst_stride=%d, width=%d (offset=%ld)\n", __FUNCTION__, srcStride, dstStride, width, (long)(s - d))); if (width == srcStride && width == dstStride) { width *= height; height = 1; } if ((s < d && s + width > d) || (d < s && d + width > s)) func = memmove; else func = memcpy; if (!upsidedown) { for (i = 0; i < height; i++) func(d + i * dstStride, s + i * srcStride, width); } else { for (i = height; i--; ) func(d + i * dstStride, s + i * srcStride, width); } return; } fbBlt__rop(srcLine, srcStride, srcX, dstLine, dstStride, dstX, width, height, alu, pm, bpp, reverse, upsidedown); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbbltone.c000066400000000000000000000243121267532330400241730ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #ifdef __clang__ /* shift overflow is intentional */ #pragma clang diagnostic ignored "-Wshift-overflow" #endif /* * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8) * * **** **** **** **** **** **** **** **** * ^ * ******** ******** ******** ******** * ^ * leftShift = 12 * rightShift = 20 * * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8) * * **** **** **** **** **** **** **** **** * ^ * ******** ******** ******** ******** * ^ * * leftShift = 24 * rightShift = 8 */ #define LoadBits {\ if (leftShift) { \ bitsRight = (src < srcEnd ? READ(src++) : 0); \ bits = (FbStipLeft (bitsLeft, leftShift) | \ FbStipRight(bitsRight, rightShift)); \ bitsLeft = bitsRight; \ } else \ bits = (src < srcEnd ? READ(src++) : 0); \ } #define LaneCases1(n,a) case n: FbLaneCase(n,a); break #define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a) #define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a) #define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a) #define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a) #define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a) #define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a) #define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a) #define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a) #define LaneCases(a) LaneCases16(0,a) static const CARD8 fb8Lane[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; static const CARD8 fb16Lane[16] = { 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const CARD8 fb32Lane[16] = { 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const CARD8 * const fbLaneTable[33] = { 0, 0, 0, 0, 0, 0, 0, 0, fb8Lane, 0, 0, 0, 0, 0, 0, 0, fb16Lane, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fb32Lane }; void fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */ int srcX, /* bit position of source */ FbBits * dst, FbStride dstStride, /* FbBits units per scanline */ int dstX, /* bit position of dest */ int dstBpp, /* bits per destination unit */ int width, /* width in bits of destination */ int height, /* height in scanlines */ FbBits fgand, /* rrop values */ FbBits fgxor, FbBits bgand, FbBits bgxor) { const FbBits *fbBits; FbBits *srcEnd; int pixelsPerDst; /* dst pixels per FbBits */ int unitsPerSrc; /* src patterns per FbStip */ int leftShift, rightShift; /* align source with dest */ FbBits startmask, endmask; /* dest scanline masks */ FbStip bits = 0, bitsLeft, bitsRight; /* source bits */ FbStip left; FbBits mask; int nDst; /* dest longwords (w.o. end) */ int w; int n, nmiddle; int dstS; /* stipple-relative dst X coordinate */ Bool copy; /* accelerate dest-invariant */ Bool transparent; /* accelerate 0 nop */ int srcinc; /* source units consumed */ Bool endNeedsLoad = FALSE; /* need load for endmask */ const CARD8 *fbLane; int startbyte, endbyte; /* * Do not read past the end of the buffer! */ srcEnd = src + height * srcStride; /* * Number of destination units in FbBits == number of stipple pixels * used each time */ pixelsPerDst = FB_UNIT / dstBpp; /* * Number of source stipple patterns in FbStip */ unitsPerSrc = FB_STIP_UNIT / pixelsPerDst; copy = FALSE; transparent = FALSE; if (bgand == 0 && fgand == 0) copy = TRUE; else if (bgand == FB_ALLONES && bgxor == 0) transparent = TRUE; /* * Adjust source and dest to nearest FbBits boundary */ src += srcX >> FB_STIP_SHIFT; dst += dstX >> FB_SHIFT; srcX &= FB_STIP_MASK; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, copy, startmask, startbyte, nmiddle, endmask, endbyte); /* * Compute effective dest alignment requirement for * source -- must align source to dest unit boundary */ dstS = dstX / dstBpp; /* * Compute shift constants for effective alignement */ if (srcX >= dstS) { leftShift = srcX - dstS; rightShift = FB_STIP_UNIT - leftShift; } else { rightShift = dstS - srcX; leftShift = FB_STIP_UNIT - rightShift; } /* * Get pointer to stipple mask array for this depth */ fbBits = 0; /* unused */ if (pixelsPerDst <= 8) fbBits = fbStippleTable[pixelsPerDst]; fbLane = 0; if (transparent && fgand == 0 && dstBpp >= 8) fbLane = fbLaneTable[dstBpp]; /* * Compute total number of destination words written, but * don't count endmask */ nDst = nmiddle; if (startmask) nDst++; dstStride -= nDst; /* * Compute total number of source words consumed */ srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc; if (srcX > dstS) srcinc++; if (endmask) { endNeedsLoad = nDst % unitsPerSrc == 0; if (endNeedsLoad) srcinc++; } srcStride -= srcinc; /* * Copy rectangle */ while (height--) { w = nDst; /* total units across scanline */ n = unitsPerSrc; /* units avail in single stipple */ if (n > w) n = w; bitsLeft = 0; if (srcX > dstS) bitsLeft = READ(src++); if (n) { /* * Load first set of stipple bits */ LoadBits; /* * Consume stipple bits for startmask */ if (startmask) { mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; if (fbLane) { fbTransparentSpan(dst, mask & startmask, fgxor, 1); } else { if (mask || !transparent) FbDoLeftMaskByteStippleRRop(dst, mask, fgand, fgxor, bgand, bgxor, startbyte, startmask); } bits = FbStipLeft(bits, pixelsPerDst); dst++; n--; w--; } /* * Consume stipple bits across scanline */ for (;;) { w -= n; if (copy) { while (n--) { #if FB_UNIT > 32 if (pixelsPerDst == 16) mask = FbStipple16Bits(FbLeftStipBits(bits, 16)); else #endif mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; WRITE(dst, FbOpaqueStipple(mask, fgxor, bgxor)); dst++; bits = FbStipLeft(bits, pixelsPerDst); } } else { if (fbLane) { while (bits && n) { switch (fbLane[FbLeftStipBits(bits, pixelsPerDst)]) { LaneCases((CARD8 *) dst); } bits = FbStipLeft(bits, pixelsPerDst); dst++; n--; } dst += n; } else { while (n--) { left = FbLeftStipBits(bits, pixelsPerDst); if (left || !transparent) { mask = fbBits[left]; WRITE(dst, FbStippleRRop(READ(dst), mask, fgand, fgxor, bgand, bgxor)); } dst++; bits = FbStipLeft(bits, pixelsPerDst); } } } if (!w) break; /* * Load another set and reset number of available units */ LoadBits; n = unitsPerSrc; if (n > w) n = w; } } /* * Consume stipple bits for endmask */ if (endmask) { if (endNeedsLoad) { LoadBits; } mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; if (fbLane) { fbTransparentSpan(dst, mask & endmask, fgxor, 1); } else { if (mask || !transparent) FbDoRightMaskByteStippleRRop(dst, mask, fgand, fgxor, bgand, bgxor, endbyte, endmask); } } dst += dstStride; src += srcStride; } } /* * Not very efficient, but simple -- copy a single plane * from an N bit image to a 1 bit image */ void fbBltPlane(FbBits * src, FbStride srcStride, int srcX, int srcBpp, FbStip * dst, FbStride dstStride, int dstX, int width, int height, FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask) { FbBits *s; FbBits pm; FbBits srcMask; FbBits srcMaskFirst; FbBits srcMask0 = 0; FbBits srcBits; FbStip dstBits; FbStip *d; FbStip dstMask; FbStip dstMaskFirst; FbStip dstUnion; int w; int wt; if (!width) return; src += srcX >> FB_SHIFT; srcX &= FB_MASK; dst += dstX >> FB_STIP_SHIFT; dstX &= FB_STIP_MASK; w = width / srcBpp; pm = fbReplicatePixel(planeMask, srcBpp); srcMaskFirst = pm & FbBitsMask(srcX, srcBpp); srcMask0 = pm & FbBitsMask(0, srcBpp); dstMaskFirst = FbStipMask(dstX, 1); while (height--) { d = dst; dst += dstStride; s = src; src += srcStride; srcMask = srcMaskFirst; srcBits = READ(s++); dstMask = dstMaskFirst; dstUnion = 0; dstBits = 0; wt = w; while (wt--) { if (!srcMask) { srcBits = READ(s++); srcMask = srcMask0; } if (!dstMask) { WRITE(d, FbStippleRRopMask(READ(d), dstBits, fgand, fgxor, bgand, bgxor, dstUnion)); d++; dstMask = FbStipMask(0, 1); dstUnion = 0; dstBits = 0; } if (srcBits & srcMask) dstBits |= dstMask; dstUnion |= dstMask; if (srcBpp == FB_UNIT) srcMask = 0; else srcMask = FbScrRight(srcMask, srcBpp); dstMask = FbStipRight(dstMask, 1); } if (dstUnion) WRITE(d, FbStippleRRopMask(READ(d), dstBits, fgand, fgxor, bgand, bgxor, dstUnion)); } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbclip.c000066400000000000000000000054031267532330400236370ustar00rootroot00000000000000/* * Copyright © 2012 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #include "fb.h" #include "fbclip.h" static const BoxRec * find_clip_row_for_y(const BoxRec *begin, const BoxRec *end, int16_t y) { const BoxRec *mid; if (end == begin) return end; if (end - begin == 1) { if (begin->y2 > y) return begin; else return end; } mid = begin + (end - begin) / 2; if (mid->y2 > y) return find_clip_row_for_y(begin, mid, y); else return find_clip_row_for_y(mid, end, y); } const BoxRec * fbClipBoxes(const RegionRec *region, const BoxRec *box, const BoxRec **end) { const BoxRec *c0, *c1; DBG(("%s: box=(%d, %d),(%d, %d); region=(%d, %d),(%d, %d) x %ld\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region->data ? region->data->numRects : 1)); if (box->x1 >= region->extents.x2 || box->x2 <= region->extents.x1 || box->y1 >= region->extents.y2 || box->y2 <= region->extents.y1) { DBG(("%s: no intersection\n", __FUNCTION__)); return *end = box; } if (region->data == NULL) { *end = ®ion->extents + 1; return ®ion->extents; } c0 = (const BoxRec *)(region->data + 1); c1 = c0 + region->data->numRects; if (c0->y2 <= box->y1) { DBG(("%s: first clip (%d, %d), (%d, %d) before box (%d, %d), (%d, %d)\n", __FUNCTION__, c0->x1, c0->y1, c0->x2, c0->y2, box->x1, box->y1, box->x2, box->y2)); c0 = find_clip_row_for_y(c0, c1, box->y1); } DBG(("%s: c0=(%d, %d),(%d, %d) x %ld\n", __FUNCTION__, c0->x1, c0->y1, c0->x2, c0->y2, (long)(c1 - c0))); *end = c1; return c0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbclip.h000066400000000000000000000052151267532330400236450ustar00rootroot00000000000000/* * Copyright © 2012 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef FBCLIP_H #define FBCLIP_H extern const BoxRec * fbClipBoxes(const RegionRec *region, const BoxRec *box, const BoxRec **end); inline static bool box_intersect(BoxPtr a, const BoxRec *b) { if (a->x1 < b->x1) a->x1 = b->x1; if (a->x2 > b->x2) a->x2 = b->x2; if (a->x1 >= a->x2) return false; if (a->y1 < b->y1) a->y1 = b->y1; if (a->y2 > b->y2) a->y2 = b->y2; if (a->y1 >= a->y2) return false; return true; } #define run_box(b, c) \ DBG(("%s: box=(%d, %d), (%d, %d), clip=(%d, %d), (%d, %d)\n", \ __FUNCTION__, (b)->x1, (b)->y1, (b)->x2, (b)->y2, (c)->x1, (c)->y1, (c)->x2, (c)->y2)); \ if ((b)->y2 <= (c)->y1) break; \ if ((b)->x1 >= (c)->x2) continue; \ if ((b)->x2 <= (c)->x1) { if ((b)->y2 <= (c)->y2) break; continue; } static inline void fbDrawableRun(DrawablePtr d, GCPtr gc, const BoxRec *box, void (*func)(DrawablePtr, GCPtr, const BoxRec *b, void *data), void *data) { const BoxRec *c, *end; for (c = fbClipBoxes(gc->pCompositeClip, box, &end); c != end; c++) { BoxRec b; run_box(box, c); b = *box; if (box_intersect(&b, c)) func(d, gc, &b, data); } } static inline void fbDrawableRunUnclipped(DrawablePtr d, GCPtr gc, const BoxRec *box, void (*func)(DrawablePtr, GCPtr, const BoxRec *b, void *data), void *data) { const BoxRec *c, *end; for (c = fbClipBoxes(gc->pCompositeClip, box, &end); c != end; c++) { run_box(box, c); func(d, gc, c, data); } } #endif /* FBCLIP_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbcopy.c000066400000000000000000000147101267532330400236630ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" #include void fbCopyNtoN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { CARD8 alu = gc ? gc->alu : GXcopy; FbBits pm = gc ? fb_gc(gc)->pm : FB_ALLONES; FbBits *src, *dst; FbStride srcStride, dstStride; int dstBpp, srcBpp; int srcXoff, srcYoff; int dstXoff, dstYoff; fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); src += (dy + srcYoff) * srcStride; srcXoff += dx; dst += dstYoff * dstStride; do { fbBlt(src + box->y1 * srcStride, srcStride, (box->x1 + srcXoff) * srcBpp, dst + box->y1 * dstStride, dstStride, (box->x1 + dstXoff) * dstBpp, (box->x2 - box->x1) * dstBpp, (box->y2 - box->y1), alu, pm, dstBpp, reverse, upsidedown); } while (box++, --nbox); } void fbCopy1toN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { FbGCPrivPtr pgc = fb_gc(gc); FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); while (nbox--) { if (dstBpp == 1) { fbBlt(src + (box->y1 + dy + srcYoff) * srcStride, srcStride, (box->x1 + dx + srcXoff) * srcBpp, dst + (box->y1 + dstYoff) * dstStride, dstStride, (box->x1 + dstXoff) * dstBpp, (box->x2 - box->x1) * dstBpp, (box->y2 - box->y1), FbOpaqueStipple1Rop(gc->alu, gc->fgPixel, gc->bgPixel), pgc->pm, dstBpp, reverse, upsidedown); } else { fbBltOne((FbStip *) (src + (box->y1 + dy + srcYoff) * srcStride), srcStride * (FB_UNIT / FB_STIP_UNIT), (box->x1 + dx + srcXoff), dst + (box->y1 + dstYoff) * dstStride, dstStride, (box->x1 + dstXoff) * dstBpp, dstBpp, (box->x2 - box->x1) * dstBpp, (box->y2 - box->y1), pgc->and, pgc->xor, pgc->bgand, pgc->bgxor); } box++; } } void fbCopyNto1(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { FbGCPrivPtr pgc = fb_gc(gc); while (nbox--) { if (dst_drawable->bitsPerPixel == 1) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetStipDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride, srcStride, (box->x1 + dx + srcXoff) * srcBpp, srcBpp, dst + (box->y1 + dstYoff) * dstStride, dstStride, (box->x1 + dstXoff) * dstBpp, (box->x2 - box->x1) * srcBpp, (box->y2 - box->y1), (FbStip) pgc->and, (FbStip) pgc->xor, (FbStip) pgc->bgand, (FbStip) pgc->bgxor, bitplane); } else { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbStip *tmp; FbStride tmpStride; int width, height; width = box->x2 - box->x1; height = box->y2 - box->y1; tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); tmp = malloc(tmpStride * height * sizeof(FbStip)); if (!tmp) return; fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff); fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride, srcStride, (box->x1 + dx + srcXoff) * srcBpp, srcBpp, tmp, tmpStride, 0, width * srcBpp, height, fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES), fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES), fbAndStip(GXcopy, 0, FB_ALLONES), fbXorStip(GXcopy, 0, FB_ALLONES), bitplane); fbBltOne(tmp, tmpStride, 0, dst + (box->y1 + dstYoff) * dstStride, dstStride, (box->x1 + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, pgc->and, pgc->xor, pgc->bgand, pgc->bgxor); free(tmp); } box++; } } RegionPtr fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, int width, int height, int dx, int dy) { return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy, fbCopyNtoN, 0, 0); } RegionPtr fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, int width, int height, int dx, int dy, unsigned long bitplane) { if (src->bitsPerPixel > 1) return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy, fbCopyNto1, (Pixel) bitplane, 0); else if (bitplane & 1) return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy, fbCopy1toN, (Pixel) bitplane, 0); else return miHandleExposures(src, dst, gc, sx, sy, width, height, dx, dy, bitplane); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbfill.c000066400000000000000000000143221267532330400236360ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include "fbclip.h" static void fbSolid(FbBits * dst, FbStride dstStride, int dstX, int bpp, int width, int height, FbBits and, FbBits xor) { FbBits startmask, endmask; int n, nmiddle; int startbyte, endbyte; dst += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte, nmiddle, endmask, endbyte); if (startmask) dstStride--; dstStride -= nmiddle; while (height--) { if (startmask) { FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); dst++; } n = nmiddle; if (!and) while (n--) WRITE(dst++, xor); else while (n--) { WRITE(dst, FbDoRRop(READ(dst), and, xor)); dst++; } if (endmask) FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); dst += dstStride; } } void fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; FbGCPrivPtr pgc = fb_gc(gc); DBG(("%s (%d, %d)x(%d, %d), style=%d\n", __FUNCTION__, x, y, width, height, gc->fillStyle)); fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); switch (gc->fillStyle) { case FillSolid: if (pgc->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, x + dstXoff, y + dstYoff, width, height, pgc->xor)) fbSolid(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, pgc->and, pgc->xor); break; case FillStippled: case FillOpaqueStippled: { PixmapPtr pStip = gc->stipple; int stipWidth = pStip->drawable.width; int stipHeight = pStip->drawable.height; if (dstBpp == 1) { int alu; FbBits *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; if (gc->fillStyle == FillStippled) alu = FbStipple1Rop(gc->alu, gc->fgPixel); else alu = FbOpaqueStipple1Rop(gc->alu, gc->fgPixel, gc->bgPixel); fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff, width, height, stip, stipStride, stipWidth, stipHeight, alu, pgc->pm, dstBpp, (gc->patOrg.x + drawable->x + dstXoff), gc->patOrg.y + drawable->y - y); } else { FbStip *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; FbBits fgand, fgxor, bgand, bgxor; fgand = pgc->and; fgxor = pgc->xor; if (gc->fillStyle == FillStippled) { bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); } else { bgand = pgc->bgand; bgxor = pgc->bgxor; } fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbStipple(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, stip, stipStride, stipWidth, stipHeight, pgc->evenStipple, fgand, fgxor, bgand, bgxor, gc->patOrg.x + drawable->x + dstXoff, gc->patOrg.y + drawable->y - y); } break; } case FillTiled: { PixmapPtr tile = gc->tile.pixmap; fbTile(dst + (y + dstYoff) * dstStride, dstStride, (x + dstXoff) * dstBpp, width * dstBpp, height, tile->devPrivate.ptr, tile->devKind / sizeof(FbBits), tile->drawable.width * tile->drawable.bitsPerPixel, tile->drawable.height, gc->alu, pgc->pm, dstBpp, (gc->patOrg.x + drawable->x + dstXoff) * dstBpp, gc->patOrg.y + drawable->y - y); break; } } } static void _fbSolidBox(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { FbBits *dst; FbStride stride; int dx, dy, bpp; FbBits and = fbAnd(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm); FbBits xor = fbXor(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm); fbGetDrawable(drawable, dst, stride, bpp, dx, dy); if (and || !pixman_fill((uint32_t *) dst, stride, bpp, b->x1 + dx, b->y1 + dy, (b->x2 - b->x1), (b->y2 - b->y1), xor)) fbSolid(dst + (b->y1 + dy) * stride, stride, (b->x1 + dx) * bpp, bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), and, xor); } void fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc, int x1, int y1, int x2, int y2) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; fbDrawableRun(drawable, gc, &box, _fbSolidBox, NULL); } inline static void fbFillBox(DrawablePtr drawable, GCPtr gc, const BoxRec *box, void *data) { DBG(("%s box=(%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); fbFill(drawable, gc, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); } void fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r) { DBG(("%s x %d\n", __FUNCTION__, n)); while (n--) { BoxRec b; b.x1 = r->x + drawable->x; b.y1 = r->y + drawable->y; b.x2 = fbBound(b.x1, r->width); b.y2 = fbBound(b.y1, r->height); r++; DBG(("%s: rectangle (%d, %d), (%d, %d)\n", __FUNCTION__, b.x1, b.y1, b.x2, b.y2)); fbDrawableRun(drawable, gc, &b, fbFillBox, NULL); } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbgc.c000066400000000000000000000120111267532330400232720ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include #include /* * Pad pixmap to FB_UNIT bits wide */ void fbPadPixmap(PixmapPtr pPixmap) { int width; FbBits *bits; FbBits b; FbBits mask; int height; int w; int stride; int bpp; _X_UNUSED int xOff, yOff; fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff); width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel; height = pPixmap->drawable.height; mask = FbBitsMask(0, width); while (height--) { b = READ(bits) & mask; w = width; while (w < FB_UNIT) { b = b | FbScrRight(b, w); w <<= 1; } WRITE(bits, b); bits += stride; } } /* * Verify that 'bits' repeats every 'len' bits */ static Bool fbBitsRepeat(FbBits bits, int len, int width) { FbBits mask = FbBitsMask(0, len); FbBits orig = bits & mask; int i; if (width > FB_UNIT) width = FB_UNIT; for (i = 0; i < width / len; i++) { if ((bits & mask) != orig) return FALSE; bits = FbScrLeft(bits, len); } return TRUE; } /* * Check whether an entire bitmap line is a repetition of * the first 'len' bits */ static Bool fbLineRepeat(FbBits * bits, int len, int width) { FbBits first = bits[0]; if (!fbBitsRepeat(first, len, width)) return FALSE; width = (width + FB_UNIT - 1) >> FB_SHIFT; bits++; while (--width) if (READ(bits) != first) return FALSE; return TRUE; } /* * The even stipple code wants the first FB_UNIT/bpp bits on * each scanline to represent the entire stipple */ static Bool fbCanEvenStipple(PixmapPtr pStipple, int bpp) { int len = FB_UNIT / bpp; FbBits *bits; int stride; int stip_bpp; _X_UNUSED int stipXoff, stipYoff; int h; /* make sure the stipple width is a multiple of the even stipple width */ if (pStipple->drawable.width % len != 0) return FALSE; fbGetDrawable(&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff); h = pStipple->drawable.height; /* check to see that the stipple repeats horizontally */ while (h--) { if (!fbLineRepeat(bits, len, pStipple->drawable.width)) return FALSE; bits += stride; } return TRUE; } void fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable) { FbGCPrivPtr pgc = fb_gc(gc); FbBits mask; DBG(("%s changes=%lx\n", __FUNCTION__, changes)); if (changes & GCStipple) { pgc->evenStipple = FALSE; if (gc->stipple) { /* can we do an even stipple ?? */ if (FbEvenStip(gc->stipple->drawable.width, drawable->bitsPerPixel) && (fbCanEvenStipple(gc->stipple, drawable->bitsPerPixel))) pgc->evenStipple = TRUE; } } /* * Recompute reduced rop values */ if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) { int s; FbBits depthMask; mask = FbFullMask(drawable->bitsPerPixel); depthMask = FbFullMask(drawable->depth); DBG(("%s: computing rrop mask=%08x, depthMask=%08x, fg=%08x, bg=%08x, planemask=%08x\n", __FUNCTION__, mask, depthMask, (int)gc->fgPixel, (int)gc->bgPixel, (int)gc->planemask)); pgc->fg = gc->fgPixel & mask; pgc->bg = gc->bgPixel & mask; if ((gc->planemask & depthMask) == depthMask) pgc->pm = mask; else pgc->pm = gc->planemask & mask; s = drawable->bitsPerPixel; while (s < FB_UNIT) { pgc->fg |= pgc->fg << s; pgc->bg |= pgc->bg << s; pgc->pm |= pgc->pm << s; s <<= 1; } pgc->and = fbAnd(gc->alu, pgc->fg, pgc->pm); pgc->xor = fbXor(gc->alu, pgc->fg, pgc->pm); pgc->bgand = fbAnd(gc->alu, pgc->bg, pgc->pm); pgc->bgxor = fbXor(gc->alu, pgc->bg, pgc->pm); DBG(("%s: rrop fg=%08x, bg=%08x, pm=%08x, and=%08x, xor=%08x, bgand=%08x, bgxor=%08x\n", __FUNCTION__, pgc->fg, pgc->bg, pgc->pm, pgc->and, pgc->xor, pgc->bgand, pgc->bgxor)); } if (changes & GCDashList) { unsigned short n = gc->numInDashList; unsigned char *dash = gc->dash; unsigned int dashLength = 0; while (n--) dashLength += (unsigned int) *dash++; pgc->dashLength = dashLength; } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbglyph.c000066400000000000000000000160331267532330400240340ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include #include #define GLYPH fbGlyph8 #define BITS BYTE #define BITS2 CARD16 #define BITS4 CARD32 #include "fbglyphbits.h" #undef BITS #undef BITS2 #undef BITS4 #undef GLYPH #define GLYPH fbGlyph16 #define BITS CARD16 #define BITS2 CARD32 #include "fbglyphbits.h" #undef BITS #undef BITS2 #undef GLYPH #define GLYPH fbGlyph32 #define BITS CARD32 #include "fbglyphbits.h" #undef BITS #undef GLYPH static bool fbGlyphIn(GCPtr gc, int x, int y, int width, int height) { BoxRec box; BoxPtr extents = RegionExtents(gc->pCompositeClip); /* * Check extents by hand to avoid 16 bit overflows */ if (x < (int) extents->x1 || (int) extents->x2 < x + width) return FALSE; if (y < (int) extents->y1 || (int) extents->y2 < y + height) return FALSE; box.x1 = x; box.x2 = x + width; box.y1 = y; box.y2 = y + height; return RegionContainsRect(gc->pCompositeClip, &box) == rgnIN; } #define WRITE1(d,n,fg) WRITE((d) + (n), (CARD8) fg) #define WRITE2(d,n,fg) WRITE((CARD16 *) &(d[n]), (CARD16) fg) #define WRITE4(d,n,fg) WRITE((CARD32 *) &(d[n]), (CARD32) fg) /* * This is a bit tricky, but it's brief. Write 12 bytes worth * of dest, which is four pixels, at a time. This gives constant * code for each pattern as they're always aligned the same * * a b c d a b c d a b c d bytes * A B C A B C A B C A B C pixels * * f0 f1 f2 * A B C A B C A B C A B C pixels LSB * C A B C A B C A B C A B pixels MSB * * LSB MSB * A f0 f1 * B f1 f2 * C f2 f0 * A B f0 f2 * B C f1 f0 * C A f2 f1 * A B C A f0 f1 * B C A B f1 f2 * C A B C f2 f0 */ #undef _A #undef _B #undef _C #undef _AB #undef _BC #undef _CA #undef _ABCA #undef _BCAB #undef _CABC #define _A f0 #define _B f1 #define _C f2 #define _AB f0 #define _BC f1 #define _CA f2 #define _ABCA f0 #define _BCAB f1 #define _CABC f2 #define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3)) void fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer glyphs) { FbGCPrivPtr pgc = fb_gc(gc); CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gx, gy; int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ void (*raster) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; DBG(("%s x %d\n", __FUNCTION__, nglyph)); raster = 0; if (gc->fillStyle == FillSolid && pgc->and == 0) { dstBpp = drawable->bitsPerPixel; switch (dstBpp) { case 8: raster = fbGlyph8; break; case 16: raster = fbGlyph16; break; case 32: raster = fbGlyph32; break; } } x += drawable->x; y += drawable->y; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(glyphs, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (raster && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(gc, gx, gy, gWidth, gHeight)) { fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pgc->xor, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPushImage(drawable, gc, (FbStip *)pglyph, gStride, 0, gx, gy, gWidth, gHeight); } } x += pci->metrics.characterWidth; } } void fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, pointer glyphs) { FbGCPrivPtr pgc = fb_gc(gc); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ bool opaque; int n; int gx, gy; void (*raster)(FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; DBG(("%s x %d\n", __FUNCTION__, nglyph)); raster = 0; if (pgc->and == 0) { dstBpp = drawable->bitsPerPixel; switch (dstBpp) { case 8: raster = fbGlyph8; break; case 16: raster = fbGlyph16; break; case 32: raster = fbGlyph32; break; } } x += drawable->x; y += drawable->y; if (TERMINALFONT(gc->font) && !raster) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(gc->font); heightBack = FONTASCENT(gc->font) + FONTDESCENT(gc->font); fbSolidBoxClipped(drawable, gc, xBack, yBack, xBack + widthBack, yBack + heightBack); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(glyphs, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (raster && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(gc, gx, gy, gWidth, gHeight)) { fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pgc->fg, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(drawable, gc, pgc->fg, pgc->bg, pgc->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbglyphbits.h000066400000000000000000000066221267532330400247260ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) #define WRITE_ADDR1(n) (n) #define WRITE_ADDR2(n) (n) #define WRITE_ADDR4(n) (n) #define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg)) #ifdef BITS2 #define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg)) #else #define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg)) #endif #ifdef BITS4 #define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg)) #else #define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg)) #endif static void GLYPH(FbBits * dstBits, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int x, int height) { int lshift; FbStip bits; BITS *dstLine; BITS *dst; int n; int shift; dstLine = (BITS *) dstBits; dstLine += x & ~3; dstStride *= (sizeof(FbBits) / sizeof(BITS)); shift = x & 3; lshift = 4 - shift; while (height--) { bits = *stipple++; dst = (BITS *) dstLine; n = lshift; while (bits) { switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) { case 0: break; case 1: WRITE1(dst, 0, fg); break; case 2: WRITE1(dst, 1, fg); break; case 3: WRITE2(dst, 0, fg); break; case 4: WRITE1(dst, 2, fg); break; case 5: WRITE1(dst, 0, fg); WRITE1(dst, 2, fg); break; case 6: WRITE1(dst, 1, fg); WRITE1(dst, 2, fg); break; case 7: WRITE2(dst, 0, fg); WRITE1(dst, 2, fg); break; case 8: WRITE1(dst, 3, fg); break; case 9: WRITE1(dst, 0, fg); WRITE1(dst, 3, fg); break; case 10: WRITE1(dst, 1, fg); WRITE1(dst, 3, fg); break; case 11: WRITE2(dst, 0, fg); WRITE1(dst, 3, fg); break; case 12: WRITE2(dst, 2, fg); break; case 13: WRITE1(dst, 0, fg); WRITE2(dst, 2, fg); break; case 14: WRITE1(dst, 1, fg); WRITE2(dst, 2, fg); break; case 15: WRITE4(dst, 0, fg); break; } bits = FbStipLeft(bits, n); n = 4; dst += 4; } dstLine += dstStride; } } #undef WRITE_ADDR1 #undef WRITE_ADDR2 #undef WRITE_ADDR4 #undef WRITE1 #undef WRITE2 #undef WRITE4 #undef RROP #undef isClipped xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbimage.c000066400000000000000000000157731267532330400240050ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" #include "fbclip.h" struct fbPutZImage { FbStip *src, *dst; FbStride src_stride, dst_stride; int dst_x, dst_y; int x0, y0; }; inline static void _fbPutZImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutZImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) * bpp, data->dst + (b->y1 + data->dst_y) * data->dst_stride, data->dst_stride, (b->x1 + data->dst_x) * bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), gc->alu, fb_gc(gc)->pm, bpp); } static void fbPutZImage(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height, FbStip *src, FbStride srcStride) { PixmapPtr pixmap; struct fbPutZImage data; BoxRec box; box.x1 = data.x0 = x; box.y1 = data.y0 = y; box.x2 = x + width; box.y2 = y + height; data.src = src; data.src_stride = srcStride; fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); data.dst = pixmap->devPrivate.ptr; data.dst_stride = pixmap->devKind / sizeof(FbStip); fbDrawableRun(drawable, gc, &box, _fbPutZImage, &data); } struct fbPutXYImage { FbStip *src, *dst; FbStride src_stride, dst_stride; int dst_x, dst_y, src_x; int x0, y0; int alu, pm; FbBits fgand, fgxor, bgand, bgxor; }; inline static void _fbPutXYImage1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutXYImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) + data->src_x, (FbStip *) (data->dst + (b->y1 + data->dst_y) * data->dst_stride), data->dst_stride, (b->x1 + data->dst_x) * bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), data->alu, data->pm, bpp); } inline static void _fbPutXYImageN(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPutXYImage *data = _data; int bpp = drawable->bitsPerPixel; fbBltOne(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride, (b->x1 - data->x0) + data->src_x, data->dst + (b->y1 + data->dst_y) * data->dst_stride, data->dst_stride, (b->x1 + data->dst_x) * bpp, bpp, (b->x2 - b->x1) * bpp, (b->y2 - b->y1), data->fgand, data->fgxor, data->bgand, data->bgxor); } void fbPutXYImage(DrawablePtr drawable, GCPtr gc, FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque, int x, int y, int width, int height, FbStip *src, FbStride srcStride, int srcX) { PixmapPtr pixmap; struct fbPutXYImage data; BoxRec box; box.x1 = data.x0 = x; box.y1 = data.y0 = y; box.x2 = x + width; box.y2 = y + height; data.src = src; data.src_stride = srcStride; data.src_x = srcX; fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y); data.dst = pixmap->devPrivate.ptr; data.dst_stride = pixmap->devKind / sizeof(FbStip); if (drawable->bitsPerPixel == 1) { if (opaque) data.alu = FbOpaqueStipple1Rop(alu, fg, bg); else data.alu = FbStipple1Rop(alu, fg); data.pm = pm; fbDrawableRun(drawable, gc, &box, _fbPutXYImage1, &data); } else { data.fgand = fbAnd(alu, fg, pm); data.fgxor = fbXor(alu, fg, pm); if (opaque) { data.bgand = fbAnd(alu, bg, pm); data.bgxor = fbXor(alu, bg, pm); } else { data.bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); data.bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); } fbDrawableRun(drawable, gc, &box, _fbPutXYImageN, &data); } } void fbPutImage(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *image) { FbGCPrivPtr pgc = fb_gc(gc); unsigned long i; FbStride srcStride; FbStip *src = (FbStip *)image; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); x += drawable->x; y += drawable->y; switch (format) { case XYBitmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); fbPutXYImage(drawable, gc, pgc->fg, pgc->bg, pgc->pm, gc->alu, TRUE, x, y, w, h, src, srcStride, leftPad); break; case XYPixmap: srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip); for (i = (unsigned long) 1 << (drawable->depth - 1); i; i >>= 1) { if (i & gc->planemask) { fbPutXYImage(drawable, gc, FB_ALLONES, 0, fbReplicatePixel(i, drawable->bitsPerPixel), gc->alu, TRUE, x, y, w, h, src, srcStride, leftPad); src += srcStride * h; } } break; case ZPixmap: srcStride = PixmapBytePad(w, drawable->depth) / sizeof(FbStip); fbPutZImage(drawable, gc, x, y, w, h, src, srcStride); } } void fbGetImage(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff); x += drawable->x; y += drawable->y; dst = (FbStip *) d; if (format == ZPixmap || srcBpp == 1) { FbBits pm; pm = fbReplicatePixel(planeMask, srcBpp); dstStride = PixmapBytePad(w, drawable->depth); if (pm != FB_ALLONES) memset(d, 0, dstStride * h); dstStride /= sizeof(FbStip); fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride, (x + srcXoff) * srcBpp, dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp); } else { dstStride = BitmapBytePad(w) / sizeof(FbStip); fbBltPlane(src + (y + srcYoff) * srcStride, srcStride, (x + srcXoff) * srcBpp, srcBpp, dst, dstStride, 0, w * srcBpp, h, fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES), fbAndStip(GXcopy, 0, FB_STIP_ALLONES), fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask); } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbline.c000066400000000000000000000107431267532330400236420ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include #include #include #include #define POLYLINE fbPolyline8 #define POLYSEGMENT fbPolySegment8 #define BITS BYTE #define BITS2 CARD16 #define BITS4 CARD32 #include "fblinebits.h" #undef BITS #undef BITS2 #undef BITS4 #undef POLYSEGMENT #undef POLYLINE #define POLYLINE fbPolyline16 #define POLYSEGMENT fbPolySegment16 #define BITS CARD16 #define BITS2 CARD32 #include "fblinebits.h" #undef BITS #undef BITS2 #undef POLYSEGMENT #undef POLYLINE #define POLYLINE fbPolyline32 #define POLYSEGMENT fbPolySegment32 #define BITS CARD32 #include "fblinebits.h" #undef BITS #undef POLYSEGMENT #undef POLYLINE static void fbZeroLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { int x1, y1, x2, y2; int x, y; int dashOffset; x = drawable->x; y = drawable->y; x1 = pt->x; y1 = pt->y; dashOffset = gc->dashOffset; while (--n) { ++pt; x2 = pt->x; y2 = pt->y; if (mode == CoordModePrevious) { x2 += x1; y2 += y1; } fbSegment(drawable, gc, x1 + x, y1 + y, x2 + x, y2 + y, n == 1 && gc->capStyle != CapNotLast, &dashOffset); x1 = x2; y1 = y2; } } static void fbZeroSegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg) { int dashOffset; int16_t x, y; Bool drawLast = gc->capStyle != CapNotLast; x = drawable->x; y = drawable->y; while (n--) { dashOffset = gc->dashOffset; fbSegment(drawable, gc, seg->x1 + x, seg->y1 + y, seg->x2 + x, seg->y2 + y, drawLast, &dashOffset); seg++; } } void fbFixCoordModePrevious(int n, DDXPointPtr pt) { int16_t x = pt->x; int16_t y = pt->y; while (--n) { pt++; x = (pt->x += x); y = (pt->y += y); } } void fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { void (*raster)(DrawablePtr, GCPtr, int mode, int n, DDXPointPtr pt); DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n", __FUNCTION__, n, gc->lineWidth, gc->fillStyle, gc->fillStyle == FillSolid, gc->lineStyle, gc->lineStyle == LineSolid, drawable->bitsPerPixel)); if (gc->lineWidth == 0) { raster = fbZeroLine; if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) { switch (drawable->bitsPerPixel) { case 8: raster = fbPolyline8; break; case 16: raster = fbPolyline16; break; case 32: raster = fbPolyline32; break; } } } else { if (gc->lineStyle != LineSolid) raster = miWideDash; else raster = miWideLine; } raster(drawable, gc, mode, n, pt); } void fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg) { void (*raster)(DrawablePtr drawable, GCPtr gc, int n, xSegment * seg); DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n", __FUNCTION__, n, gc->lineWidth, gc->fillStyle, gc->fillStyle == FillSolid, gc->lineStyle, gc->lineStyle == LineSolid, drawable->bitsPerPixel)); if (gc->lineWidth == 0) { raster = fbZeroSegment; if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) { switch (drawable->bitsPerPixel) { case 8: raster = fbPolySegment8; break; case 16: raster = fbPolySegment16; break; case 32: raster = fbPolySegment32; break; } } } else raster = miPolySegment; raster(drawable, gc, n, seg); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fblinebits.h000066400000000000000000000173751267532330400245410ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) static void POLYLINE(DrawablePtr drawable, GCPtr gc, int mode, int n_0, DDXPointPtr pt_0) { int xoff = drawable->x; int yoff = drawable->y; unsigned int bias = miGetZeroLineBias(drawable->pScreen); const BoxRec *clip = region_rects(gc->pCompositeClip); const BoxRec *const last_clip = clip + region_num_rects(gc->pCompositeClip); FbBits *dst; int dstStride; int dstBpp; int dstXoff, dstYoff; BITS *bits, *bitsBase; FbStride bitsStride; BITS xor = fb_gc(gc)->xor; BITS and = fb_gc(gc)->and; int e, e1, e3, len; int stepmajor, stepminor; int octant; if (mode == CoordModePrevious) fbFixCoordModePrevious(n_0, pt_0); fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); bitsBase = ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff); DBG(("%s: processing %ld clip boxes\n", __FUNCTION__, (long)(last_clip - clip))); do { INT32 *pt = (INT32 *)pt_0; int n = n_0; INT32 pt1, pt2; INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff); INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1); DBG(("%s: clip box=(%d, %d), (%d, %d)\n", __FUNCTION__, clip->x1, clip->y1, clip->x2, clip->y2)); pt1 = *pt++; n--; pt2 = *pt++; n--; for (;;) { if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) { int dashoffset = 0; fbSegment1(drawable, gc, clip, intToX(pt1) + xoff, intToY(pt1) + yoff, intToX(pt2) + xoff, intToY(pt2) + yoff, n == 0 && gc->capStyle != CapNotLast, &dashoffset); if (!n) goto next_clip; pt1 = pt2; pt2 = *pt++; n--; } else { bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1); for (;;) { CalcLineDeltas(intToX(pt1), intToY(pt1), intToX(pt2), intToY(pt2), len, e1, stepmajor, stepminor, 1, bitsStride, octant); if (len < e1) { e3 = len; len = e1; e1 = e3; e3 = stepminor; stepminor = stepmajor; stepmajor = e3; SetYMajorOctant(octant); } e = -len; e1 <<= 1; e3 = e << 1; FIXUP_ERROR(e, octant, bias); if (and == 0) { while (len--) { WRITE(bits, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } else { while (len--) { RROP(bits, and, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } if (!n) { if (gc->capStyle != CapNotLast && pt2 != *((INT32 *)pt_0)) { RROP(bits, and, xor); } goto next_clip; } pt1 = pt2; pt2 = *pt++; --n; if (isClipped(pt2, ul, lr)) break; } } } next_clip: (void)clip; } while (++clip != last_clip); } static void POLYSEGMENT(DrawablePtr drawable, GCPtr gc, int n_0, xSegment *seg_0) { int xoff = drawable->x; int yoff = drawable->y; unsigned int bias = miGetZeroLineBias(drawable->pScreen); const BoxRec *clip = region_rects(gc->pCompositeClip); const BoxRec *const last_clip = clip + region_num_rects(gc->pCompositeClip); FbBits *dst; int dstStride; int dstBpp; int dstXoff, dstYoff; BITS *bits, *bitsBase; FbStride bitsStride; FbBits xor = fb_gc(gc)->xor; FbBits and = fb_gc(gc)->and; int e, e1, e3, len; int stepmajor, stepminor; int octant; bool capNotLast = gc->capStyle == CapNotLast; fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); bitsBase = ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff); DBG(("%s: processing %ld clip boxes\n", __FUNCTION__, (long)(last_clip - clip))); do { INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff); INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1); uint64_t *pt = (uint64_t *)seg_0; int n = n_0; DBG(("%s: clip box=(%d, %d), (%d, %d)\n", __FUNCTION__, clip->x1, clip->y1, clip->x2, clip->y2)); while (n--) { union { int32_t pt32[2]; uint64_t pt64; } u; u.pt64 = *pt++; if (isClipped(u.pt32[0], ul, lr) | isClipped(u.pt32[1], ul, lr)) { int dashoffset = 0; fbSegment1(drawable, gc, clip, intToX(u.pt32[0]) + xoff, intToY(u.pt32[0]) + yoff, intToX(u.pt32[1]) + xoff, intToY(u.pt32[1]) + yoff, !capNotLast, &dashoffset); } else { CalcLineDeltas(intToX(u.pt32[0]), intToY(u.pt32[0]), intToX(u.pt32[1]), intToY(u.pt32[1]), len, e1, stepmajor, stepminor, 1, bitsStride, octant); if (e1 == 0 && len > 3) { int x1, x2; FbBits *dstLine; int dstX, width; FbBits startmask, endmask; int nmiddle; if (stepmajor < 0) { x1 = intToX(u.pt32[1]); x2 = intToX(u.pt32[0]) + 1; if (capNotLast) x1++; } else { x1 = intToX(u.pt32[0]); x2 = intToX(u.pt32[1]); if (!capNotLast) x2++; } dstX = (x1 + xoff + dstXoff) * (sizeof(BITS) * 8); width = (x2 - x1) * (sizeof(BITS) * 8); dstLine = dst + (intToY(u.pt32[0]) + yoff + dstYoff) * dstStride; dstLine += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBits(dstX, width, startmask, nmiddle, endmask); if (startmask) { WRITE(dstLine, FbDoMaskRRop(READ(dstLine), and, xor, startmask)); dstLine++; } if (!and) while (nmiddle--) WRITE(dstLine++, xor); else while (nmiddle--) { WRITE(dstLine, FbDoRRop(READ(dstLine), and, xor)); dstLine++; } if (endmask) WRITE(dstLine, FbDoMaskRRop(READ(dstLine), and, xor, endmask)); } else { bits = bitsBase + intToY(u.pt32[0]) * bitsStride + intToX(u.pt32[0]); if (len < e1) { e3 = len; len = e1; e1 = e3; e3 = stepminor; stepminor = stepmajor; stepmajor = e3; SetYMajorOctant(octant); } e = -len; e1 <<= 1; e3 = e << 1; FIXUP_ERROR(e, octant, bias); if (!capNotLast) len++; if (and == 0) { while (len--) { WRITE(bits, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } else { while (len--) { RROP(bits, and, xor); bits += stepmajor; e += e1; if (e >= 0) { bits += stepminor; e += e3; } } } } } } } while (++clip != last_clip); } #undef RROP #undef isClipped xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbpict.c000066400000000000000000000224071267532330400236520ustar00rootroot00000000000000/* * Copyright © 2000 SuSE, Inc. * Copyright © 2007 Red Hat, Inc. * Copyright © 2012 Intel Corporation * * 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, and that the name of SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, SuSE, Inc. */ #include #include "fb.h" #include "fbpict.h" static void SourceValidateOnePicture(PicturePtr picture) { DrawablePtr drawable = picture->pDrawable; if (!drawable) return; SourceValidate(drawable, 0, 0, drawable->width, drawable->height, picture->subWindowMode); } static void fbCompositeSourceValidate(PicturePtr picture) { SourceValidateOnePicture(picture); if (picture->alphaMap) SourceValidateOnePicture(picture->alphaMap); } void fbComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { pixman_image_t *src, *mask, *dest; int src_xoff, src_yoff; int msk_xoff, msk_yoff; int dst_xoff, dst_yoff; fbCompositeSourceValidate(pSrc); if (pMask) fbCompositeSourceValidate(pMask); src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff); mask = image_from_pict(pMask, FALSE, &msk_xoff, &msk_yoff); dest = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff); if (src && dest && !(pMask && !mask)) { pixman_image_composite(op, src, mask, dest, xSrc + src_xoff, ySrc + src_yoff, xMask + msk_xoff, yMask + msk_yoff, xDst + dst_xoff, yDst + dst_yoff, width, height); } free_pixman_pict(pSrc, src); free_pixman_pict(pMask, mask); free_pixman_pict(pDst, dest); } static pixman_image_t * create_solid_fill_image(PicturePtr pict) { PictSolidFill *solid = &pict->pSourcePict->solidFill; pixman_color_t color; CARD32 a, r, g, b; a = (solid->color & 0xff000000) >> 24; r = (solid->color & 0x00ff0000) >> 16; g = (solid->color & 0x0000ff00) >> 8; b = (solid->color & 0x000000ff) >> 0; color.alpha = (a << 8) | a; color.red = (r << 8) | r; color.green = (g << 8) | g; color.blue = (b << 8) | b; return pixman_image_create_solid_fill(&color); } static pixman_image_t * create_linear_gradient_image(PictGradient * gradient) { PictLinearGradient *linear = (PictLinearGradient *) gradient; pixman_point_fixed_t p1; pixman_point_fixed_t p2; p1.x = linear->p1.x; p1.y = linear->p1.y; p2.x = linear->p2.x; p2.y = linear->p2.y; return pixman_image_create_linear_gradient(&p1, &p2, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static pixman_image_t * create_radial_gradient_image(PictGradient * gradient) { PictRadialGradient *radial = (PictRadialGradient *) gradient; pixman_point_fixed_t c1; pixman_point_fixed_t c2; c1.x = radial->c1.x; c1.y = radial->c1.y; c2.x = radial->c2.x; c2.y = radial->c2.y; return pixman_image_create_radial_gradient(&c1, &c2, radial->c1.radius, radial->c2.radius, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static pixman_image_t * create_conical_gradient_image(PictGradient * gradient) { PictConicalGradient *conical = (PictConicalGradient *) gradient; pixman_point_fixed_t center; center.x = conical->center.x; center.y = conical->center.y; return pixman_image_create_conical_gradient(¢er, conical->angle, (pixman_gradient_stop_t *) gradient->stops, gradient->nstops); } static inline bool picture_has_clip(PicturePtr p) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,16,99,1,0) return p->clientClip; #else return p->clientClipType != CT_NONE; #endif } static pixman_image_t * create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff) { PixmapPtr pixmap; FbBits *bits; FbStride stride; int bpp; pixman_image_t *image; fbGetDrawablePixmap(pict->pDrawable, pixmap, *xoff, *yoff); fbGetPixmapBitsData(pixmap, bits, stride, bpp); image = pixman_image_create_bits((pixman_format_code_t) pict->format, pixmap->drawable.width, pixmap->drawable.height, (uint32_t *) bits, stride * sizeof(FbStride)); if (!image) return NULL; /* pCompositeClip is undefined for source pictures, so * only set the clip region for pictures with drawables */ if (has_clip) { if (picture_has_clip(pict)) pixman_image_set_has_client_clip(image, TRUE); if (*xoff || *yoff) pixman_region_translate(pict->pCompositeClip, *xoff, *yoff); pixman_image_set_clip_region(image, pict->pCompositeClip); if (*xoff || *yoff) pixman_region_translate(pict->pCompositeClip, -*xoff, -*yoff); } /* Indexed table */ if (pict->pFormat->index.devPrivate) pixman_image_set_indexed(image, pict->pFormat->index.devPrivate); /* Add in drawable origin to position within the image */ *xoff += pict->pDrawable->x; *yoff += pict->pDrawable->y; return image; } static pixman_image_t *image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map); static void set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map) { pixman_repeat_t repeat; pixman_filter_t filter; if (pict->transform) { /* For source images, adjust the transform to account * for the drawable offset within the pixman image, * then set the offset to 0 as it will be used * to compute positions within the transformed image. */ if (!has_clip) { struct pixman_transform adjusted; adjusted = *pict->transform; pixman_transform_translate(&adjusted, NULL, pixman_int_to_fixed(*xoff), pixman_int_to_fixed(*yoff)); pixman_image_set_transform(image, &adjusted); *xoff = 0; *yoff = 0; } else pixman_image_set_transform(image, pict->transform); } switch (pict->repeatType) { default: case RepeatNone: repeat = PIXMAN_REPEAT_NONE; break; case RepeatPad: repeat = PIXMAN_REPEAT_PAD; break; case RepeatNormal: repeat = PIXMAN_REPEAT_NORMAL; break; case RepeatReflect: repeat = PIXMAN_REPEAT_REFLECT; break; } pixman_image_set_repeat(image, repeat); /* Fetch alpha map unless 'pict' is being used * as the alpha map for this operation */ if (pict->alphaMap && !is_alpha_map) { int alpha_xoff, alpha_yoff; pixman_image_t *alpha_map = image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE); pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y); free_pixman_pict(pict->alphaMap, alpha_map); } pixman_image_set_component_alpha(image, pict->componentAlpha); switch (pict->filter) { default: case PictFilterNearest: case PictFilterFast: filter = PIXMAN_FILTER_NEAREST; break; case PictFilterBilinear: case PictFilterGood: filter = PIXMAN_FILTER_BILINEAR; break; case PictFilterConvolution: filter = PIXMAN_FILTER_CONVOLUTION; break; } pixman_image_set_filter(image, filter, (pixman_fixed_t *) pict->filter_params, pict->filter_nparams); pixman_image_set_source_clipping(image, TRUE); } static pixman_image_t * image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map) { pixman_image_t *image = NULL; if (!pict) return NULL; if (pict->pDrawable) { image = create_bits_picture(pict, has_clip, xoff, yoff); } else if (pict->pSourcePict) { SourcePict *sp = pict->pSourcePict; if (sp->type == SourcePictTypeSolidFill) { image = create_solid_fill_image(pict); } else { PictGradient *gradient = &pict->pSourcePict->gradient; if (sp->type == SourcePictTypeLinear) image = create_linear_gradient_image(gradient); else if (sp->type == SourcePictTypeRadial) image = create_radial_gradient_image(gradient); else if (sp->type == SourcePictTypeConical) image = create_conical_gradient_image(gradient); } *xoff = *yoff = 0; } if (image) set_image_properties(image, pict, has_clip, xoff, yoff, is_alpha_map); return image; } pixman_image_t * image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff) { return image_from_pict_internal(pict, has_clip, xoff, yoff, FALSE); } void free_pixman_pict(PicturePtr pict, pixman_image_t * image) { if (image) pixman_image_unref(image); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbpict.h000066400000000000000000000033471267532330400236610ustar00rootroot00000000000000/* * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef FBPICT_H #define FBPICT_H #include #include #include "sfb.h" extern void fbComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); extern pixman_image_t *image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff); extern void free_pixman_pict(PicturePtr, pixman_image_t *); #endif /* FBPICT_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbpoint.c000066400000000000000000000071111267532330400240370ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include #define DOTS fbDots8 #define DOTS__SIMPLE fbDots8__simple #define BITS BYTE #include "fbpointbits.h" #undef BITS #undef DOTS__SIMPLE #undef DOTS #define DOTS fbDots16 #define DOTS__SIMPLE fbDots16__simple #define BITS CARD16 #include "fbpointbits.h" #undef BITS #undef DOTS__SIMPLE #undef DOTS #define DOTS fbDots32 #define DOTS__SIMPLE fbDots32__simple #define BITS CARD32 #include "fbpointbits.h" #undef BITS #undef DOTS__SIMPLE #undef DOTS static void fbDots(FbBits *dstOrig, FbStride dstStride, int dstBpp, RegionPtr clip, xPoint *pts, int n, int xorg, int yorg, int xoff, int yoff, FbBits andOrig, FbBits xorOrig) { FbStip *dst = (FbStip *) dstOrig; FbStip and = andOrig; FbStip xor = xorOrig; while (n--) { int x = pts->x + xorg; int y = pts->y + yorg; pts++; if (RegionContainsPoint(clip, x, y, NULL)) { FbStip mask; FbStip *d; x = (x + xoff) * dstBpp; d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT); x &= FB_STIP_MASK; mask = FbStipMask(x, dstBpp); WRITE(d, FbDoMaskRRop(READ(d), and, xor, mask)); } } } void fbPolyPoint(DrawablePtr drawable, GCPtr gc, int mode, int n, xPoint *pt, unsigned flags) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; void (*dots)(FbBits *dst, FbStride dstStride, int dstBpp, RegionPtr clip, xPoint *pts, int n, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor); DBG(("%s x %d, clip=[(%d, %d), (%d, %d)]x%d\n", __FUNCTION__, n, gc->pCompositeClip->extents.x1, gc->pCompositeClip->extents.y1, gc->pCompositeClip->extents.x2, gc->pCompositeClip->extents.y2, region_num_rects(gc->pCompositeClip))); if (mode == CoordModePrevious) fbFixCoordModePrevious(n, pt); fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); dots = fbDots; if ((flags & 2) == 0 && fb_gc(gc)->and == 0) { switch (dstBpp) { case 8: dots = fbDots8__simple; break; case 16: dots = fbDots16__simple; break; case 32: dots = fbDots32__simple; break; } } else { switch (dstBpp) { case 8: dots = fbDots8; break; case 16: dots = fbDots16; break; case 32: dots = fbDots32; break; } } dots(dst, dstStride, dstBpp, gc->pCompositeClip, pt, n, drawable->x, drawable->y, dstXoff, dstYoff, fb_gc(gc)->and, fb_gc(gc)->xor); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbpointbits.h000066400000000000000000000104171267532330400247310ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) static void DOTS(FbBits * dst, FbStride dstStride, int dstBpp, RegionPtr region, xPoint * ptsOrig, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor) { uint32_t *pts = (uint32_t *) ptsOrig; BITS *bits = (BITS *) dst; BITS bxor = (BITS) xor; BITS band = (BITS) and; FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); if (region->data == NULL) { INT32 ul = coordToInt(region->extents.x1 - xorg, region->extents.y1 - yorg); INT32 lr = coordToInt(region->extents.x2 - xorg - 1, region->extents.y2 - yorg - 1); bits += bitsStride * (yorg + yoff) + (xorg + xoff); if (and == 0) { while (npt >= 2) { union { uint32_t pt32[2]; uint64_t pt64; } pt; pt.pt64 = *(uint64_t *)pts; if (!isClipped(pt.pt32[0], ul, lr)) { BITS *point = bits + intToY(pt.pt32[0]) * bitsStride + intToX(pt.pt32[0]); WRITE(point, bxor); } if (!isClipped(pt.pt32[1], ul, lr)) { BITS *point = bits + intToY(pt.pt32[1]) * bitsStride + intToX(pt.pt32[1]); WRITE(point, bxor); } pts += 2; npt -= 2; } if (npt) { uint32_t pt = *pts; if (!isClipped(pt, ul, lr)) { BITS *point = bits + intToY(pt) * bitsStride + intToX(pt); WRITE(point, bxor); } } } else { while (npt--) { uint32_t pt = *pts++; if (!isClipped(pt, ul, lr)) { BITS *point = bits + intToY(pt) * bitsStride + intToX(pt); RROP(point, band, bxor); } } } } else { bits += bitsStride * yoff + xoff; if (and == 0) { while (npt--) { uint32_t pt = *pts++; int x = intToX(pt) + xorg; int y = intToY(pt) + yorg; if (RegionContainsPoint(region, x, y, NULL)) { BITS *point = bits + y * bitsStride + x; WRITE(point, bxor); } } } else { while (npt--) { uint32_t pt = *pts++; int x = intToX(pt) + xorg; int y = intToY(pt) + yorg; if (RegionContainsPoint(region, x, y, NULL)) { BITS *point = bits + y * bitsStride + x; RROP(point, band, bxor); } } } } } static void DOTS__SIMPLE(FbBits * dst, FbStride dstStride, int dstBpp, RegionPtr region, xPoint * ptsOrig, int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor) { uint32_t *pts = (uint32_t *) ptsOrig; BITS *bits = (BITS *) dst; BITS bxor = (BITS) xor; unsigned bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS)); bits += bitsStride * (yorg + yoff) + (xorg + xoff); #if __x86_64__ while (npt >= 2) { union { uint32_t pt32[2]; uint64_t pt64; } pt; pt.pt64 = *(uint64_t *)pts; bits[intToY(pt.pt32[0]) * bitsStride + intToX(pt.pt32[0])] = bxor; bits[intToY(pt.pt32[1]) * bitsStride + intToX(pt.pt32[1])] = bxor; pts += 2; npt -= 2; } if (npt) { uint32_t pt = *pts; bits[intToY(pt) * bitsStride + intToX(pt)] = bxor; } #else while (npt--) { uint32_t pt = *pts++; bits[intToY(pt) * bitsStride + intToX(pt)] = bxor; } #endif } #undef RROP #undef isClipped xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbpush.c000066400000000000000000000107371267532330400236750ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include "fbclip.h" static void fbPushPattern(DrawablePtr drawable, GCPtr gc, FbStip *src, FbStride srcStride, int srcX, int x, int y, int width, int height) { FbStip *s, bitsMask, bitsMask0, bits; int xspan; int w; int lenspan; src += srcX >> FB_STIP_SHIFT; srcX &= FB_STIP_MASK; bitsMask0 = FbStipMask(srcX, 1); while (height--) { bitsMask = bitsMask0; w = width; s = src; src += srcStride; bits = READ(s++); xspan = x; while (w) { if (bits & bitsMask) { lenspan = 0; do { if (++lenspan == w) break; bitsMask = FbStipRight(bitsMask, 1); if (!bitsMask) { bits = READ(s++); bitsMask = FbBitsMask(0, 1); } } while (bits & bitsMask); fbFill(drawable, gc, xspan, y, lenspan, 1); xspan += lenspan; w -= lenspan; } else { do { xspan++; if (!--w) break; bitsMask = FbStipRight(bitsMask, 1); if (!bitsMask) { bits = READ(s++); bitsMask = FbBitsMask(0, 1); } } while (!(bits & bitsMask)); } } y++; } } static void fbPushFill(DrawablePtr drawable, GCPtr gc, FbStip *src, FbStride srcStride, int srcX, int x, int y, int width, int height) { FbGCPrivPtr pgc = fb_gc(gc); if (gc->fillStyle == FillSolid) { FbBits *dst; FbStride dstStride; int dstBpp; int dstXoff, dstYoff; int dstX; int dstWidth; fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); dst = dst + (y + dstYoff) * dstStride; dstX = (x + dstXoff) * dstBpp; dstWidth = width * dstBpp; if (dstBpp == 1) { fbBltStip(src, srcStride, srcX, (FbStip *)dst, dstStride, dstX, dstWidth, height, FbStipple1Rop(gc->alu, gc->fgPixel), pgc->pm, dstBpp); } else { fbBltOne(src, srcStride, srcX, dst, dstStride, dstX, dstBpp, dstWidth, height, pgc->and, pgc->xor, fbAnd(GXnoop, (FbBits) 0, FB_ALLONES), fbXor(GXnoop, (FbBits) 0, FB_ALLONES)); } } else fbPushPattern(drawable, gc, src, srcStride, srcX, x, y, width, height); } struct fbPushImage { FbStip *src; FbStride stride; int x0, y0; }; inline static void _fbPushImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbPushImage *data = _data; fbPushFill(drawable, gc, data->src + (b->y1 - data->y0) * data->stride, data->stride, b->x1 - data->x0, b->x1, b->y1, b->x2 - b->x1, b->y2 - b->y1); } void fbPushImage(DrawablePtr drawable, GCPtr gc, FbStip *src, FbStride stride, int dx, int x, int y, int width, int height) { struct fbPushImage data; BoxRec box; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, width, height)); data.src = src; data.stride = stride; data.y0 = y; data.x0 = x - dx; box.x1 = x; box.y1 = y; box.x2 = x + width; box.y2 = y + height; fbDrawableRun(drawable, gc, &box, _fbPushImage, &data); } void fbPushPixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, int dx, int dy, int xOrg, int yOrg) { FbStip *stip; FbStride stipStride; int stipBpp; _X_UNUSED int stipXoff, stipYoff; DBG(("%s bitmap=%x%d\n", __FUNCTION__, bitmap->drawable.width, bitmap->drawable.height)); fbGetStipDrawable(&bitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); fbPushImage(drawable, gc, stip, stipStride, 0, xOrg, yOrg, dx, dy); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbrop.h000066400000000000000000000077061267532330400235250ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef _FBROP_H_ #define _FBROP_H_ #define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \ (((alu) >> 1 & 5) == ((alu) & 5))) #define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0) /* AND has higher precedence than XOR */ #define FbDoMergeRop(src, dst) \ (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2)) #define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2) #define FbDoMaskMergeRop(src, dst, mask) \ (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask))) #define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \ FbBits __xor = ((src) & _ca2) ^ _cx2; \ FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \ } #define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \ FbBits __xor = ((src) & _ca2) ^ _cx2; \ FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \ } #define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor)) #define FbDoMaskRRop(dst, and, xor, mask) \ (((dst) & ((and) | ~(mask))) ^ (xor & mask)) /* * Take a single bit (0 or 1) and generate a full mask */ #define fbFillFromBit(b,t) (~((t) ((b) & 1)-1)) #define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \ (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm)) #define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \ (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \ ~(pm)) #define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits) #define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits) #define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip) #define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip) /* * Stippling operations; */ extern const FbBits *const fbStippleTable[]; #define FbStippleRRop(dst, b, fa, fx, ba, bx) \ (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b) #define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \ (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b)) #define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ } #define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \ FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \ } #define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b))) /* * Compute rop for using tile code for 1-bit dest stipples; modifies * existing rop to flip depending on pixel values */ #define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3) #define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \ (FbStipple1RopPick(alu,bg) << 2)) #define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4) #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbseg.c000066400000000000000000000307351267532330400234740ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include #include "fb.h" #include "fbclip.h" #include #include #define FbDashDeclare \ unsigned char *__dash, *__firstDash, *__lastDash #define FbDashInit(gc,pgc,dashOffset,dashlen,even) { \ (even) = TRUE; \ __firstDash = (gc)->dash; \ __lastDash = __firstDash + (gc)->numInDashList; \ (dashOffset) %= (pgc)->dashLength; \ \ __dash = __firstDash; \ while ((dashOffset) >= ((dashlen) = *__dash)) { \ (dashOffset) -= (dashlen); \ (even) = 1-(even); \ if (++__dash == __lastDash) \ __dash = __firstDash; \ } \ (dashlen) -= (dashOffset); \ } #define FbDashNext(dashlen) { \ if (++__dash == __lastDash) \ __dash = __firstDash; \ (dashlen) = *__dash; \ } /* as numInDashList is always even, this case can skip a test */ #define FbDashNextEven(dashlen) { \ (dashlen) = *++__dash; \ } #define FbDashNextOdd(dashlen) FbDashNext(dashlen) #define FbDashStep(dashlen,even) { \ if (!--(dashlen)) { \ FbDashNext(dashlen); \ (even) = 1-(even); \ } \ } #define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ ((dir < 0) ? FbStipLeft(mask,bpp) : \ FbStipRight(mask,bpp))) typedef void FbBres(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x, int y, int e, int e1, int e3, int len); #define BRESSOLID fbBresSolid8 #define BRESSOLIDR fbBresSolidR8 #define BRESDASH fbBresDash8 #define BITS BYTE #define BITS2 CARD16 #define BITS4 CARD32 #include "fbsegbits.h" #undef BRESSOLID #undef BRESSOLIDR #undef BRESDASH #undef BITS #undef BITS2 #undef BITS4 #define BRESSOLID fbBresSolid16 #define BRESSOLIDR fbBresSolidR16 #define BRESDASH fbBresDash16 #define BITS CARD16 #define BITS2 CARD32 #include "fbsegbits.h" #undef BRESSOLID #undef BRESSOLIDR #undef BRESDASH #undef BITS #undef BITS2 #define BRESSOLID fbBresSolid32 #define BRESSOLIDR fbBresSolidR32 #define BRESDASH fbBresDash32 #define BITS CARD32 #include "fbsegbits.h" #undef BRESSOLID #undef BRESSOLIDR #undef BRESDASH #undef BITS static void fbBresSolid(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbStip *dst; FbStride stride; int bpp; int dx, dy; FbGCPrivPtr pgc = fb_gc(gc); FbStip and = (FbStip) pgc->and; FbStip xor = (FbStip) pgc->xor; FbStip mask, mask0; FbStip bits; fbGetStipDrawable(drawable, dst, stride, bpp, dx, dy); dst += ((y1 + dy) * stride); x1 = (x1 + dx) * bpp; dst += x1 >> FB_STIP_SHIFT; x1 &= FB_STIP_MASK; mask0 = FbStipMask(0, bpp); mask = FbStipRight(mask0, x1); if (sdx < 0) mask0 = FbStipRight(mask0, FB_STIP_UNIT - bpp); if (sdy < 0) stride = -stride; if (axis == X_AXIS) { bits = 0; while (len--) { bits |= mask; mask = fbBresShiftMask(mask, sdx, bpp); if (!mask) { WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); bits = 0; dst += sdx; mask = mask0; } e += e1; if (e >= 0) { WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); bits = 0; dst += stride; e += e3; } } if (bits) WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits)); } else { while (len--) { WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); dst += stride; e += e1; if (e >= 0) { e += e3; mask = fbBresShiftMask(mask, sdx, bpp); if (!mask) { dst += sdx; mask = mask0; } } } } } static void fbBresDash(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbStip *dst; FbStride stride; int bpp; int dx, dy; FbGCPrivPtr pgc = fb_gc(gc); FbStip and = (FbStip) pgc->and; FbStip xor = (FbStip) pgc->xor; FbStip bgand = (FbStip) pgc->bgand; FbStip bgxor = (FbStip) pgc->bgxor; FbStip mask, mask0; FbDashDeclare; int dashlen; bool even; bool doOdd; fbGetStipDrawable(drawable, dst, stride, bpp, dx, dy); doOdd = gc->lineStyle == LineDoubleDash; FbDashInit(gc, pgc, dashOffset, dashlen, even); dst += ((y1 + dy) * stride); x1 = (x1 + dx) * bpp; dst += x1 >> FB_STIP_SHIFT; x1 &= FB_STIP_MASK; mask0 = FbStipMask(0, bpp); mask = FbStipRight(mask0, x1); if (sdx < 0) mask0 = FbStipRight(mask0, FB_STIP_UNIT - bpp); if (sdy < 0) stride = -stride; while (len--) { if (even) WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask)); else if (doOdd) WRITE(dst, FbDoMaskRRop(READ(dst), bgand, bgxor, mask)); if (axis == X_AXIS) { mask = fbBresShiftMask(mask, sdx, bpp); if (!mask) { dst += sdx; mask = mask0; } e += e1; if (e >= 0) { dst += stride; e += e3; } } else { dst += stride; e += e1; if (e >= 0) { e += e3; mask = fbBresShiftMask(mask, sdx, bpp); if (!mask) { dst += sdx; mask = mask0; } } } FbDashStep(dashlen, even); } } static void fbBresFill(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { while (len--) { fbFill(drawable, gc, x1, y1, 1, 1); if (axis == X_AXIS) { x1 += sdx; e += e1; if (e >= 0) { e += e3; y1 += sdy; } } else { y1 += sdy; e += e1; if (e >= 0) { e += e3; x1 += sdx; } } } } static void fbSetFg(DrawablePtr drawable, GCPtr gc, Pixel fg) { if (fg != gc->fgPixel) { gc->fgPixel = fg; fbValidateGC(gc, GCForeground, drawable); } } static void fbBresFillDash(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbGCPrivPtr pgc = fb_gc(gc); FbDashDeclare; int dashlen; bool even; bool doOdd; bool doBg; Pixel fg, bg; fg = gc->fgPixel; bg = gc->bgPixel; /* whether to fill the odd dashes */ doOdd = gc->lineStyle == LineDoubleDash; /* whether to switch fg to bg when filling odd dashes */ doBg = doOdd && (gc->fillStyle == FillSolid || gc->fillStyle == FillStippled); /* compute current dash position */ FbDashInit(gc, pgc, dashOffset, dashlen, even); while (len--) { if (even || doOdd) { if (doBg) { if (even) fbSetFg(drawable, gc, fg); else fbSetFg(drawable, gc, bg); } fbFill(drawable, gc, x1, y1, 1, 1); } if (axis == X_AXIS) { x1 += sdx; e += e1; if (e >= 0) { e += e3; y1 += sdy; } } else { y1 += sdy; e += e1; if (e >= 0) { e += e3; x1 += sdx; } } FbDashStep(dashlen, even); } if (doBg) fbSetFg(drawable, gc, fg); } static FbBres * fbSelectBres(DrawablePtr drawable, GCPtr gc) { FbGCPrivPtr pgc = fb_gc(gc); int bpp = drawable->bitsPerPixel; FbBres *bres; DBG(("%s: line=%d, fill=%d, and=%lx, bgand=%lx\n", __FUNCTION__, gc->lineStyle, gc->fillStyle, (long)pgc->and, (long)pgc->bgand)); assert(gc->lineWidth == 0); if (gc->lineStyle == LineSolid) { bres = fbBresFill; if (gc->fillStyle == FillSolid) { bres = fbBresSolid; if (pgc->and == 0) { switch (bpp) { case 8: bres = fbBresSolid8; break; case 16: bres = fbBresSolid16; break; case 32: bres = fbBresSolid32; break; } } else { switch (bpp) { case 8: bres = fbBresSolidR8; break; case 16: bres = fbBresSolidR16; break; case 32: bres = fbBresSolidR32; break; } } } } else { bres = fbBresFillDash; if (gc->fillStyle == FillSolid) { bres = fbBresDash; if (pgc->and == 0 && (gc->lineStyle == LineOnOffDash || pgc->bgand == 0)) { switch (bpp) { case 8: bres = fbBresDash8; break; case 16: bres = fbBresDash16; break; case 32: bres = fbBresDash32; break; } } } } return bres; } struct fbSegment { FbBres *bres; bool drawLast; int *dashOffset; int x1, y1, x2, y2; }; static void _fbSegment(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbSegment *data = _data; const unsigned int bias = miGetZeroLineBias(drawable->pScreen); int adx, ady; /* abs values of dx and dy */ int sdx, sdy; /* sign of dx and dy */ int e, e1, e2, e3; /* bresenham error and increments */ int len, axis, octant; int dashoff, doff; unsigned int oc1, oc2; DBG(("%s box=(%d, %d),(%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2, b->y2)); CalcLineDeltas(data->x1, data->y1, data->x2, data->y2, adx, ady, sdx, sdy, 1, 1, octant); if (adx > ady) { axis = X_AXIS; e1 = ady << 1; e2 = e1 - (adx << 1); e = e1 - adx; len = adx; } else { axis = Y_AXIS; e1 = adx << 1; e2 = e1 - (ady << 1); e = e1 - ady; SetYMajorOctant(octant); len = ady; } FIXUP_ERROR(e, octant, bias); /* * Adjust error terms to compare against zero */ e3 = e2 - e1; e = e - e1; if (data->drawLast) len++; dashoff = *data->dashOffset; *data->dashOffset = dashoff + len; oc1 = 0; oc2 = 0; OUTCODES(oc1, data->x1, data->y1, b); OUTCODES(oc2, data->x2, data->y2, b); if ((oc1 | oc2) == 0) { data->bres(drawable, gc, dashoff, sdx, sdy, axis, data->x1, data->y1, e, e1, e3, len); } else if (oc1 & oc2) { } else { int new_x1 = data->x1, new_y1 = data->y1; int new_x2 = data->x2, new_y2 = data->y2; int clip1 = 0, clip2 = 0; int clipdx, clipdy; int err; if (miZeroClipLine(b->x1, b->y1, b->x2-1, b->y2-1, &new_x1, &new_y1, &new_x2, &new_y2, adx, ady, &clip1, &clip2, octant, bias, oc1, oc2) == -1) return; if (axis == X_AXIS) len = abs(new_x2 - new_x1); else len = abs(new_y2 - new_y1); if (clip2 != 0 || data->drawLast) len++; if (len) { /* unwind bresenham error term to first point */ doff = dashoff; err = e; if (clip1) { clipdx = abs(new_x1 - data->x1); clipdy = abs(new_y1 - data->y1); if (axis == X_AXIS) { doff += clipdx; err += e3 * clipdy + e1 * clipdx; } else { doff += clipdy; err += e3 * clipdx + e1 * clipdy; } } data->bres(drawable, gc, doff, sdx, sdy, axis, new_x1, new_y1, err, e1, e3, len); } } } void fbSegment(DrawablePtr drawable, GCPtr gc, int x1, int y1, int x2, int y2, bool drawLast, int *dashOffset) { struct fbSegment data; BoxRec box; DBG(("%s (%d, %d), (%d, %d), drawLast?=%d\n", __FUNCTION__, x1, y1, x2, y2, drawLast)); /* simple overestimate of line extents for clipping */ box.x1 = x1 - 1; box.y1 = y1 - 1; box.x2 = x2 + 1; box.y2 = y2 + 1; data.x1 = x1; data.y1 = y1; data.x2 = x2; data.y2 = y2; data.dashOffset = dashOffset; data.drawLast = drawLast; data.bres = fbSelectBres(drawable, gc); fbDrawableRunUnclipped(drawable, gc, &box, _fbSegment, &data); } void fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, int x1, int y1, int x2, int y2, bool drawLast, int *dashOffset) { struct fbSegment data; DBG(("%s (%d, %d), (%d, %d), drawLast?=%d\n", __FUNCTION__, x1, y1, x2, y2, drawLast)); data.x1 = x1; data.y1 = y1; data.x2 = x2; data.y2 = y2; data.dashOffset = dashOffset; data.drawLast = drawLast; data.bres = fbSelectBres(drawable, gc); _fbSegment(drawable, gc, b, &data); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbsegbits.h000066400000000000000000000111301267532330400243470ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000) #define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x))) static void BRESSOLID(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbBits *dst; FbStride stride; int bpp, dx, dy; BITS *bits; FbStride major, minor; BITS xor = fb_gc(gc)->xor; fbGetDrawable(drawable, dst, stride, bpp, dx, dy); bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx); stride = stride * (sizeof(FbBits) / sizeof(BITS)); if (sdy < 0) stride = -stride; if (axis == X_AXIS) { major = sdx; minor = stride; } else { major = stride; minor = sdx; } while (len--) { WRITE(bits, xor); bits += major; e += e1; if (e >= 0) { bits += minor; e += e3; } } } static void BRESSOLIDR(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbBits *dst; FbStride stride; int bpp, dx, dy; BITS *bits; FbStride major, minor; BITS and = fb_gc(gc)->and; BITS xor = fb_gc(gc)->xor; fbGetDrawable(drawable, dst, stride, bpp, dx, dy); bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx); stride = stride * (sizeof(FbBits) / sizeof(BITS)); if (sdy < 0) stride = -stride; if (axis == X_AXIS) { major = sdx; minor = stride; } else { major = stride; minor = sdx; } while (len--) { RROP(bits, and, xor); bits += major; e += e1; if (e >= 0) { bits += minor; e += e3; } } } static void BRESDASH(DrawablePtr drawable, GCPtr gc, int dashOffset, int sdx, int sdy, int axis, int x1, int y1, int e, int e1, int e3, int len) { FbBits *dst; FbStride stride; int bpp, dx, dy; BITS *bits; FbStride major, minor; FbDashDeclare; int dashlen; bool even; bool doOdd = gc->lineStyle == LineDoubleDash; BITS xorfg = fb_gc(gc)->xor; BITS xorbg = fb_gc(gc)->bgxor; fbGetDrawable(drawable, dst, stride, bpp, dx, dy); FbDashInit(gc, fb_gc(gc), dashOffset, dashlen, even); bits = ((BITS *) (dst + ((y1 + dy) * stride))) + (x1 + dx); stride = stride * (sizeof(FbBits) / sizeof(BITS)); if (sdy < 0) stride = -stride; if (axis == X_AXIS) { major = sdx; minor = stride; } else { major = stride; minor = sdx; } if (dashlen >= len) dashlen = len; if (doOdd) { if (!even) goto doubleOdd; for (;;) { len -= dashlen; while (dashlen--) { WRITE(bits, xorfg); bits += major; if ((e += e1) >= 0) { e += e3; bits += minor; } } if (!len) break; FbDashNextEven(dashlen); if (dashlen >= len) dashlen = len; doubleOdd: len -= dashlen; while (dashlen--) { WRITE(bits, xorbg); bits += major; if ((e += e1) >= 0) { e += e3; bits += minor; } } if (!len) break; FbDashNextOdd(dashlen); if (dashlen >= len) dashlen = len; } } else { if (!even) goto onOffOdd; for (;;) { len -= dashlen; while (dashlen--) { WRITE(bits, xorfg); bits += major; if ((e += e1) >= 0) { e += e3; bits += minor; } } if (!len) break; FbDashNextEven(dashlen); if (dashlen >= len) dashlen = len; onOffOdd: len -= dashlen; while (dashlen--) { bits += major; if ((e += e1) >= 0) { e += e3; bits += minor; } } if (!len) break; FbDashNextOdd(dashlen); if (dashlen >= len) dashlen = len; } } } #undef RROP #undef isClipped xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbspan.c000066400000000000000000000071441267532330400236550ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" #include "fbclip.h" inline static void fbFillSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *data) { DBG(("%s (%d,%d)+%d\n", __FUNCTION__, b->x1, b->y1, b->x2-b->x1)); fbFill(drawable, gc, b->x1, b->y1, b->x2 - b->x1, 1); } void fbFillSpans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int fSorted) { DBG(("%s x %d\n", __FUNCTION__, n)); while (n--) { BoxRec box; *(DDXPointPtr)&box = *pt++; box.x2 = box.x1 + *width++; box.y2 = box.y1 + 1; /* XXX fSorted */ fbDrawableRun(drawable, gc, &box, fbFillSpan, NULL); } } struct fbSetSpan { char *src; DDXPointRec pt; FbStride stride; FbBits *dst; int dx, dy; }; inline static void fbSetSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) { struct fbSetSpan *data = _data; int xoff, bpp; xoff = (int) (((long)data->src) & (FB_MASK >> 3)); bpp = drawable->bitsPerPixel; fbBlt((FbBits *)(data->src - xoff), 0, (b->x1 - data->pt.x) * bpp + (xoff << 3), data->dst + (b->y1 + data->dy) * data->stride, data->stride, (b->x1 + data->dx) * bpp, (b->x2 - b->x1) * bpp, 1, gc->alu, fb_gc(gc)->pm, bpp, FALSE, FALSE); } void fbSetSpans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr pt, int *width, int n, int fSorted) { struct fbSetSpan data; PixmapPtr pixmap; DBG(("%s x %d\n", __FUNCTION__, n)); fbGetDrawablePixmap(drawable, pixmap, data.dx, data.dy); data.dst = pixmap->devPrivate.ptr; data.stride = pixmap->devKind / sizeof(FbStip); data.src = src; while (n--) { BoxRec box; *(DDXPointPtr)&box = data.pt = *pt; box.x2 = box.x1 + *width; box.y2 = box.y1 + 1; fbDrawableRun(drawable, gc, &box, fbSetSpan, &data); data.src += PixmapBytePad(*width, drawable->depth); width++; pt++; } } void fbGetSpans(DrawablePtr drawable, int wMax, DDXPointPtr pt, int *width, int n, char *dst) { FbBits *src, *d; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; int xoff; fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff); DBG(("%s x %d\n", __FUNCTION__, n)); while (n--) { xoff = (int) (((long) dst) & (FB_MASK >> 3)); d = (FbBits *) (dst - xoff); fbBlt(src + (pt->y + srcYoff) * srcStride, srcStride, (pt->x + srcXoff) * srcBpp, d, 1, xoff << 3, *width * srcBpp, 1, GXcopy, FB_ALLONES, srcBpp, FALSE, FALSE); dst += PixmapBytePad(*width, drawable->depth); pt++; width++; } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbstipple.c000066400000000000000000000137601267532330400243750ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" /* * This is a slight abuse of the preprocessor to generate repetitive * code, the idea is to generate code for each case of a copy-mode * transparent stipple */ #define LaneCases1(c,a) \ case c: while (n--) { FbLaneCase(c,a); a++; } break #define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a) #define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a) #define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a) #define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a) #define LaneCases(a) LaneCases16(0,a) /* * Repeat a transparent stipple across a scanline n times */ void fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n) { FbStip s; s = ((FbStip) (stip) & 0x01); s |= ((FbStip) (stip >> 8) & 0x02); s |= ((FbStip) (stip >> 16) & 0x04); s |= ((FbStip) (stip >> 24) & 0x08); switch (s) { LaneCases(dst); } } static void fbEvenStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbStip *stip, FbStride stipStride, int stipHeight, FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot) { FbBits startmask, endmask; FbBits mask, and, xor; int nmiddle, n; FbStip *s, *stipEnd, bits; int rot, stipX, stipY; int pixelsPerDst; const FbBits *fbBits; Bool transparent; int startbyte, endbyte; /* * Check for a transparent stipple (stencil) */ transparent = FALSE; if (dstBpp >= 8 && fgand == 0 && bgand == FB_ALLONES && bgxor == 0) transparent = TRUE; pixelsPerDst = FB_UNIT / dstBpp; /* * Adjust dest pointers */ dst += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, fgand == 0 && bgand == 0, startmask, startbyte, nmiddle, endmask, endbyte); if (startmask) dstStride--; dstStride -= nmiddle; xRot *= dstBpp; /* * Compute stip start scanline and rotation parameters */ stipEnd = stip + stipStride * stipHeight; modulus(-yRot, stipHeight, stipY); s = stip + stipStride * stipY; modulus(-xRot, FB_UNIT, stipX); rot = stipX; /* * Get pointer to stipple mask array for this depth */ /* fbStippleTable covers all valid bpp (4,8,16,32) */ fbBits = fbStippleTable[pixelsPerDst]; while (height--) { /* * Extract stipple bits for this scanline; */ bits = READ(s); s += stipStride; if (s == stipEnd) s = stip; mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)]; /* * Rotate into position and compute reduced rop values */ mask = FbRotLeft(mask, rot); and = (fgand & mask) | (bgand & ~mask); xor = (fgxor & mask) | (bgxor & ~mask); if (transparent) { if (startmask) { fbTransparentSpan(dst, mask & startmask, fgxor, 1); dst++; } fbTransparentSpan(dst, mask, fgxor, nmiddle); dst += nmiddle; if (endmask) fbTransparentSpan(dst, mask & endmask, fgxor, 1); } else { /* * Fill scanline */ if (startmask) { FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); dst++; } n = nmiddle; if (!and) while (n--) WRITE(dst++, xor); else { while (n--) { WRITE(dst, FbDoRRop(READ(dst), and, xor)); dst++; } } if (endmask) FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); } dst += dstStride; } } static void fbOddStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbStip *stip, FbStride stipStride, int stipWidth, int stipHeight, FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot) { int stipX, stipY, sx; int widthTmp; int h, w; int x, y; modulus(-yRot, stipHeight, stipY); modulus(dstX / dstBpp - xRot, stipWidth, stipX); y = 0; while (height) { h = stipHeight - stipY; if (h > height) h = height; height -= h; widthTmp = width; x = dstX; sx = stipX; while (widthTmp) { w = (stipWidth - sx) * dstBpp; if (w > widthTmp) w = widthTmp; widthTmp -= w; fbBltOne(stip + stipY * stipStride, stipStride, sx, dst + y * dstStride, dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor); x += w; sx = 0; } y += h; stipY = 0; } } void fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp, int width, int height, FbStip *stip, FbStride stipStride, int stipWidth, int stipHeight, Bool even, FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot) { DBG(("%s stipple=%dx%d, size=%dx%d\n", __FUNCTION__, stipWidth, stipHeight, width, height)); if (even) fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height, stip, stipStride, stipHeight, fgand, fgxor, bgand, bgxor, xRot, yRot); else fbOddStipple(dst, dstStride, dstX, dstBpp, width, height, stip, stipStride, stipWidth, stipHeight, fgand, fgxor, bgand, bgxor, xRot, yRot); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbtile.c000066400000000000000000000100461267532330400236440ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" /* * Accelerated tile fill -- tile width is a power of two not greater * than FB_UNIT */ static void fbEvenTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, FbBits *tile, FbStride tileStride, int tileHeight, int alu, FbBits pm, int xRot, int yRot) { FbBits *t, *tileEnd, bits; FbBits startmask, endmask; FbBits and, xor; int n, nmiddle; int tileX, tileY; int rot; int startbyte, endbyte; dst += dstX >> FB_SHIFT; dstX &= FB_MASK; FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm), startmask, startbyte, nmiddle, endmask, endbyte); if (startmask) dstStride--; dstStride -= nmiddle; /* * Compute tile start scanline and rotation parameters */ tileEnd = tile + tileHeight * tileStride; modulus(-yRot, tileHeight, tileY); t = tile + tileY * tileStride; modulus(-xRot, FB_UNIT, tileX); rot = tileX; while (height--) { /* * Pick up bits for this scanline */ bits = READ(t); t += tileStride; if (t >= tileEnd) t = tile; bits = FbRotLeft(bits, rot); and = fbAnd(alu, bits, pm); xor = fbXor(alu, bits, pm); if (startmask) { FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); dst++; } n = nmiddle; if (!and) while (n--) WRITE(dst++, xor); else while (n--) { WRITE(dst, FbDoRRop(READ(dst), and, xor)); dst++; } if (endmask) FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); dst += dstStride; } } static void fbOddTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot) { int tileX, tileY; int x, y; DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__, tileWidth, tileHeight, width, height)); modulus(-yRot, tileHeight, tileY); y = 0; while (height) { int ww = width; int h = tileHeight - tileY; if (h > height) h = height; height -= h; x = dstX; modulus(dstX - xRot, tileWidth, tileX); while (ww) { int w = tileWidth - tileX; if (w > ww) w = ww; ww -= w; fbBlt(tile + tileY * tileStride, tileStride, tileX, dst + y * dstStride, dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE); x += w; tileX = 0; } y += h; tileY = 0; } } void fbTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height, FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight, int alu, FbBits pm, int bpp, int xRot, int yRot) { DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__, tileWidth, tileHeight, width, height)); if (FbEvenTile(tileWidth)) fbEvenTile(dst, dstStride, dstX, width, height, tile, tileStride, tileHeight, alu, pm, xRot, yRot); else fbOddTile(dst, dstStride, dstX, width, height, tile, tileStride, tileWidth, tileHeight, alu, pm, bpp, xRot, yRot); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/fbutil.c000066400000000000000000000126361267532330400236730ustar00rootroot00000000000000/* * Copyright © 1998 Keith Packard * Copyright © 2012 Intel Corporation * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "fb.h" FbBits fbReplicatePixel(Pixel p, int bpp) { FbBits b = p; b &= FbFullMask(bpp); while (bpp < FB_UNIT) { b |= b << bpp; bpp <<= 1; } return b; } /* * Stipple masks are independent of bit/byte order as long * as bitorder == byteorder. FB doesn't handle the case * where these differ */ #define __mask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \ (FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK))) #define _mask(x,w) __mask((x)*(w),(w)) #define mask(b,n,w) ((((b) >> (n)) & 1) * _mask(n,w)) #define _C1(b,n,w) mask(b,n,w) #define _C2(b,n,w) (_C1(b,n,w) | _C1(b,n+1,w)) #define _C4(b,n,w) (_C2(b,n,w) | _C2(b,n+2,w)) #define C8(b,w) (_C4(b,0,w) | _C4(b,4,w)) #define C4(b,w) _C4(b,0,w) #define C2(b,w) _C2(b,0,w) #define C1(b,w) _C1(b,0,w) static const FbBits fbStipple8Bits[256] = { C8(0, 4), C8(1, 4), C8(2, 4), C8(3, 4), C8(4, 4), C8(5, 4), C8(6, 4), C8(7, 4), C8(8, 4), C8(9, 4), C8(10, 4), C8(11, 4), C8(12, 4), C8(13, 4), C8(14, 4), C8(15, 4), C8(16, 4), C8(17, 4), C8(18, 4), C8(19, 4), C8(20, 4), C8(21, 4), C8(22, 4), C8(23, 4), C8(24, 4), C8(25, 4), C8(26, 4), C8(27, 4), C8(28, 4), C8(29, 4), C8(30, 4), C8(31, 4), C8(32, 4), C8(33, 4), C8(34, 4), C8(35, 4), C8(36, 4), C8(37, 4), C8(38, 4), C8(39, 4), C8(40, 4), C8(41, 4), C8(42, 4), C8(43, 4), C8(44, 4), C8(45, 4), C8(46, 4), C8(47, 4), C8(48, 4), C8(49, 4), C8(50, 4), C8(51, 4), C8(52, 4), C8(53, 4), C8(54, 4), C8(55, 4), C8(56, 4), C8(57, 4), C8(58, 4), C8(59, 4), C8(60, 4), C8(61, 4), C8(62, 4), C8(63, 4), C8(64, 4), C8(65, 4), C8(66, 4), C8(67, 4), C8(68, 4), C8(69, 4), C8(70, 4), C8(71, 4), C8(72, 4), C8(73, 4), C8(74, 4), C8(75, 4), C8(76, 4), C8(77, 4), C8(78, 4), C8(79, 4), C8(80, 4), C8(81, 4), C8(82, 4), C8(83, 4), C8(84, 4), C8(85, 4), C8(86, 4), C8(87, 4), C8(88, 4), C8(89, 4), C8(90, 4), C8(91, 4), C8(92, 4), C8(93, 4), C8(94, 4), C8(95, 4), C8(96, 4), C8(97, 4), C8(98, 4), C8(99, 4), C8(100, 4), C8(101, 4), C8(102, 4), C8(103, 4), C8(104, 4), C8(105, 4), C8(106, 4), C8(107, 4), C8(108, 4), C8(109, 4), C8(110, 4), C8(111, 4), C8(112, 4), C8(113, 4), C8(114, 4), C8(115, 4), C8(116, 4), C8(117, 4), C8(118, 4), C8(119, 4), C8(120, 4), C8(121, 4), C8(122, 4), C8(123, 4), C8(124, 4), C8(125, 4), C8(126, 4), C8(127, 4), C8(128, 4), C8(129, 4), C8(130, 4), C8(131, 4), C8(132, 4), C8(133, 4), C8(134, 4), C8(135, 4), C8(136, 4), C8(137, 4), C8(138, 4), C8(139, 4), C8(140, 4), C8(141, 4), C8(142, 4), C8(143, 4), C8(144, 4), C8(145, 4), C8(146, 4), C8(147, 4), C8(148, 4), C8(149, 4), C8(150, 4), C8(151, 4), C8(152, 4), C8(153, 4), C8(154, 4), C8(155, 4), C8(156, 4), C8(157, 4), C8(158, 4), C8(159, 4), C8(160, 4), C8(161, 4), C8(162, 4), C8(163, 4), C8(164, 4), C8(165, 4), C8(166, 4), C8(167, 4), C8(168, 4), C8(169, 4), C8(170, 4), C8(171, 4), C8(172, 4), C8(173, 4), C8(174, 4), C8(175, 4), C8(176, 4), C8(177, 4), C8(178, 4), C8(179, 4), C8(180, 4), C8(181, 4), C8(182, 4), C8(183, 4), C8(184, 4), C8(185, 4), C8(186, 4), C8(187, 4), C8(188, 4), C8(189, 4), C8(190, 4), C8(191, 4), C8(192, 4), C8(193, 4), C8(194, 4), C8(195, 4), C8(196, 4), C8(197, 4), C8(198, 4), C8(199, 4), C8(200, 4), C8(201, 4), C8(202, 4), C8(203, 4), C8(204, 4), C8(205, 4), C8(206, 4), C8(207, 4), C8(208, 4), C8(209, 4), C8(210, 4), C8(211, 4), C8(212, 4), C8(213, 4), C8(214, 4), C8(215, 4), C8(216, 4), C8(217, 4), C8(218, 4), C8(219, 4), C8(220, 4), C8(221, 4), C8(222, 4), C8(223, 4), C8(224, 4), C8(225, 4), C8(226, 4), C8(227, 4), C8(228, 4), C8(229, 4), C8(230, 4), C8(231, 4), C8(232, 4), C8(233, 4), C8(234, 4), C8(235, 4), C8(236, 4), C8(237, 4), C8(238, 4), C8(239, 4), C8(240, 4), C8(241, 4), C8(242, 4), C8(243, 4), C8(244, 4), C8(245, 4), C8(246, 4), C8(247, 4), C8(248, 4), C8(249, 4), C8(250, 4), C8(251, 4), C8(252, 4), C8(253, 4), C8(254, 4), C8(255, 4), }; static const FbBits fbStipple4Bits[16] = { C4(0, 8), C4(1, 8), C4(2, 8), C4(3, 8), C4(4, 8), C4(5, 8), C4(6, 8), C4(7, 8), C4(8, 8), C4(9, 8), C4(10, 8), C4(11, 8), C4(12, 8), C4(13, 8), C4(14, 8), C4(15, 8), }; static const FbBits fbStipple2Bits[4] = { C2(0, 16), C2(1, 16), C2(2, 16), C2(3, 16), }; static const FbBits fbStipple1Bits[2] = { C1(0, 32), C1(1, 32), }; const FbBits *const fbStippleTable[] = { 0, fbStipple1Bits, fbStipple2Bits, 0, fbStipple4Bits, 0, 0, 0, fbStipple8Bits, }; xserver-xorg-video-intel-2.99.917+git20160325/src/sna/fb/sfb.h000066400000000000000000000025031267532330400231550ustar00rootroot00000000000000/* And rename to avoid symbol clashes with UXA */ #define fbPolyArc sfbPolyArc #define fbBlt sfbBlt #define fbBltOne sfbBltOne #define fbBltPlane sfbBltPlane #define fbCopyNtoN sfbCopyNtoN #define fbCopy1toN sfbCopy1toN #define fbCopyNto1 sfbCopyNto1 #define fbCopyArea sfbCopyArea #define fbCopyPlane sfbCopyPlane #define fbFill sfbFill #define fbSolidBoxClipped sfbSolidBoxClipped #define fbPolyFillRect sfbPolyFillRect #define fbFillSpans sfbFillSpans #define fbPadPixmap sfbPadPixmap #define fbValidateGC sfbValidateGC #define fbGetSpans sfbGetSpans #define fbPolyGlyphBlt sfbPolyGlyphBlt #define fbImageGlyphBlt sfbImageGlyphBlt #define fbPutImage sfbPutImage #define fbPuXYtImage sfbPutXYImage #define fbGetImage sfbGetImage #define fbPolyLine sfbPolyLine #define fbFixCoordModePrevious sfbFixCoordModePrevious #define fbPolySegment sfbPolySegment #define fbBitmapToRegion sfbBitmapToRegion #define fbPolyPoint sfbPolyPoint #define fbPushImage sfbPushImage #define fbPushPixels sfbPushPixels #define fbSetSpans sfbSetSpans #define fbSegment sfbSegment #define fbSegment1 sfbSegment1 #define fbTransparentSpan sfbTransparentSpan #define fbStipple sfbStipple #define fbTile sfbTile #define fbReplicatePixel sfbReplicatePixel #define fbComposite sfbComposite #define image_from_pict simage_from_pict #define free_pixmap_pict sfree_pixmap_pict xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen2_render.c000066400000000000000000002674431267532330400242210ustar00rootroot00000000000000/* * Copyright © 2006,2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "gen2_render.h" #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_ONE 0 #define NO_FILL_BOXES 0 #define MAX_3D_SIZE 2048 #define MAX_3D_PITCH 8192 #define BATCH(v) batch_emit(sna, v) #define BATCH_F(v) batch_emit_float(sna, v) #define VERTEX(v) batch_emit_float(sna, v) static const struct blendinfo { bool dst_alpha; bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen2_blend_op[] = { /* Clear */ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO}, /* Src */ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO}, /* Dst */ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE}, /* Over */ {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE}, /* In */ {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO}, /* InReverse */ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA}, /* Out */ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO}, /* OutReverse */ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE}, }; static const struct formatinfo { unsigned int fmt; uint32_t card_fmt; } i8xx_tex_formats[] = { {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8}, {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888}, {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888}, {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565}, {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555}, {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444}, }, i85x_tex_formats[] = { {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888}, {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888}, }; static inline bool too_large(int width, int height) { return width > MAX_3D_SIZE || height > MAX_3D_SIZE; } static inline uint32_t gen2_buf_tiling(uint32_t tiling) { uint32_t v = 0; switch (tiling) { default: assert(0); case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y; case I915_TILING_X: v |= BUF_3D_TILED_SURFACE; case I915_TILING_NONE: break; } return v; } static uint32_t gen2_get_dst_format(uint32_t format) { #define BIAS DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8) switch (format) { default: assert(0); case PICT_a8r8g8b8: case PICT_x8r8g8b8: return COLR_BUF_ARGB8888 | BIAS; case PICT_r5g6b5: return COLR_BUF_RGB565 | BIAS; case PICT_a1r5g5b5: case PICT_x1r5g5b5: return COLR_BUF_ARGB1555 | BIAS; case PICT_a8: return COLR_BUF_8BIT | BIAS; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return COLR_BUF_ARGB4444 | BIAS; } #undef BIAS } static bool gen2_check_dst_format(uint32_t format) { switch (format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_r5g6b5: case PICT_a1r5g5b5: case PICT_x1r5g5b5: case PICT_a8: case PICT_a4r4g4b4: case PICT_x4r4g4b4: return true; default: return false; } } static uint32_t gen2_get_card_format(struct sna *sna, uint32_t format) { unsigned int i; for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) if (i8xx_tex_formats[i].fmt == format) return i8xx_tex_formats[i].card_fmt; if (sna->kgem.gen < 021) { /* Whilst these are not directly supported on 830/845, * we only enable them when we can implicitly convert * them to a supported variant through the texture * combiners. */ for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) if (i85x_tex_formats[i].fmt == format) return i8xx_tex_formats[1+i].card_fmt; } else { for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) if (i85x_tex_formats[i].fmt == format) return i85x_tex_formats[i].card_fmt; } assert(0); return 0; } static uint32_t gen2_check_format(struct sna *sna, PicturePtr p) { unsigned int i; for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) if (i8xx_tex_formats[i].fmt == p->format) return true; if (sna->kgem.gen > 021) { for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) if (i85x_tex_formats[i].fmt == p->format) return true; } return false; } static uint32_t gen2_sampler_tiling_bits(uint32_t tiling) { uint32_t bits = 0; switch (tiling) { default: assert(0); case I915_TILING_Y: bits |= TM0S1_TILE_WALK; case I915_TILING_X: bits |= TM0S1_TILED_SURFACE; case I915_TILING_NONE: break; } return bits; } static bool gen2_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: return false; } } static bool gen2_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: return false; } } static void gen2_emit_texture(struct sna *sna, const struct sna_composite_channel *channel, int unit) { uint32_t wrap_mode_u, wrap_mode_v; uint32_t texcoordtype; uint32_t filter; assert(channel->bo); if (channel->is_affine) texcoordtype = TEXCOORDTYPE_CARTESIAN; else texcoordtype = TEXCOORDTYPE_HOMOGENEOUS; switch (channel->repeat) { default: assert(0); case RepeatNone: wrap_mode_u = TEXCOORDMODE_CLAMP_BORDER; break; case RepeatNormal: wrap_mode_u = TEXCOORDMODE_WRAP; break; case RepeatPad: wrap_mode_u = TEXCOORDMODE_CLAMP; break; case RepeatReflect: wrap_mode_u = TEXCOORDMODE_MIRROR; break; } if (channel->is_linear) wrap_mode_v = TEXCOORDMODE_WRAP; else wrap_mode_v = wrap_mode_u; switch (channel->filter) { default: assert(0); case PictFilterNearest: filter = (FILTER_NEAREST << TM0S3_MAG_FILTER_SHIFT | FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT | MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); break; case PictFilterBilinear: filter = (FILTER_LINEAR << TM0S3_MAG_FILTER_SHIFT | FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT | MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); break; } BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4); BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, channel->bo, I915_GEM_DOMAIN_SAMPLER << 16, 0)); BATCH(((channel->height - 1) << TM0S1_HEIGHT_SHIFT) | ((channel->width - 1) << TM0S1_WIDTH_SHIFT) | gen2_get_card_format(sna, channel->pict_format) | gen2_sampler_tiling_bits(channel->bo->tiling)); BATCH((channel->bo->pitch / 4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D); BATCH(filter); BATCH(0); /* default color */ BATCH(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | texcoordtype | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(wrap_mode_v) | ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode_u)); } static void gen2_get_blend_factors(const struct sna_composite_op *op, int blend, uint32_t *c_out, uint32_t *a_out) { uint32_t cblend, ablend; /* If component alpha is active in the mask and the blend operation * uses the source alpha, then we know we don't need the source * value (otherwise we would have hit a fallback earlier), so we * provide the source alpha (src.A * mask.X) as output color. * Conversely, if CA is set and we don't need the source alpha, then * we produce the source value (src.X * mask.X) and the source alpha * is unused.. Otherwise, we provide the non-CA source value * (src.X * mask.A). * * The PICT_FORMAT_RGB(pict) == 0 fixups are not needed on 855+'s a8 * pictures, but we need to implement it for 830/845 and there's no * harm done in leaving it in. */ cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OUTPUT_WRITE_CURRENT; ablend = TB0A_RESULT_SCALE_1X | TB0A_OUTPUT_WRITE_CURRENT; /* Get the source picture's channels into TBx_ARG1 */ if ((op->has_component_alpha && gen2_blend_op[blend].src_alpha) || op->dst.format == PICT_a8) { /* Producing source alpha value, so the first set of channels * is src.A instead of src.X. We also do this if the destination * is a8, in which case src.G is what's written, and the other * channels are ignored. */ if (op->src.is_opaque) { ablend |= TB0C_ARG1_SEL_ONE; cblend |= TB0C_ARG1_SEL_ONE; } else if (op->src.is_solid) { ablend |= TB0C_ARG1_SEL_DIFFUSE; cblend |= TB0C_ARG1_SEL_DIFFUSE | TB0C_ARG1_REPLICATE_ALPHA; } else { ablend |= TB0C_ARG1_SEL_TEXEL0; cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA; } } else { if (op->src.is_solid) cblend |= TB0C_ARG1_SEL_DIFFUSE; else if (PICT_FORMAT_RGB(op->src.pict_format) != 0) cblend |= TB0C_ARG1_SEL_TEXEL0; else cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */ if (op->src.is_opaque) ablend |= TB0A_ARG1_SEL_ONE; else if (op->src.is_solid) ablend |= TB0A_ARG1_SEL_DIFFUSE; else ablend |= TB0A_ARG1_SEL_TEXEL0; } if (op->mask.bo) { if (op->src.is_solid) { cblend |= TB0C_ARG2_SEL_TEXEL0; ablend |= TB0A_ARG2_SEL_TEXEL0; } else { cblend |= TB0C_ARG2_SEL_TEXEL1; ablend |= TB0A_ARG2_SEL_TEXEL1; } if (op->dst.format == PICT_a8 || !op->has_component_alpha) cblend |= TB0C_ARG2_REPLICATE_ALPHA; cblend |= TB0C_OP_MODULATE; ablend |= TB0A_OP_MODULATE; } else if (op->mask.is_solid) { cblend |= TB0C_ARG2_SEL_DIFFUSE; ablend |= TB0A_ARG2_SEL_DIFFUSE; if (op->dst.format == PICT_a8 || !op->has_component_alpha) cblend |= TB0C_ARG2_REPLICATE_ALPHA; cblend |= TB0C_OP_MODULATE; ablend |= TB0A_OP_MODULATE; } else { cblend |= TB0C_OP_ARG1; ablend |= TB0A_OP_ARG1; } *c_out = cblend; *a_out = ablend; } static uint32_t gen2_get_blend_cntl(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t sblend, dblend; if (op <= PictOpSrc) return S8_ENABLE_COLOR_BUFFER_WRITE; sblend = gen2_blend_op[op].src_blend; dblend = gen2_blend_op[op].dst_blend; if (gen2_blend_op[op].dst_alpha) { /* If there's no dst alpha channel, adjust the blend op so that * we'll treat it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (sblend == BLENDFACTOR_DST_ALPHA) sblend = BLENDFACTOR_ONE; else if (sblend == BLENDFACTOR_INV_DST_ALPHA) sblend = BLENDFACTOR_ZERO; } /* gen2 engine reads 8bit color buffer into green channel * in cases like color buffer blending etc., and also writes * back green channel. So with dst_alpha blend we should use * color factor. */ if (dst_format == PICT_a8) { if (sblend == BLENDFACTOR_DST_ALPHA) sblend = BLENDFACTOR_DST_COLR; else if (sblend == BLENDFACTOR_INV_DST_ALPHA) sblend = BLENDFACTOR_INV_DST_COLR; } } /* If the source alpha is being used, then we should only be in a case * where the source blend factor is 0, and the source blend value is * the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen2_blend_op[op].src_alpha) { if (dblend == BLENDFACTOR_SRC_ALPHA) dblend = BLENDFACTOR_SRC_COLR; else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) dblend = BLENDFACTOR_INV_SRC_COLR; } return (sblend << S8_SRC_BLEND_FACTOR_SHIFT | dblend << S8_DST_BLEND_FACTOR_SHIFT | S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | S8_ENABLE_COLOR_BUFFER_WRITE); } static void gen2_emit_invariant(struct sna *sna) { int i; for (i = 0; i < 4; i++) { BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(i)); BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(i) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(i) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(i)); BATCH(_3DSTATE_MAP_COORD_TRANSFORM); BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(i)); } BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD); BATCH(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); BATCH(_3DSTATE_VERTEX_TRANSFORM); BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); BATCH(_3DSTATE_W_STATE_CMD); BATCH(MAGIC_W_STATE_DWORD1); BATCH_F(1.0); BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND | ENABLE_ALPHA_BLENDFUNC | ABLENDFUNC_ADD); BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD); BATCH(0); BATCH(_3DSTATE_MODES_1_CMD | ENABLE_COLR_BLND_FUNC | BLENDFUNC_ADD | ENABLE_SRC_BLND_FACTOR | SRC_BLND_FACT(BLENDFACTOR_ONE) | ENABLE_DST_BLND_FACTOR | DST_BLND_FACT(BLENDFACTOR_ZERO)); BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | DISABLE_DEPTH_TEST | ENABLE_COLOR_BLEND); BATCH(_3DSTATE_ENABLES_2_CMD | DISABLE_STENCIL_WRITE | DISABLE_DITHER | DISABLE_DEPTH_WRITE | ENABLE_COLOR_MASK | ENABLE_COLOR_WRITE | ENABLE_TEX_CACHE); BATCH(_3DSTATE_STIPPLE); BATCH(0); BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) | TEXPIPE_COLOR | ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT | DISABLE_TEX_CNTRL_STAGE | TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) | TEXPIPE_ALPHA | ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT | TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) | TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE); BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) | TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE); #define INVARIANT_SIZE 35 sna->render_state.gen2.need_invariant = false; } static void gen2_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch(&sna->kgem, INVARIANT_SIZE+40)) { DBG(("%s: flushing batch: size %d > %d\n", __FUNCTION__, INVARIANT_SIZE+40, sna->kgem.surface-sna->kgem.nbatch)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (!kgem_check_reloc(&sna->kgem, 3)) { DBG(("%s: flushing batch: reloc %d >= %d\n", __FUNCTION__, sna->kgem.nreloc + 3, (int)KGEM_RELOC_SIZE(&sna->kgem))); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (!kgem_check_exec(&sna->kgem, 3)) { DBG(("%s: flushing batch: exec %d >= %d\n", __FUNCTION__, sna->kgem.nexec + 1, (int)KGEM_EXEC_SIZE(&sna->kgem))); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen2.need_invariant) gen2_emit_invariant(sna); } static void gen2_emit_target(struct sna *sna, const struct sna_composite_op *op) { assert(!too_large(op->dst.width, op->dst.height)); assert(op->dst.bo->pitch >= 8 && op->dst.bo->pitch <= MAX_3D_PITCH); assert(sna->render.vertex_offset == 0); assert(op->dst.bo->unique_id); if (sna->render_state.gen2.target == op->dst.bo->unique_id) { kgem_bo_mark_dirty(op->dst.bo); return; } BATCH(_3DSTATE_BUF_INFO_CMD); BATCH(BUF_3D_ID_COLOR_BACK | gen2_buf_tiling(op->dst.bo->tiling) | BUF_3D_PITCH(op->dst.bo->pitch)); BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, op->dst.bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER, 0)); BATCH(_3DSTATE_DST_BUF_VARS_CMD); BATCH(gen2_get_dst_format(op->dst.format)); BATCH(_3DSTATE_DRAW_RECT_CMD); BATCH(0); BATCH(0); /* ymin, xmin */ BATCH(DRAW_YMAX(op->dst.height - 1) | DRAW_XMAX(op->dst.width - 1)); BATCH(0); /* yorig, xorig */ sna->render_state.gen2.target = op->dst.bo->unique_id; } static void gen2_disable_logic_op(struct sna *sna) { if (!sna->render_state.gen2.logic_op_enabled) return; DBG(("%s\n", __FUNCTION__)); BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | ENABLE_COLOR_BLEND); sna->render_state.gen2.logic_op_enabled = 0; } static void gen2_enable_logic_op(struct sna *sna, int op) { static const uint8_t logic_op[] = { LOGICOP_CLEAR, /* GXclear */ LOGICOP_AND, /* GXand */ LOGICOP_AND_RVRSE, /* GXandReverse */ LOGICOP_COPY, /* GXcopy */ LOGICOP_AND_INV, /* GXandInverted */ LOGICOP_NOOP, /* GXnoop */ LOGICOP_XOR, /* GXxor */ LOGICOP_OR, /* GXor */ LOGICOP_NOR, /* GXnor */ LOGICOP_EQUIV, /* GXequiv */ LOGICOP_INV, /* GXinvert */ LOGICOP_OR_RVRSE, /* GXorReverse */ LOGICOP_COPY_INV, /* GXcopyInverted */ LOGICOP_OR_INV, /* GXorInverted */ LOGICOP_NAND, /* GXnand */ LOGICOP_SET /* GXset */ }; if (sna->render_state.gen2.logic_op_enabled != op+1) { if (!sna->render_state.gen2.logic_op_enabled) { if (op == GXclear || op == GXcopy) return; DBG(("%s\n", __FUNCTION__)); BATCH(_3DSTATE_ENABLES_1_CMD | ENABLE_LOGIC_OP | DISABLE_COLOR_BLEND); } BATCH(_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(logic_op[op])); sna->render_state.gen2.logic_op_enabled = op+1; } } static void gen2_emit_composite_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t texcoordfmt, v, unwind; uint32_t cblend, ablend; int tex; gen2_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo) BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE); else BATCH(_3DSTATE_MODES_5_CMD | PIPELINE_FLUSH_RENDER_CACHE | PIPELINE_FLUSH_TEXTURE_CACHE); kgem_clear_dirty(&sna->kgem); } gen2_emit_target(sna, op); unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); BATCH((!op->src.is_solid + (op->mask.bo != NULL)) << 12); BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); BATCH(gen2_get_blend_cntl(op->op, op->has_component_alpha, op->dst.format)); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls1 + 1, sna->kgem.batch + unwind + 1, 3 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls1 = unwind; gen2_disable_logic_op(sna); gen2_get_blend_factors(op, op->op, &cblend, &ablend); unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); BATCH(cblend); BATCH(ablend); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls2 + 1, sna->kgem.batch + unwind + 1, 2 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls2 = unwind; tex = texcoordfmt = 0; if (!op->src.is_solid) { if (op->src.is_affine) texcoordfmt |= TEXCOORDFMT_2D << (2*tex); else texcoordfmt |= TEXCOORDFMT_3D << (2*tex); gen2_emit_texture(sna, &op->src, tex++); } else { if (op->src.u.gen2.pixel != sna->render_state.gen2.diffuse) { BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); BATCH(op->src.u.gen2.pixel); sna->render_state.gen2.diffuse = op->src.u.gen2.pixel; } } if (op->mask.bo) { if (op->mask.is_affine) texcoordfmt |= TEXCOORDFMT_2D << (2*tex); else texcoordfmt |= TEXCOORDFMT_3D << (2*tex); gen2_emit_texture(sna, &op->mask, tex++); } else if (op->mask.is_solid) { if (op->mask.u.gen2.pixel != sna->render_state.gen2.diffuse) { BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); BATCH(op->mask.u.gen2.pixel); sna->render_state.gen2.diffuse = op->mask.u.gen2.pixel; } } v = _3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt; if (sna->render_state.gen2.vft != v) { BATCH(v); sna->render_state.gen2.vft = v; } } static inline void gen2_emit_composite_dstcoord(struct sna *sna, int dstX, int dstY) { VERTEX(dstX); VERTEX(dstY); } inline static void gen2_emit_composite_linear(struct sna *sna, const struct sna_composite_channel *channel, int16_t x, int16_t y) { float v; v = (x * channel->u.linear.dx + y * channel->u.linear.dy + channel->u.linear.offset); DBG(("%s: (%d, %d) -> %f\n", __FUNCTION__, x, y, v)); VERTEX(v); VERTEX(v); } static void gen2_emit_composite_texcoord(struct sna *sna, const struct sna_composite_channel *channel, int16_t x, int16_t y) { float s = 0, t = 0, w = 1; x += channel->offset[0]; y += channel->offset[1]; if (channel->is_affine) { sna_get_transformed_coordinates(x, y, channel->transform, &s, &t); VERTEX(s * channel->scale[0]); VERTEX(t * channel->scale[1]); } else { sna_get_transformed_coordinates_3d(x, y, channel->transform, &s, &t, &w); VERTEX(s * channel->scale[0]); VERTEX(t * channel->scale[1]); VERTEX(w); } } static void gen2_emit_composite_vertex(struct sna *sna, const struct sna_composite_op *op, int16_t srcX, int16_t srcY, int16_t mskX, int16_t mskY, int16_t dstX, int16_t dstY) { gen2_emit_composite_dstcoord(sna, dstX, dstY); if (op->src.is_linear) gen2_emit_composite_linear(sna, &op->src, srcX, srcY); else if (!op->src.is_solid) gen2_emit_composite_texcoord(sna, &op->src, srcX, srcY); if (op->mask.is_linear) gen2_emit_composite_linear(sna, &op->mask, mskX, mskY); else if (op->mask.bo) gen2_emit_composite_texcoord(sna, &op->mask, mskX, mskY); } fastcall static void gen2_emit_composite_primitive(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { gen2_emit_composite_vertex(sna, op, r->src.x + r->width, r->src.y + r->height, r->mask.x + r->width, r->mask.y + r->height, op->dst.x + r->dst.x + r->width, op->dst.y + r->dst.y + r->height); gen2_emit_composite_vertex(sna, op, r->src.x, r->src.y + r->height, r->mask.x, r->mask.y + r->height, op->dst.x + r->dst.x, op->dst.y + r->dst.y + r->height); gen2_emit_composite_vertex(sna, op, r->src.x, r->src.y, r->mask.x, r->mask.y, op->dst.x + r->dst.x, op->dst.y + r->dst.y); } fastcall static void gen2_emit_composite_primitive_constant(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; gen2_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y); } fastcall static void gen2_emit_composite_primitive_linear(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; gen2_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); gen2_emit_composite_linear(sna, &op->src, r->src.x + r->width, r->src.y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); gen2_emit_composite_linear(sna, &op->src, r->src.x, r->src.y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y); gen2_emit_composite_linear(sna, &op->src, r->src.x, r->src.y); } fastcall static void gen2_emit_composite_primitive_identity(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[2] = v[6] + w * op->src.scale[0]; v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } fastcall static void gen2_emit_composite_primitive_affine(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int src_x = r->src.x + (int)op->src.offset[0]; int src_y = r->src.y + (int)op->src.offset[1]; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + r->width; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + r->height; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } fastcall static void gen2_emit_composite_primitive_constant_identity_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0]; v[2] = v[6] + w * op->mask.scale[0]; v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } #if defined(sse2) && !defined(__x86_64__) sse2 fastcall static void gen2_emit_composite_primitive_constant__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; gen2_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y); } sse2 fastcall static void gen2_emit_composite_primitive_linear__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; gen2_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); gen2_emit_composite_linear(sna, &op->src, r->src.x + r->width, r->src.y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); gen2_emit_composite_linear(sna, &op->src, r->src.x, r->src.y + r->height); gen2_emit_composite_dstcoord(sna, dst_x, dst_y); gen2_emit_composite_linear(sna, &op->src, r->src.x, r->src.y); } sse2 fastcall static void gen2_emit_composite_primitive_identity__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[2] = v[6] + w * op->src.scale[0]; v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } sse2 fastcall static void gen2_emit_composite_primitive_affine__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int src_x = r->src.x + (int)op->src.offset[0]; int src_y = r->src.y + (int)op->src.offset[1]; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + r->width; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + r->height; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } sse2 fastcall static void gen2_emit_composite_primitive_constant_identity_mask__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 12; v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0]; v[2] = v[6] + w * op->mask.scale[0]; v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } #endif static void gen2_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { uint32_t ablend, cblend, *src, *dst; int n; if (!op->need_magic_ca_pass) return; DBG(("%s: batch=%x, vertex=%x\n", __FUNCTION__, sna->kgem.nbatch, sna->render.vertex_offset)); assert(op->mask.bo); assert(op->has_component_alpha); BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0); BATCH(BLENDFACTOR_ONE << S8_SRC_BLEND_FACTOR_SHIFT | BLENDFACTOR_ONE << S8_DST_BLEND_FACTOR_SHIFT | S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | S8_ENABLE_COLOR_BUFFER_WRITE); sna->render_state.gen2.ls1 = 0; gen2_get_blend_factors(op, PictOpAdd, &cblend, &ablend); BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); BATCH(cblend); BATCH(ablend); sna->render_state.gen2.ls2 = 0; src = sna->kgem.batch + sna->render.vertex_offset; dst = sna->kgem.batch + sna->kgem.nbatch; n = 1 + sna->render.vertex_index; sna->kgem.nbatch += n; assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem)); while (n--) *dst++ = *src++; } static void gen2_vertex_flush(struct sna *sna, const struct sna_composite_op *op) { if (sna->render.vertex_index == 0) return; sna->kgem.batch[sna->render.vertex_offset] |= sna->render.vertex_index - 1; gen2_magic_ca_pass(sna, op); sna->render.vertex_offset = 0; sna->render.vertex_index = 0; } inline static int gen2_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want) { int rem = batch_space(sna), size, need; DBG(("%s: want=%d, floats_per_vertex=%d, rem=%d\n", __FUNCTION__, want, op->floats_per_vertex, rem)); assert(op->floats_per_vertex); assert(op->floats_per_rect == 3 * op->floats_per_vertex); need = 1; size = op->floats_per_rect; if (op->need_magic_ca_pass) need += 6 + size*sna->render.vertex_index, size *= 2; DBG(("%s: want=%d, need=%d,size=%d, rem=%d\n", __FUNCTION__, want, need, size, rem)); if (rem < need + size) { gen2_vertex_flush(sna, op); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); return 0; } rem -= need; if (sna->render.vertex_offset == 0) { if ((sna->kgem.batch[sna->kgem.nbatch-1] & ~0xffff) == (PRIM3D_INLINE | PRIM3D_RECTLIST)) { uint32_t *b = &sna->kgem.batch[sna->kgem.nbatch-1]; assert(*b & 0xffff); sna->render.vertex_index = 1 + (*b & 0xffff); *b = PRIM3D_INLINE | PRIM3D_RECTLIST; sna->render.vertex_offset = sna->kgem.nbatch - 1; assert(!op->need_magic_ca_pass); } else { sna->render.vertex_offset = sna->kgem.nbatch; BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST); } } if (want > 1 && want * size > rem) want = rem / size; assert(want); sna->render.vertex_index += want*op->floats_per_rect; return want; } fastcall static void gen2_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { if (!gen2_get_rectangles(sna, op, 1)) { gen2_emit_composite_state(sna, op); gen2_get_rectangles(sna, op, 1); } op->prim_emit(sna, op, r); } fastcall static void gen2_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; if (!gen2_get_rectangles(sna, op, 1)) { gen2_emit_composite_state(sna, op); gen2_get_rectangles(sna, op, 1); } DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); } static void gen2_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { do { int nbox_this_time; nbox_this_time = gen2_get_rectangles(sna, op, nbox); if (nbox_this_time == 0) { gen2_emit_composite_state(sna, op); nbox_this_time = gen2_get_rectangles(sna, op, nbox); } nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen2_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { gen2_vertex_flush(sna, op); if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } static bool gen2_composite_solid_init(struct sna *sna, struct sna_composite_channel *channel, uint32_t color) { channel->filter = PictFilterNearest; channel->repeat = RepeatNormal; channel->is_solid = true; channel->is_affine = true; channel->width = 1; channel->height = 1; channel->pict_format = PICT_a8r8g8b8; channel->bo = NULL; channel->u.gen2.pixel = color; channel->scale[0] = channel->scale[1] = 1; channel->offset[0] = channel->offset[1] = 0; return true; } #define xFixedToDouble(f) pixman_fixed_to_double(f) static bool gen2_composite_linear_init(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y) { PictLinearGradient *linear = (PictLinearGradient *)picture->pSourcePict; pixman_fixed_t tx, ty; float x0, y0, sf; float dx, dy; DBG(("%s: p1=(%f, %f), p2=(%f, %f)\n", __FUNCTION__, xFixedToDouble(linear->p1.x), xFixedToDouble(linear->p1.y), xFixedToDouble(linear->p2.x), xFixedToDouble(linear->p2.y))); if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) return 0; if (!sna_transform_is_affine(picture->transform)) { DBG(("%s: fallback due to projective transform\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); if (!channel->bo) return 0; channel->filter = PictFilterNearest; channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->is_linear = true; channel->width = channel->bo->pitch / 4; channel->height = 1; channel->pict_format = PICT_a8r8g8b8; channel->scale[0] = channel->scale[1] = 1; channel->offset[0] = channel->offset[1] = 0; if (sna_transform_is_translation(picture->transform, &tx, &ty)) { dx = xFixedToDouble(linear->p2.x - linear->p1.x); dy = xFixedToDouble(linear->p2.y - linear->p1.y); x0 = xFixedToDouble(linear->p1.x); y0 = xFixedToDouble(linear->p1.y); if (tx | ty) { x0 -= pixman_fixed_to_double(tx); y0 -= pixman_fixed_to_double(ty); } } else { struct pixman_f_vector p1, p2; struct pixman_f_transform m, inv; pixman_f_transform_from_pixman_transform(&m, picture->transform); DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", __FUNCTION__, m.m[0][0], m.m[0][1], m.m[0][2], m.m[1][0], m.m[1][1], m.m[1][2], m.m[2][0], m.m[2][1], m.m[2][2])); if (!pixman_f_transform_invert(&inv, &m)) return 0; p1.v[0] = pixman_fixed_to_double(linear->p1.x); p1.v[1] = pixman_fixed_to_double(linear->p1.y); p1.v[2] = 1.; pixman_f_transform_point(&inv, &p1); p2.v[0] = pixman_fixed_to_double(linear->p2.x); p2.v[1] = pixman_fixed_to_double(linear->p2.y); p2.v[2] = 1.; pixman_f_transform_point(&inv, &p2); DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", __FUNCTION__, p1.v[0], p1.v[1], p1.v[2], p2.v[0], p2.v[1], p2.v[2])); dx = p2.v[0] - p1.v[0]; dy = p2.v[1] - p1.v[1]; x0 = p1.v[0]; y0 = p1.v[1]; } sf = dx*dx + dy*dy; dx /= sf; dy /= sf; channel->u.linear.dx = dx; channel->u.linear.dy = dy; channel->u.linear.offset = -dx*(x0+dst_x-x) + -dy*(y0+dst_y-y); DBG(("%s: dx=%f, dy=%f, offset=%f\n", __FUNCTION__, dx, dy, channel->u.linear.offset)); return channel->bo != NULL; } static bool source_is_covered(PicturePtr picture, int x, int y, int width, int height) { int x1, y1, x2, y2; if (picture->repeat && picture->repeatType != RepeatNone) return true; if (picture->pDrawable == NULL) return false; if (picture->transform) { pixman_box16_t sample; sample.x1 = x; sample.y1 = y; sample.x2 = x + width; sample.y2 = y + height; pixman_transform_bounds(picture->transform, &sample); x1 = sample.x1; x2 = sample.x2; y1 = sample.y1; y2 = sample.y2; } else { x1 = x; y1 = y; x2 = x + width; y2 = y + height; } return x1 >= 0 && y1 >= 0 && x2 <= picture->pDrawable->width && y2 <= picture->pDrawable->height; } static bool gen2_check_card_format(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, bool *fixup_alpha) { uint32_t format = picture->format; unsigned int i; for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) { if (i8xx_tex_formats[i].fmt == format) return true; } for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) { if (i85x_tex_formats[i].fmt == format) { if (sna->kgem.gen >= 021) return true; if (source_is_covered(picture, x, y, w,h)) { channel->is_opaque = true; return true; } *fixup_alpha = true; return false; } } *fixup_alpha = false; return false; } static int gen2_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; bool fixup_alpha; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->is_solid = false; channel->is_linear = false; channel->is_opaque = false; channel->is_affine = true; channel->transform = NULL; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen2_composite_solid_init(sna, channel, color); if (!gen2_check_repeat(picture)) { DBG(("%s -- fallback, unhandled repeat %d\n", __FUNCTION__, picture->repeat)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen2_check_filter(picture)) { DBG(("%s -- fallback, unhandled filter %d\n", __FUNCTION__, picture->filter)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen2_composite_linear_init(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fallback, unhandled source %d\n", __FUNCTION__, picture->pSourcePict->type)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat && (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen2_composite_solid_init(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; if (!gen2_check_card_format(sna, picture, channel, x, y, w ,h, &fixup_alpha)) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, fixup_alpha); channel->pict_format = picture->format; if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } static bool gen2_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned hint; op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.format = dst->format; op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; if (w && h) { box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } assert((op->dst.bo->pitch & 7) == 0); get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (((too_large(op->dst.width, op->dst.height) || op->dst.bo->pitch > MAX_3D_PITCH)) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool is_unhandled_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(PicturePtr p) { return p->pDrawable && unattached(p->pDrawable) && untransformed(p); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (is_unhandled_gradient(p, precise) || !gen2_check_repeat(p)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen2_check_filter(p) || need_upload(p); } static bool gen2_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen2_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = NULL; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (sna_picture_is_solid(mask, &color)) return gen2_composite_solid_init(sna, mc, color); if (sc->is_solid) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen2_check_repeat(mask)) return false; if (!gen2_check_filter(mask)) return false; if (!gen2_check_format(sna, mask)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = mask->repeat ? mask->repeatType : RepeatNone; mc->filter = mask->filter; mc->pict_format = mask->format; mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen2_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { DBG(("%s()\n", __FUNCTION__)); if (op >= ARRAY_SIZE(gen2_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen2_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height, tmp); tmp->op = op; sna_render_composite_redirect_init(tmp); if (!gen2_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) { DBG(("%s: unable to set render target\n", __FUNCTION__)); goto fallback; } switch (gen2_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: fallback -- unable to prepare source\n", __FUNCTION__)); goto cleanup_dst; case 0: gen2_composite_solid_init(sna, &tmp->src, 0); break; case 1: if (mask == NULL && tmp->src.bo && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; break; } if (mask) { if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, mask_x, mask_y)) { switch (gen2_composite_picture(sna, mask, &tmp->mask, mask_x, mask_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: fallback -- unable to prepare mask\n", __FUNCTION__)); goto cleanup_src; case 0: gen2_composite_solid_init(sna, &tmp->mask, 0); case 1: break; } } if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { /* Check if it's component alpha that relies on a source alpha * and on the source value. We can only get one of those * into the single source value that we get to blend with. */ tmp->has_component_alpha = true; if (gen2_blend_op[op].src_alpha && (gen2_blend_op[op].src_blend != BLENDFACTOR_ZERO)) { if (op != PictOpOver) { DBG(("%s: fallback -- unsupported CA blend (src_blend=%d)\n", __FUNCTION__, gen2_blend_op[op].src_blend)); goto cleanup_src; } tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } /* convert solid to a texture (pure convenience) */ if (tmp->mask.is_solid && tmp->src.is_solid) { assert(tmp->mask.is_affine); tmp->mask.bo = sna_render_get_solid(sna, tmp->mask.u.gen2.pixel); if (!tmp->mask.bo) goto cleanup_src; } } tmp->floats_per_vertex = 2; if (!tmp->src.is_solid) tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 3; if (tmp->mask.bo) tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 3; tmp->floats_per_rect = 3*tmp->floats_per_vertex; tmp->prim_emit = gen2_emit_composite_primitive; if (tmp->mask.bo) { if (tmp->mask.transform == NULL) { if (tmp->src.is_solid) { assert(tmp->floats_per_rect == 12); #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_primitive_constant_identity_mask__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_primitive_constant_identity_mask; } } } } else { if (tmp->src.is_solid) { assert(tmp->floats_per_rect == 6); #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_primitive_constant__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_primitive_constant; } } else if (tmp->src.is_linear) { assert(tmp->floats_per_rect == 12); #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_primitive_linear__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_primitive_linear; } } else if (tmp->src.transform == NULL) { assert(tmp->floats_per_rect == 12); #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_primitive_identity__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_primitive_identity; } } else if (tmp->src.is_affine) { assert(tmp->floats_per_rect == 12); tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_primitive_affine__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_primitive_affine; } } } tmp->blt = gen2_render_composite_blt; tmp->box = gen2_render_composite_box; tmp->boxes = gen2_render_composite_boxes; tmp->done = gen2_render_composite_done; if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { DBG(("%s: fallback, operation does not fit into GTT\n", __FUNCTION__)); goto cleanup_mask; } } gen2_emit_composite_state(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } fastcall static void gen2_emit_composite_spans_primitive_constant(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = (float *)sna->kgem.batch + sna->kgem.nbatch; uint32_t alpha = (uint8_t)(255 * opacity) << 24; sna->kgem.nbatch += 9; v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; *((uint32_t *)v + 2) = alpha; v[3] = op->base.dst.x + box->x1; v[4] = v[1]; *((uint32_t *)v + 5) = alpha; v[6] = v[3]; v[7] = op->base.dst.y + box->y1; *((uint32_t *)v + 8) = alpha; } fastcall static void gen2_emit_composite_spans_primitive_linear(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { float f; uint32_t u; } alpha; alpha.u = (uint8_t)(255 * opacity) << 24; gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x2, op->base.dst.y + box->y2); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x2, box->y2); gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x1, op->base.dst.y + box->y2); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x1, box->y2); gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x1, op->base.dst.y + box->y1); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x1, box->y1); } fastcall static void gen2_emit_composite_spans_primitive_identity_source(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = (float *)sna->kgem.batch + sna->kgem.nbatch; uint32_t alpha = (uint8_t)(255 * opacity) << 24; sna->kgem.nbatch += 15; v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; *((uint32_t *)v + 2) = alpha; v[3] = (op->base.src.offset[0] + box->x2) * op->base.src.scale[0]; v[4] = (op->base.src.offset[1] + box->y2) * op->base.src.scale[1]; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; *((uint32_t *)v + 7) = alpha; v[8] = (op->base.src.offset[0] + box->x1) * op->base.src.scale[0]; v[9] = v[4]; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; *((uint32_t *)v + 12) = alpha; v[13] = v[8]; v[14] = (op->base.src.offset[1] + box->y1) * op->base.src.scale[1]; } fastcall static void gen2_emit_composite_spans_primitive_affine_source(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; uint32_t alpha = (uint8_t)(255 * opacity) << 24; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 15; v[0] = op->base.dst.x + box->x2; v[6] = v[1] = op->base.dst.y + box->y2; v[10] = v[5] = op->base.dst.x + box->x1; v[11] = op->base.dst.y + box->y1; *((uint32_t *)v + 2) = alpha; *((uint32_t *)v + 7) = alpha; *((uint32_t *)v + 12) = alpha; _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x2, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[3], &v[4]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[8], &v[9]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[13], &v[14]); } #if defined(sse2) && !defined(__x86_64__) sse2 fastcall static void gen2_emit_composite_spans_primitive_constant__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = (float *)sna->kgem.batch + sna->kgem.nbatch; uint32_t alpha = (uint8_t)(255 * opacity) << 24; sna->kgem.nbatch += 9; v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; *((uint32_t *)v + 2) = alpha; v[3] = op->base.dst.x + box->x1; v[4] = v[1]; *((uint32_t *)v + 5) = alpha; v[6] = v[3]; v[7] = op->base.dst.y + box->y1; *((uint32_t *)v + 8) = alpha; } sse2 fastcall static void gen2_emit_composite_spans_primitive_linear__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { float f; uint32_t u; } alpha; alpha.u = (uint8_t)(255 * opacity) << 24; gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x2, op->base.dst.y + box->y2); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x2, box->y2); gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x1, op->base.dst.y + box->y2); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x1, box->y2); gen2_emit_composite_dstcoord(sna, op->base.dst.x + box->x1, op->base.dst.y + box->y1); VERTEX(alpha.f); gen2_emit_composite_linear(sna, &op->base.src, box->x1, box->y1); } sse2 fastcall static void gen2_emit_composite_spans_primitive_identity_source__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = (float *)sna->kgem.batch + sna->kgem.nbatch; uint32_t alpha = (uint8_t)(255 * opacity) << 24; sna->kgem.nbatch += 15; v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; *((uint32_t *)v + 2) = alpha; v[3] = (op->base.src.offset[0] + box->x2) * op->base.src.scale[0]; v[4] = (op->base.src.offset[1] + box->y2) * op->base.src.scale[1]; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; *((uint32_t *)v + 7) = alpha; v[8] = (op->base.src.offset[0] + box->x1) * op->base.src.scale[0]; v[9] = v[4]; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; *((uint32_t *)v + 12) = alpha; v[13] = v[8]; v[14] = (op->base.src.offset[1] + box->y1) * op->base.src.scale[1]; } sse2 fastcall static void gen2_emit_composite_spans_primitive_affine_source__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; uint32_t alpha = (uint8_t)(255 * opacity) << 24; float *v; v = (float *)sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 15; v[0] = op->base.dst.x + box->x2; v[6] = v[1] = op->base.dst.y + box->y2; v[10] = v[5] = op->base.dst.x + box->x1; v[11] = op->base.dst.y + box->y1; *((uint32_t *)v + 2) = alpha; *((uint32_t *)v + 7) = alpha; *((uint32_t *)v + 12) = alpha; _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x2, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[3], &v[4]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[8], &v[9]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[13], &v[14]); } #endif static void gen2_emit_composite_spans_vertex(struct sna *sna, const struct sna_composite_spans_op *op, int16_t x, int16_t y, float opacity) { gen2_emit_composite_dstcoord(sna, x + op->base.dst.x, y + op->base.dst.y); BATCH((uint8_t)(opacity * 255) << 24); assert(!op->base.src.is_solid); if (op->base.src.is_linear) gen2_emit_composite_linear(sna, &op->base.src, x, y); else gen2_emit_composite_texcoord(sna, &op->base.src, x, y); } fastcall static void gen2_emit_composite_spans_primitive(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { gen2_emit_composite_spans_vertex(sna, op, box->x2, box->y2, opacity); gen2_emit_composite_spans_vertex(sna, op, box->x1, box->y2, opacity); gen2_emit_composite_spans_vertex(sna, op, box->x1, box->y1, opacity); } static void gen2_emit_spans_pipeline(struct sna *sna, const struct sna_composite_spans_op *op) { uint32_t cblend, ablend; uint32_t unwind; cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULATE | TB0C_ARG1_SEL_DIFFUSE | TB0C_ARG1_REPLICATE_ALPHA | TB0C_OUTPUT_WRITE_CURRENT; ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULATE | TB0A_ARG1_SEL_DIFFUSE | TB0A_OUTPUT_WRITE_CURRENT; if (op->base.src.is_solid) { ablend |= TB0A_ARG2_SEL_SPECULAR; cblend |= TB0C_ARG2_SEL_SPECULAR; if (op->base.dst.format == PICT_a8) cblend |= TB0C_ARG2_REPLICATE_ALPHA; } else if (op->base.dst.format == PICT_a8) { ablend |= TB0A_ARG2_SEL_TEXEL0; cblend |= TB0C_ARG2_SEL_TEXEL0 | TB0C_ARG2_REPLICATE_ALPHA; } else { if (PICT_FORMAT_RGB(op->base.src.pict_format) != 0) cblend |= TB0C_ARG2_SEL_TEXEL0; else cblend |= TB0C_ARG2_SEL_ONE | TB0C_ARG2_INVERT; if (op->base.src.is_opaque) ablend |= TB0A_ARG2_SEL_ONE; else ablend |= TB0A_ARG2_SEL_TEXEL0; } unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); BATCH(cblend); BATCH(ablend); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls2 + 1, sna->kgem.batch + unwind + 1, 2 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls2 = unwind; } static void gen2_emit_composite_spans_state(struct sna *sna, const struct sna_composite_spans_op *op) { uint32_t unwind; gen2_get_batch(sna, &op->base); gen2_emit_target(sna, &op->base); unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); BATCH(!op->base.src.is_solid << 12); BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY | S3_DIFFUSE_PRESENT); BATCH(gen2_get_blend_cntl(op->base.op, false, op->base.dst.format)); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls1 + 1, sna->kgem.batch + unwind + 1, 3 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls1 = unwind; gen2_disable_logic_op(sna); gen2_emit_spans_pipeline(sna, op); if (op->base.src.is_solid) { if (op->base.src.u.gen2.pixel != sna->render_state.gen2.specular) { BATCH(_3DSTATE_DFLT_SPECULAR_CMD); BATCH(op->base.src.u.gen2.pixel); sna->render_state.gen2.specular = op->base.src.u.gen2.pixel; } } else { uint32_t v =_3DSTATE_VERTEX_FORMAT_2_CMD | (op->base.src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_3D); if (sna->render_state.gen2.vft != v) { BATCH(v); sna->render_state.gen2.vft = v; } gen2_emit_texture(sna, &op->base.src, 0); } } fastcall static void gen2_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); if (gen2_get_rectangles(sna, &op->base, 1) == 0) { gen2_emit_composite_spans_state(sna, op); gen2_get_rectangles(sna, &op->base, 1); } op->prim_emit(sna, op, box, opacity); } static void gen2_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox); if (nbox_this_time == 0) { gen2_emit_composite_spans_state(sna, op); nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox); } nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen2_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { DBG(("%s()\n", __FUNCTION__)); gen2_vertex_flush(sna, &op->base); if (op->base.src.bo) kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen2_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { if (op >= ARRAY_SIZE(gen2_blend_op)) return false; if (gen2_composite_fallback(sna, src, NULL, dst)) return false; if (need_tiling(sna, width, height)) { if (!is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } } return true; } static bool gen2_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s(src=(%d, %d), dst=(%d, %d), size=(%d, %d))\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height)); assert(gen2_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; sna_render_composite_redirect_init(&tmp->base); if (!gen2_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) { DBG(("%s: unable to set render target\n", __FUNCTION__)); return false; } switch (gen2_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: gen2_composite_solid_init(sna, &tmp->base.src, 0); case 1: break; } assert(tmp->base.src.bo || tmp->base.src.is_solid); tmp->prim_emit = gen2_emit_composite_spans_primitive; tmp->base.floats_per_vertex = 3; if (tmp->base.src.is_solid) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_spans_primitive_constant__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_spans_primitive_constant; } } else if (tmp->base.src.is_linear) { tmp->base.floats_per_vertex += 2; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_spans_primitive_linear__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_spans_primitive_linear; } } else { assert(tmp->base.src.bo); tmp->base.floats_per_vertex += tmp->base.src.is_affine ? 2 : 3; if (tmp->base.src.transform == NULL) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_spans_primitive_identity_source__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_spans_primitive_identity_source; } } else if (tmp->base.src.is_affine) { tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2]; tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen2_emit_composite_spans_primitive_affine_source__sse2; } else #endif { tmp->prim_emit = gen2_emit_composite_spans_primitive_affine_source; } } } tmp->base.mask.bo = NULL; tmp->base.floats_per_rect = 3*tmp->base.floats_per_vertex; tmp->box = gen2_render_composite_spans_box; tmp->boxes = gen2_render_composite_spans_boxes; tmp->done = gen2_render_composite_spans_done; if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; } gen2_emit_composite_spans_state(sna, tmp); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } static void gen2_emit_fill_pipeline(struct sna *sna, const struct sna_composite_op *op) { uint32_t blend, unwind; unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); blend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_ARG1 | TB0C_ARG1_SEL_DIFFUSE | TB0C_OUTPUT_WRITE_CURRENT; if (op->dst.format == PICT_a8) blend |= TB0C_ARG1_REPLICATE_ALPHA; BATCH(blend); BATCH(TB0A_RESULT_SCALE_1X | TB0A_OP_ARG1 | TB0A_ARG1_SEL_DIFFUSE | TB0A_OUTPUT_WRITE_CURRENT); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls2 + 1, sna->kgem.batch + unwind + 1, 2 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls2 = unwind; } static void gen2_emit_fill_composite_state(struct sna *sna, const struct sna_composite_op *op, uint32_t pixel) { uint32_t ls1; gen2_get_batch(sna, op); gen2_emit_target(sna, op); ls1 = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); BATCH(0); BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); BATCH(gen2_get_blend_cntl(op->op, false, op->dst.format)); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls1 + 1, sna->kgem.batch + ls1 + 1, 3 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = ls1; else sna->render_state.gen2.ls1 = ls1; gen2_emit_fill_pipeline(sna, op); if (pixel != sna->render_state.gen2.diffuse) { BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); BATCH(pixel); sna->render_state.gen2.diffuse = pixel; } } static bool gen2_render_fill_boxes_try_blt(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { uint8_t alu; uint32_t pixel; if (op > PictOpSrc) return false; if (op == PictOpClear) { alu = GXclear; pixel = 0; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) return false; else alu = GXcopy; return sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n); } static bool gen2_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; if (op >= ARRAY_SIZE(gen2_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } #if NO_FILL_BOXES return gen2_render_fill_boxes_try_blt(sna, op, format, color, dst, dst_bo, box, n); #endif if (gen2_render_fill_boxes_try_blt(sna, op, format, color, dst, dst_bo, box, n)) return true; DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x))\n", __FUNCTION__, op, (int)format, color->red, color->green, color->blue, color->alpha)); if (too_large(dst->width, dst->height) || dst_bo->pitch < 8 || dst_bo->pitch > MAX_3D_PITCH || !gen2_check_dst_format(format)) { DBG(("%s: try blt, too large or incompatible destination\n", __FUNCTION__)); if (!gen2_check_dst_format(format)) return false; assert(dst_bo->pitch >= 8); return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } if (op == PictOpClear) pixel = 0; else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s: using shader for op=%d, format=%x, pixel=%x\n", __FUNCTION__, op, (int)format, pixel)); memset(&tmp, 0, sizeof(tmp)); tmp.op = op; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) return false; } gen2_emit_fill_composite_state(sna, &tmp, pixel); do { int n_this_time = gen2_get_rectangles(sna, &tmp, n); if (n_this_time == 0) { gen2_emit_fill_composite_state(sna, &tmp, pixel); n_this_time = gen2_get_rectangles(sna, &tmp, n); } n -= n_this_time; do { DBG((" (%d, %d), (%d, %d): %x\n", box->x1, box->y1, box->x2, box->y2, pixel)); VERTEX(box->x2); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y1); box++; } while (--n_this_time); } while (n); gen2_vertex_flush(sna, &tmp); return true; } static void gen2_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t ls1; gen2_get_batch(sna, op); gen2_emit_target(sna, op); ls1 = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); BATCH(0); BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); BATCH(S8_ENABLE_COLOR_BUFFER_WRITE); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls1 + 1, sna->kgem.batch + ls1 + 1, 3 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = ls1; else sna->render_state.gen2.ls1 = ls1; gen2_enable_logic_op(sna, op->op); gen2_emit_fill_pipeline(sna, op); if (op->src.u.gen2.pixel != sna->render_state.gen2.diffuse) { BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); BATCH(op->src.u.gen2.pixel); sna->render_state.gen2.diffuse = op->src.u.gen2.pixel; } } static void gen2_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { if (!gen2_get_rectangles(sna, &op->base, 1)) { gen2_emit_fill_state(sna, &op->base); gen2_get_rectangles(sna, &op->base, 1); } VERTEX(x+w); VERTEX(y+h); VERTEX(x); VERTEX(y+h); VERTEX(x); VERTEX(y); } fastcall static void gen2_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { if (!gen2_get_rectangles(sna, &op->base, 1)) { gen2_emit_fill_state(sna, &op->base); gen2_get_rectangles(sna, &op->base, 1); } VERTEX(box->x2); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y1); } fastcall static void gen2_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox); if (nbox_this_time == 0) { gen2_emit_fill_state(sna, &op->base); nbox_this_time = gen2_get_rectangles(sna, &op->base, nbox); } nbox -= nbox_this_time; do { VERTEX(box->x2); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y2); VERTEX(box->x1); VERTEX(box->y1); box++; } while (--nbox_this_time); } while (nbox); } static void gen2_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { gen2_vertex_flush(sna, &op->base); } static bool gen2_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *tmp) { #if NO_FILL return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp); #endif /* Prefer to use the BLT if already engaged */ if (sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(dst->drawable.width, dst->drawable.height) || dst_bo->pitch < 8 || dst_bo->pitch > MAX_3D_PITCH) return false; tmp->base.op = alu; tmp->base.dst.pixmap = dst; tmp->base.dst.width = dst->drawable.width; tmp->base.dst.height = dst->drawable.height; tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth); tmp->base.dst.bo = dst_bo; tmp->base.dst.x = tmp->base.dst.y = 0; tmp->base.floats_per_vertex = 2; tmp->base.floats_per_rect = 6; tmp->base.src.u.gen2.pixel = sna_rgba_for_color(color, dst->drawable.depth); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp); } tmp->blt = gen2_render_fill_op_blt; tmp->box = gen2_render_fill_op_box; tmp->boxes = gen2_render_fill_op_boxes; tmp->points = NULL; tmp->done = gen2_render_fill_op_done; gen2_emit_fill_state(sna, &tmp->base); return true; } static bool gen2_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen2_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; #if NO_FILL_ONE return gen2_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); #endif /* Prefer to use the BLT if already engaged */ if (gen2_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(dst->drawable.width, dst->drawable.height) || bo->pitch < 8 || bo->pitch > MAX_3D_PITCH) return false; if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (gen2_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; if (!kgem_check_bo(&sna->kgem, bo, NULL)) return false; } tmp.op = alu; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.src.u.gen2.pixel = sna_rgba_for_color(color, dst->drawable.depth); gen2_emit_fill_state(sna, &tmp); gen2_get_rectangles(sna, &tmp, 1); DBG(("%s: (%d, %d), (%d, %d): %x\n", __FUNCTION__, x1, y1, x2, y2, tmp.src.u.gen2.pixel)); VERTEX(x2); VERTEX(y2); VERTEX(x1); VERTEX(y2); VERTEX(x1); VERTEX(y1); gen2_vertex_flush(sna, &tmp); return true; } static void gen2_render_copy_setup_source(struct sna_composite_channel *channel, const DrawableRec *draw, struct kgem_bo *bo) { assert(draw->width && draw->height); channel->filter = PictFilterNearest; channel->repeat = RepeatNone; channel->width = draw->width; channel->height = draw->height; channel->scale[0] = 1.f/draw->width; channel->scale[1] = 1.f/draw->height; channel->offset[0] = 0; channel->offset[1] = 0; channel->pict_format = sna_format_for_depth(draw->depth); channel->bo = bo; channel->is_affine = 1; DBG(("%s: source=%d, (%dx%d), format=%08x\n", __FUNCTION__, bo->handle, channel->width, channel->height, channel->pict_format)); } static void gen2_emit_copy_pipeline(struct sna *sna, const struct sna_composite_op *op) { uint32_t blend, unwind; unwind = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); blend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_ARG1 | TB0C_OUTPUT_WRITE_CURRENT; if (op->dst.format == PICT_a8) blend |= TB0C_ARG1_REPLICATE_ALPHA | TB0C_ARG1_SEL_TEXEL0; else if (PICT_FORMAT_RGB(op->src.pict_format) != 0) blend |= TB0C_ARG1_SEL_TEXEL0; else blend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */ BATCH(blend); blend = TB0A_RESULT_SCALE_1X | TB0A_OP_ARG1 | TB0A_OUTPUT_WRITE_CURRENT; if (PICT_FORMAT_A(op->src.pict_format) == 0) blend |= TB0A_ARG1_SEL_ONE; else blend |= TB0A_ARG1_SEL_TEXEL0; BATCH(blend); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls2 + 1, sna->kgem.batch + unwind + 1, 2 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = unwind; else sna->render_state.gen2.ls2 = unwind; } static void gen2_emit_copy_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t ls1, v; gen2_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo)) { if (op->src.bo == op->dst.bo) BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE); else BATCH(_3DSTATE_MODES_5_CMD | PIPELINE_FLUSH_RENDER_CACHE | PIPELINE_FLUSH_TEXTURE_CACHE); kgem_clear_dirty(&sna->kgem); } gen2_emit_target(sna, op); ls1 = sna->kgem.nbatch; BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); BATCH(1<<12); BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); BATCH(S8_ENABLE_COLOR_BUFFER_WRITE); if (memcmp(sna->kgem.batch + sna->render_state.gen2.ls1 + 1, sna->kgem.batch + ls1 + 1, 3 * sizeof(uint32_t)) == 0) sna->kgem.nbatch = ls1; else sna->render_state.gen2.ls1 = ls1; gen2_enable_logic_op(sna, op->op); gen2_emit_copy_pipeline(sna, op); v = _3DSTATE_VERTEX_FORMAT_2_CMD | TEXCOORDFMT_2D; if (sna->render_state.gen2.vft != v) { BATCH(v); sna->render_state.gen2.vft = v; } gen2_emit_texture(sna, &op->src, 0); } static bool gen2_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; #if NO_COPY_BOXES if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->drawable.bitsPerPixel, box, n); #endif DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (src_bo == dst_bo || /* XXX handle overlap using 3D ? */ too_large(src->width, src->height) || src_bo->pitch > MAX_3D_PITCH || dst_bo->pitch < 8) { fallback: return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; } assert(dst_bo->pitch >= 8); memset(&tmp, 0, sizeof(tmp)); tmp.op = alu; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = sna_format_for_depth(dst->depth); tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; DBG(("%s: target=%d, format=%08x, size=%dx%d\n", __FUNCTION__, dst_bo->handle, (unsigned)tmp.dst.format, tmp.dst.width, tmp.dst.height)); sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height) || dst_bo->pitch > MAX_3D_PITCH) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, alu != GXcopy || n > 1)) goto fallback_tiled; } tmp.floats_per_vertex = 4; tmp.floats_per_rect = 12; dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; gen2_render_copy_setup_source(&tmp.src, src, src_bo); gen2_emit_copy_state(sna, &tmp); do { int n_this_time; n_this_time = gen2_get_rectangles(sna, &tmp, n); if (n_this_time == 0) { gen2_emit_copy_state(sna, &tmp); n_this_time = gen2_get_rectangles(sna, &tmp, n); } n -= n_this_time; do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); VERTEX(box->x2 + dst_dx); VERTEX(box->y2 + dst_dy); VERTEX((box->x2 + src_dx) * tmp.src.scale[0]); VERTEX((box->y2 + src_dy) * tmp.src.scale[1]); VERTEX(box->x1 + dst_dx); VERTEX(box->y2 + dst_dy); VERTEX((box->x1 + src_dx) * tmp.src.scale[0]); VERTEX((box->y2 + src_dy) * tmp.src.scale[1]); VERTEX(box->x1 + dst_dx); VERTEX(box->y1 + dst_dy); VERTEX((box->x1 + src_dx) * tmp.src.scale[0]); VERTEX((box->y1 + src_dy) * tmp.src.scale[1]); box++; } while (--n_this_time); } while (n); gen2_vertex_flush(sna, &tmp); sna_render_composite_redirect_done(sna, &tmp); return true; fallback_tiled: return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen2_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { if (!gen2_get_rectangles(sna, &op->base, 1)) { gen2_emit_copy_state(sna, &op->base); gen2_get_rectangles(sna, &op->base, 1); } VERTEX(dx+w); VERTEX(dy+h); VERTEX((sx+w)*op->base.src.scale[0]); VERTEX((sy+h)*op->base.src.scale[1]); VERTEX(dx); VERTEX(dy+h); VERTEX(sx*op->base.src.scale[0]); VERTEX((sy+h)*op->base.src.scale[1]); VERTEX(dx); VERTEX(dy); VERTEX(sx*op->base.src.scale[0]); VERTEX(sy*op->base.src.scale[1]); } static void gen2_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { gen2_vertex_flush(sna, &op->base); } static bool gen2_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *tmp) { #if NO_COPY if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp); #endif /* Prefer to use the BLT */ if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height) || src_bo->pitch > MAX_3D_PITCH || dst_bo->pitch < 8 || dst_bo->pitch > MAX_3D_PITCH) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp); } tmp->base.op = alu; tmp->base.dst.pixmap = dst; tmp->base.dst.width = dst->drawable.width; tmp->base.dst.height = dst->drawable.height; tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth); tmp->base.dst.bo = dst_bo; gen2_render_copy_setup_source(&tmp->base.src, &src->drawable, src_bo); tmp->base.mask.bo = NULL; tmp->base.floats_per_vertex = 4; tmp->base.floats_per_rect = 12; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; } tmp->blt = gen2_render_copy_blt; tmp->done = gen2_render_copy_done; gen2_emit_composite_state(sna, &tmp->base); return true; } static void gen2_render_reset(struct sna *sna) { sna->render_state.gen2.need_invariant = true; sna->render_state.gen2.logic_op_enabled = 0; sna->render_state.gen2.target = 0; sna->render_state.gen2.ls1 = 0; sna->render_state.gen2.ls2 = 0; sna->render_state.gen2.vft = 0; sna->render_state.gen2.diffuse = 0x0c0ffee0; sna->render_state.gen2.specular = 0x0c0ffee0; } static void gen2_render_flush(struct sna *sna) { assert(sna->render.vertex_index == 0); assert(sna->render.vertex_offset == 0); } static void gen2_render_context_switch(struct kgem *kgem, int new_mode) { struct sna *sna = container_of(kgem, struct sna, kgem); if (!kgem->nbatch) return; /* Reload BLT registers following a lost context */ sna->blt_state.fill_bo = 0; if (kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: GPU idle, flushing\n", __FUNCTION__)); _kgem_submit(kgem); } } const char *gen2_render_init(struct sna *sna, const char *backend) { struct sna_render *render = &sna->render; sna->kgem.context_switch = gen2_render_context_switch; /* Use the BLT (and overlay) for everything except when forced to * use the texture combiners. */ #if !NO_COMPOSITE render->composite = gen2_render_composite; render->prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS render->check_composite_spans = gen2_check_composite_spans; render->composite_spans = gen2_render_composite_spans; render->prefer_gpu |= PREFER_GPU_SPANS; #endif render->fill_boxes = gen2_render_fill_boxes; render->fill = gen2_render_fill; render->fill_one = gen2_render_fill_one; render->copy = gen2_render_copy; render->copy_boxes = gen2_render_copy_boxes; /* XXX YUV color space conversion for video? */ render->reset = gen2_render_reset; render->flush = gen2_render_flush; render->max_3d_size = MAX_3D_SIZE; render->max_3d_pitch = MAX_3D_PITCH; return "Almador (gen2)"; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen2_render.h000066400000000000000000000701541267532330400242150ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 GEN2_RENDER_H #define GEN2_RENDER_H #define CMD_3D (0x3<<29) #define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) #define PRIM3D_TRILIST (0x0<<18) #define PRIM3D_TRISTRIP (0x1<<18) #define PRIM3D_TRISTRIP_RVRSE (0x2<<18) #define PRIM3D_TRIFAN (0x3<<18) #define PRIM3D_POLY (0x4<<18) #define PRIM3D_LINELIST (0x5<<18) #define PRIM3D_LINESTRIP (0x6<<18) #define PRIM3D_RECTLIST (0x7<<18) #define PRIM3D_POINTLIST (0x8<<18) #define PRIM3D_DIB (0x9<<18) #define PRIM3D_CLEAR_RECT (0xa<<18) #define PRIM3D_ZONE_INIT (0xd<<18) #define PRIM3D_MASK (0x1f<<18) #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) #define AA_LINE_ENABLE ((1<<1) | 1) #define AA_LINE_DISABLE (1<<1) #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) #define BUF_3D_PITCH(x) (((x)/4)<<2) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) #define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) #define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ ((0x90+(stage))<<16)) #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) #define _3DSTATE_DFLT_SPECULAR_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define DEPTH_IS_Z 0 #define DEPTH_IS_W (1<<6) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 0 #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((x)<<16) #define DRAW_XMIN(x) (x) /* Dword 3 */ #define DRAW_YMAX(x) ((x)<<16) #define DRAW_XMAX(x) (x) /* Dword 4 */ #define DRAW_YORG(x) ((x)<<16) #define DRAW_XORG(x) (x) #define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) #define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) #define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) #define DISABLE_LOGIC_OP (1<<23) #define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) #define DISABLE_STENCIL_TEST (1<<21) #define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) #define DISABLE_DEPTH_BIAS (1<<11) #define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) #define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) #define DISABLE_SPEC_ADD (1<<9) #define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) #define ENABLE_FOG ((1<<7)|(1<<6)) #define DISABLE_FOG (1<<7) #define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) #define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) #define DISABLE_ALPHA_TEST (1<<5) #define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) #define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) #define DISABLE_COLOR_BLEND (1<<3) #define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) #define ENABLE_DEPTH_TEST ((1<<1)|1) #define DISABLE_DEPTH_TEST (1<<1) /* _3DSTATE_ENABLES_2, p138 */ #define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) #define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) #define DISABLE_STENCIL_WRITE (1<<21) #define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) #define DISABLE_TEX_CACHE (1<<17) #define ENABLE_DITHER ((1<<9)|(1<<8)) #define DISABLE_DITHER (1<<9) #define ENABLE_COLOR_MASK (1<<10) #define WRITEMASK_ALPHA (1<<7) #define WRITEMASK_ALPHA_SHIFT 7 #define WRITEMASK_RED (1<<6) #define WRITEMASK_RED_SHIFT 6 #define WRITEMASK_GREEN (1<<5) #define WRITEMASK_GREEN_SHIFT 5 #define WRITEMASK_BLUE (1<<4) #define WRITEMASK_BLUE_SHIFT 4 #define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) #define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) #define DISABLE_COLOR_WRITE (1<<3) #define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 #define ENABLE_DEPTH_WRITE ((1<<1)|1) #define DISABLE_DEPTH_WRITE (1<<1) /* _3DSTATE_FOG_COLOR, p139 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p140 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FOGFUNC_ENABLE (1<<31) #define FOGFUNC_VERTEX 0 #define FOGFUNC_PIXEL_EXP (1<<28) #define FOGFUNC_PIXEL_EXP2 (2<<28) #define FOGFUNC_PIXEL_LINEAR (3<<28) #define FOGSRC_INDEX_Z (1<<27) #define FOGSRC_INDEX_W ((1<<27)|(1<<25)) #define FOG_LINEAR_CONST (1<<24) #define FOG_CONST_1(x) ((x)<<4) #define ENABLE_FOG_DENSITY (1<<23) /* Dword 2 */ #define FOG_CONST_2(x) (x) /* Dword 3 */ #define FOG_DENSITY(x) (x) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ #define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) #define DISABLE_INDPT_ALPHA_BLEND (1<<23) #define ALPHA_BLENDFUNC_MASK 0x3f0000 #define ENABLE_ALPHA_BLENDFUNC (1<<21) #define ABLENDFUNC_ADD 0 #define ABLENDFUNC_SUB (1<<16) #define ABLENDFUNC_RVSE_SUB (2<<16) #define ABLENDFUNC_MIN (3<<16) #define ABLENDFUNC_MAX (4<<16) #define SRC_DST_ABLEND_MASK 0xfff #define ENABLE_SRC_ABLEND_FACTOR (1<<11) #define SRC_ABLEND_FACT(x) ((x)<<6) #define ENABLE_DST_ABLEND_FACTOR (1<<5) #define DST_ABLEND_FACT(x) (x) #define BLENDFACTOR_ZERO 0x01 #define BLENDFACTOR_ONE 0x02 #define BLENDFACTOR_SRC_COLR 0x03 #define BLENDFACTOR_INV_SRC_COLR 0x04 #define BLENDFACTOR_SRC_ALPHA 0x05 #define BLENDFACTOR_INV_SRC_ALPHA 0x06 #define BLENDFACTOR_DST_ALPHA 0x07 #define BLENDFACTOR_INV_DST_ALPHA 0x08 #define BLENDFACTOR_DST_COLR 0x09 #define BLENDFACTOR_INV_DST_COLR 0x0a #define BLENDFACTOR_SRC_ALPHA_SATURATE 0x0b #define BLENDFACTOR_CONST_COLOR 0x0c #define BLENDFACTOR_INV_CONST_COLOR 0x0d #define BLENDFACTOR_CONST_ALPHA 0x0e #define BLENDFACTOR_INV_CONST_ALPHA 0x0f #define BLENDFACTOR_MASK 0x0f /* _3DSTATE_MAP_BLEND_ARG, p152 */ #define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) #define TEXPIPE_COLOR 0 #define TEXPIPE_ALPHA (1<<18) #define TEXPIPE_KILL (2<<18) #define TEXBLEND_ARG0 0 #define TEXBLEND_ARG1 (1<<15) #define TEXBLEND_ARG2 (2<<15) #define TEXBLEND_ARG3 (3<<15) #define TEXBLENDARG_MODIFY_PARMS (1<<6) #define TEXBLENDARG_REPLICATE_ALPHA (1<<5) #define TEXBLENDARG_INV_ARG (1<<4) #define TEXBLENDARG_ONE 0 #define TEXBLENDARG_FACTOR 0x01 #define TEXBLENDARG_ACCUM 0x02 #define TEXBLENDARG_DIFFUSE 0x03 #define TEXBLENDARG_SPEC 0x04 #define TEXBLENDARG_CURRENT 0x05 #define TEXBLENDARG_TEXEL0 0x06 #define TEXBLENDARG_TEXEL1 0x07 #define TEXBLENDARG_TEXEL2 0x08 #define TEXBLENDARG_TEXEL3 0x09 #define TEXBLENDARG_FACTOR_N 0x0e /* _3DSTATE_MAP_BLEND_OP, p155 */ #define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) #if 0 # define TEXPIPE_COLOR 0 # define TEXPIPE_ALPHA (1<<18) # define TEXPIPE_KILL (2<<18) #endif #define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) #define TEXOP_OUTPUT_CURRENT 0 #define TEXOP_OUTPUT_ACCUM (1<<15) #define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) #define DISABLE_TEX_CNTRL_STAGE (1<<12) #define TEXOP_SCALE_SHIFT 9 #define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) #define TEXOP_MODIFY_PARMS (1<<8) #define TEXOP_LAST_STAGE (1<<7) #define TEXBLENDOP_KILLPIXEL 0x02 #define TEXBLENDOP_ARG1 0x01 #define TEXBLENDOP_ARG2 0x02 #define TEXBLENDOP_MODULATE 0x03 #define TEXBLENDOP_ADD 0x06 #define TEXBLENDOP_ADDSIGNED 0x07 #define TEXBLENDOP_BLEND 0x08 #define TEXBLENDOP_BLEND_AND_ADD 0x09 #define TEXBLENDOP_SUBTRACT 0x0a #define TEXBLENDOP_DOT3 0x0b #define TEXBLENDOP_DOT4 0x0c #define TEXBLENDOP_MODULATE_AND_ADD 0x0d #define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e #define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f /* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ /* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ #define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) #define DISABLE_TEX_TRANSFORM (1<<28) #define TEXTURE_SET(x) (x<<29) #define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define DISABLE_PERSPECTIVE_DIVIDE (1<<29) /* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ #define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) #define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) #define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) #define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) #define TEXBIND_SET3(x) ((x)<<12) #define TEXBIND_SET2(x) ((x)<<8) #define TEXBIND_SET1(x) ((x)<<4) #define TEXBIND_SET0(x) (x) #define TEXCOORDSRC_KEEP 0 #define TEXCOORDSRC_DEFAULT 0x01 #define TEXCOORDSRC_VTXSET_0 0x08 #define TEXCOORDSRC_VTXSET_1 0x09 #define TEXCOORDSRC_VTXSET_2 0x0a #define TEXCOORDSRC_VTXSET_3 0x0b #define TEXCOORDSRC_VTXSET_4 0x0c #define TEXCOORDSRC_VTXSET_5 0x0d #define TEXCOORDSRC_VTXSET_6 0x0e #define TEXCOORDSRC_VTXSET_7 0x0f #define MAP_UNIT(unit) ((unit)<<16) #define MAP_UNIT_MASK (0x7<<16) /* _3DSTATE_MAP_COORD_SETS, p164 */ #define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) #define TEXCOORD_SET(n) ((n)<<16) #define ENABLE_TEXCOORD_PARAMS (1<<15) #define TEXCOORDS_ARE_NORMAL (1<<14) #define TEXCOORDS_ARE_IN_TEXELUNITS 0 #define TEXCOORDTYPE_CARTESIAN 0 #define TEXCOORDTYPE_HOMOGENEOUS (1<<11) #define TEXCOORDTYPE_VECTOR (2<<11) #define TEXCOORDTYPE_MASK (0x7<<11) #define ENABLE_ADDR_V_CNTL (1<<7) #define ENABLE_ADDR_U_CNTL (1<<3) #define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) #define TEXCOORD_ADDR_U_MODE(x) (x) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP 2 #define TEXCOORDMODE_WRAP_SHORTEST 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORD_ADDR_V_MASK 0x70 #define TEXCOORD_ADDR_U_MASK 0x7 /* _3DSTATE_MAP_CUBE, p168 TODO */ #define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) #define CUBE_NEGX_ENABLE (1<<5) #define CUBE_POSX_ENABLE (1<<4) #define CUBE_NEGY_ENABLE (1<<3) #define CUBE_POSY_ENABLE (1<<2) #define CUBE_NEGZ_ENABLE (1<<1) #define CUBE_POSZ_ENABLE (1<<0) #define _3DSTATE_MAP_INFO_CMD (CMD_3D|(0x1d<<24)|(0x0<<16)|3) #define TEXMAP_INDEX(x) ((x)<<28) #define MAP_SURFACE_8BIT (1<<24) #define MAP_SURFACE_16BIT (2<<24) #define MAP_SURFACE_32BIT (3<<24) #define MAP_FORMAT_2D (0) #define MAP_FORMAT_3D_CUBE (1<<11) /* _3DSTATE_MODES_1, p190 */ #define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) #define BLENDFUNC_MASK 0x3f0000 #define ENABLE_COLR_BLND_FUNC (1<<21) #define BLENDFUNC_ADD 0 #define BLENDFUNC_SUB (1<<16) #define BLENDFUNC_RVRSE_SUB (2<<16) #define BLENDFUNC_MIN (3<<16) #define BLENDFUNC_MAX (4<<16) #define SRC_DST_BLND_MASK 0xfff #define ENABLE_SRC_BLND_FACTOR (1<<11) #define ENABLE_DST_BLND_FACTOR (1<<5) #define SRC_BLND_FACT(x) ((x)<<6) #define DST_BLND_FACT(x) (x) /* _3DSTATE_MODES_2, p192 */ #define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) #define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) #define GLOBAL_DEPTH_BIAS(x) ((x)<<14) #define ENABLE_ALPHA_TEST_FUNC (1<<13) #define ENABLE_ALPHA_REF_VALUE (1<<8) #define ALPHA_TEST_FUNC(x) ((x)<<9) #define ALPHA_REF_VALUE(x) (x) #define ALPHA_TEST_REF_MASK 0x3fff /* _3DSTATE_MODES_3, p193 */ #define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) #define DEPTH_TEST_FUNC_MASK 0x1f0000 #define ENABLE_DEPTH_TEST_FUNC (1<<20) /* Uses COMPAREFUNC */ #define DEPTH_TEST_FUNC(x) ((x)<<16) #define ENABLE_ALPHA_SHADE_MODE (1<<11) #define ENABLE_FOG_SHADE_MODE (1<<9) #define ENABLE_SPEC_SHADE_MODE (1<<7) #define ENABLE_COLOR_SHADE_MODE (1<<5) #define ALPHA_SHADE_MODE(x) ((x)<<10) #define FOG_SHADE_MODE(x) ((x)<<8) #define SPEC_SHADE_MODE(x) ((x)<<6) #define COLOR_SHADE_MODE(x) ((x)<<4) #define CULLMODE_MASK 0xf #define ENABLE_CULL_MODE (1<<3) #define CULLMODE_BOTH 0 #define CULLMODE_NONE 1 #define CULLMODE_CW 2 #define CULLMODE_CCW 3 #define SHADE_MODE_LINEAR 0 #define SHADE_MODE_FLAT 0x1 /* _3DSTATE_MODES_4, p195 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) #define LOGICOP_CLEAR 0 #define LOGICOP_NOR 0x1 #define LOGICOP_AND_INV 0x2 #define LOGICOP_COPY_INV 0x3 #define LOGICOP_AND_RVRSE 0x4 #define LOGICOP_INV 0x5 #define LOGICOP_XOR 0x6 #define LOGICOP_NAND 0x7 #define LOGICOP_AND 0x8 #define LOGICOP_EQUIV 0x9 #define LOGICOP_NOOP 0xa #define LOGICOP_OR_INV 0xb #define LOGICOP_COPY 0xc #define LOGICOP_OR_RVRSE 0xd #define LOGICOP_OR 0xe #define LOGICOP_SET 0xf #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p196 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define ENABLE_SPRITE_POINT_TEX (1<<23) #define SPRITE_POINT_TEX_ON (1<<22) #define PIPELINE_FLUSH_RENDER_CACHE (1<<18) #define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) #define FIXED_LINE_WIDTH_MASK 0xfc00 #define ENABLE_FIXED_LINE_WIDTH (1<<15) #define FIXED_LINE_WIDTH(x) ((x)<<10) #define FIXED_POINT_WIDTH_MASK 0x3ff #define ENABLE_FIXED_POINT_WIDTH (1<<9) #define FIXED_POINT_WIDTH(x) (x) /* _3DSTATE_RASTERIZATION_RULES, p198 */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) #define TRI_STRIP_PROVOKE_VRTX(x) (x) /* _3DSTATE_SCISSOR_ENABLE, p200 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* _3DSTATE_STENCIL_TEST, p202 */ #define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) #define ENABLE_STENCIL_PARMS (1<<23) #define STENCIL_OPS_MASK (0xffc000) #define STENCIL_FAIL_OP(x) ((x)<<20) #define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) #define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) #define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) #define ENABLE_STENCIL_TEST_FUNC (1<<13) /* Uses COMPAREFUNC */ #define STENCIL_TEST_FUNC(x) ((x)<<9) #define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) #define ENABLE_STENCIL_REF_VALUE (1<<8) #define STENCIL_REF_VALUE(x) (x) /* _3DSTATE_VERTEX_FORMAT, p204 */ #define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) #define VFT0_POINT_WIDTH (1<<12) #define VFT0_TEX_COUNT_MASK (7<<8) #define VFT0_TEX_COUNT_SHIFT 8 #define VFT0_TEX_COUNT(x) ((x)<<8) #define VFT0_SPEC (1<<7) #define VFT0_DIFFUSE (1<<6) #define VFT0_DEPTH_OFFSET (1<<5) #define VFT0_XYZ (1<<1) #define VFT0_XYZW (2<<1) #define VFT0_XY (3<<1) #define VFT0_XYW (4<<1) #define VFT0_XYZW_MASK (7<<1) /* _3DSTATE_VERTEX_FORMAT_2, p206 */ #define _3DSTATE_VERTEX_FORMAT_2_CMD (CMD_3D|(0x0a<<24)) #define VFT1_TEX7_FMT(x) ((x)<<14) #define VFT1_TEX6_FMT(x) ((x)<<12) #define VFT1_TEX5_FMT(x) ((x)<<10) #define VFT1_TEX4_FMT(x) ((x)<<8) #define VFT1_TEX3_FMT(x) ((x)<<6) #define VFT1_TEX2_FMT(x) ((x)<<4) #define VFT1_TEX1_FMT(x) ((x)<<2) #define VFT1_TEX0_FMT(x) (x) #define VFT1_TEX0_MASK 3 #define VFT1_TEX1_SHIFT 2 #define TEXCOORDFMT_2D 0 #define TEXCOORDFMT_3D 1 #define TEXCOORDFMT_4D 2 #define TEXCOORDFMT_1D 3 /*New stuff picked up along the way */ #define MLC_LOD_BIAS_MASK ((1<<7)-1) /* _3DSTATE_VERTEX_TRANSFORM, p207 */ #define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) #define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) /* Dword 1 */ #define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) #define DISABLE_PERSP_DIVIDE (1<<29) #define VRTX_TRANS_LOAD_MATRICES 0x7421 #define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 /* Dword 2 -> 7 are matrix elements */ /* _3DSTATE_W_STATE, p209 */ #define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) /* Dword 1 */ #define MAGIC_W_STATE_DWORD1 0x00000008 /* Dword 2 */ #define WFAR_VALUE(x) (x) /* Stipple command, carried over from the i810, apparently: */ #define _3DSTATE_STIPPLE (CMD_3D|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<((n)+4)) #define S3_POINT_WIDTH_SHIFT 23 #define S3_LINE_WIDTH_SHIFT 19 #define S3_ALPHA_SHADE_MODE_SHIFT 18 #define S3_FOG_SHADE_MODE_SHIFT 17 #define S3_SPEC_SHADE_MODE_SHIFT 16 #define S3_COLOR_SHADE_MODE_SHIFT 15 #define S3_CULL_MODE_SHIFT 13 #define S3_CULLMODE_BOTH (0) #define S3_CULLMODE_NONE (1<<13) #define S3_CULLMODE_CW (2<<13) #define S3_CULLMODE_CCW (3<<13) #define S3_POINT_WIDTH_PRESENT (1<<12) #define S3_SPEC_FOG_PRESENT (1<<11) #define S3_DIFFUSE_PRESENT (1<<10) #define S3_DEPTH_OFFSET_PRESENT (1<<9) #define S3_POSITION_SHIFT 6 #define S3_VERTEXHAS_XYZ (1<<6) #define S3_VERTEXHAS_XYZW (2<<6) #define S3_VERTEXHAS_XY (3<<6) #define S3_VERTEXHAS_XYW (4<<6) #define S3_ENABLE_SPEC_ADD (1<<5) #define S3_ENABLE_FOG (1<<4) #define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3) #define S3_ENABLE_SPRITE_POINT (1<<1) #define S3_ENABLE_ANTIALIASING 1 #define S7_ENABLE_LOGIC_OP (1<<0) #define S8_ENABLE_ALPHA_TEST (1<<31) #define S8_ALPHA_TEST_FUNC_SHIFT 28 #define S8_ALPHA_REFVALUE_SHIFT 20 #define S8_ENABLE_DEPTH_TEST (1<<19) #define S8_DEPTH_TEST_FUNC_SHIFT 16 #define S8_ENABLE_COLOR_BLEND (1<<15) #define S8_COLOR_BLEND_FUNC_SHIFT 12 #define S8_BLENDFUNC_ADD (0) #define S8_BLENDFUNC_SUB (1<<12) #define S8_BLENDFUNC_RVRSE_SUB (2<<12) #define S8_BLENDFUNC_MIN (3<<12) #define S8_BLENDFUNC_MAX (4<<12) #define S8_SRC_BLEND_FACTOR_SHIFT 8 #define S8_DST_BLEND_FACTOR_SHIFT 4 #define S8_ENABLE_DEPTH_BUFFER_WRITE (1<<3) #define S8_ENABLE_COLOR_BUFFER_WRITE (1<<2) #define _3DSTATE_LOAD_STATE_IMMEDIATE_2 (CMD_3D|(0x1d<<24)|(0x03<<16)) #define LOAD_TEXTURE_MAP(x) (1<<((x)+11)) #define LOAD_TEXTURE_BLEND_STAGE(x) (1<<((x)+7)) #define LOAD_GLOBAL_COLOR_FACTOR (1<<6) #define TM0S0_ADDRESS_MASK 0xfffffffc #define TM0S0_USE_FENCE (1<<1) #define TM0S1_HEIGHT_SHIFT 21 #define TM0S1_WIDTH_SHIFT 10 #define TM0S1_PALETTE_SELECT (1<<9) #define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) #define TM0S1_MAPSURF_FORMAT_SHIFT 6 #define MAPSURF_8BIT_INDEXED (0<<6) #define MAPSURF_8BIT (1<<6) #define MAPSURF_16BIT (2<<6) #define MAPSURF_32BIT (3<<6) #define MAPSURF_411 (4<<6) #define MAPSURF_422 (5<<6) #define MAPSURF_COMPRESSED (6<<6) #define MAPSURF_4BIT_INDEXED (7<<6) #define TM0S1_MT_FORMAT_MASK (0x7 << 3) #define TM0S1_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ #define MT_8BIT_IDX_ARGB1555 (1<<3) #define MT_8BIT_IDX_ARGB4444 (2<<3) #define MT_8BIT_IDX_AY88 (3<<3) #define MT_8BIT_IDX_ABGR8888 (4<<3) #define MT_8BIT_IDX_BUMP_88DVDU (5<<3) #define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) #define MT_8BIT_IDX_ARGB8888 (7<<3) #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_DIB_ARGB1555_8888 (4<<3) #define MT_16BIT_BUMP_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_DIB_RGB565_8888 (7<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) #define MT_32BIT_DIB_8888 (7<<3) #define MT_411_YUV411 (0<<3) /* SURFACE_411 */ #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define TM0S1_COLORSPACE_CONVERSION (1 << 2) #define TM0S1_TILED_SURFACE (1 << 1) #define TM0S1_TILE_WALK (1 << 0) #define TM0S2_PITCH_SHIFT 21 #define TM0S2_CUBE_FACE_ENA_SHIFT 15 #define TM0S2_CUBE_FACE_ENA_MASK (1<<15) #define TM0S2_MAP_FORMAT (1<<14) #define TM0S2_MAP_2D (0<<14) #define TM0S2_MAP_3D_CUBE (1<<14) #define TM0S2_VERTICAL_LINE_STRIDE (1<<13) #define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) #define TM0S2_OUTPUT_CHAN_SHIFT 10 #define TM0S2_OUTPUT_CHAN_MASK (3<<10) #define TM0S3_MIP_FILTER_MASK (0x3<<30) #define TM0S3_MIP_FILTER_SHIFT 30 #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define TM0S3_MAG_FILTER_MASK (0x3<<28) #define TM0S3_MAG_FILTER_SHIFT 28 #define TM0S3_MIN_FILTER_MASK (0x3<<26) #define TM0S3_MIN_FILTER_SHIFT 26 #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define TM0S3_LOD_BIAS_SHIFT 17 #define TM0S3_LOD_BIAS_MASK (0x1ff<<17) #define TM0S3_MAX_MIP_SHIFT 9 #define TM0S3_MAX_MIP_MASK (0xff<<9) #define TM0S3_MIN_MIP_SHIFT 3 #define TM0S3_MIN_MIP_MASK (0x3f<<3) #define TM0S3_KILL_PIXEL (1<<2) #define TM0S3_KEYED_FILTER (1<<1) #define TM0S3_CHROMA_KEY (1<<0) /* _3DSTATE_MAP_TEXEL_STREAM, p188 */ #define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) #define DISABLE_TEX_STREAM_BUMP (1<<12) #define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) #define TEX_MODIFY_UNIT_0 0 #define TEX_MODIFY_UNIT_1 (1<<8) #define ENABLE_TEX_STREAM_COORD_SET (1<<7) #define TEX_STREAM_COORD_SET(x) ((x)<<4) #define ENABLE_TEX_STREAM_MAP_IDX (1<<3) #define TEX_STREAM_MAP_IDX(x) (x) #define FLUSH_MAP_CACHE (1<<0) #define _3DSTATE_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19)) #define FILTER_TEXMAP_INDEX(x) ((x) << 16) #define MAG_MODE_FILTER_ENABLE (1 << 5) #define MIN_MODE_FILTER_ENABLE (1 << 2) #define MAG_MAPFILTER_NEAREST (0 << 3) #define MAG_MAPFILTER_LINEAR (1 << 3) #define MAG_MAPFILTER_ANISOTROPIC (2 << 3) #define MIN_MAPFILTER_NEAREST (0) #define MIN_MAPFILTER_LINEAR (1) #define MIN_MAPFILTER_ANISOTROPIC (2) #define ENABLE_KEYS (1<<15) #define DISABLE_COLOR_KEY 0 #define DISABLE_CHROMA_KEY 0 #define DISABLE_KILL_PIXEL 0 #define ENABLE_MIP_MODE_FILTER (1 << 9) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define TB0C_LAST_STAGE (1 << 31) #define TB0C_RESULT_SCALE_1X (0 << 29) #define TB0C_RESULT_SCALE_2X (1 << 29) #define TB0C_RESULT_SCALE_4X (2 << 29) #define TB0C_OP_ARG1 (1 << 25) #define TB0C_OP_MODULATE (3 << 25) #define TB0C_OUTPUT_WRITE_CURRENT (0 << 24) #define TB0C_OUTPUT_WRITE_ACCUM (1 << 24) #define TB0C_ARG3_REPLICATE_ALPHA (1<<23) #define TB0C_ARG3_INVERT (1<<22) #define TB0C_ARG3_SEL_XXX #define TB0C_ARG2_REPLICATE_ALPHA (1<<17) #define TB0C_ARG2_INVERT (1<<16) #define TB0C_ARG2_SEL_ONE (0 << 12) #define TB0C_ARG2_SEL_DIFFUSE (3 << 12) #define TB0C_ARG2_SEL_SPECULAR (4 << 12) #define TB0C_ARG2_SEL_FACTOR (1 << 12) #define TB0C_ARG2_SEL_TEXEL0 (6 << 12) #define TB0C_ARG2_SEL_TEXEL1 (7 << 12) #define TB0C_ARG2_SEL_TEXEL2 (8 << 12) #define TB0C_ARG2_SEL_TEXEL3 (9 << 12) #define TB0C_ARG1_REPLICATE_ALPHA (1<<11) #define TB0C_ARG1_INVERT (1<<10) #define TB0C_ARG1_SEL_ONE (0 << 6) #define TB0C_ARG1_SEL_DIFFUSE (3 << 6) #define TB0C_ARG1_SEL_SPECULAR (4 << 6) #define TB0C_ARG1_SEL_TEXEL0 (6 << 6) #define TB0C_ARG1_SEL_TEXEL1 (7 << 6) #define TB0C_ARG1_SEL_TEXEL2 (8 << 6) #define TB0C_ARG1_SEL_TEXEL3 (9 << 6) #define TB0C_ARG0_REPLICATE_ALPHA (1<<5) #define TB0C_ARG0_SEL_XXX #define TB0A_CTR_STAGE_ENABLE (1<<31) #define TB0A_RESULT_SCALE_1X (0 << 29) #define TB0A_RESULT_SCALE_2X (1 << 29) #define TB0A_RESULT_SCALE_4X (2 << 29) #define TB0A_OP_ARG1 (1 << 25) #define TB0A_OP_MODULATE (3 << 25) #define TB0A_OUTPUT_WRITE_CURRENT (0<<24) #define TB0A_OUTPUT_WRITE_ACCUM (1<<24) #define TB0A_CTR_STAGE_SEL_BITS_XXX #define TB0A_ARG3_SEL_XXX #define TB0A_ARG3_INVERT (1<<17) #define TB0A_ARG2_INVERT (1<<16) #define TB0A_ARG2_SEL_ONE (0 << 12) #define TB0A_ARG2_SEL_DIFFUSE (3 << 12) #define TB0A_ARG2_SEL_SPECULAR (4 << 12) #define TB0A_ARG2_SEL_TEXEL0 (6 << 12) #define TB0A_ARG2_SEL_TEXEL1 (7 << 12) #define TB0A_ARG2_SEL_TEXEL2 (8 << 12) #define TB0A_ARG2_SEL_TEXEL3 (9 << 12) #define TB0A_ARG1_INVERT (1<<10) #define TB0A_ARG1_SEL_ONE (0 << 6) #define TB0A_ARG1_SEL_DIFFUSE (3 << 6) #define TB0A_ARG1_SEL_SPECULAR (4 << 6) #define TB0A_ARG1_SEL_TEXEL0 (6 << 6) #define TB0A_ARG1_SEL_TEXEL1 (7 << 6) #define TB0A_ARG1_SEL_TEXEL2 (8 << 6) #define TB0A_ARG1_SEL_TEXEL3 (9 << 6) #endif /* GEN2_RENDER_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen3_render.c000066400000000000000000005207161267532330400242150ustar00rootroot00000000000000/* * Copyright © 2010-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_reg.h" #include "sna_video.h" #include "gen3_render.h" #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_ONE 0 #define NO_FILL_BOXES 0 #define PREFER_BLT_FILL 1 enum { SHADER_NONE = 0, SHADER_ZERO, SHADER_BLACK, SHADER_WHITE, SHADER_CONSTANT, SHADER_LINEAR, SHADER_RADIAL, SHADER_TEXTURE, SHADER_OPACITY, }; #define MAX_3D_SIZE 2048 #define MAX_3D_PITCH 8192 #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_BATCH_F(v) batch_emit_float(sna, v) #define OUT_VERTEX(v) vertex_emit(sna, v) enum gen3_radial_mode { RADIAL_ONE, RADIAL_TWO }; static const struct blendinfo { bool dst_alpha; bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen3_blend_op[] = { /* Clear */ {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO}, /* Src */ {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO}, /* Dst */ {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE}, /* Over */ {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA}, /* OverReverse */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE}, /* In */ {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO}, /* InReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA}, /* Out */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO}, /* OutReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA}, /* Atop */ {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA}, /* AtopReverse */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA}, /* Xor */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA}, /* Add */ {0, 0, BLENDFACT_ONE, BLENDFACT_ONE}, }; #define S6_COLOR_WRITE_ONLY \ (S6_COLOR_WRITE_ENABLE | \ BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | \ BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT | \ BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT) static const struct formatinfo { unsigned int fmt, xfmt; uint32_t card_fmt; bool rb_reversed; } gen3_tex_formats[] = { {PICT_a8, 0, MAPSURF_8BIT | MT_8BIT_A8, false}, {PICT_a8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_ARGB8888, false}, {PICT_x8r8g8b8, 0, MAPSURF_32BIT | MT_32BIT_XRGB8888, false}, {PICT_a8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_ABGR8888, false}, {PICT_x8b8g8r8, 0, MAPSURF_32BIT | MT_32BIT_XBGR8888, false}, #ifdef PICT_a2r10g10b10 {PICT_a2r10g10b10, PICT_x2r10g10b10, MAPSURF_32BIT | MT_32BIT_ARGB2101010, false}, {PICT_a2b10g10r10, PICT_x2b10g10r10, MAPSURF_32BIT | MT_32BIT_ABGR2101010, false}, #endif {PICT_r5g6b5, 0, MAPSURF_16BIT | MT_16BIT_RGB565, false}, {PICT_b5g6r5, 0, MAPSURF_16BIT | MT_16BIT_RGB565, true}, {PICT_a1r5g5b5, PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555, false}, {PICT_a1b5g5r5, PICT_x1b5g5r5, MAPSURF_16BIT | MT_16BIT_ARGB1555, true}, {PICT_a4r4g4b4, PICT_x4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444, false}, {PICT_a4b4g4r4, PICT_x4b4g4r4, MAPSURF_16BIT | MT_16BIT_ARGB4444, true}, }; #define xFixedToDouble(f) pixman_fixed_to_double(f) static inline bool too_large(int width, int height) { return width > MAX_3D_SIZE || height > MAX_3D_SIZE; } static inline uint32_t gen3_buf_tiling(uint32_t tiling) { uint32_t v = 0; switch (tiling) { case I915_TILING_Y: v |= BUF_3D_TILE_WALK_Y; case I915_TILING_X: v |= BUF_3D_TILED_SURFACE; case I915_TILING_NONE: break; } return v; } static inline bool gen3_check_pitch_3d(struct kgem_bo *bo) { return bo->pitch <= MAX_3D_PITCH; } static uint32_t gen3_get_blend_cntl(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t sblend = gen3_blend_op[op].src_blend; uint32_t dblend = gen3_blend_op[op].dst_blend; if (op <= PictOpSrc) /* for clear and src disable blending */ return S6_COLOR_WRITE_ONLY; /* If there's no dst alpha channel, adjust the blend op so that we'll * treat it as always 1. */ if (gen3_blend_op[op].dst_alpha) { if (PICT_FORMAT_A(dst_format) == 0) { if (sblend == BLENDFACT_DST_ALPHA) sblend = BLENDFACT_ONE; else if (sblend == BLENDFACT_INV_DST_ALPHA) sblend = BLENDFACT_ZERO; } /* gen3 engine reads 8bit color buffer into green channel * in cases like color buffer blending etc., and also writes * back green channel. So with dst_alpha blend we should use * color factor. See spec on "8-bit rendering". */ if (dst_format == PICT_a8) { if (sblend == BLENDFACT_DST_ALPHA) sblend = BLENDFACT_DST_COLR; else if (sblend == BLENDFACT_INV_DST_ALPHA) sblend = BLENDFACT_INV_DST_COLR; } } /* If the source alpha is being used, then we should only be in a case * where the source blend factor is 0, and the source blend value is the * mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen3_blend_op[op].src_alpha) { if (dblend == BLENDFACT_SRC_ALPHA) dblend = BLENDFACT_SRC_COLR; else if (dblend == BLENDFACT_INV_SRC_ALPHA) dblend = BLENDFACT_INV_SRC_COLR; } return (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT | sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT | dblend << S6_CBUF_DST_BLEND_FACT_SHIFT); } static bool gen3_check_dst_format(uint32_t format) { switch (format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: case PICT_r5g6b5: case PICT_b5g6r5: case PICT_a1r5g5b5: case PICT_x1r5g5b5: case PICT_a1b5g5r5: case PICT_x1b5g5r5: #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: case PICT_a2b10g10r10: case PICT_x2b10g10r10: #endif case PICT_a8: case PICT_a4r4g4b4: case PICT_x4r4g4b4: case PICT_a4b4g4r4: case PICT_x4b4g4r4: return true; default: return false; } } static bool gen3_dst_rb_reversed(uint32_t format) { switch (format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_r5g6b5: case PICT_a1r5g5b5: case PICT_x1r5g5b5: #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: #endif case PICT_a8: case PICT_a4r4g4b4: case PICT_x4r4g4b4: return false; default: return true; } } #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) static uint32_t gen3_get_dst_format(uint32_t format) { #define BIAS (DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8)) switch (format) { default: case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: return BIAS | COLR_BUF_ARGB8888; case PICT_r5g6b5: case PICT_b5g6r5: return BIAS | COLR_BUF_RGB565; case PICT_a1r5g5b5: case PICT_x1r5g5b5: case PICT_a1b5g5r5: case PICT_x1b5g5r5: return BIAS | COLR_BUF_ARGB1555; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: case PICT_a2b10g10r10: case PICT_x2b10g10r10: return BIAS | COLR_BUF_ARGB2AAA; #endif case PICT_a8: return BIAS | COLR_BUF_8BIT; case PICT_a4r4g4b4: case PICT_x4r4g4b4: case PICT_a4b4g4r4: case PICT_x4b4g4r4: return BIAS | COLR_BUF_ARGB4444; } #undef BIAS } static bool gen3_check_format(PicturePtr p) { switch (p->format) { case PICT_a8: case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_a2b10g10r10: #endif case PICT_r5g6b5: case PICT_b5g6r5: case PICT_a1r5g5b5: case PICT_a1b5g5r5: case PICT_a4r4g4b4: case PICT_a4b4g4r4: return true; default: return false; } } static bool gen3_check_xformat(PicturePtr p) { switch (p->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: case PICT_r5g6b5: case PICT_b5g6r5: case PICT_a1r5g5b5: case PICT_x1r5g5b5: case PICT_a1b5g5r5: case PICT_x1b5g5r5: #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: case PICT_a2b10g10r10: case PICT_x2b10g10r10: #endif case PICT_a8: case PICT_a4r4g4b4: case PICT_x4r4g4b4: case PICT_a4b4g4r4: case PICT_x4b4g4r4: return true; default: return false; } } static uint32_t gen3_texture_repeat(uint32_t repeat) { #define REPEAT(x) \ (SS3_NORMALIZED_COORDS | \ TEXCOORDMODE_##x << SS3_TCX_ADDR_MODE_SHIFT | \ TEXCOORDMODE_##x << SS3_TCY_ADDR_MODE_SHIFT) switch (repeat) { default: case RepeatNone: return REPEAT(CLAMP_BORDER); case RepeatNormal: return REPEAT(WRAP); case RepeatPad: return REPEAT(CLAMP_EDGE); case RepeatReflect: return REPEAT(MIRROR); } #undef REPEAT } static uint32_t gen3_gradient_repeat(uint32_t repeat) { #define REPEAT(x) \ (SS3_NORMALIZED_COORDS | \ TEXCOORDMODE_##x << SS3_TCX_ADDR_MODE_SHIFT | \ TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) switch (repeat) { default: case RepeatNone: return REPEAT(CLAMP_BORDER); case RepeatNormal: return REPEAT(WRAP); case RepeatPad: return REPEAT(CLAMP_EDGE); case RepeatReflect: return REPEAT(MIRROR); } #undef REPEAT } static bool gen3_check_repeat(PicturePtr p) { if (!p->repeat) return true; switch (p->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: return false; } } static uint32_t gen3_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT | FILTER_NEAREST << SS2_MIN_FILTER_SHIFT | MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT); case PictFilterBilinear: return (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT | FILTER_LINEAR << SS2_MIN_FILTER_SHIFT | MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT); } } static bool gen3_check_filter(PicturePtr p) { switch (p->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: return false; } } static inline void gen3_emit_composite_dstcoord(struct sna *sna, int16_t dstX, int16_t dstY) { OUT_VERTEX(dstX); OUT_VERTEX(dstY); } fastcall static void gen3_emit_composite_primitive_constant(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; gen3_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); gen3_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); gen3_emit_composite_dstcoord(sna, dst_x, dst_y); } fastcall static void gen3_emit_composite_boxes_constant(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[1] = box->y2 + op->dst.y; v[2] = box->x1 + op->dst.x; v[3] = box->y2 + op->dst.y; v[4] = box->x1 + op->dst.x; v[5] = box->y1 + op->dst.y; box++; v += 6; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_identity_gradient(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t dst_x, dst_y; int16_t src_x, src_y; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; gen3_emit_composite_dstcoord(sna, dst_x + r->width, dst_y + r->height); OUT_VERTEX(src_x + r->width); OUT_VERTEX(src_y + r->height); gen3_emit_composite_dstcoord(sna, dst_x, dst_y + r->height); OUT_VERTEX(src_x); OUT_VERTEX(src_y + r->height); gen3_emit_composite_dstcoord(sna, dst_x, dst_y); OUT_VERTEX(src_x); OUT_VERTEX(src_y); } fastcall static void gen3_emit_composite_boxes_identity_gradient(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[1] = box->y2 + op->dst.y; v[2] = box->x2 + op->src.offset[0]; v[3] = box->y2 + op->src.offset[1]; v[4] = box->x1 + op->dst.x; v[5] = box->y2 + op->dst.y; v[6] = box->x1 + op->src.offset[0]; v[7] = box->y2 + op->src.offset[1]; v[8] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; v[10] = box->x1 + op->src.offset[0]; v[11] = box->y1 + op->src.offset[1]; v += 12; box++; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_affine_gradient(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int16_t dst_x, dst_y; int16_t src_x, src_y; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + r->width; v[1] = dst_y + r->height; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); v[4] = dst_x; v[5] = dst_y + r->height; _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); v[8] = dst_x; v[9] = dst_y; _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } fastcall static void gen3_emit_composite_boxes_affine_gradient(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { const PictTransform *transform = op->src.transform; do { v[0] = box->x2 + op->dst.x; v[1] = box->y2 + op->dst.y; _sna_get_transformed_scaled(box->x2 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[2], &v[3]); v[4] = box->x1 + op->dst.x; v[5] = box->y2 + op->dst.y; _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[6], &v[7]); v[8] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y1 + op->src.offset[1], transform, op->src.scale, &v[10], &v[11]); box++; v += 12; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_identity_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[2] = v[6] + w * op->src.scale[0]; v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } fastcall static void gen3_emit_composite_boxes_identity_source(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[8] = v[4] = box->x1 + op->dst.x; v[5] = v[1] = box->y2 + op->dst.y; v[9] = box->y1 + op->dst.y; v[10] = v[6] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; v[2] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; v[11] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; v += 12; box++; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_identity_source_no_offset(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x; v[9] = r->dst.y; v[0] = v[4] + w; v[5] = v[1] = v[9] + h; v[10] = v[6] = r->src.x * op->src.scale[0]; v[11] = r->src.y * op->src.scale[1]; v[2] = v[6] + w * op->src.scale[0]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } fastcall static void gen3_emit_composite_boxes_identity_source_no_offset(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[10] = v[6] = box->x1 * op->src.scale[0]; v[2] = box->x2 * op->src.scale[0]; v[11] = box->y1 * op->src.scale[1]; v[7] = v[3] = box->y2 * op->src.scale[1]; v += 12; box++; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_affine_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; int src_x = r->src.x + (int)op->src.offset[0]; int src_y = r->src.y + (int)op->src.offset[1]; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + r->width; v[5] = v[1] = dst_y + r->height; v[8] = v[4] = dst_x; v[9] = dst_y; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } fastcall static void gen3_emit_composite_boxes_affine_source(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { const PictTransform *transform = op->src.transform; do { v[0] = box->x2 + op->dst.x; v[5] = v[1] = box->y2 + op->dst.y; v[8] = v[4] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; _sna_get_transformed_scaled(box->x2 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y1 + op->src.offset[1], transform, op->src.scale, &v[10], &v[11]); v += 12; box++; } while (--nbox); } fastcall static void gen3_emit_composite_primitive_constant_identity_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0]; v[2] = v[6] + w * op->mask.scale[0]; v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } fastcall static void gen3_emit_composite_primitive_constant_identity_mask_no_offset(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x; v[9] = r->dst.y; v[0] = v[4] + w; v[5] = v[1] = v[9] + h; v[10] = v[6] = r->mask.x * op->mask.scale[0]; v[11] = r->mask.y * op->mask.scale[1]; v[2] = v[6] + w * op->mask.scale[0]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } fastcall static void gen3_emit_composite_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float dst_x, dst_y; float src_x, src_y; float msk_x, msk_y; float w, h; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 18; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + w; v[1] = dst_y + h; v[2] = (src_x + w) * op->src.scale[0]; v[3] = (src_y + h) * op->src.scale[1]; v[4] = (msk_x + w) * op->mask.scale[0]; v[5] = (msk_y + h) * op->mask.scale[1]; v[6] = dst_x; v[7] = v[1]; v[8] = src_x * op->src.scale[0]; v[9] = v[3]; v[10] = msk_x * op->mask.scale[0]; v[11] =v[5]; v[12] = v[6]; v[13] = dst_y; v[14] = v[8]; v[15] = src_y * op->src.scale[1]; v[16] = v[10]; v[17] = msk_y * op->mask.scale[1]; } fastcall static void gen3_emit_composite_primitive_affine_source_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t src_x, src_y; float dst_x, dst_y; float msk_x, msk_y; float w, h; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 18; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + w; v[1] = dst_y + h; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, op->src.transform, op->src.scale, &v[2], &v[3]); v[4] = (msk_x + w) * op->mask.scale[0]; v[5] = (msk_y + h) * op->mask.scale[1]; v[6] = dst_x; v[7] = v[1]; _sna_get_transformed_scaled(src_x, src_y + r->height, op->src.transform, op->src.scale, &v[8], &v[9]); v[10] = msk_x * op->mask.scale[0]; v[11] =v[5]; v[12] = v[6]; v[13] = dst_y; _sna_get_transformed_scaled(src_x, src_y, op->src.transform, op->src.scale, &v[14], &v[15]); v[16] = v[10]; v[17] = msk_y * op->mask.scale[1]; } static void gen3_emit_composite_texcoord(struct sna *sna, const struct sna_composite_channel *channel, int16_t x, int16_t y) { float s = 0, t = 0, w = 1; switch (channel->u.gen3.type) { case SHADER_OPACITY: case SHADER_NONE: case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: case SHADER_CONSTANT: break; case SHADER_LINEAR: case SHADER_RADIAL: case SHADER_TEXTURE: x += channel->offset[0]; y += channel->offset[1]; if (channel->is_affine) { sna_get_transformed_coordinates(x, y, channel->transform, &s, &t); OUT_VERTEX(s * channel->scale[0]); OUT_VERTEX(t * channel->scale[1]); } else { sna_get_transformed_coordinates_3d(x, y, channel->transform, &s, &t, &w); OUT_VERTEX(s * channel->scale[0]); OUT_VERTEX(t * channel->scale[1]); OUT_VERTEX(0); OUT_VERTEX(w); } break; } } static void gen3_emit_composite_vertex(struct sna *sna, const struct sna_composite_op *op, int16_t srcX, int16_t srcY, int16_t maskX, int16_t maskY, int16_t dstX, int16_t dstY) { gen3_emit_composite_dstcoord(sna, dstX, dstY); gen3_emit_composite_texcoord(sna, &op->src, srcX, srcY); gen3_emit_composite_texcoord(sna, &op->mask, maskX, maskY); } fastcall static void gen3_emit_composite_primitive(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { gen3_emit_composite_vertex(sna, op, r->src.x + r->width, r->src.y + r->height, r->mask.x + r->width, r->mask.y + r->height, op->dst.x + r->dst.x + r->width, op->dst.y + r->dst.y + r->height); gen3_emit_composite_vertex(sna, op, r->src.x, r->src.y + r->height, r->mask.x, r->mask.y + r->height, op->dst.x + r->dst.x, op->dst.y + r->dst.y + r->height); gen3_emit_composite_vertex(sna, op, r->src.x, r->src.y, r->mask.x, r->mask.y, op->dst.x + r->dst.x, op->dst.y + r->dst.y); } #if defined(sse2) && !defined(__x86_64__) sse2 fastcall static void gen3_emit_composite_primitive_constant__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[4] = v[2] = r->dst.x + op->dst.x; v[5] = r->dst.y + op->dst.y; v[0] = v[2] + r->width; v[3] = v[1] = v[5] + r->height; } sse2 fastcall static void gen3_emit_composite_boxes_constant__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[3] = v[1] = box->y2 + op->dst.y; v[4] = v[2] = box->x1 + op->dst.x; v[5] = box->y1 + op->dst.y; box++; v += 6; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_identity_gradient__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t x, y; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); x = r->dst.x + op->dst.x; y = r->dst.y + op->dst.y; v[0] = x + r->width; v[5] = v[1] = y + r->height; v[8] = v[4] = x; v[9] = y; x = r->src.x + op->src.offset[0]; y = r->src.y + op->src.offset[1]; v[2] = x + r->width; v[7] = v[3] = y + r->height; v[10] = v[6] = x; v[11] = y; } sse2 fastcall static void gen3_emit_composite_boxes_identity_gradient__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[5] = v[1] = box->y2 + op->dst.y; v[8] = v[4] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; v[2] = box->x2 + op->src.offset[0]; v[7] = v[3] = box->y2 + op->src.offset[1]; v[10] = v[6] = box->x1 + op->src.offset[0]; v[11] = box->y1 + op->src.offset[1]; v += 12; box++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_affine_gradient__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int16_t dst_x, dst_y; int16_t src_x, src_y; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + r->width; v[1] = dst_y + r->height; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); v[4] = dst_x; v[5] = dst_y + r->height; _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); v[8] = dst_x; v[9] = dst_y; _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } sse2 fastcall static void gen3_emit_composite_boxes_affine_gradient__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { const PictTransform *transform = op->src.transform; do { v[0] = box->x2 + op->dst.x; v[1] = box->y2 + op->dst.y; _sna_get_transformed_scaled(box->x2 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[2], &v[3]); v[4] = box->x1 + op->dst.x; v[5] = box->y2 + op->dst.y; _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[6], &v[7]); v[8] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y1 + op->src.offset[1], transform, op->src.scale, &v[10], &v[11]); box++; v += 12; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_identity_source__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[2] = v[6] + w * op->src.scale[0]; v[11] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } sse2 fastcall static void gen3_emit_composite_boxes_identity_source__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2 + op->dst.x; v[8] = v[4] = box->x1 + op->dst.x; v[5] = v[1] = box->y2 + op->dst.y; v[9] = box->y1 + op->dst.y; v[10] = v[6] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; v[2] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; v[11] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; v[7] = v[3] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; v += 12; box++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_identity_source_no_offset__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x; v[9] = r->dst.y; v[0] = v[4] + w; v[5] = v[1] = v[9] + h; v[10] = v[6] = r->src.x * op->src.scale[0]; v[11] = r->src.y * op->src.scale[1]; v[2] = v[6] + w * op->src.scale[0]; v[7] = v[3] = v[11] + h * op->src.scale[1]; } sse2 fastcall static void gen3_emit_composite_boxes_identity_source_no_offset__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[10] = v[6] = box->x1 * op->src.scale[0]; v[2] = box->x2 * op->src.scale[0]; v[11] = box->y1 * op->src.scale[1]; v[7] = v[3] = box->y2 * op->src.scale[1]; v += 12; box++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_affine_source__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PictTransform *transform = op->src.transform; int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; int src_x = r->src.x + (int)op->src.offset[0]; int src_y = r->src.y + (int)op->src.offset[1]; float *v; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, r->width, r->height)); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + r->width; v[5] = v[1] = dst_y + r->height; v[8] = v[4] = dst_x; v[9] = dst_y; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(src_x, src_y + r->height, transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(src_x, src_y, transform, op->src.scale, &v[10], &v[11]); } sse2 fastcall static void gen3_emit_composite_boxes_affine_source__sse2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { const PictTransform *transform = op->src.transform; do { DBG(("%s: box=(%d, %d), (%d, %d), src.offset=(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, op->src.offset[0], op->src.offset[1])); v[0] = box->x2 + op->dst.x; v[5] = v[1] = box->y2 + op->dst.y; v[8] = v[4] = box->x1 + op->dst.x; v[9] = box->y1 + op->dst.y; _sna_get_transformed_scaled(box->x2 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[2], &v[3]); _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y2 + op->src.offset[1], transform, op->src.scale, &v[6], &v[7]); _sna_get_transformed_scaled(box->x1 + op->src.offset[0], box->y1 + op->src.offset[1], transform, op->src.scale, &v[10], &v[11]); v += 12; box++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_primitive_constant_identity_mask__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x + op->dst.x; v[0] = v[4] + w; v[9] = r->dst.y + op->dst.y; v[5] = v[1] = v[9] + h; v[10] = v[6] = (r->mask.x + op->mask.offset[0]) * op->mask.scale[0]; v[2] = v[6] + w * op->mask.scale[0]; v[11] = (r->mask.y + op->mask.offset[1]) * op->mask.scale[1]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } sse2 fastcall static void gen3_emit_composite_primitive_constant_identity_mask_no_offset__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float w = r->width; float h = r->height; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; assert(sna->render.vertex_used <= sna->render.vertex_size); v[8] = v[4] = r->dst.x; v[9] = r->dst.y; v[0] = v[4] + w; v[5] = v[1] = v[9] + h; v[10] = v[6] = r->mask.x * op->mask.scale[0]; v[11] = r->mask.y * op->mask.scale[1]; v[2] = v[6] + w * op->mask.scale[0]; v[7] = v[3] = v[11] + h * op->mask.scale[1]; } sse2 fastcall static void gen3_emit_composite_primitive_identity_source_mask__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float dst_x, dst_y; float src_x, src_y; float msk_x, msk_y; float w, h; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 18; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + w; v[1] = dst_y + h; v[2] = (src_x + w) * op->src.scale[0]; v[3] = (src_y + h) * op->src.scale[1]; v[4] = (msk_x + w) * op->mask.scale[0]; v[5] = (msk_y + h) * op->mask.scale[1]; v[6] = dst_x; v[7] = v[1]; v[8] = src_x * op->src.scale[0]; v[9] = v[3]; v[10] = msk_x * op->mask.scale[0]; v[11] =v[5]; v[12] = v[6]; v[13] = dst_y; v[14] = v[8]; v[15] = src_y * op->src.scale[1]; v[16] = v[10]; v[17] = msk_y * op->mask.scale[1]; } sse2 fastcall static void gen3_emit_composite_primitive_affine_source_mask__sse2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int16_t src_x, src_y; float dst_x, dst_y; float msk_x, msk_y; float w, h; float *v; dst_x = r->dst.x + op->dst.x; dst_y = r->dst.y + op->dst.y; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 18; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst_x + w; v[1] = dst_y + h; _sna_get_transformed_scaled(src_x + r->width, src_y + r->height, op->src.transform, op->src.scale, &v[2], &v[3]); v[4] = (msk_x + w) * op->mask.scale[0]; v[5] = (msk_y + h) * op->mask.scale[1]; v[6] = dst_x; v[7] = v[1]; _sna_get_transformed_scaled(src_x, src_y + r->height, op->src.transform, op->src.scale, &v[8], &v[9]); v[10] = msk_x * op->mask.scale[0]; v[11] =v[5]; v[12] = v[6]; v[13] = dst_y; _sna_get_transformed_scaled(src_x, src_y, op->src.transform, op->src.scale, &v[14], &v[15]); v[16] = v[10]; v[17] = msk_y * op->mask.scale[1]; } #endif static inline void gen3_2d_perspective(struct sna *sna, int in, int out) { gen3_fs_rcp(out, 0, gen3_fs_operand(in, W, W, W, W)); gen3_fs_mul(out, gen3_fs_operand(in, X, Y, ZERO, ONE), gen3_fs_operand_reg(out)); } static inline void gen3_linear_coord(struct sna *sna, const struct sna_composite_channel *channel, int in, int out) { int c = channel->u.gen3.constants; if (!channel->is_affine) { gen3_2d_perspective(sna, in, FS_U0); in = FS_U0; } gen3_fs_mov(out, gen3_fs_operand_zero()); gen3_fs_dp3(out, MASK_X, gen3_fs_operand(in, X, Y, ONE, ZERO), gen3_fs_operand_reg(c)); } static void gen3_radial_coord(struct sna *sna, const struct sna_composite_channel *channel, int in, int out) { int c = channel->u.gen3.constants; if (!channel->is_affine) { gen3_2d_perspective(sna, in, FS_U0); in = FS_U0; } switch (channel->u.gen3.mode) { case RADIAL_ONE: /* pdx = (x - c1x) / dr, pdy = (y - c1y) / dr; r² = pdx*pdx + pdy*pdy t = r²/sqrt(r²) - r1/dr; */ gen3_fs_mad(FS_U0, MASK_X | MASK_Y, gen3_fs_operand(in, X, Y, ZERO, ZERO), gen3_fs_operand(c, Z, Z, ZERO, ZERO), gen3_fs_operand(c, NEG_X, NEG_Y, ZERO, ZERO)); gen3_fs_dp2add(FS_U0, MASK_X, gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO), gen3_fs_operand(FS_U0, X, Y, ZERO, ZERO), gen3_fs_operand_zero()); gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U0, X, X, X, X)); gen3_fs_mad(out, 0, gen3_fs_operand(FS_U0, X, ZERO, ZERO, ZERO), gen3_fs_operand(out, X, ZERO, ZERO, ZERO), gen3_fs_operand(c, W, ZERO, ZERO, ZERO)); break; case RADIAL_TWO: /* pdx = x - c1x, pdy = y - c1y; A = dx² + dy² - dr² B = -2*(pdx*dx + pdy*dy + r1*dr); C = pdx² + pdy² - r1²; det = B*B - 4*A*C; t = (-B + sqrt (det)) / (2 * A) */ /* u0.x = pdx, u0.y = pdy, u[0].z = r1; */ gen3_fs_add(FS_U0, gen3_fs_operand(in, X, Y, ZERO, ZERO), gen3_fs_operand(c, X, Y, Z, ZERO)); /* u0.x = pdx, u0.y = pdy, u[0].z = r1, u[0].w = B; */ gen3_fs_dp3(FS_U0, MASK_W, gen3_fs_operand(FS_U0, X, Y, ONE, ZERO), gen3_fs_operand(c+1, X, Y, Z, ZERO)); /* u1.x = pdx² + pdy² - r1²; [C] */ gen3_fs_dp3(FS_U1, MASK_X, gen3_fs_operand(FS_U0, X, Y, Z, ZERO), gen3_fs_operand(FS_U0, X, Y, NEG_Z, ZERO)); /* u1.x = C, u1.y = B, u1.z=-4*A; */ gen3_fs_mov_masked(FS_U1, MASK_Y, gen3_fs_operand(FS_U0, W, W, W, W)); gen3_fs_mov_masked(FS_U1, MASK_Z, gen3_fs_operand(c, W, W, W, W)); /* u1.x = B² - 4*A*C */ gen3_fs_dp2add(FS_U1, MASK_X, gen3_fs_operand(FS_U1, X, Y, ZERO, ZERO), gen3_fs_operand(FS_U1, Z, Y, ZERO, ZERO), gen3_fs_operand_zero()); /* out.x = -B + sqrt (B² - 4*A*C), */ gen3_fs_rsq(out, MASK_X, gen3_fs_operand(FS_U1, X, X, X, X)); gen3_fs_mad(out, MASK_X, gen3_fs_operand(out, X, ZERO, ZERO, ZERO), gen3_fs_operand(FS_U1, X, ZERO, ZERO, ZERO), gen3_fs_operand(FS_U0, NEG_W, ZERO, ZERO, ZERO)); /* out.x = (-B + sqrt (B² - 4*A*C)) / (2 * A), */ gen3_fs_mul(out, gen3_fs_operand(out, X, ZERO, ZERO, ZERO), gen3_fs_operand(c+1, W, ZERO, ZERO, ZERO)); break; } } static void gen3_composite_emit_shader(struct sna *sna, const struct sna_composite_op *op, uint8_t blend) { bool dst_is_alpha = PIXMAN_FORMAT_RGB(op->dst.format) == 0; const struct sna_composite_channel *src, *mask; struct gen3_render_state *state = &sna->render_state.gen3; uint32_t shader_offset, id; int src_reg, mask_reg; int t, length; src = &op->src; mask = &op->mask; if (mask->u.gen3.type == SHADER_NONE) mask = NULL; id = (src->u.gen3.type | src->is_affine << 4 | src->alpha_fixup << 5 | src->rb_reversed << 6); if (mask) { id |= (mask->u.gen3.type << 8 | mask->is_affine << 12 | gen3_blend_op[blend].src_alpha << 13 | op->has_component_alpha << 14 | mask->alpha_fixup << 15 | mask->rb_reversed << 16); } id |= dst_is_alpha << 24; id |= op->rb_reversed << 25; if (id == state->last_shader) return; state->last_shader = id; shader_offset = sna->kgem.nbatch++; t = 0; switch (src->u.gen3.type) { case SHADER_NONE: case SHADER_OPACITY: assert(0); case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: break; case SHADER_CONSTANT: gen3_fs_dcl(FS_T8); src_reg = FS_T8; break; case SHADER_TEXTURE: case SHADER_RADIAL: case SHADER_LINEAR: gen3_fs_dcl(FS_S0); gen3_fs_dcl(FS_T0); t++; break; } if (mask == NULL) { switch (src->u.gen3.type) { case SHADER_ZERO: gen3_fs_mov(FS_OC, gen3_fs_operand_zero()); goto done; case SHADER_BLACK: if (dst_is_alpha) gen3_fs_mov(FS_OC, gen3_fs_operand_one()); else gen3_fs_mov(FS_OC, gen3_fs_operand(FS_R0, ZERO, ZERO, ZERO, ONE)); goto done; case SHADER_WHITE: gen3_fs_mov(FS_OC, gen3_fs_operand_one()); goto done; } if (src->alpha_fixup && dst_is_alpha) { gen3_fs_mov(FS_OC, gen3_fs_operand_one()); goto done; } /* No mask, so load directly to output color */ if (src->u.gen3.type != SHADER_CONSTANT) { if (dst_is_alpha || src->rb_reversed ^ op->rb_reversed) src_reg = FS_R0; else src_reg = FS_OC; } switch (src->u.gen3.type) { case SHADER_LINEAR: gen3_linear_coord(sna, src, FS_T0, FS_R0); gen3_fs_texld(src_reg, FS_S0, FS_R0); break; case SHADER_RADIAL: gen3_radial_coord(sna, src, FS_T0, FS_R0); gen3_fs_texld(src_reg, FS_S0, FS_R0); break; case SHADER_TEXTURE: if (src->is_affine) gen3_fs_texld(src_reg, FS_S0, FS_T0); else gen3_fs_texldp(src_reg, FS_S0, FS_T0); break; case SHADER_NONE: case SHADER_WHITE: case SHADER_BLACK: case SHADER_ZERO: assert(0); case SHADER_CONSTANT: break; } if (src_reg != FS_OC) { if (src->alpha_fixup) gen3_fs_mov(FS_OC, src->rb_reversed ^ op->rb_reversed ? gen3_fs_operand(src_reg, Z, Y, X, ONE) : gen3_fs_operand(src_reg, X, Y, Z, ONE)); else if (dst_is_alpha) gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, W, W, W, W)); else if (src->rb_reversed ^ op->rb_reversed) gen3_fs_mov(FS_OC, gen3_fs_operand(src_reg, Z, Y, X, W)); else gen3_fs_mov(FS_OC, gen3_fs_operand_reg(src_reg)); } else if (src->alpha_fixup) gen3_fs_mov_masked(FS_OC, MASK_W, gen3_fs_operand_one()); } else { int out_reg = FS_OC; if (op->rb_reversed) out_reg = FS_U0; switch (mask->u.gen3.type) { case SHADER_CONSTANT: gen3_fs_dcl(FS_T9); mask_reg = FS_T9; break; case SHADER_TEXTURE: case SHADER_LINEAR: case SHADER_RADIAL: gen3_fs_dcl(FS_S0 + t); /* fall through */ case SHADER_OPACITY: gen3_fs_dcl(FS_T0 + t); break; case SHADER_ZERO: case SHADER_BLACK: assert(0); case SHADER_NONE: case SHADER_WHITE: break; } t = 0; switch (src->u.gen3.type) { case SHADER_LINEAR: gen3_linear_coord(sna, src, FS_T0, FS_R0); gen3_fs_texld(FS_R0, FS_S0, FS_R0); src_reg = FS_R0; t++; break; case SHADER_RADIAL: gen3_radial_coord(sna, src, FS_T0, FS_R0); gen3_fs_texld(FS_R0, FS_S0, FS_R0); src_reg = FS_R0; t++; break; case SHADER_TEXTURE: if (src->is_affine) gen3_fs_texld(FS_R0, FS_S0, FS_T0); else gen3_fs_texldp(FS_R0, FS_S0, FS_T0); src_reg = FS_R0; t++; break; case SHADER_CONSTANT: case SHADER_NONE: case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: break; } if (src->alpha_fixup) gen3_fs_mov_masked(src_reg, MASK_W, gen3_fs_operand_one()); if (src->rb_reversed) gen3_fs_mov(src_reg, gen3_fs_operand(src_reg, Z, Y, X, W)); switch (mask->u.gen3.type) { case SHADER_LINEAR: gen3_linear_coord(sna, mask, FS_T0 + t, FS_R1); gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1); mask_reg = FS_R1; break; case SHADER_RADIAL: gen3_radial_coord(sna, mask, FS_T0 + t, FS_R1); gen3_fs_texld(FS_R1, FS_S0 + t, FS_R1); mask_reg = FS_R1; break; case SHADER_TEXTURE: if (mask->is_affine) gen3_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t); else gen3_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t); mask_reg = FS_R1; break; case SHADER_OPACITY: switch (src->u.gen3.type) { case SHADER_BLACK: case SHADER_WHITE: if (dst_is_alpha || src->u.gen3.type == SHADER_WHITE) { gen3_fs_mov(out_reg, gen3_fs_operand(FS_T0 + t, X, X, X, X)); } else { gen3_fs_mov(out_reg, gen3_fs_operand(FS_T0 + t, ZERO, ZERO, ZERO, X)); } break; default: if (dst_is_alpha) { gen3_fs_mul(out_reg, gen3_fs_operand(src_reg, W, W, W, W), gen3_fs_operand(FS_T0 + t, X, X, X, X)); } else { gen3_fs_mul(out_reg, gen3_fs_operand(src_reg, X, Y, Z, W), gen3_fs_operand(FS_T0 + t, X, X, X, X)); } } goto mask_done; case SHADER_CONSTANT: case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: case SHADER_NONE: break; } if (mask->alpha_fixup) gen3_fs_mov_masked(mask_reg, MASK_W, gen3_fs_operand_one()); if (mask->rb_reversed) gen3_fs_mov(mask_reg, gen3_fs_operand(mask_reg, Z, Y, X, W)); if (dst_is_alpha) { switch (src->u.gen3.type) { case SHADER_BLACK: case SHADER_WHITE: gen3_fs_mov(out_reg, gen3_fs_operand(mask_reg, W, W, W, W)); break; default: gen3_fs_mul(out_reg, gen3_fs_operand(src_reg, W, W, W, W), gen3_fs_operand(mask_reg, W, W, W, W)); break; } } else { /* If component alpha is active in the mask and the blend * operation uses the source alpha, then we know we don't * need the source value (otherwise we would have hit a * fallback earlier), so we provide the source alpha (src.A * * mask.X) as output color. * Conversely, if CA is set and we don't need the source alpha, * then we produce the source value (src.X * mask.X) and the * source alpha is unused. Otherwise, we provide the non-CA * source value (src.X * mask.A). */ if (op->has_component_alpha) { switch (src->u.gen3.type) { case SHADER_BLACK: if (gen3_blend_op[blend].src_alpha) gen3_fs_mov(out_reg, gen3_fs_operand_reg(mask_reg)); else gen3_fs_mov(out_reg, gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W)); break; case SHADER_WHITE: gen3_fs_mov(out_reg, gen3_fs_operand_reg(mask_reg)); break; default: if (gen3_blend_op[blend].src_alpha) gen3_fs_mul(out_reg, gen3_fs_operand(src_reg, W, W, W, W), gen3_fs_operand_reg(mask_reg)); else gen3_fs_mul(out_reg, gen3_fs_operand_reg(src_reg), gen3_fs_operand_reg(mask_reg)); break; } } else { switch (src->u.gen3.type) { case SHADER_WHITE: gen3_fs_mov(out_reg, gen3_fs_operand(mask_reg, W, W, W, W)); break; case SHADER_BLACK: gen3_fs_mov(out_reg, gen3_fs_operand(mask_reg, ZERO, ZERO, ZERO, W)); break; default: gen3_fs_mul(out_reg, gen3_fs_operand_reg(src_reg), gen3_fs_operand(mask_reg, W, W, W, W)); break; } } } mask_done: if (op->rb_reversed) gen3_fs_mov(FS_OC, gen3_fs_operand(FS_U0, Z, Y, X, W)); } done: length = sna->kgem.nbatch - shader_offset; sna->kgem.batch[shader_offset] = _3DSTATE_PIXEL_SHADER_PROGRAM | (length - 2); } static uint32_t gen3_ms_tiling(uint32_t tiling) { uint32_t v = 0; switch (tiling) { case I915_TILING_Y: v |= MS3_TILE_WALK; case I915_TILING_X: v |= MS3_TILED_SURFACE; case I915_TILING_NONE: break; } return v; } static void gen3_emit_invariant(struct sna *sna) { /* Disable independent alpha blend */ OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_MODIFY_FUNC | BLENDFUNC_ADD << IAB_FUNC_SHIFT | IAB_MODIFY_SRC_FACTOR | BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT | IAB_MODIFY_DST_FACTOR | BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT); OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | CSB_TCB(0, 0) | CSB_TCB(1, 1) | CSB_TCB(2, 2) | CSB_TCB(3, 3) | CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | I1_LOAD_S(6) | 3); OUT_BATCH(0); /* Disable texture coordinate wrap-shortest */ OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE | S4_CULLMODE_NONE | S4_VFMT_XY); OUT_BATCH(0); /* Disable fog/stencil. *Enable* write mask. */ OUT_BATCH(S6_COLOR_WRITE_ONLY); /* Disable blending, depth */ OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); OUT_BATCH(_3DSTATE_LOAD_INDIRECT); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_STIPPLE); OUT_BATCH(0x00000000); sna->render_state.gen3.need_invariant = false; } #define MAX_OBJECTS 3 /* worst case: dst + src + mask */ static void gen3_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch(&sna->kgem, 200)) { DBG(("%s: flushing batch: size %d > %d\n", __FUNCTION__, 200, sna->kgem.surface-sna->kgem.nbatch)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (!kgem_check_reloc(&sna->kgem, MAX_OBJECTS)) { DBG(("%s: flushing batch: reloc %d >= %d\n", __FUNCTION__, sna->kgem.nreloc, (int)KGEM_RELOC_SIZE(&sna->kgem) - MAX_OBJECTS)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (!kgem_check_exec(&sna->kgem, MAX_OBJECTS)) { DBG(("%s: flushing batch: exec %d >= %d\n", __FUNCTION__, sna->kgem.nexec, (int)KGEM_EXEC_SIZE(&sna->kgem) - MAX_OBJECTS - 1)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen3.need_invariant) gen3_emit_invariant(sna); #undef MAX_OBJECTS } static void gen3_emit_target(struct sna *sna, struct kgem_bo *bo, int width, int height, int format) { struct gen3_render_state *state = &sna->render_state.gen3; assert(!too_large(width, height)); /* BUF_INFO is an implicit flush, so skip if the target is unchanged. */ assert(bo->unique_id != 0); if (bo->unique_id != state->current_dst) { uint32_t v; DBG(("%s: setting new target id=%d, handle=%d\n", __FUNCTION__, bo->unique_id, bo->handle)); OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | gen3_buf_tiling(bo->tiling) | bo->pitch); OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER, 0)); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(gen3_get_dst_format(format)); v = DRAW_YMAX(height - 1) | DRAW_XMAX(width - 1); if (v != state->last_drawrect_limit) { OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(0); /* XXX dither origin? */ OUT_BATCH(0); OUT_BATCH(v); OUT_BATCH(0); state->last_drawrect_limit = v; } state->current_dst = bo->unique_id; } assert(bo->exec); kgem_bo_mark_dirty(bo); } static void gen3_emit_composite_state(struct sna *sna, const struct sna_composite_op *op) { struct gen3_render_state *state = &sna->render_state.gen3; uint32_t map[4]; uint32_t sampler[4]; struct kgem_bo *bo[2]; unsigned int tex_count, n; uint32_t ss2; gen3_get_batch(sna, op); if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { if (op->src.bo == op->dst.bo || op->mask.bo == op->dst.bo) OUT_BATCH(MI_FLUSH | MI_INVALIDATE_MAP_CACHE); else OUT_BATCH(_3DSTATE_MODES_5_CMD | PIPELINE_FLUSH_RENDER_CACHE | PIPELINE_FLUSH_TEXTURE_CACHE); kgem_clear_dirty(&sna->kgem); } gen3_emit_target(sna, op->dst.bo, op->dst.width, op->dst.height, op->dst.format); ss2 = ~0; tex_count = 0; switch (op->src.u.gen3.type) { case SHADER_OPACITY: case SHADER_NONE: assert(0); case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: break; case SHADER_CONSTANT: if (op->src.u.gen3.mode != state->last_diffuse) { OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH(op->src.u.gen3.mode); state->last_diffuse = op->src.u.gen3.mode; } break; case SHADER_LINEAR: case SHADER_RADIAL: case SHADER_TEXTURE: ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(tex_count, op->src.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); assert(op->src.card_format); map[tex_count * 2 + 0] = op->src.card_format | gen3_ms_tiling(op->src.bo->tiling) | (op->src.height - 1) << MS3_HEIGHT_SHIFT | (op->src.width - 1) << MS3_WIDTH_SHIFT; map[tex_count * 2 + 1] = (op->src.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT; sampler[tex_count * 2 + 0] = op->src.filter; sampler[tex_count * 2 + 1] = op->src.repeat | tex_count << SS3_TEXTUREMAP_INDEX_SHIFT; bo[tex_count] = op->src.bo; tex_count++; break; } switch (op->mask.u.gen3.type) { case SHADER_NONE: case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: break; case SHADER_CONSTANT: if (op->mask.u.gen3.mode != state->last_specular) { OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); OUT_BATCH(op->mask.u.gen3.mode); state->last_specular = op->mask.u.gen3.mode; } break; case SHADER_LINEAR: case SHADER_RADIAL: case SHADER_TEXTURE: ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(tex_count, op->mask.is_affine ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); assert(op->mask.card_format); map[tex_count * 2 + 0] = op->mask.card_format | gen3_ms_tiling(op->mask.bo->tiling) | (op->mask.height - 1) << MS3_HEIGHT_SHIFT | (op->mask.width - 1) << MS3_WIDTH_SHIFT; map[tex_count * 2 + 1] = (op->mask.bo->pitch / 4 - 1) << MS4_PITCH_SHIFT; sampler[tex_count * 2 + 0] = op->mask.filter; sampler[tex_count * 2 + 1] = op->mask.repeat | tex_count << SS3_TEXTUREMAP_INDEX_SHIFT; bo[tex_count] = op->mask.bo; tex_count++; break; case SHADER_OPACITY: ss2 &= ~S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(tex_count, TEXCOORDFMT_1D); break; } { uint32_t blend_offset = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1); OUT_BATCH(ss2); OUT_BATCH(gen3_get_blend_cntl(op->op, op->has_component_alpha, op->dst.format)); if (memcmp(sna->kgem.batch + state->last_blend + 1, sna->kgem.batch + blend_offset + 1, 2 * 4) == 0) sna->kgem.nbatch = blend_offset; else state->last_blend = blend_offset; } if (op->u.gen3.num_constants) { int count = op->u.gen3.num_constants; if (state->last_constants) { int last = sna->kgem.batch[state->last_constants+1]; if (last == (1 << (count >> 2)) - 1 && memcmp(&sna->kgem.batch[state->last_constants+2], op->u.gen3.constants, count * sizeof(uint32_t)) == 0) count = 0; } if (count) { state->last_constants = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | count); OUT_BATCH((1 << (count >> 2)) - 1); memcpy(sna->kgem.batch + sna->kgem.nbatch, op->u.gen3.constants, count * sizeof(uint32_t)); sna->kgem.nbatch += count; } } if (tex_count != 0) { uint32_t rewind; n = 0; if (tex_count == state->tex_count) { for (; n < tex_count; n++) { if (map[2*n+0] != state->tex_map[2*n+0] || map[2*n+1] != state->tex_map[2*n+1] || state->tex_handle[n] != bo[n]->handle || state->tex_delta[n] != bo[n]->delta) break; } } if (n < tex_count) { OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (n = 0; n < tex_count; n++) { OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, bo[n], I915_GEM_DOMAIN_SAMPLER<< 16, 0)); OUT_BATCH(map[2*n + 0]); OUT_BATCH(map[2*n + 1]); state->tex_map[2*n+0] = map[2*n+0]; state->tex_map[2*n+1] = map[2*n+1]; state->tex_handle[n] = bo[n]->handle; state->tex_delta[n] = bo[n]->delta; } state->tex_count = n; } rewind = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (n = 0; n < tex_count; n++) { OUT_BATCH(sampler[2*n + 0]); OUT_BATCH(sampler[2*n + 1]); OUT_BATCH(0); } if (state->last_sampler && memcmp(&sna->kgem.batch[state->last_sampler+1], &sna->kgem.batch[rewind + 1], (3*tex_count + 1)*sizeof(uint32_t)) == 0) sna->kgem.nbatch = rewind; else state->last_sampler = rewind; } gen3_composite_emit_shader(sna, op, op->op); } static bool gen3_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { if (!op->need_magic_ca_pass) return false; DBG(("%s(%d)\n", __FUNCTION__, sna->render.vertex_index - sna->render.vertex_start)); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0); OUT_BATCH(gen3_get_blend_cntl(PictOpAdd, true, op->dst.format)); gen3_composite_emit_shader(sna, op, PictOpAdd); OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL | (sna->render.vertex_index - sna->render.vertex_start)); OUT_BATCH(sna->render.vertex_start); sna->render_state.gen3.last_blend = 0; return true; } static void gen3_vertex_flush(struct sna *sna) { assert(sna->render.vertex_offset); DBG(("%s[%x] = %d\n", __FUNCTION__, 4*sna->render.vertex_offset, sna->render.vertex_index - sna->render.vertex_start)); sna->kgem.batch[sna->render.vertex_offset] = PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL | (sna->render.vertex_index - sna->render.vertex_start); sna->kgem.batch[sna->render.vertex_offset + 1] = sna->render.vertex_start; sna->render.vertex_offset = 0; } static int gen3_vertex_finish(struct sna *sna) { struct kgem_bo *bo; unsigned hint, size; DBG(("%s: used=%d/%d, vbo active? %d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size, sna->render.vbo ? sna->render.vbo->handle : 0)); assert(sna->render.vertex_offset == 0); assert(sna->render.vertex_used); assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_wait__locked(&sna->render); hint = CREATE_GTT_MAP; bo = sna->render.vbo; if (bo) { DBG(("%s: reloc = %d\n", __FUNCTION__, sna->render.vertex_reloc[0])); if (sna->render.vertex_reloc[0]) { sna->kgem.batch[sna->render.vertex_reloc[0]] = kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0], bo, I915_GEM_DOMAIN_VERTEX << 16 | KGEM_RELOC_FENCED, 0); sna->render.vertex_reloc[0] = 0; } sna->render.vertex_used = 0; sna->render.vertex_index = 0; sna->render.vbo = NULL; kgem_bo_destroy(&sna->kgem, bo); hint |= CREATE_CACHED | CREATE_NO_THROTTLE; } size = 256*1024; sna->render.vertices = NULL; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); while (sna->render.vbo == NULL && size > sizeof(sna->render.vertex_data)) { size /= 2; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); } if (sna->render.vbo == NULL) sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024, CREATE_GTT_MAP); if (sna->render.vbo && kgem_check_bo(&sna->kgem, sna->render.vbo, NULL)) sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo); if (sna->render.vertices == NULL) { if (sna->render.vbo) { kgem_bo_destroy(&sna->kgem, sna->render.vbo); sna->render.vbo = NULL; } sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); return 0; } assert(sna->render.vbo->snoop == false); if (sna->render.vertex_used) { memcpy(sna->render.vertices, sna->render.vertex_data, sizeof(float)*sna->render.vertex_used); } size = __kgem_bo_size(sna->render.vbo)/4; if (size >= UINT16_MAX) size = UINT16_MAX - 1; assert(size > sna->render.vertex_used); sna->render.vertex_size = size; return size - sna->render.vertex_used; } static void gen3_vertex_close(struct sna *sna) { struct kgem_bo *bo, *free_bo = NULL; unsigned int delta = 0; assert(sna->render.vertex_offset == 0); if (sna->render.vertex_reloc[0] == 0) return; DBG(("%s: used=%d/%d, vbo active? %d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size, sna->render.vbo ? sna->render.vbo->handle : 0)); bo = sna->render.vbo; if (bo) { if (sna->render.vertex_size - sna->render.vertex_used < 64) { DBG(("%s: discarding full vbo\n", __FUNCTION__)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } else if (sna->render.vertices == MAP(bo->map__cpu)) { DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, bo); if (sna->render.vertices == NULL) { DBG(("%s: discarding non-mappable vertices\n",__FUNCTION__)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } } } else { if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) { DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__, sna->render.vertex_used, sna->kgem.nbatch)); memcpy(sna->kgem.batch + sna->kgem.nbatch, sna->render.vertex_data, sna->render.vertex_used * 4); delta = sna->kgem.nbatch * 4; bo = NULL; sna->kgem.nbatch += sna->render.vertex_used; } else { DBG(("%s: new vbo: %d\n", __FUNCTION__, sna->render.vertex_used)); bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used, CREATE_NO_THROTTLE); if (bo) { assert(bo->snoop == false); kgem_bo_write(&sna->kgem, bo, sna->render.vertex_data, 4*sna->render.vertex_used); } free_bo = bo; } } DBG(("%s: reloc = %d\n", __FUNCTION__, sna->render.vertex_reloc[0])); sna->kgem.batch[sna->render.vertex_reloc[0]] = kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[0], bo, I915_GEM_DOMAIN_VERTEX << 16 | KGEM_RELOC_FENCED, delta); sna->render.vertex_reloc[0] = 0; if (sna->render.vbo == NULL) { DBG(("%s: resetting vbo\n", __FUNCTION__)); sna->render.vertex_used = 0; sna->render.vertex_index = 0; assert(sna->render.vertices == sna->render.vertex_data); assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data)); } if (free_bo) kgem_bo_destroy(&sna->kgem, free_bo); } static bool gen3_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { struct gen3_render_state *state = &sna->render_state.gen3; int ndwords, i1_cmd = 0, i1_len = 0; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; ndwords = 2; if (op->need_magic_ca_pass) ndwords += 100; if (sna->render.vertex_reloc[0] == 0) i1_len++, i1_cmd |= I1_LOAD_S(0), ndwords++; if (state->floats_per_vertex != op->floats_per_vertex) i1_len++, i1_cmd |= I1_LOAD_S(1), ndwords++; if (!kgem_check_batch(&sna->kgem, ndwords+1)) return false; if (i1_cmd) { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | i1_cmd | (i1_len - 1)); if (sna->render.vertex_reloc[0] == 0) sna->render.vertex_reloc[0] = sna->kgem.nbatch++; if (state->floats_per_vertex != op->floats_per_vertex) { state->floats_per_vertex = op->floats_per_vertex; OUT_BATCH(state->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT | state->floats_per_vertex << S1_VERTEX_PITCH_SHIFT); } } if (sna->kgem.nbatch == 2 + state->last_vertex_offset && !op->need_magic_ca_pass) { sna->render.vertex_offset = state->last_vertex_offset; } else { sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(MI_NOOP); /* to be filled later */ OUT_BATCH(MI_NOOP); sna->render.vertex_start = sna->render.vertex_index; state->last_vertex_offset = sna->render.vertex_offset; } return true; } static int gen3_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 105: 5)) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 1)) return 0; if (sna->render.vertex_offset) { gen3_vertex_flush(sna); if (gen3_magic_ca_pass(sna, op)) { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(6) | 0); OUT_BATCH(gen3_get_blend_cntl(op->op, op->has_component_alpha, op->dst.format)); gen3_composite_emit_shader(sna, op, op->op); } } return gen3_vertex_finish(sna); } inline static int gen3_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want) { int rem; DBG(("%s: want=%d, rem=%d\n", __FUNCTION__, want*op->floats_per_rect, vertex_space(sna))); assert(want); assert(sna->render.vertex_index * op->floats_per_vertex == sna->render.vertex_used); start: rem = vertex_space(sna); if (unlikely(op->floats_per_rect > rem)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen3_get_rectangles__flush(sna, op); if (unlikely(rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen3_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; sna->render.vertex_index += 3*want; assert(want); assert(sna->render.vertex_index * op->floats_per_vertex <= sna->render.vertex_size); return want; flush: DBG(("%s: flushing batch\n", __FUNCTION__)); if (sna->render.vertex_offset) { gen3_vertex_flush(sna); gen3_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); gen3_emit_composite_state(sna, op); assert(sna->render.vertex_offset == 0); assert(sna->render.vertex_reloc[0] == 0); goto start; } fastcall static void gen3_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, op->src.offset[0], op->src.offset[1], r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1], r->dst.x, r->dst.y, op->dst.x, op->dst.y, r->width, r->height)); gen3_get_rectangles(sna, op, 1); op->prim_emit(sna, op, r); } fastcall static void gen3_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; DBG(("%s: src=+(%d, %d), mask=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, op->src.offset[0], op->src.offset[1], op->mask.offset[0], op->mask.offset[1], op->dst.x, op->dst.y)); gen3_get_rectangles(sna, op, 1); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); } static void gen3_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), mask=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->src.offset[0], op->src.offset[1], op->mask.offset[0], op->mask.offset[1], op->dst.x, op->dst.y)); do { int nbox_this_time; nbox_this_time = gen3_get_rectangles(sna, op, nbox); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen3_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen3_get_rectangles(sna, op, nbox); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; assert(sna->render.vertex_used <= sna->render.vertex_size); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } static void gen3_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen3_get_rectangles(sna, op, nbox); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } static void gen3_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { DBG(("%s()\n", __FUNCTION__)); if (sna->render.vertex_offset) { gen3_vertex_flush(sna); gen3_magic_ca_pass(sna, op); } if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } static void discard_vbo(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render.vbo); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); sna->render.vertex_used = 0; sna->render.vertex_index = 0; } static void gen3_render_reset(struct sna *sna) { struct gen3_render_state *state = &sna->render_state.gen3; state->need_invariant = true; state->current_dst = 0; state->tex_count = 0; state->last_drawrect_limit = ~0U; state->last_target = 0; state->last_blend = 0; state->last_constants = 0; state->last_sampler = 0; state->last_shader = 0x7fffffff; state->last_diffuse = 0xcc00ffee; state->last_specular = 0xcc00ffee; state->floats_per_vertex = 0; state->last_floats_per_vertex = 0; state->last_vertex_offset = 0; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding vbo as next access will stall: %lx\n", __FUNCTION__, (long)sna->render.vbo->presumed_offset)); discard_vbo(sna); } sna->render.vertex_reloc[0] = 0; sna->render.vertex_offset = 0; } static void gen3_render_retire(struct kgem *kgem) { struct sna *sna; sna = container_of(kgem, struct sna, kgem); if (sna->render.vertex_reloc[0] == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) { DBG(("%s: resetting idle vbo\n", __FUNCTION__)); sna->render.vertex_used = 0; sna->render.vertex_index = 0; } } static void gen3_render_expire(struct kgem *kgem) { struct sna *sna; sna = container_of(kgem, struct sna, kgem); if (sna->render.vbo && !sna->render.vertex_used) { DBG(("%s: discarding vbo\n", __FUNCTION__)); discard_vbo(sna); } } static bool gen3_composite_channel_set_format(struct sna_composite_channel *channel, CARD32 format) { unsigned int i; for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) { if (gen3_tex_formats[i].fmt == format) { channel->card_format = gen3_tex_formats[i].card_fmt; channel->rb_reversed = gen3_tex_formats[i].rb_reversed; return true; } } return false; } static bool source_is_covered(PicturePtr picture, int x, int y, int width, int height) { int x1, y1, x2, y2; if (picture->repeat && picture->repeatType != RepeatNone) return true; if (picture->pDrawable == NULL) return false; if (picture->transform) { pixman_box16_t sample; sample.x1 = x; sample.y1 = y; sample.x2 = x + width; sample.y2 = y + height; pixman_transform_bounds(picture->transform, &sample); x1 = sample.x1; x2 = sample.x2; y1 = sample.y1; y2 = sample.y2; } else { x1 = x; y1 = y; x2 = x + width; y2 = y + height; } return x1 >= 0 && y1 >= 0 && x2 <= picture->pDrawable->width && y2 <= picture->pDrawable->height; } static bool gen3_composite_channel_set_xformat(PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int width, int height) { unsigned int i; if (PICT_FORMAT_A(picture->format) != 0) return false; if (width == 0 || height == 0) return false; if (!source_is_covered(picture, x, y, width, height)) return false; for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) { if (gen3_tex_formats[i].xfmt == picture->format) { channel->card_format = gen3_tex_formats[i].card_fmt; channel->rb_reversed = gen3_tex_formats[i].rb_reversed; channel->alpha_fixup = true; return true; } } return false; } static int gen3_init_solid(struct sna_composite_channel *channel, uint32_t color) { channel->u.gen3.mode = color; channel->u.gen3.type = SHADER_CONSTANT; if (color == 0) channel->u.gen3.type = SHADER_ZERO; else if (color == 0xff000000) channel->u.gen3.type = SHADER_BLACK; else if (color == 0xffffffff) channel->u.gen3.type = SHADER_WHITE; channel->bo = NULL; channel->is_opaque = (color >> 24) == 0xff; channel->is_affine = 1; channel->alpha_fixup = 0; channel->rb_reversed = 0; DBG(("%s: color=%08x, is_opaque=%d, type=%d\n", __FUNCTION__, color, channel->is_opaque, channel->u.gen3.type)); /* for consistency */ channel->repeat = RepeatNormal; channel->filter = PictFilterNearest; channel->pict_format = PICT_a8r8g8b8; channel->card_format = MAPSURF_32BIT | MT_32BIT_ARGB8888; return 1; } static void gen3_composite_channel_convert(struct sna_composite_channel *channel) { if (channel->u.gen3.type == SHADER_TEXTURE) channel->repeat = gen3_texture_repeat(channel->repeat); else channel->repeat = gen3_gradient_repeat(channel->repeat); channel->filter = gen3_filter(channel->filter); if (channel->card_format == 0) gen3_composite_channel_set_format(channel, channel->pict_format); assert(channel->card_format); } static bool gen3_gradient_setup(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t ox, int16_t oy) { int16_t dx, dy; if (picture->repeat == 0) { channel->repeat = RepeatNone; } else switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: channel->repeat = picture->repeatType; break; default: return false; } channel->bo = sna_render_get_gradient(sna, (PictGradient *)picture->pSourcePict); if (channel->bo == NULL) return false; channel->pict_format = PICT_a8r8g8b8; channel->card_format = MAPSURF_32BIT | MT_32BIT_ARGB8888; channel->filter = PictFilterNearest; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, PictFilterNearest, false, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); ox += dx; oy += dy; channel->transform = NULL; } else channel->transform = picture->transform; channel->width = channel->bo->pitch / 4; channel->height = 1; channel->offset[0] = ox; channel->offset[1] = oy; channel->scale[0] = channel->scale[1] = 1; return true; } static int gen3_init_linear(struct sna *sna, PicturePtr picture, struct sna_composite_op *op, struct sna_composite_channel *channel, int ox, int oy) { PictLinearGradient *linear = (PictLinearGradient *)picture->pSourcePict; float x0, y0, sf; float dx, dy, offset; int n; DBG(("%s: p1=(%f, %f), p2=(%f, %f)\n", __FUNCTION__, xFixedToDouble(linear->p1.x), xFixedToDouble(linear->p1.y), xFixedToDouble(linear->p2.x), xFixedToDouble(linear->p2.y))); if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) return 0; dx = xFixedToDouble(linear->p2.x - linear->p1.x); dy = xFixedToDouble(linear->p2.y - linear->p1.y); sf = dx*dx + dy*dy; dx /= sf; dy /= sf; x0 = xFixedToDouble(linear->p1.x); y0 = xFixedToDouble(linear->p1.y); offset = dx*x0 + dy*y0; n = op->u.gen3.num_constants; channel->u.gen3.constants = FS_C0 + n / 4; op->u.gen3.constants[n++] = dx; op->u.gen3.constants[n++] = dy; op->u.gen3.constants[n++] = -offset; op->u.gen3.constants[n++] = 0; if (!gen3_gradient_setup(sna, picture, channel, ox, oy)) return -1; channel->u.gen3.type = SHADER_LINEAR; op->u.gen3.num_constants = n; DBG(("%s: dx=%f, dy=%f, offset=%f, constants=%d\n", __FUNCTION__, dx, dy, -offset, channel->u.gen3.constants - FS_C0)); return 1; } static int gen3_init_radial(struct sna *sna, PicturePtr picture, struct sna_composite_op *op, struct sna_composite_channel *channel, int ox, int oy) { PictRadialGradient *radial = (PictRadialGradient *)picture->pSourcePict; double dx, dy, dr, r1; int n; dx = xFixedToDouble(radial->c2.x - radial->c1.x); dy = xFixedToDouble(radial->c2.y - radial->c1.y); dr = xFixedToDouble(radial->c2.radius - radial->c1.radius); r1 = xFixedToDouble(radial->c1.radius); n = op->u.gen3.num_constants; channel->u.gen3.constants = FS_C0 + n / 4; if (radial->c2.x == radial->c1.x && radial->c2.y == radial->c1.y) { if (radial->c2.radius == radial->c1.radius) { channel->u.gen3.type = SHADER_ZERO; return 1; } op->u.gen3.constants[n++] = xFixedToDouble(radial->c1.x) / dr; op->u.gen3.constants[n++] = xFixedToDouble(radial->c1.y) / dr; op->u.gen3.constants[n++] = 1. / dr; op->u.gen3.constants[n++] = -r1 / dr; channel->u.gen3.mode = RADIAL_ONE; } else { op->u.gen3.constants[n++] = -xFixedToDouble(radial->c1.x); op->u.gen3.constants[n++] = -xFixedToDouble(radial->c1.y); op->u.gen3.constants[n++] = r1; op->u.gen3.constants[n++] = -4 * (dx*dx + dy*dy - dr*dr); op->u.gen3.constants[n++] = -2 * dx; op->u.gen3.constants[n++] = -2 * dy; op->u.gen3.constants[n++] = -2 * r1 * dr; op->u.gen3.constants[n++] = 1 / (2 * (dx*dx + dy*dy - dr*dr)); channel->u.gen3.mode = RADIAL_TWO; } if (!gen3_gradient_setup(sna, picture, channel, ox, oy)) return -1; channel->u.gen3.type = SHADER_RADIAL; op->u.gen3.num_constants = n; return 1; } static bool sna_picture_is_clear(PicturePtr picture, int x, int y, int w, int h, uint32_t *color) { struct sna_pixmap *priv; if (!picture->pDrawable) return false; priv = sna_pixmap(get_drawable_pixmap(picture->pDrawable)); if (priv == NULL || !priv->clear) return false; if (!source_is_covered(picture, x, y, w, h)) return false; *color = priv->clear_color; return true; } static int gen3_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_op *op, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->card_format = 0; if (picture->pDrawable == NULL) { SourcePict *source = picture->pSourcePict; int ret = -1; switch (source->type) { case SourcePictTypeSolidFill: DBG(("%s: solid fill [%08x], format %08x\n", __FUNCTION__, (unsigned)source->solidFill.color, (unsigned)picture->format)); ret = gen3_init_solid(channel, source->solidFill.color); break; case SourcePictTypeLinear: ret = gen3_init_linear(sna, picture, op, channel, x - dst_x, y - dst_y); break; case SourcePictTypeRadial: ret = gen3_init_radial(sna, picture, op, channel, x - dst_x, y - dst_y); break; } if (ret == -1) { if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (sna_picture_is_solid(picture, &color)) { DBG(("%s: solid drawable [%08x]\n", __FUNCTION__, color)); return gen3_init_solid(channel, color); } if (sna_picture_is_clear(picture, x, y, w, h, &color)) { DBG(("%s: clear drawable [%08x]\n", __FUNCTION__, color)); return gen3_init_solid(channel, solid_color(picture->format, color)); } if (!gen3_check_repeat(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (!gen3_check_filter(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; channel->pict_format = picture->format; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat || (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen3_init_solid(channel, solid_color(picture->format, priv->clear_color)); } } } else { channel->transform = picture->transform; channel->is_affine = sna_transform_is_affine(picture->transform); } if (!gen3_composite_channel_set_format(channel, picture->format) && !gen3_composite_channel_set_xformat(picture, channel, x, y, w, h)) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); assert(channel->card_format); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height, x, y, w, h)); return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); } return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } static void gen3_align_vertex(struct sna *sna, const struct sna_composite_op *op) { int vertex_index; if (op->floats_per_vertex == sna->render_state.gen3.last_floats_per_vertex) return; DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen3.last_floats_per_vertex, op->floats_per_vertex)); assert(op->floats_per_rect == 3*op->floats_per_vertex); vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; if ((int)sna->render.vertex_size - vertex_index * op->floats_per_vertex < 2*op->floats_per_rect) { DBG(("%s: flushing vertex buffer: new index=%d, max=%d\n", __FUNCTION__, vertex_index, sna->render.vertex_size / op->floats_per_vertex)); if (gen3_vertex_finish(sna) < 2*op->floats_per_vertex) kgem_submit(&sna->kgem); vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; } sna->render.vertex_index = vertex_index; sna->render.vertex_used = vertex_index * op->floats_per_vertex; } static bool gen3_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned hint; op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.format = dst->format; op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; if (w && h) { box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } assert(op->dst.bo->unique_id); /* For single-stream mode there should be no minimum alignment * required, except that the width must be at least 2 elements. * Furthermore, it appears that the pitch must be a multiple of * 2 elements. */ if (op->dst.bo->pitch & ((2*op->dst.pixmap->drawable.bitsPerPixel >> 3) - 1)) return false; get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if ((too_large(op->dst.width, op->dst.height) || !gen3_check_pitch_3d(op->dst.bo)) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static inline uint8_t mul_8_8(uint8_t a, uint8_t b) { uint16_t t = a * (uint16_t)b + 0x7f; return ((t >> 8) + t) >> 8; } static inline uint32_t multa(uint32_t s, uint32_t m, int shift) { return mul_8_8((s >> shift) & 0xff, m >> 24) << shift; } static inline bool is_constant_ps(uint32_t type) { switch (type) { case SHADER_NONE: /* be warned! */ case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: case SHADER_CONSTANT: return true; default: return false; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(PicturePtr p) { return p->pDrawable && unattached(p->pDrawable) && untransformed(p); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool is_unhandled_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: case SourcePictTypeRadial: return false; default: return precise; } } static bool source_fallback(PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (is_unhandled_gradient(p, precise)) return true; if (!gen3_check_xformat(p) || !gen3_check_repeat(p)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen3_check_filter(p) || need_upload(p); } static bool gen3_composite_fallback(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen3_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) && gen3_blend_op[op].src_alpha && gen3_blend_op[op].src_blend != BLENDFACT_ZERO && op != PictOpOver) { DBG(("%s: component-alpha mask with op=%d, should fallback\n", __FUNCTION__, op)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback: use-cpu? %d\n", __FUNCTION__, dst_use_cpu(dst_pixmap))); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { if (src_x != msk_x || src_y != msk_y) return false; if (mask == src) { *mc = *sc; if (mc->bo) kgem_bo_reference(mc->bo); return true; } if ((src->pDrawable == NULL || mask->pDrawable != src->pDrawable)) return false; if (sc->is_solid) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen3_check_repeat(mask)) return false; if (!gen3_check_filter(mask)) return false; if (!gen3_check_format(mask)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen3_texture_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen3_filter(mask->filter); mc->pict_format = mask->format; gen3_composite_channel_set_format(mc, mask->format); assert(mc->card_format); if (mc->bo) kgem_bo_reference(mc->bo); return true; } static bool gen3_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { DBG(("%s()\n", __FUNCTION__)); if (op >= ARRAY_SIZE(gen3_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } /* Try to use the BLT engine unless it implies a * 3D -> 2D context switch. */ if (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen3_composite_fallback(sna, op, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height, tmp); if (!gen3_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) { DBG(("%s: unable to set render target\n", __FUNCTION__)); goto fallback; } tmp->op = op; tmp->rb_reversed = gen3_dst_rb_reversed(tmp->dst.format); tmp->u.gen3.num_constants = 0; tmp->src.u.gen3.type = SHADER_TEXTURE; tmp->src.is_affine = true; DBG(("%s: preparing source\n", __FUNCTION__)); switch (gen3_composite_picture(sna, src, tmp, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: tmp->src.u.gen3.type = SHADER_ZERO; break; case 1: if (mask == NULL && tmp->src.bo && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; gen3_composite_channel_convert(&tmp->src); break; } DBG(("%s: source type=%d\n", __FUNCTION__, tmp->src.u.gen3.type)); tmp->mask.u.gen3.type = SHADER_NONE; tmp->mask.is_affine = true; tmp->need_magic_ca_pass = false; tmp->has_component_alpha = false; if (mask && tmp->src.u.gen3.type != SHADER_ZERO) { if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, mask_x, mask_y)) { tmp->mask.u.gen3.type = SHADER_TEXTURE; DBG(("%s: preparing mask\n", __FUNCTION__)); switch (gen3_composite_picture(sna, mask, tmp, &tmp->mask, mask_x, mask_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_src; case 0: tmp->mask.u.gen3.type = SHADER_ZERO; break; case 1: gen3_composite_channel_convert(&tmp->mask); break; } } DBG(("%s: mask type=%d\n", __FUNCTION__, tmp->mask.u.gen3.type)); if (tmp->mask.u.gen3.type == SHADER_ZERO) { if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } tmp->src.u.gen3.type = SHADER_ZERO; tmp->mask.u.gen3.type = SHADER_NONE; } if (tmp->mask.u.gen3.type != SHADER_NONE) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { /* Check if it's component alpha that relies on a source alpha * and on the source value. We can only get one of those * into the single source value that we get to blend with. */ DBG(("%s: component-alpha mask: %d\n", __FUNCTION__, tmp->mask.u.gen3.type)); tmp->has_component_alpha = true; if (tmp->mask.u.gen3.type == SHADER_WHITE) { tmp->mask.u.gen3.type = SHADER_NONE; tmp->has_component_alpha = false; } else if (gen3_blend_op[op].src_alpha && gen3_blend_op[op].src_blend != BLENDFACT_ZERO) { if (op != PictOpOver) goto cleanup_mask; tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } else { if (tmp->mask.is_opaque) { tmp->mask.u.gen3.type = SHADER_NONE; } else if (is_constant_ps(tmp->src.u.gen3.type) && is_constant_ps(tmp->mask.u.gen3.type)) { uint32_t v; v = multa(tmp->src.u.gen3.mode, tmp->mask.u.gen3.mode, 24); v |= multa(tmp->src.u.gen3.mode, tmp->mask.u.gen3.mode, 16); v |= multa(tmp->src.u.gen3.mode, tmp->mask.u.gen3.mode, 8); v |= multa(tmp->src.u.gen3.mode, tmp->mask.u.gen3.mode, 0); DBG(("%s: combining constant source/mask: %x x %x -> %x\n", __FUNCTION__, tmp->src.u.gen3.mode, tmp->mask.u.gen3.mode, v)); tmp->src.u.gen3.type = SHADER_CONSTANT; tmp->src.u.gen3.mode = v; tmp->src.is_opaque = false; tmp->mask.u.gen3.type = SHADER_NONE; } } } } DBG(("%s: final src/mask type=%d/%d [constant? %d/%d], transform? %d/%d, affine=%d/%d\n", __FUNCTION__, tmp->src.u.gen3.type, tmp->mask.u.gen3.type, is_constant_ps(tmp->src.u.gen3.type), is_constant_ps(tmp->mask.u.gen3.type), !!tmp->src.transform, !!tmp->mask.transform, tmp->src.is_affine, tmp->mask.is_affine)); tmp->prim_emit = gen3_emit_composite_primitive; if (is_constant_ps(tmp->mask.u.gen3.type)) { switch (tmp->src.u.gen3.type) { case SHADER_NONE: case SHADER_ZERO: case SHADER_BLACK: case SHADER_WHITE: case SHADER_CONSTANT: #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_constant__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_constant__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_constant; tmp->emit_boxes = gen3_emit_composite_boxes_constant; } break; case SHADER_LINEAR: case SHADER_RADIAL: if (tmp->src.transform == NULL) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_identity_gradient__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_identity_gradient__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_identity_gradient; tmp->emit_boxes = gen3_emit_composite_boxes_identity_gradient; } } else if (tmp->src.is_affine) { tmp->src.scale[1] = tmp->src.scale[0] = 1. / tmp->src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_affine_gradient__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_affine_gradient__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_affine_gradient; tmp->emit_boxes = gen3_emit_composite_boxes_affine_gradient; } } break; case SHADER_TEXTURE: if (tmp->src.transform == NULL) { if ((tmp->src.offset[0]|tmp->src.offset[1]|tmp->dst.x|tmp->dst.y) == 0) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_identity_source_no_offset__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_identity_source_no_offset__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_identity_source_no_offset; tmp->emit_boxes = gen3_emit_composite_boxes_identity_source_no_offset; } } else { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_identity_source__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_identity_source__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_identity_source; tmp->emit_boxes = gen3_emit_composite_boxes_identity_source; } } } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_affine_source__sse2; tmp->emit_boxes = gen3_emit_composite_boxes_affine_source__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_affine_source; tmp->emit_boxes = gen3_emit_composite_boxes_affine_source; } } break; } } else if (tmp->mask.u.gen3.type == SHADER_TEXTURE) { if (tmp->mask.transform == NULL) { if (is_constant_ps(tmp->src.u.gen3.type)) { if ((tmp->mask.offset[0]|tmp->mask.offset[1]|tmp->dst.x|tmp->dst.y) == 0) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask_no_offset__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask_no_offset; } } else { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_constant_identity_mask; } } } else if (tmp->src.transform == NULL) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_identity_source_mask; } } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_primitive_affine_source_mask__sse2; } else #endif { tmp->prim_emit = gen3_emit_composite_primitive_affine_source_mask; } } } } tmp->floats_per_vertex = 2; if (!is_constant_ps(tmp->src.u.gen3.type)) tmp->floats_per_vertex += tmp->src.is_affine ? 2 : 4; if (!is_constant_ps(tmp->mask.u.gen3.type)) tmp->floats_per_vertex += tmp->mask.is_affine ? 2 : 4; DBG(("%s: floats_per_vertex = 2 + %d + %d = %d [specialised emitter? %d]\n", __FUNCTION__, !is_constant_ps(tmp->src.u.gen3.type) ? tmp->src.is_affine ? 2 : 4 : 0, !is_constant_ps(tmp->mask.u.gen3.type) ? tmp->mask.is_affine ? 2 : 4 : 0, tmp->floats_per_vertex, tmp->prim_emit != gen3_emit_composite_primitive)); tmp->floats_per_rect = 3 * tmp->floats_per_vertex; tmp->blt = gen3_render_composite_blt; tmp->box = gen3_render_composite_box; tmp->boxes = gen3_render_composite_boxes__blt; if (tmp->emit_boxes) { tmp->boxes = gen3_render_composite_boxes; tmp->thread_boxes = gen3_render_composite_boxes__thread; } tmp->done = gen3_render_composite_done; if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; } gen3_align_vertex(sna, tmp); gen3_emit_composite_state(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } static void gen3_emit_composite_spans_vertex(struct sna *sna, const struct sna_composite_spans_op *op, int16_t x, int16_t y, float opacity) { gen3_emit_composite_dstcoord(sna, x + op->base.dst.x, y + op->base.dst.y); gen3_emit_composite_texcoord(sna, &op->base.src, x, y); OUT_VERTEX(opacity); } fastcall static void gen3_emit_composite_spans_primitive_zero(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; v[2] = op->base.dst.x + box->x1; v[3] = v[1]; v[4] = v[2]; v[5] = op->base.dst.x + box->y1; } fastcall static void gen3_emit_composite_spans_primitive_zero__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; v[2] = op->base.dst.x + b->box.x1; v[3] = v[1]; v[4] = v[2]; v[5] = op->base.dst.x + b->box.y1; v += 6; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_zero_no_offset(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[3] = v[1] = box->y2; v[4] = v[2] = box->x1; v[5] = box->y1; } fastcall static void gen3_emit_composite_spans_primitive_zero_no_offset__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = b->box.x2; v[3] = v[1] = b->box.y2; v[4] = v[2] = b->box.x1; v[5] = b->box.y1; b++; v += 6; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_constant(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[6] = v[3] = op->base.dst.x + box->x1; v[4] = v[1] = op->base.dst.y + box->y2; v[7] = op->base.dst.y + box->y1; v[8] = v[5] = v[2] = opacity; } fastcall static void gen3_emit_composite_spans_primitive_constant__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[6] = v[3] = op->base.dst.x + b->box.x1; v[4] = v[1] = op->base.dst.y + b->box.y2; v[7] = op->base.dst.y + b->box.y1; v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_constant_no_offset(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[6] = v[3] = box->x1; v[4] = v[1] = box->y2; v[7] = box->y1; v[8] = v[5] = v[2] = opacity; } fastcall static void gen3_emit_composite_spans_primitive_constant_no_offset__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = b->box.x2; v[6] = v[3] = b->box.x1; v[4] = v[1] = b->box.y2; v[7] = b->box.y1; v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_identity_source(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; v[2] = (op->base.src.offset[0] + box->x2) * op->base.src.scale[0]; v[3] = (op->base.src.offset[1] + box->y2) * op->base.src.scale[1]; v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; v[7] = (op->base.src.offset[0] + box->x1) * op->base.src.scale[0]; v[8] = v[3]; v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; v[12] = v[7]; v[13] = (op->base.src.offset[1] + box->y1) * op->base.src.scale[1]; v[14] = opacity; } fastcall static void gen3_emit_composite_spans_primitive_identity_source__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; v[2] = (op->base.src.offset[0] + b->box.x2) * op->base.src.scale[0]; v[3] = (op->base.src.offset[1] + b->box.y2) * op->base.src.scale[1]; v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; v[7] = (op->base.src.offset[0] + b->box.x1) * op->base.src.scale[0]; v[8] = v[3]; v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; v[12] = v[7]; v[13] = (op->base.src.offset[1] + b->box.y1) * op->base.src.scale[1]; v[14] = b->alpha; v += 15; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_affine_source(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[6] = v[1] = op->base.dst.y + box->y2; v[10] = v[5] = op->base.dst.x + box->x1; v[11] = op->base.dst.y + box->y1; v[14] = v[9] = v[4] = opacity; _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x2, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[2], &v[3]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[7], &v[8]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[12], &v[13]); } fastcall static void gen3_emit_composite_spans_primitive_affine_source__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { PictTransform *transform = op->base.src.transform; do { v[0] = op->base.dst.x + b->box.x2; v[6] = v[1] = op->base.dst.y + b->box.y2; v[10] = v[5] = op->base.dst.x + b->box.x1; v[11] = op->base.dst.y + b->box.y1; v[14] = v[9] = v[4] = b->alpha; _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x2, (int)op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[2], &v[3]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x1, (int)op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[7], &v[8]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x1, (int)op->base.src.offset[1] + b->box.y1, transform, op->base.src.scale, &v[12], &v[13]); v += 15; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive_identity_gradient(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; v[2] = op->base.src.offset[0] + box->x2; v[3] = op->base.src.offset[1] + box->y2; v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; v[7] = op->base.src.offset[0] + box->x1; v[8] = v[3]; v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; v[12] = v[7]; v[13] = op->base.src.offset[1] + box->y1; v[14] = opacity; } fastcall static void gen3_emit_composite_spans_primitive_identity_gradient__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; v[2] = op->base.src.offset[0] + b->box.x2; v[3] = op->base.src.offset[1] + b->box.y2; v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; v[7] = op->base.src.offset[0] + b->box.x1; v[8] = v[3]; v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; v[12] = v[7]; v[13] = op->base.src.offset[1] + b->box.y1; v[14] = b->alpha; v += 15; b++; } while (--nbox); } #if defined(sse2) && !defined(__x86_64__) sse2 fastcall static void gen3_emit_composite_spans_primitive_constant__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[6] = v[3] = op->base.dst.x + box->x1; v[4] = v[1] = op->base.dst.y + box->y2; v[7] = op->base.dst.y + box->y1; v[8] = v[5] = v[2] = opacity; } sse2 fastcall static void gen3_emit_composite_spans_primitive_constant__sse2__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[6] = v[3] = op->base.dst.x + b->box.x1; v[4] = v[1] = op->base.dst.y + b->box.y2; v[7] = op->base.dst.y + b->box.y1; v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } sse2 fastcall static void gen3_render_composite_spans_constant_box__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen3_get_rectangles(sna, &op->base, 1); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[6] = v[3] = box->x1; v[4] = v[1] = box->y2; v[7] = box->y1; v[8] = v[5] = v[2] = opacity; } sse2 fastcall static void gen3_render_composite_spans_constant_thread__sse2__boxes(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen3_get_rectangles(sna, &op->base, nbox); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * 9; assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); do { v[0] = box->box.x2; v[6] = v[3] = box->box.x1; v[4] = v[1] = box->box.y2; v[7] = box->box.y1; v[8] = v[5] = v[2] = box->alpha; v += 9; box++; } while (--nbox_this_time); sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } sse2 fastcall static void gen3_emit_composite_spans_primitive_constant__sse2__no_offset(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[6] = v[3] = box->x1; v[4] = v[1] = box->y2; v[7] = box->y1; v[8] = v[5] = v[2] = opacity; } sse2 fastcall static void gen3_emit_composite_spans_primitive_constant__sse2__no_offset__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = b->box.x2; v[6] = v[3] = b->box.x1; v[4] = v[1] = b->box.y2; v[7] = b->box.y1; v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_spans_primitive_identity_source__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; v[2] = (op->base.src.offset[0] + box->x2) * op->base.src.scale[0]; v[3] = (op->base.src.offset[1] + box->y2) * op->base.src.scale[1]; v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; v[7] = (op->base.src.offset[0] + box->x1) * op->base.src.scale[0]; v[8] = v[3]; v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; v[12] = v[7]; v[13] = (op->base.src.offset[1] + box->y1) * op->base.src.scale[1]; v[14] = opacity; } sse2 fastcall static void gen3_emit_composite_spans_primitive_identity_source__sse2__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; v[2] = (op->base.src.offset[0] + b->box.x2) * op->base.src.scale[0]; v[3] = (op->base.src.offset[1] + b->box.y2) * op->base.src.scale[1]; v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; v[7] = (op->base.src.offset[0] + b->box.x1) * op->base.src.scale[0]; v[8] = v[3]; v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; v[12] = v[7]; v[13] = (op->base.src.offset[1] + b->box.y1) * op->base.src.scale[1]; v[14] = b->alpha; v += 15; b++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_spans_primitive_affine_source__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; float *v; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[6] = v[1] = op->base.dst.y + box->y2; v[10] = v[5] = op->base.dst.x + box->x1; v[11] = op->base.dst.y + box->y1; v[14] = v[9] = v[4] = opacity; _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x2, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[2], &v[3]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[7], &v[8]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + box->x1, (int)op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[12], &v[13]); } sse2 fastcall static void gen3_emit_composite_spans_primitive_affine_source__sse2__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { PictTransform *transform = op->base.src.transform; do { v[0] = op->base.dst.x + b->box.x2; v[6] = v[1] = op->base.dst.y + b->box.y2; v[10] = v[5] = op->base.dst.x + b->box.x1; v[11] = op->base.dst.y + b->box.y1; v[14] = v[9] = v[4] = b->alpha; _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x2, (int)op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[2], &v[3]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x1, (int)op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[7], &v[8]); _sna_get_transformed_scaled((int)op->base.src.offset[0] + b->box.x1, (int)op->base.src.offset[1] + b->box.y1, transform, op->base.src.scale, &v[12], &v[13]); v += 15; b++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_spans_primitive_identity_gradient__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; v[2] = op->base.src.offset[0] + box->x2; v[3] = op->base.src.offset[1] + box->y2; v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; v[7] = op->base.src.offset[0] + box->x1; v[8] = v[3]; v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; v[12] = v[7]; v[13] = op->base.src.offset[1] + box->y1; v[14] = opacity; } sse2 fastcall static void gen3_emit_composite_spans_primitive_identity_gradient__sse2__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; v[2] = op->base.src.offset[0] + b->box.x2; v[3] = op->base.src.offset[1] + b->box.y2; v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; v[7] = op->base.src.offset[0] + b->box.x1; v[8] = v[3]; v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; v[12] = v[7]; v[13] = op->base.src.offset[1] + b->box.y1; v[14] = b->alpha; v += 15; b++; } while (--nbox); } sse2 fastcall static void gen3_emit_composite_spans_primitive_affine_gradient__sse2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x2, op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[2], &v[3]); v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[7], &v[8]); v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[12], &v[13]); v[14] = opacity; } sse2 fastcall static void gen3_emit_composite_spans_primitive_affine_gradient__sse2__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { PictTransform *transform = op->base.src.transform; do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x2, op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[2], &v[3]); v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[7], &v[8]); v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y1, transform, op->base.src.scale, &v[12], &v[13]); v[14] = b->alpha; v += 15; b++; } while (--nbox); } #endif fastcall static void gen3_emit_composite_spans_primitive_affine_gradient(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { PictTransform *transform = op->base.src.transform; float *v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = op->base.dst.x + box->x2; v[1] = op->base.dst.y + box->y2; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x2, op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[2], &v[3]); v[4] = opacity; v[5] = op->base.dst.x + box->x1; v[6] = v[1]; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y2, transform, op->base.src.scale, &v[7], &v[8]); v[9] = opacity; v[10] = v[5]; v[11] = op->base.dst.y + box->y1; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y1, transform, op->base.src.scale, &v[12], &v[13]); v[14] = opacity; } fastcall static void gen3_emit_composite_spans_primitive_affine_gradient__boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { PictTransform *transform = op->base.src.transform; do { v[0] = op->base.dst.x + b->box.x2; v[1] = op->base.dst.y + b->box.y2; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x2, op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[2], &v[3]); v[4] = b->alpha; v[5] = op->base.dst.x + b->box.x1; v[6] = v[1]; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y2, transform, op->base.src.scale, &v[7], &v[8]); v[9] = b->alpha; v[10] = v[5]; v[11] = op->base.dst.y + b->box.y1; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y1, transform, op->base.src.scale, &v[12], &v[13]); v[14] = b->alpha; v += 15; b++; } while (--nbox); } fastcall static void gen3_emit_composite_spans_primitive(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { gen3_emit_composite_spans_vertex(sna, op, box->x2, box->y2, opacity); gen3_emit_composite_spans_vertex(sna, op, box->x1, box->y2, opacity); gen3_emit_composite_spans_vertex(sna, op, box->x1, box->y1, opacity); } fastcall static void gen3_render_composite_spans_constant_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen3_get_rectangles(sna, &op->base, 1); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[6] = v[3] = box->x1; v[4] = v[1] = box->y2; v[7] = box->y1; v[8] = v[5] = v[2] = opacity; } fastcall static void gen3_render_composite_spans_constant_thread_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen3_get_rectangles(sna, &op->base, nbox); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * 9; assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); do { v[0] = box->box.x2; v[6] = v[3] = box->box.x1; v[4] = v[1] = box->box.y2; v[7] = box->box.y1; v[8] = v[5] = v[2] = box->alpha; v += 9; box++; } while (--nbox_this_time); sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen3_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen3_get_rectangles(sna, &op->base, 1); op->prim_emit(sna, op, box, opacity); } static void gen3_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen3_get_rectangles(sna, &op->base, nbox); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen3_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen3_get_rectangles(sna, &op->base, nbox); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen3_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { if (sna->render.vertex_offset) gen3_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); if (op->base.src.bo) kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen3_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { if (op >= ARRAY_SIZE(gen3_blend_op)) return false; if (gen3_composite_fallback(sna, op, src, NULL, dst)) return false; if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } return true; } static bool gen3_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { bool no_offset; DBG(("%s(src=(%d, %d), dst=(%d, %d), size=(%d, %d))\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height)); assert(gen3_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } if (!gen3_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) { DBG(("%s: unable to set render target\n", __FUNCTION__)); return false; } tmp->base.op = op; tmp->base.rb_reversed = gen3_dst_rb_reversed(tmp->base.dst.format); tmp->base.src.u.gen3.type = SHADER_TEXTURE; tmp->base.src.is_affine = true; DBG(("%s: preparing source\n", __FUNCTION__)); switch (gen3_composite_picture(sna, src, &tmp->base, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: tmp->base.src.u.gen3.type = SHADER_ZERO; break; case 1: gen3_composite_channel_convert(&tmp->base.src); break; } DBG(("%s: source type=%d\n", __FUNCTION__, tmp->base.src.u.gen3.type)); if (tmp->base.src.u.gen3.type != SHADER_ZERO) tmp->base.mask.u.gen3.type = SHADER_OPACITY; no_offset = tmp->base.dst.x == 0 && tmp->base.dst.y == 0; tmp->box = gen3_render_composite_spans_box; tmp->boxes = gen3_render_composite_spans_boxes; tmp->thread_boxes = gen3_render_composite_spans_boxes__thread; tmp->done = gen3_render_composite_spans_done; tmp->prim_emit = gen3_emit_composite_spans_primitive; switch (tmp->base.src.u.gen3.type) { case SHADER_NONE: assert(0); case SHADER_ZERO: if (no_offset) { tmp->prim_emit = gen3_emit_composite_spans_primitive_zero_no_offset; tmp->emit_boxes = gen3_emit_composite_spans_primitive_zero_no_offset__boxes; } else { tmp->prim_emit = gen3_emit_composite_spans_primitive_zero; tmp->emit_boxes = gen3_emit_composite_spans_primitive_zero__boxes; } break; case SHADER_BLACK: case SHADER_WHITE: case SHADER_CONSTANT: if (no_offset) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->box = gen3_render_composite_spans_constant_box__sse2; tmp->thread_boxes = gen3_render_composite_spans_constant_thread__sse2__boxes; tmp->prim_emit = gen3_emit_composite_spans_primitive_constant__sse2__no_offset; tmp->emit_boxes = gen3_emit_composite_spans_primitive_constant__sse2__no_offset__boxes; } else #endif { tmp->box = gen3_render_composite_spans_constant_box; tmp->thread_boxes = gen3_render_composite_spans_constant_thread_boxes; tmp->prim_emit = gen3_emit_composite_spans_primitive_constant_no_offset; tmp->emit_boxes = gen3_emit_composite_spans_primitive_constant_no_offset__boxes; } } else { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_spans_primitive_constant__sse2; tmp->emit_boxes = gen3_emit_composite_spans_primitive_constant__sse2__boxes; } else #endif { tmp->prim_emit = gen3_emit_composite_spans_primitive_constant; tmp->emit_boxes = gen3_emit_composite_spans_primitive_constant__boxes; } } break; case SHADER_LINEAR: case SHADER_RADIAL: if (tmp->base.src.transform == NULL) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_spans_primitive_identity_gradient__sse2; tmp->emit_boxes = gen3_emit_composite_spans_primitive_identity_gradient__sse2__boxes; } else #endif { tmp->prim_emit = gen3_emit_composite_spans_primitive_identity_gradient; tmp->emit_boxes = gen3_emit_composite_spans_primitive_identity_gradient__boxes; } } else if (tmp->base.src.is_affine) { tmp->base.src.scale[1] = tmp->base.src.scale[0] = 1. / tmp->base.src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_spans_primitive_affine_gradient__sse2; tmp->emit_boxes = gen3_emit_composite_spans_primitive_affine_gradient__sse2__boxes; } else #endif { tmp->prim_emit = gen3_emit_composite_spans_primitive_affine_gradient; tmp->emit_boxes = gen3_emit_composite_spans_primitive_affine_gradient__boxes; } } break; case SHADER_TEXTURE: if (tmp->base.src.transform == NULL) { #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_spans_primitive_identity_source__sse2; tmp->emit_boxes = gen3_emit_composite_spans_primitive_identity_source__sse2__boxes; } else #endif { tmp->prim_emit = gen3_emit_composite_spans_primitive_identity_source; tmp->emit_boxes = gen3_emit_composite_spans_primitive_identity_source__boxes; } } else if (tmp->base.src.is_affine) { tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2]; tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2]; #if defined(sse2) && !defined(__x86_64__) if (sna->cpu_features & SSE2) { tmp->prim_emit = gen3_emit_composite_spans_primitive_affine_source__sse2; tmp->emit_boxes = gen3_emit_composite_spans_primitive_affine_source__sse2__boxes; } else #endif { tmp->prim_emit = gen3_emit_composite_spans_primitive_affine_source; tmp->emit_boxes = gen3_emit_composite_spans_primitive_affine_source__boxes; } } break; } if (tmp->emit_boxes == NULL) tmp->thread_boxes = NULL; tmp->base.mask.bo = NULL; tmp->base.floats_per_vertex = 2; if (!is_constant_ps(tmp->base.src.u.gen3.type)) tmp->base.floats_per_vertex += tmp->base.src.is_affine ? 2 : 3; tmp->base.floats_per_vertex += tmp->base.mask.u.gen3.type == SHADER_OPACITY; tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex; if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; } gen3_align_vertex(sna, &tmp->base); gen3_emit_composite_state(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } static void gen3_emit_video_state(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, PixmapPtr pixmap, struct kgem_bo *dst_bo, int width, int height, bool bilinear) { struct gen3_render_state *state = &sna->render_state.gen3; uint32_t id, ms3, rewind; gen3_emit_target(sna, dst_bo, width, height, sna_format_for_depth(pixmap->drawable.depth)); /* XXX share with composite? Is it worth the effort? */ if ((state->last_shader & (1<<31)) == 0) { OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2); OUT_BATCH((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT)); OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); OUT_BATCH((2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) | (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE); state->last_blend = 0; state->floats_per_vertex = 4; } if (!is_planar_fourcc(frame->id)) { rewind = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4); OUT_BATCH(0x0000001); /* constant 0 */ /* constant 0: brightness/contrast */ OUT_BATCH_F(video->brightness / 128.0); OUT_BATCH_F(video->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); if (state->last_constants && memcmp(&sna->kgem.batch[state->last_constants], &sna->kgem.batch[rewind], 6*sizeof(uint32_t)) == 0) sna->kgem.nbatch = rewind; else state->last_constants = rewind; rewind = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3); OUT_BATCH(0x00000001); OUT_BATCH(SS2_COLORSPACE_CONVERSION | (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); if (state->last_sampler && memcmp(&sna->kgem.batch[state->last_sampler], &sna->kgem.batch[rewind], 5*sizeof(uint32_t)) == 0) sna->kgem.nbatch = rewind; else state->last_sampler = rewind; OUT_BATCH(_3DSTATE_MAP_STATE | 3); OUT_BATCH(0x00000001); /* texture map #1 */ OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, frame->bo, I915_GEM_DOMAIN_SAMPLER << 16, 0)); ms3 = MAPSURF_422; switch (frame->id) { case FOURCC_YUY2: ms3 |= MT_422_YCRCB_NORMAL; break; case FOURCC_UYVY: ms3 |= MT_422_YCRCB_SWAPY; break; } ms3 |= (frame->height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (frame->width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((frame->pitch[0] / 4) - 1) << MS4_PITCH_SHIFT); id = 1<<31 | 1<<1 | !!video->brightness; if (state->last_shader != id) { state->last_shader = id; id = sna->kgem.nbatch++; gen3_fs_dcl(FS_S0); gen3_fs_dcl(FS_T0); gen3_fs_texld(FS_OC, FS_S0, FS_T0); if (video->brightness != 0) { gen3_fs_add(FS_OC, gen3_fs_operand_reg(FS_OC), gen3_fs_operand(FS_C0, X, X, X, ZERO)); } sna->kgem.batch[id] = _3DSTATE_PIXEL_SHADER_PROGRAM | (sna->kgem.nbatch - id - 2); } } else { /* For the planar formats, we set up three samplers -- * one for each plane, in a Y8 format. Because I * couldn't get the special PLANAR_TO_PACKED * shader setup to work, I did the manual pixel shader: * * y' = y - .0625 * u' = u - .5 * v' = v - .5; * * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' * * register assignment: * r0 = (y',u',v',0) * r1 = (y,y,y,y) * r2 = (u,u,u,u) * r3 = (v,v,v,v) * OC = (r,g,b,1) */ rewind = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2)); OUT_BATCH(0x000001f); /* constants 0-4 */ /* constant 0: normalization offsets */ OUT_BATCH_F(-0.0625); OUT_BATCH_F(-0.5); OUT_BATCH_F(-0.5); OUT_BATCH_F(0.0); /* constant 1: r coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(0.0); OUT_BATCH_F(1.5958); OUT_BATCH_F(0.0); /* constant 2: g coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(-0.39173); OUT_BATCH_F(-0.81290); OUT_BATCH_F(0.0); /* constant 3: b coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(2.017); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); /* constant 4: brightness/contrast */ OUT_BATCH_F(video->brightness / 128.0); OUT_BATCH_F(video->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); if (state->last_constants && memcmp(&sna->kgem.batch[state->last_constants], &sna->kgem.batch[rewind], 22*sizeof(uint32_t)) == 0) sna->kgem.nbatch = rewind; else state->last_constants = rewind; rewind = sna->kgem.nbatch; OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9); OUT_BATCH(0x00000007); /* sampler 0 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 1 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (1 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 2 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (2 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); if (state->last_sampler && memcmp(&sna->kgem.batch[state->last_sampler], &sna->kgem.batch[rewind], 11*sizeof(uint32_t)) == 0) sna->kgem.nbatch = rewind; else state->last_sampler = rewind; OUT_BATCH(_3DSTATE_MAP_STATE | 9); OUT_BATCH(0x00000007); OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, frame->bo, I915_GEM_DOMAIN_SAMPLER << 16, 0)); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (frame->height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (frame->width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); /* check to see if Y has special pitch than normal * double u/v pitch, e.g i915 XvMC hw requires at * least 1K alignment, so Y pitch might * be same as U/V's.*/ if (frame->pitch[1]) OUT_BATCH(((frame->pitch[1] / 4) - 1) << MS4_PITCH_SHIFT); else OUT_BATCH(((frame->pitch[0] * 2 / 4) - 1) << MS4_PITCH_SHIFT); OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, frame->bo, I915_GEM_DOMAIN_SAMPLER << 16, frame->UBufOffset)); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (frame->height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (frame->width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((frame->pitch[0] / 4) - 1) << MS4_PITCH_SHIFT); OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, frame->bo, I915_GEM_DOMAIN_SAMPLER << 16, frame->VBufOffset)); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (frame->height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (frame->width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((frame->pitch[0] / 4) - 1) << MS4_PITCH_SHIFT); id = 1<<31 | 2<<1 | !!video->brightness; if (state->last_shader != id) { state->last_shader = id; id = sna->kgem.nbatch++; /* Declare samplers */ gen3_fs_dcl(FS_S0); /* Y */ gen3_fs_dcl(FS_S1); /* U */ gen3_fs_dcl(FS_S2); /* V */ gen3_fs_dcl(FS_T0); /* normalized coords */ /* Load samplers to temporaries. */ gen3_fs_texld(FS_R1, FS_S0, FS_T0); gen3_fs_texld(FS_R2, FS_S1, FS_T0); gen3_fs_texld(FS_R3, FS_S2, FS_T0); /* Move the sampled YUV data in R[123] to the first * 3 channels of R0. */ gen3_fs_mov_masked(FS_R0, MASK_X, gen3_fs_operand_reg(FS_R1)); gen3_fs_mov_masked(FS_R0, MASK_Y, gen3_fs_operand_reg(FS_R2)); gen3_fs_mov_masked(FS_R0, MASK_Z, gen3_fs_operand_reg(FS_R3)); /* Normalize the YUV data */ gen3_fs_add(FS_R0, gen3_fs_operand_reg(FS_R0), gen3_fs_operand_reg(FS_C0)); /* dot-product the YUV data in R0 by the vectors of * coefficients for calculating R, G, and B, storing * the results in the R, G, or B channels of the output * color. The OC results are implicitly clamped * at the end of the program. */ gen3_fs_dp3(FS_OC, MASK_X, gen3_fs_operand_reg(FS_R0), gen3_fs_operand_reg(FS_C1)); gen3_fs_dp3(FS_OC, MASK_Y, gen3_fs_operand_reg(FS_R0), gen3_fs_operand_reg(FS_C2)); gen3_fs_dp3(FS_OC, MASK_Z, gen3_fs_operand_reg(FS_R0), gen3_fs_operand_reg(FS_C3)); /* Set alpha of the output to 1.0, by wiring W to 1 * and not actually using the source. */ gen3_fs_mov_masked(FS_OC, MASK_W, gen3_fs_operand_one()); if (video->brightness != 0) { gen3_fs_add(FS_OC, gen3_fs_operand_reg(FS_OC), gen3_fs_operand(FS_C4, X, X, X, ZERO)); } sna->kgem.batch[id] = _3DSTATE_PIXEL_SHADER_PROGRAM | (sna->kgem.nbatch - id - 2); } } } static void gen3_video_get_batch(struct sna *sna, struct kgem_bo *bo) { kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_batch(&sna->kgem, 120) || !kgem_check_reloc(&sna->kgem, 4) || !kgem_check_exec(&sna->kgem, 2)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen3.need_invariant) gen3_emit_invariant(sna); } static int gen3_get_inline_rectangles(struct sna *sna, int want, int floats_per_vertex) { int size = floats_per_vertex * 3; int rem = batch_space(sna) - 1; if (size * want > rem) want = rem / size; return want; } static bool gen3_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); const BoxRec *pbox = region_rects(dstRegion); int nbox = region_num_rects(dstRegion); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; int pix_xoff, pix_yoff; struct kgem_bo *dst_bo; bool bilinear; int copy = 0; DBG(("%s: src:%dx%d (frame:%dx%d) -> dst:%dx%d\n", __FUNCTION__, src_width, src_height, frame->width, frame->height, dst_width, dst_height)); assert(priv->gpu_bo); dst_bo = priv->gpu_bo; bilinear = src_width != dst_width || src_height != dst_height; src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; DBG(("%s: src offset (%f, %f), scale (%f, %f)\n", __FUNCTION__, src_offset_x, src_offset_y, src_scale_x, src_scale_y)); if (too_large(pixmap->drawable.width, pixmap->drawable.height) || !gen3_check_pitch_3d(dst_bo)) { int bpp = pixmap->drawable.bitsPerPixel; if (too_large(dst_width, dst_height)) return false; dst_bo = kgem_create_2d(&sna->kgem, dst_width, dst_height, bpp, kgem_choose_tiling(&sna->kgem, I915_TILING_X, dst_width, dst_height, bpp), 0); if (!dst_bo) return false; pix_xoff = -dstRegion->extents.x1; pix_yoff = -dstRegion->extents.y1; copy = 1; } else { pix_xoff = pix_yoff = 0; dst_width = pixmap->drawable.width; dst_height = pixmap->drawable.height; } gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, dst_bo, dst_width, dst_height, bilinear); do { int nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); if (nbox_this_time == 0) { gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, dst_bo, dst_width, dst_height, bilinear); nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); assert(nbox_this_time); } nbox -= nbox_this_time; OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1)); do { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; int box_y2 = pbox->y2; pbox++; DBG(("%s: dst (%d, %d), (%d, %d) + (%d, %d); src (%f, %f), (%f, %f)\n", __FUNCTION__, box_x1, box_y1, box_x2, box_y2, pix_xoff, pix_yoff, box_x1 * src_scale_x + src_offset_x, box_y1 * src_scale_y + src_offset_y, box_x2 * src_scale_x + src_offset_x, box_y2 * src_scale_y + src_offset_y)); /* bottom right */ OUT_BATCH_F(box_x2 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F(box_x2 * src_scale_x + src_offset_x); OUT_BATCH_F(box_y2 * src_scale_y + src_offset_y); /* bottom left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F(box_x1 * src_scale_x + src_offset_x); OUT_BATCH_F(box_y2 * src_scale_y + src_offset_y); /* top left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y1 + pix_yoff); OUT_BATCH_F(box_x1 * src_scale_x + src_offset_x); OUT_BATCH_F(box_y1 * src_scale_y + src_offset_y); } while (--nbox_this_time); } while (nbox); if (copy) { sna_blt_copy_boxes(sna, GXcopy, dst_bo, -dstRegion->extents.x1, -dstRegion->extents.y1, priv->gpu_bo, 0, 0, pixmap->drawable.bitsPerPixel, region_rects(dstRegion), region_num_rects(dstRegion)); kgem_bo_destroy(&sna->kgem, dst_bo); } if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } static void gen3_render_copy_setup_source(struct sna_composite_channel *channel, const DrawableRec *draw, struct kgem_bo *bo) { int i; channel->u.gen3.type = SHADER_TEXTURE; channel->filter = gen3_filter(PictFilterNearest); channel->repeat = gen3_texture_repeat(RepeatNone); channel->width = draw->width; channel->height = draw->height; channel->scale[0] = 1.f/draw->width; channel->scale[1] = 1.f/draw->height; channel->offset[0] = 0; channel->offset[1] = 0; channel->pict_format = sna_format_for_depth(draw->depth); if (!gen3_composite_channel_set_format(channel, channel->pict_format)) { for (i = 0; i < ARRAY_SIZE(gen3_tex_formats); i++) { if (gen3_tex_formats[i].xfmt == channel->pict_format) { channel->card_format = gen3_tex_formats[i].card_fmt; channel->rb_reversed = gen3_tex_formats[i].rb_reversed; channel->alpha_fixup = true; break; } } } assert(channel->card_format); channel->bo = bo; channel->is_affine = 1; } static bool gen3_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; #if NO_COPY_BOXES if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n); #endif DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || /* XXX handle overlap using 3D ? */ src_bo->pitch > MAX_3D_PITCH || too_large(src->width, src->height)) { fallback_blt: if (!kgem_bo_can_blt(&sna->kgem, src_bo) || !kgem_bo_can_blt(&sna->kgem, dst_bo)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback_blt; } memset(&tmp, 0, sizeof(tmp)); tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = sna_format_for_depth(dst->depth); tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height) || dst_bo->pitch > MAX_3D_PITCH) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } gen3_render_copy_setup_source(&tmp.src, src, src_bo); tmp.floats_per_vertex = 4; tmp.floats_per_rect = 12; tmp.mask.bo = NULL; tmp.mask.u.gen3.type = SHADER_NONE; dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; gen3_align_vertex(sna, &tmp); gen3_emit_composite_state(sna, &tmp); do { int n_this_time; n_this_time = gen3_get_rectangles(sna, &tmp, n); n -= n_this_time; do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); OUT_VERTEX(box->x2 + dst_dx); OUT_VERTEX(box->y2 + dst_dy); OUT_VERTEX((box->x2 + src_dx) * tmp.src.scale[0]); OUT_VERTEX((box->y2 + src_dy) * tmp.src.scale[1]); OUT_VERTEX(box->x1 + dst_dx); OUT_VERTEX(box->y2 + dst_dy); OUT_VERTEX((box->x1 + src_dx) * tmp.src.scale[0]); OUT_VERTEX((box->y2 + src_dy) * tmp.src.scale[1]); OUT_VERTEX(box->x1 + dst_dx); OUT_VERTEX(box->y1 + dst_dy); OUT_VERTEX((box->x1 + src_dx) * tmp.src.scale[0]); OUT_VERTEX((box->y1 + src_dy) * tmp.src.scale[1]); box++; } while (--n_this_time); } while (n); gen3_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); return true; fallback_tiled: return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen3_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { gen3_get_rectangles(sna, &op->base, 1); OUT_VERTEX(dx+w); OUT_VERTEX(dy+h); OUT_VERTEX((sx+w)*op->base.src.scale[0]); OUT_VERTEX((sy+h)*op->base.src.scale[1]); OUT_VERTEX(dx); OUT_VERTEX(dy+h); OUT_VERTEX(sx*op->base.src.scale[0]); OUT_VERTEX((sy+h)*op->base.src.scale[1]); OUT_VERTEX(dx); OUT_VERTEX(dy); OUT_VERTEX(sx*op->base.src.scale[0]); OUT_VERTEX(sy*op->base.src.scale[1]); } static void gen3_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { if (sna->render.vertex_offset) gen3_vertex_flush(sna); } static bool gen3_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *tmp) { #if NO_COPY if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp); #endif /* Prefer to use the BLT */ if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height) || src_bo->pitch > MAX_3D_PITCH || dst_bo->pitch > MAX_3D_PITCH) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp); } tmp->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; tmp->base.dst.pixmap = dst; tmp->base.dst.width = dst->drawable.width; tmp->base.dst.height = dst->drawable.height; tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth); tmp->base.dst.bo = dst_bo; gen3_render_copy_setup_source(&tmp->base.src, &src->drawable, src_bo); tmp->base.floats_per_vertex = 4; tmp->base.floats_per_rect = 12; tmp->base.mask.bo = NULL; tmp->base.mask.u.gen3.type = SHADER_NONE; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; } tmp->blt = gen3_render_copy_blt; tmp->done = gen3_render_copy_done; gen3_align_vertex(sna, &tmp->base); gen3_emit_composite_state(sna, &tmp->base); return true; } static bool gen3_render_fill_boxes_try_blt(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { uint8_t alu; uint32_t pixel; if (dst_bo->tiling == I915_TILING_Y) { DBG(("%s: y-tiling, can't blit\n", __FUNCTION__)); assert(!too_large(dst->width, dst->height)); return false; } if (op > PictOpSrc) return false; if (op == PictOpClear) { alu = GXclear; pixel = 0; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) return false; else alu = GXcopy; return sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n); } static inline bool prefer_fill_blt(struct sna *sna) { #if PREFER_BLT_FILL return true; #else return sna->kgem.mode != KGEM_RENDER; #endif } static bool gen3_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; if (op >= ARRAY_SIZE(gen3_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } #if NO_FILL_BOXES return gen3_render_fill_boxes_try_blt(sna, op, format, color, dst, dst_bo, box, n); #endif DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x))\n", __FUNCTION__, op, (int)format, color->red, color->green, color->blue, color->alpha)); if (too_large(dst->width, dst->height) || dst_bo->pitch > MAX_3D_PITCH || !gen3_check_dst_format(format)) { DBG(("%s: try blt, too large or incompatible destination\n", __FUNCTION__)); if (gen3_render_fill_boxes_try_blt(sna, op, format, color, dst, dst_bo, box, n)) return true; if (!gen3_check_dst_format(format)) return false; return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } if (prefer_fill_blt(sna) && gen3_render_fill_boxes_try_blt(sna, op, format, color, dst, dst_bo, box, n)) return true; if (op == PictOpClear) { pixel = 0; } else { if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) { assert(0); return false; } } DBG(("%s: using shader for op=%d, format=%08x, pixel=%08x\n", __FUNCTION__, op, (int)format, pixel)); tmp.op = op; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; tmp.damage = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.rb_reversed = 0; tmp.has_component_alpha = 0; tmp.need_magic_ca_pass = false; gen3_init_solid(&tmp.src, pixel); tmp.mask.bo = NULL; tmp.mask.u.gen3.type = SHADER_NONE; tmp.u.gen3.num_constants = 0; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) return false; } gen3_align_vertex(sna, &tmp); gen3_emit_composite_state(sna, &tmp); do { int n_this_time; n_this_time = gen3_get_rectangles(sna, &tmp, n); n -= n_this_time; do { DBG((" (%d, %d), (%d, %d): %x\n", box->x1, box->y1, box->x2, box->y2, pixel)); OUT_VERTEX(box->x2); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y1); box++; } while (--n_this_time); } while (n); gen3_vertex_flush(sna); return true; } static void gen3_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { gen3_get_rectangles(sna, &op->base, 1); OUT_VERTEX(x+w); OUT_VERTEX(y+h); OUT_VERTEX(x); OUT_VERTEX(y+h); OUT_VERTEX(x); OUT_VERTEX(y); } fastcall static void gen3_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { gen3_get_rectangles(sna, &op->base, 1); OUT_VERTEX(box->x2); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y1); } fastcall static void gen3_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time; nbox_this_time = gen3_get_rectangles(sna, &op->base, nbox); nbox -= nbox_this_time; do { OUT_VERTEX(box->x2); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y2); OUT_VERTEX(box->x1); OUT_VERTEX(box->y1); box++; } while (--nbox_this_time); } while (nbox); } static void gen3_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { if (sna->render.vertex_offset) gen3_vertex_flush(sna); } static bool gen3_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *tmp) { #if NO_FILL return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp); #endif /* Prefer to use the BLT if already engaged */ if (prefer_fill_blt(sna) && sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height) || dst_bo->pitch > MAX_3D_PITCH) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp); if (alu == GXclear) color = 0; tmp->base.op = color == 0 ? PictOpClear : PictOpSrc; tmp->base.dst.pixmap = dst; tmp->base.dst.width = dst->drawable.width; tmp->base.dst.height = dst->drawable.height; tmp->base.dst.format = sna_format_for_depth(dst->drawable.depth); tmp->base.dst.bo = dst_bo; tmp->base.floats_per_vertex = 2; tmp->base.floats_per_rect = 6; tmp->base.need_magic_ca_pass = 0; tmp->base.has_component_alpha = 0; tmp->base.rb_reversed = 0; gen3_init_solid(&tmp->base.src, sna_rgba_for_color(color, dst->drawable.depth)); tmp->base.mask.bo = NULL; tmp->base.mask.u.gen3.type = SHADER_NONE; tmp->base.u.gen3.num_constants = 0; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) return false; } tmp->blt = gen3_render_fill_op_blt; tmp->box = gen3_render_fill_op_box; tmp->boxes = gen3_render_fill_op_boxes; tmp->points = NULL; tmp->done = gen3_render_fill_op_done; gen3_align_vertex(sna, &tmp->base); gen3_emit_composite_state(sna, &tmp->base); return true; } static bool gen3_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen3_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; #if NO_FILL_ONE return gen3_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); #endif /* Prefer to use the BLT if already engaged */ if (prefer_fill_blt(sna) && gen3_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height) || bo->pitch > MAX_3D_PITCH) return gen3_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); if (alu == GXclear) color = 0; tmp.op = color == 0 ? PictOpClear : PictOpSrc; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = 0; tmp.has_component_alpha = 0; tmp.rb_reversed = 0; gen3_init_solid(&tmp.src, sna_rgba_for_color(color, dst->drawable.depth)); tmp.mask.bo = NULL; tmp.mask.u.gen3.type = SHADER_NONE; tmp.u.gen3.num_constants = 0; if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (gen3_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; if (!kgem_check_bo(&sna->kgem, bo, NULL)) return false; } gen3_align_vertex(sna, &tmp); gen3_emit_composite_state(sna, &tmp); gen3_get_rectangles(sna, &tmp, 1); DBG((" (%d, %d), (%d, %d): %x\n", x1, y1, x2, y2, color)); OUT_VERTEX(x2); OUT_VERTEX(y2); OUT_VERTEX(x1); OUT_VERTEX(y2); OUT_VERTEX(x1); OUT_VERTEX(y1); gen3_vertex_flush(sna); return true; } static void gen3_render_flush(struct sna *sna) { gen3_vertex_close(sna); assert(sna->render.vertex_reloc[0] == 0); assert(sna->render.vertex_offset == 0); } static void gen3_render_fini(struct sna *sna) { } const char *gen3_render_init(struct sna *sna, const char *backend) { struct sna_render *render = &sna->render; #if !NO_COMPOSITE render->composite = gen3_render_composite; render->prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS render->check_composite_spans = gen3_check_composite_spans; render->composite_spans = gen3_render_composite_spans; render->prefer_gpu |= PREFER_GPU_SPANS; #endif render->video = gen3_render_video; render->copy_boxes = gen3_render_copy_boxes; render->copy = gen3_render_copy; render->fill_boxes = gen3_render_fill_boxes; render->fill = gen3_render_fill; render->fill_one = gen3_render_fill_one; render->reset = gen3_render_reset; render->flush = gen3_render_flush; render->fini = gen3_render_fini; render->max_3d_size = MAX_3D_SIZE; render->max_3d_pitch = MAX_3D_PITCH; sna->kgem.retire = gen3_render_retire; sna->kgem.expire = gen3_render_expire; return "Alviso (gen3)"; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen3_render.h000066400000000000000000001561101267532330400242130ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 _I915_REG_H_ #define _I915_REG_H_ #define CMD_3D (3 << 29) #define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) #define PRIM3D (CMD_3D | (0x1f<<24)) #define PRIM3D_INDIRECT_SEQUENTIAL ((1<<23) | (0<<17)) #define PRIM3D_TRILIST (PRIM3D | (0x0<<18)) #define PRIM3D_TRISTRIP (PRIM3D | (0x1<<18)) #define PRIM3D_TRISTRIP_RVRSE (PRIM3D | (0x2<<18)) #define PRIM3D_TRIFAN (PRIM3D | (0x3<<18)) #define PRIM3D_POLY (PRIM3D | (0x4<<18)) #define PRIM3D_LINELIST (PRIM3D | (0x5<<18)) #define PRIM3D_LINESTRIP (PRIM3D | (0x6<<18)) #define PRIM3D_RECTLIST (PRIM3D | (0x7<<18)) #define PRIM3D_POINTLIST (PRIM3D | (0x8<<18)) #define PRIM3D_DIB (PRIM3D | (0x9<<18)) #define PRIM3D_CLEAR_RECT (PRIM3D | (0xa<<18)) #define PRIM3D_ZONE_INIT (PRIM3D | (0xd<<18)) #define PRIM3D_MASK (0x1f<<18) /* p137 */ #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) /* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ #define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) #define BFO_ENABLE_STENCIL_REF (1<<23) #define BFO_STENCIL_REF_SHIFT 15 #define BFO_STENCIL_REF_MASK (0xff<<15) #define BFO_ENABLE_STENCIL_FUNCS (1<<14) #define BFO_STENCIL_TEST_SHIFT 11 #define BFO_STENCIL_TEST_MASK (0x7<<11) #define BFO_STENCIL_FAIL_SHIFT 8 #define BFO_STENCIL_FAIL_MASK (0x7<<8) #define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 #define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) #define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 #define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) #define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) #define BFO_STENCIL_TWO_SIDE (1<<0) /* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ #define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) #define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) #define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) #define BFM_STENCIL_TEST_MASK_SHIFT 8 #define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) #define BFM_STENCIL_WRITE_MASK_SHIFT 0 #define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) /* 3DSTATE_BIN_CONTROL p141 */ /* p143 */ #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) /* 3DSTATE_CHROMA_KEY */ /* 3DSTATE_CLEAR_PARAMETERS, p150 */ #define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) /* Dword 1 */ #define CLEARPARAM_CLEAR_RECT (1 << 16) #define CLEARPARAM_ZONE_INIT (0 << 16) #define CLEARPARAM_WRITE_COLOR (1 << 2) #define CLEARPARAM_WRITE_DEPTH (1 << 1) #define CLEARPARAM_WRITE_STENCIL (1 << 0) /* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) /* 3DSTATE_COORD_SET_BINDINGS, p154 */ #define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) #define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) /* p156 */ #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) /* p157 */ #define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) /* p158 */ #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) /* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ #define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) /* scale in dword 1 */ /* The depth subrectangle is not supported, but must be disabled. */ /* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ #define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | (1 << 1) | (0 << 0)) /* p161 */ #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define TEX_DEFAULT_COLOR_OGL (0<<30) #define TEX_DEFAULT_COLOR_D3D (1<<30) #define ZR_EARLY_DEPTH (1<<29) #define LOD_PRECLAMP_OGL (1<<28) #define LOD_PRECLAMP_D3D (0<<28) #define DITHER_FULL_ALWAYS (0<<26) #define DITHER_FULL_ON_FB_BLEND (1<<26) #define DITHER_CLAMPED_ALWAYS (2<<26) #define LINEAR_GAMMA_BLEND_32BPP (1<<25) #define DEBUG_DISABLE_ENH_DITHER (1<<24) #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define COLR_BUF_ARGB2AAA (0xa<<8) #define DEPTH_IS_Z 0 #define DEPTH_IS_W (1<<6) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 0 #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 /* p166 */ #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((uint16_t)(x)<<16) #define DRAW_XMIN(x) ((uint16_t)(x)) /* Dword 3 */ #define DRAW_YMAX(x) ((uint16_t)(x)<<16) #define DRAW_XMAX(x) ((uint16_t)(x)) /* Dword 4 */ #define DRAW_YORG(x) ((uint16_t)(x)<<16) #define DRAW_XORG(x) ((uint16_t)(x)) /* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ /* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ /* _3DSTATE_FOG_COLOR, p173 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p174 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) #define FMC1_FOGFUNC_VERTEX (0<<28) #define FMC1_FOGFUNC_PIXEL_EXP (1<<28) #define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) #define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) #define FMC1_FOGFUNC_MASK (3<<28) #define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) #define FMC1_FOGINDEX_Z (0<<25) #define FMC1_FOGINDEX_W (1<<25) #define FMC1_C1_C2_MODIFY_ENABLE (1<<24) #define FMC1_DENSITY_MODIFY_ENABLE (1<<23) #define FMC1_C1_ONE (1<<13) #define FMC1_C1_MASK (0xffff<<4) /* Dword 2 */ #define FMC2_C2_ONE (1<<16) /* Dword 3 */ #define FMC3_D_ONE (1<<16) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ #define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define IAB_MODIFY_ENABLE (1<<23) #define IAB_ENABLE (1<<22) #define IAB_MODIFY_FUNC (1<<21) #define IAB_FUNC_SHIFT 16 #define IAB_MODIFY_SRC_FACTOR (1<<11) #define IAB_SRC_FACTOR_SHIFT 6 #define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) #define IAB_MODIFY_DST_FACTOR (1<<5) #define IAB_DST_FACTOR_SHIFT 0 #define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) #define BLENDFACT_ZERO 0x01 #define BLENDFACT_ONE 0x02 #define BLENDFACT_SRC_COLR 0x03 #define BLENDFACT_INV_SRC_COLR 0x04 #define BLENDFACT_SRC_ALPHA 0x05 #define BLENDFACT_INV_SRC_ALPHA 0x06 #define BLENDFACT_DST_ALPHA 0x07 #define BLENDFACT_INV_DST_ALPHA 0x08 #define BLENDFACT_DST_COLR 0x09 #define BLENDFACT_INV_DST_COLR 0x0a #define BLENDFACT_SRC_ALPHA_SATURATE 0x0b #define BLENDFACT_CONST_COLOR 0x0c #define BLENDFACT_INV_CONST_COLOR 0x0d #define BLENDFACT_CONST_ALPHA 0x0e #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f #define BLENDFUNC_ADD 0x0 #define BLENDFUNC_SUBTRACT 0x1 #define BLENDFUNC_REVERSE_SUBTRACT 0x2 #define BLENDFUNC_MIN 0x3 #define BLENDFUNC_MAX 0x4 #define BLENDFUNC_MASK 0x7 /* 3DSTATE_LOAD_INDIRECT, p180 */ #define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) #define LI0_STATE_STATIC_INDIRECT (0x01<<8) #define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) #define LI0_STATE_SAMPLER (0x04<<8) #define LI0_STATE_MAP (0x08<<8) #define LI0_STATE_PROGRAM (0x10<<8) #define LI0_STATE_CONSTANTS (0x20<<8) #define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SIS0_FORCE_LOAD (1<<1) #define SIS0_BUFFER_VALID (1<<0) #define SIS1_BUFFER_LENGTH(x) ((x)&0xff) #define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define DIS0_BUFFER_RESET (1<<1) #define DIS0_BUFFER_VALID (1<<0) #define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SSB0_FORCE_LOAD (1<<1) #define SSB0_BUFFER_VALID (1<<0) #define SSB1_BUFFER_LENGTH(x) ((x)&0xff) #define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define MSB0_FORCE_LOAD (1<<1) #define MSB0_BUFFER_VALID (1<<0) #define MSB1_BUFFER_LENGTH(x) ((x)&0xff) #define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSP0_FORCE_LOAD (1<<1) #define PSP0_BUFFER_VALID (1<<0) #define PSP1_BUFFER_LENGTH(x) ((x)&0xff) #define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSC0_FORCE_LOAD (1<<1) #define PSC0_BUFFER_VALID (1<<0) #define PSC1_BUFFER_LENGTH(x) ((x)&0xff) /* _3DSTATE_RASTERIZATION_RULES */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_TEXKILL_3D_4D (1<<10) #define TEXKILL_3D (0<<9) #define TEXKILL_4D (1<<9) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) /* _3DSTATE_SCISSOR_ENABLE, p256 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* p189 */ #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<(4+n)) #define S0_VB_OFFSET_MASK 0xffffffc #define S0_AUTO_CACHE_INV_DISABLE (1<<0) #define S1_VERTEX_WIDTH_SHIFT 24 #define S1_VERTEX_WIDTH_MASK (0x3f<<24) #define S1_VERTEX_PITCH_SHIFT 16 #define S1_VERTEX_PITCH_MASK (0x3f<<16) #define TEXCOORDFMT_2D 0x0 #define TEXCOORDFMT_3D 0x1 #define TEXCOORDFMT_4D 0x2 #define TEXCOORDFMT_1D 0x3 #define TEXCOORDFMT_2D_16 0x4 #define TEXCOORDFMT_4D_16 0x5 #define TEXCOORDFMT_NOT_PRESENT 0xf #define S2_TEXCOORD_FMT0_MASK 0xf #define S2_TEXCOORD_FMT1_SHIFT 4 #define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) #define S2_TEXCOORD_NONE (~0) #define TEXCOORD_WRAP_SHORTEST_TCX 8 #define TEXCOORD_WRAP_SHORTEST_TCY 4 #define TEXCOORD_WRAP_SHORTEST_TCZ 2 #define TEXCOORD_PERSPECTIVE_DISABLE 1 #define S3_WRAP_SHORTEST_TCX(unit) (TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCY(unit) (TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCZ(unit) (TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4)) #define S3_PERSPECTIVE_DISABLE(unit) (TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4)) /* S3 not interesting */ #define S4_POINT_WIDTH_SHIFT 23 #define S4_POINT_WIDTH_MASK (0x1ff<<23) #define S4_LINE_WIDTH_SHIFT 19 #define S4_LINE_WIDTH_ONE (0x2<<19) #define S4_LINE_WIDTH_MASK (0xf<<19) #define S4_FLATSHADE_ALPHA (1<<18) #define S4_FLATSHADE_FOG (1<<17) #define S4_FLATSHADE_SPECULAR (1<<16) #define S4_FLATSHADE_COLOR (1<<15) #define S4_CULLMODE_BOTH (0<<13) #define S4_CULLMODE_NONE (1<<13) #define S4_CULLMODE_CW (2<<13) #define S4_CULLMODE_CCW (3<<13) #define S4_CULLMODE_MASK (3<<13) #define S4_VFMT_POINT_WIDTH (1<<12) #define S4_VFMT_SPEC_FOG (1<<11) #define S4_VFMT_COLOR (1<<10) #define S4_VFMT_DEPTH_OFFSET (1<<9) #define S4_VFMT_XYZ (1<<6) #define S4_VFMT_XYZW (2<<6) #define S4_VFMT_XY (3<<6) #define S4_VFMT_XYW (4<<6) #define S4_VFMT_XYZW_MASK (7<<6) #define S4_FORCE_DEFAULT_DIFFUSE (1<<5) #define S4_FORCE_DEFAULT_SPECULAR (1<<4) #define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) #define S4_VFMT_FOG_PARAM (1<<2) #define S4_SPRITE_POINT_ENABLE (1<<1) #define S4_LINE_ANTIALIAS_ENABLE (1<<0) #define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ S4_VFMT_SPEC_FOG | \ S4_VFMT_COLOR | \ S4_VFMT_DEPTH_OFFSET | \ S4_VFMT_XYZW_MASK | \ S4_VFMT_FOG_PARAM) #define S5_WRITEDISABLE_ALPHA (1<<31) #define S5_WRITEDISABLE_RED (1<<30) #define S5_WRITEDISABLE_GREEN (1<<29) #define S5_WRITEDISABLE_BLUE (1<<28) #define S5_WRITEDISABLE_MASK (0xf<<28) #define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) #define S5_LAST_PIXEL_ENABLE (1<<26) #define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) #define S5_FOG_ENABLE (1<<24) #define S5_STENCIL_REF_SHIFT 16 #define S5_STENCIL_REF_MASK (0xff<<16) #define S5_STENCIL_TEST_FUNC_SHIFT 13 #define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) #define S5_STENCIL_FAIL_SHIFT 10 #define S5_STENCIL_FAIL_MASK (0x7<<10) #define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 #define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) #define S5_STENCIL_PASS_Z_PASS_SHIFT 4 #define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) #define S5_STENCIL_WRITE_ENABLE (1<<3) #define S5_STENCIL_TEST_ENABLE (1<<2) #define S5_COLOR_DITHER_ENABLE (1<<1) #define S5_LOGICOP_ENABLE (1<<0) #define S6_ALPHA_TEST_ENABLE (1<<31) #define S6_ALPHA_TEST_FUNC_SHIFT 28 #define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) #define S6_ALPHA_REF_SHIFT 20 #define S6_ALPHA_REF_MASK (0xff<<20) #define S6_DEPTH_TEST_ENABLE (1<<19) #define S6_DEPTH_TEST_FUNC_SHIFT 16 #define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) #define S6_CBUF_BLEND_ENABLE (1<<15) #define S6_CBUF_BLEND_FUNC_SHIFT 12 #define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) #define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 #define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) #define S6_CBUF_DST_BLEND_FACT_SHIFT 4 #define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) #define S6_DEPTH_WRITE_ENABLE (1<<3) #define S6_COLOR_WRITE_ENABLE (1<<2) #define S6_TRISTRIP_PV_SHIFT 0 #define S6_TRISTRIP_PV_MASK (0x3<<0) #define S7_DEPTH_OFFSET_CONST_MASK ~0 /* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ /* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ /* _3DSTATE_MODES_4, p218 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK (0xf<<18) #define LOGICOP_COPY 0xc #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p220 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define PIPELINE_FLUSH_RENDER_CACHE (1<<18) #define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) /* p221 */ #define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) #define PS1_REG(n) (1<<(n)) #define PS2_CONST_X(n) (n) #define PS3_CONST_Y(n) (n) #define PS4_CONST_Z(n) (n) #define PS5_CONST_W(n) (n) /* p222 */ #define I915_MAX_TEX_INDIRECT 4 #define I915_MAX_TEX_INSN 32 #define I915_MAX_ALU_INSN 64 #define I915_MAX_DECL_INSN 27 #define I915_MAX_TEMPORARY 16 /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. */ #define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* p207. * The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK */ #define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) #define MS1_MAPMASK_SHIFT 0 #define MS1_MAPMASK_MASK (0x8fff<<0) #define MS2_UNTRUSTED_SURFACE (1<<31) #define MS2_ADDRESS_MASK 0xfffffffc #define MS2_VERTICAL_LINE_STRIDE (1<<1) #define MS2_VERTICAL_OFFSET (1<<1) #define MS3_HEIGHT_SHIFT 21 #define MS3_WIDTH_SHIFT 10 #define MS3_PALETTE_SELECT (1<<9) #define MS3_MAPSURF_FORMAT_SHIFT 7 #define MS3_MAPSURF_FORMAT_MASK (0x7<<7) #define MAPSURF_8BIT (1<<7) #define MAPSURF_16BIT (2<<7) #define MAPSURF_32BIT (3<<7) #define MAPSURF_422 (5<<7) #define MAPSURF_COMPRESSED (6<<7) #define MAPSURF_4BIT_INDEXED (7<<7) #define MS3_MT_FORMAT_MASK (0x7 << 3) #define MS3_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_8BIT_MONO8 (5<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_I16 (7<<3) #define MT_16BIT_L16 (8<<3) #define MT_16BIT_A16 (9<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_QWVU8888 (4<<3) #define MT_32BIT_AXVU8888 (5<<3) #define MT_32BIT_LXVU8888 (6<<3) #define MT_32BIT_XLVU8888 (7<<3) #define MT_32BIT_ARGB2101010 (8<<3) #define MT_32BIT_ABGR2101010 (9<<3) #define MT_32BIT_AWVU2101010 (0xA<<3) #define MT_32BIT_GR1616 (0xB<<3) #define MT_32BIT_VU1616 (0xC<<3) #define MT_32BIT_xI824 (0xD<<3) #define MT_32BIT_xA824 (0xE<<3) #define MT_32BIT_xL824 (0xF<<3) #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define MT_COMPRESS_DXT1_RGB (4<<3) #define MS3_USE_FENCE_REGS (1<<2) #define MS3_TILED_SURFACE (1<<1) #define MS3_TILE_WALK (1<<0) /* The pitch is the pitch measured in DWORDS, minus 1 */ #define MS4_PITCH_SHIFT 21 #define MS4_CUBE_FACE_ENA_NEGX (1<<20) #define MS4_CUBE_FACE_ENA_POSX (1<<19) #define MS4_CUBE_FACE_ENA_NEGY (1<<18) #define MS4_CUBE_FACE_ENA_POSY (1<<17) #define MS4_CUBE_FACE_ENA_NEGZ (1<<16) #define MS4_CUBE_FACE_ENA_POSZ (1<<15) #define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) #define MS4_MAX_LOD_SHIFT 9 #define MS4_MAX_LOD_MASK (0x3f<<9) #define MS4_MIP_LAYOUT_LEGACY (0<<8) #define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) #define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) #define MS4_VOLUME_DEPTH_SHIFT 0 #define MS4_VOLUME_DEPTH_MASK (0xff<<0) /* p244. * The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK. */ #define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) #define SS1_MAPMASK_SHIFT 0 #define SS1_MAPMASK_MASK (0x8fff<<0) #define SS2_REVERSE_GAMMA_ENABLE (1<<31) #define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) #define SS2_COLORSPACE_CONVERSION (1<<29) #define SS2_CHROMAKEY_SHIFT 27 #define SS2_BASE_MIP_LEVEL_SHIFT 22 #define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) #define SS2_MIP_FILTER_SHIFT 20 #define SS2_MIP_FILTER_MASK (0x3<<20) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define SS2_MAG_FILTER_SHIFT 17 #define SS2_MAG_FILTER_MASK (0x7<<17) #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define FILTER_4X4_1 3 #define FILTER_4X4_2 4 #define FILTER_4X4_FLAT 5 #define FILTER_6X5_MONO 6 /* XXX - check */ #define SS2_MIN_FILTER_SHIFT 14 #define SS2_MIN_FILTER_MASK (0x7<<14) #define SS2_LOD_BIAS_SHIFT 5 #define SS2_LOD_BIAS_ONE (0x10<<5) #define SS2_LOD_BIAS_MASK (0x1ff<<5) /* Shadow requires: * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format * FILTER_4X4_x MIN and MAG filters */ #define SS2_SHADOW_ENABLE (1<<4) #define SS2_MAX_ANISO_MASK (1<<3) #define SS2_MAX_ANISO_2 (0<<3) #define SS2_MAX_ANISO_4 (1<<3) #define SS2_SHADOW_FUNC_SHIFT 0 #define SS2_SHADOW_FUNC_MASK (0x7<<0) /* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ #define SS3_MIN_LOD_SHIFT 24 #define SS3_MIN_LOD_ONE (0x10<<24) #define SS3_MIN_LOD_MASK (0xff<<24) #define SS3_KILL_PIXEL_ENABLE (1<<17) #define SS3_TCX_ADDR_MODE_SHIFT 12 #define SS3_TCX_ADDR_MODE_MASK (0x7<<12) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP_EDGE 2 #define TEXCOORDMODE_CUBE 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORDMODE_MIRROR_ONCE 5 #define SS3_TCY_ADDR_MODE_SHIFT 9 #define SS3_TCY_ADDR_MODE_MASK (0x7<<9) #define SS3_TCZ_ADDR_MODE_SHIFT 6 #define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) #define SS3_NORMALIZED_COORDS (1<<5) #define SS3_TEXTUREMAP_INDEX_SHIFT 1 #define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) #define SS3_DEINTERLACER_ENABLE (1<<0) #define SS4_BORDER_COLOR_MASK (~0) /* 3DSTATE_SPAN_STIPPLE, p258 */ #define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define FLUSH_MAP_CACHE (1<<0) #define FLUSH_RENDER_CACHE (1<<1) #endif /* -*- c-basic-offset: 4 -*- */ /* * Copyright © 2006,2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. */ #define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_TYPE_SHIFT 4 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* MASK_* are the unshifted bitmasks of the destination mask in arithmetic * operations */ #define MASK_X 0x1 #define MASK_Y 0x2 #define MASK_Z 0x4 #define MASK_W 0x8 #define MASK_XYZ (MASK_X | MASK_Y | MASK_Z) #define MASK_XYZW (MASK_XYZ | MASK_W) #define MASK_SATURATE 0x10 /* Temporary, undeclared regs. Preserved between phases */ #define FS_R0 ((REG_TYPE_R << REG_TYPE_SHIFT) | 0) #define FS_R1 ((REG_TYPE_R << REG_TYPE_SHIFT) | 1) #define FS_R2 ((REG_TYPE_R << REG_TYPE_SHIFT) | 2) #define FS_R3 ((REG_TYPE_R << REG_TYPE_SHIFT) | 3) /* Texture coordinate regs. Must be declared. */ #define FS_T0 ((REG_TYPE_T << REG_TYPE_SHIFT) | 0) #define FS_T1 ((REG_TYPE_T << REG_TYPE_SHIFT) | 1) #define FS_T2 ((REG_TYPE_T << REG_TYPE_SHIFT) | 2) #define FS_T3 ((REG_TYPE_T << REG_TYPE_SHIFT) | 3) #define FS_T4 ((REG_TYPE_T << REG_TYPE_SHIFT) | 4) #define FS_T5 ((REG_TYPE_T << REG_TYPE_SHIFT) | 5) #define FS_T6 ((REG_TYPE_T << REG_TYPE_SHIFT) | 6) #define FS_T7 ((REG_TYPE_T << REG_TYPE_SHIFT) | 7) #define FS_T8 ((REG_TYPE_T << REG_TYPE_SHIFT) | 8) #define FS_T9 ((REG_TYPE_T << REG_TYPE_SHIFT) | 9) #define FS_T10 ((REG_TYPE_T << REG_TYPE_SHIFT) | 10) /* Constant values */ #define FS_C0 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 0) #define FS_C1 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 1) #define FS_C2 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 2) #define FS_C3 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 3) #define FS_C4 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 4) #define FS_C5 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 5) #define FS_C6 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 6) #define FS_C7 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 7) /* Sampler regs */ #define FS_S0 ((REG_TYPE_S << REG_TYPE_SHIFT) | 0) #define FS_S1 ((REG_TYPE_S << REG_TYPE_SHIFT) | 1) #define FS_S2 ((REG_TYPE_S << REG_TYPE_SHIFT) | 2) #define FS_S3 ((REG_TYPE_S << REG_TYPE_SHIFT) | 3) /* Output color */ #define FS_OC ((REG_TYPE_OC << REG_TYPE_SHIFT) | 0) /* Output depth */ #define FS_OD ((REG_TYPE_OD << REG_TYPE_SHIFT) | 0) /* Unpreserved temporary regs */ #define FS_U0 ((REG_TYPE_U << REG_TYPE_SHIFT) | 0) #define FS_U1 ((REG_TYPE_U << REG_TYPE_SHIFT) | 1) #define FS_U2 ((REG_TYPE_U << REG_TYPE_SHIFT) | 2) #define FS_U3 ((REG_TYPE_U << REG_TYPE_SHIFT) | 3) #define X_CHANNEL_SHIFT (REG_TYPE_SHIFT + 3) #define Y_CHANNEL_SHIFT (X_CHANNEL_SHIFT + 4) #define Z_CHANNEL_SHIFT (Y_CHANNEL_SHIFT + 4) #define W_CHANNEL_SHIFT (Z_CHANNEL_SHIFT + 4) #define REG_CHANNEL_MASK 0xf #define REG_NR(reg) ((reg) & REG_NR_MASK) #define REG_TYPE(reg) (((reg) >> REG_TYPE_SHIFT) & REG_TYPE_MASK) #define REG_X(reg) (((reg) >> X_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_Y(reg) (((reg) >> Y_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_Z(reg) (((reg) >> Z_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_W(reg) (((reg) >> W_CHANNEL_SHIFT) & REG_CHANNEL_MASK) enum gen3_fs_channel { X_CHANNEL_VAL = 0, Y_CHANNEL_VAL, Z_CHANNEL_VAL, W_CHANNEL_VAL, ZERO_CHANNEL_VAL, ONE_CHANNEL_VAL, NEG_X_CHANNEL_VAL = X_CHANNEL_VAL | 0x8, NEG_Y_CHANNEL_VAL = Y_CHANNEL_VAL | 0x8, NEG_Z_CHANNEL_VAL = Z_CHANNEL_VAL | 0x8, NEG_W_CHANNEL_VAL = W_CHANNEL_VAL | 0x8, NEG_ONE_CHANNEL_VAL = ONE_CHANNEL_VAL | 0x8 }; #define gen3_fs_operand(reg, x, y, z, w) \ (reg) | \ (x##_CHANNEL_VAL << X_CHANNEL_SHIFT) | \ (y##_CHANNEL_VAL << Y_CHANNEL_SHIFT) | \ (z##_CHANNEL_VAL << Z_CHANNEL_SHIFT) | \ (w##_CHANNEL_VAL << W_CHANNEL_SHIFT) /** * Construct an operand description for using a register with no swizzling */ #define gen3_fs_operand_reg(reg) \ gen3_fs_operand(reg, X, Y, Z, W) #define gen3_fs_operand_reg_negate(reg) \ gen3_fs_operand(reg, NEG_X, NEG_Y, NEG_Z, NEG_W) /** * Returns an operand containing (0.0, 0.0, 0.0, 0.0). */ #define gen3_fs_operand_zero() gen3_fs_operand(FS_R0, ZERO, ZERO, ZERO, ZERO) /** * Returns an unused operand */ #define gen3_fs_operand_none() gen3_fs_operand_zero() /** * Returns an operand containing (1.0, 1.0, 1.0, 1.0). */ #define gen3_fs_operand_one() gen3_fs_operand(FS_R0, ONE, ONE, ONE, ONE) #define gen3_get_hardware_channel_val(val, shift, negate) \ (((val & 0x7) << shift) | ((val & 0x8) ? negate : 0)) /** * Outputs a fragment shader command to declare a sampler or texture register. */ #define gen3_fs_dcl(reg) \ do { \ OUT_BATCH(D0_DCL | \ (REG_TYPE(reg) << D0_TYPE_SHIFT) | \ (REG_NR(reg) << D0_NR_SHIFT) | \ ((REG_TYPE(reg) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); \ OUT_BATCH(0); \ OUT_BATCH(0); \ } while (0) #define gen3_fs_texld(dest_reg, sampler_reg, address_reg) \ do { \ OUT_BATCH(T0_TEXLD | \ (REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << T0_DEST_NR_SHIFT) | \ (REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT)); \ OUT_BATCH((REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT) | \ (REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT)); \ OUT_BATCH(0); \ } while (0) #define gen3_fs_texldp(dest_reg, sampler_reg, address_reg) \ do { \ OUT_BATCH(T0_TEXLDP | \ (REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << T0_DEST_NR_SHIFT) | \ (REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT)); \ OUT_BATCH((REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT) | \ (REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT)); \ OUT_BATCH(0); \ } while (0) #define gen3_fs_arith_masked(op, dest_reg, dest_mask, operand0, operand1, operand2) \ _gen3_fs_arith_masked(A0_##op, dest_reg, dest_mask, operand0, operand1, operand2) #define gen3_fs_arith(op, dest_reg, operand0, operand1, operand2) \ _gen3_fs_arith(A0_##op, dest_reg, operand0, operand1, operand2) #define _gen3_fs_arith_masked(cmd, dest_reg, dest_mask, operand0, operand1, operand2) \ do { \ /* Set up destination register and write mask */ \ OUT_BATCH(cmd | \ (REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << A0_DEST_NR_SHIFT) | \ (((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT) | \ (((dest_mask) & MASK_SATURATE) ? A0_DEST_SATURATE : 0) | \ /* Set up operand 0 */ \ (REG_TYPE(operand0) << A0_SRC0_TYPE_SHIFT) | \ (REG_NR(operand0) << A0_SRC0_NR_SHIFT)); \ OUT_BATCH(gen3_get_hardware_channel_val(REG_X(operand0), \ A1_SRC0_CHANNEL_X_SHIFT, \ A1_SRC0_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand0), \ A1_SRC0_CHANNEL_Y_SHIFT, \ A1_SRC0_CHANNEL_Y_NEGATE) | \ gen3_get_hardware_channel_val(REG_Z(operand0), \ A1_SRC0_CHANNEL_Z_SHIFT, \ A1_SRC0_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand0), \ A1_SRC0_CHANNEL_W_SHIFT, \ A1_SRC0_CHANNEL_W_NEGATE) | \ /* Set up operand 1 */ \ (REG_TYPE(operand1) << A1_SRC1_TYPE_SHIFT) | \ (REG_NR(operand1) << A1_SRC1_NR_SHIFT) | \ gen3_get_hardware_channel_val(REG_X(operand1), \ A1_SRC1_CHANNEL_X_SHIFT, \ A1_SRC1_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand1), \ A1_SRC1_CHANNEL_Y_SHIFT, \ A1_SRC1_CHANNEL_Y_NEGATE)); \ OUT_BATCH(gen3_get_hardware_channel_val(REG_Z(operand1), \ A2_SRC1_CHANNEL_Z_SHIFT, \ A2_SRC1_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand1), \ A2_SRC1_CHANNEL_W_SHIFT, \ A2_SRC1_CHANNEL_W_NEGATE) | \ /* Set up operand 2 */ \ (REG_TYPE(operand2) << A2_SRC2_TYPE_SHIFT) | \ (REG_NR(operand2) << A2_SRC2_NR_SHIFT) | \ gen3_get_hardware_channel_val(REG_X(operand2), \ A2_SRC2_CHANNEL_X_SHIFT, \ A2_SRC2_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand2), \ A2_SRC2_CHANNEL_Y_SHIFT, \ A2_SRC2_CHANNEL_Y_NEGATE) | \ gen3_get_hardware_channel_val(REG_Z(operand2), \ A2_SRC2_CHANNEL_Z_SHIFT, \ A2_SRC2_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand2), \ A2_SRC2_CHANNEL_W_SHIFT, \ A2_SRC2_CHANNEL_W_NEGATE)); \ } while (0) #define _gen3_fs_arith(cmd, dest_reg, operand0, operand1, operand2) do {\ /* Set up destination register and write mask */ \ OUT_BATCH(cmd | \ (REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << A0_DEST_NR_SHIFT) | \ (A0_DEST_CHANNEL_ALL) | \ /* Set up operand 0 */ \ (REG_TYPE(operand0) << A0_SRC0_TYPE_SHIFT) | \ (REG_NR(operand0) << A0_SRC0_NR_SHIFT)); \ OUT_BATCH(gen3_get_hardware_channel_val(REG_X(operand0), \ A1_SRC0_CHANNEL_X_SHIFT, \ A1_SRC0_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand0), \ A1_SRC0_CHANNEL_Y_SHIFT, \ A1_SRC0_CHANNEL_Y_NEGATE) | \ gen3_get_hardware_channel_val(REG_Z(operand0), \ A1_SRC0_CHANNEL_Z_SHIFT, \ A1_SRC0_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand0), \ A1_SRC0_CHANNEL_W_SHIFT, \ A1_SRC0_CHANNEL_W_NEGATE) | \ /* Set up operand 1 */ \ (REG_TYPE(operand1) << A1_SRC1_TYPE_SHIFT) | \ (REG_NR(operand1) << A1_SRC1_NR_SHIFT) | \ gen3_get_hardware_channel_val(REG_X(operand1), \ A1_SRC1_CHANNEL_X_SHIFT, \ A1_SRC1_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand1), \ A1_SRC1_CHANNEL_Y_SHIFT, \ A1_SRC1_CHANNEL_Y_NEGATE)); \ OUT_BATCH(gen3_get_hardware_channel_val(REG_Z(operand1), \ A2_SRC1_CHANNEL_Z_SHIFT, \ A2_SRC1_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand1), \ A2_SRC1_CHANNEL_W_SHIFT, \ A2_SRC1_CHANNEL_W_NEGATE) | \ /* Set up operand 2 */ \ (REG_TYPE(operand2) << A2_SRC2_TYPE_SHIFT) | \ (REG_NR(operand2) << A2_SRC2_NR_SHIFT) | \ gen3_get_hardware_channel_val(REG_X(operand2), \ A2_SRC2_CHANNEL_X_SHIFT, \ A2_SRC2_CHANNEL_X_NEGATE) | \ gen3_get_hardware_channel_val(REG_Y(operand2), \ A2_SRC2_CHANNEL_Y_SHIFT, \ A2_SRC2_CHANNEL_Y_NEGATE) | \ gen3_get_hardware_channel_val(REG_Z(operand2), \ A2_SRC2_CHANNEL_Z_SHIFT, \ A2_SRC2_CHANNEL_Z_NEGATE) | \ gen3_get_hardware_channel_val(REG_W(operand2), \ A2_SRC2_CHANNEL_W_SHIFT, \ A2_SRC2_CHANNEL_W_NEGATE)); \ } while (0) #define gen3_fs_mov(dest_reg, operand0) \ gen3_fs_arith(MOV, dest_reg, \ operand0, \ gen3_fs_operand_none(), \ gen3_fs_operand_none()) #define gen3_fs_mov_masked(dest_reg, dest_mask, operand0) \ gen3_fs_arith_masked (MOV, dest_reg, dest_mask, \ operand0, \ gen3_fs_operand_none(), \ gen3_fs_operand_none()) #define gen3_fs_frc(dest_reg, operand0) \ gen3_fs_arith (FRC, dest_reg, \ operand0, \ gen3_fs_operand_none(), \ gen3_fs_operand_none()) /** Add operand0 and operand1 and put the result in dest_reg */ #define gen3_fs_add(dest_reg, operand0, operand1) \ gen3_fs_arith (ADD, dest_reg, \ operand0, operand1, \ gen3_fs_operand_none()) /** Multiply operand0 and operand1 and put the result in dest_reg */ #define gen3_fs_mul(dest_reg, operand0, operand1) \ gen3_fs_arith (MUL, dest_reg, \ operand0, operand1, \ gen3_fs_operand_none()) /** Computes 1/(operand0.replicate_swizzle) puts the result in dest_reg */ #define gen3_fs_rcp(dest_reg, dest_mask, operand0) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (RCP, dest_reg, dest_mask, \ operand0, \ gen3_fs_operand_none (), \ gen3_fs_operand_none ()); \ } else { \ gen3_fs_arith (RCP, dest_reg, \ operand0, \ gen3_fs_operand_none (), \ gen3_fs_operand_none ()); \ } \ } while (0) /** Computes 1/sqrt(operand0.replicate_swizzle) puts the result in dest_reg */ #define gen3_fs_rsq(dest_reg, dest_mask, operand0) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (RSQ, dest_reg, dest_mask, \ operand0, \ gen3_fs_operand_none (), \ gen3_fs_operand_none ()); \ } else { \ gen3_fs_arith (RSQ, dest_reg, \ operand0, \ gen3_fs_operand_none (), \ gen3_fs_operand_none ()); \ } \ } while (0) /** Puts the minimum of operand0 and operand1 in dest_reg */ #define gen3_fs_min(dest_reg, operand0, operand1) \ gen3_fs_arith (MIN, dest_reg, \ operand0, operand1, \ gen3_fs_operand_none()) /** Puts the maximum of operand0 and operand1 in dest_reg */ #define gen3_fs_max(dest_reg, operand0, operand1) \ gen3_fs_arith (MAX, dest_reg, \ operand0, operand1, \ gen3_fs_operand_none()) #define gen3_fs_cmp(dest_reg, operand0, operand1, operand2) \ gen3_fs_arith (CMP, dest_reg, operand0, operand1, operand2) /** Perform operand0 * operand1 + operand2 and put the result in dest_reg */ #define gen3_fs_mad(dest_reg, dest_mask, op0, op1, op2) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (MAD, dest_reg, dest_mask, op0, op1, op2); \ } else { \ gen3_fs_arith (MAD, dest_reg, op0, op1, op2); \ } \ } while (0) #define gen3_fs_dp2add(dest_reg, dest_mask, op0, op1, op2) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (DP2ADD, dest_reg, dest_mask, op0, op1, op2); \ } else { \ gen3_fs_arith (DP2ADD, dest_reg, op0, op1, op2); \ } \ } while (0) /** * Perform a 3-component dot-product of operand0 and operand1 and put the * resulting scalar in the channels of dest_reg specified by the dest_mask. */ #define gen3_fs_dp3(dest_reg, dest_mask, op0, op1) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (DP3, dest_reg, dest_mask, \ op0, op1,\ gen3_fs_operand_none()); \ } else { \ gen3_fs_arith (DP3, dest_reg, op0, op1,\ gen3_fs_operand_none()); \ } \ } while (0) /** * Perform a 4-component dot-product of operand0 and operand1 and put the * resulting scalar in the channels of dest_reg specified by the dest_mask. */ #define gen3_fs_dp4(dest_reg, dest_mask, op0, op1) \ do { \ if (dest_mask) { \ gen3_fs_arith_masked (DP4, dest_reg, dest_mask, \ op0, op1,\ gen3_fs_operand_none()); \ } else { \ gen3_fs_arith (DP4, dest_reg, op0, op1,\ gen3_fs_operand_none()); \ } \ } while (0) #define SHADER_TRAPEZOIDS (1 << 24) xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_common.c000066400000000000000000000037541267532330400242250ustar00rootroot00000000000000/* * Copyright © 2011-2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "gen4_common.h" #include "gen4_vertex.h" void gen4_render_flush(struct sna *sna) { gen4_vertex_close(sna); assert(sna->render.vb_id == 0); assert(sna->render.vertex_offset == 0); } void gen4_render_retire(struct kgem *kgem) { struct sna *sna; sna = container_of(kgem, struct sna, kgem); if (sna->render.nvertex_reloc == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) { DBG(("%s: resetting idle vbo\n", __FUNCTION__)); sna->render.vertex_used = 0; sna->render.vertex_index = 0; } } void gen4_render_expire(struct kgem *kgem) { struct sna *sna; sna = container_of(kgem, struct sna, kgem); if (sna->render.vbo && !sna->render.vertex_used) { DBG(("%s: discarding vbo\n", __FUNCTION__)); discard_vbo(sna); } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_common.h000066400000000000000000000033221267532330400242210ustar00rootroot00000000000000/* * Copyright © 2011-2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef GEN4_COMMON_H #define GEN4_COMMON_H #include "sna.h" inline static void discard_vbo(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render.vbo); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); sna->render.vertex_used = 0; sna->render.vertex_index = 0; } void gen4_render_flush(struct sna *sna); void gen4_render_retire(struct kgem *kgem); void gen4_render_expire(struct kgem *kgem); #endif /* GEN4_COMMON_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_render.c000066400000000000000000002546461267532330400242240ustar00rootroot00000000000000/* * Copyright © 2006,2008,2011 Intel Corporation * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Carl Worth * Keith Packard * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_video.h" #include "brw/brw.h" #include "gen4_common.h" #include "gen4_render.h" #include "gen4_source.h" #include "gen4_vertex.h" /* gen4 has a serious issue with its shaders that we need to flush * after every rectangle... So until that is resolved, prefer * the BLT engine. */ #define FORCE_SPANS 0 #define FORCE_NONRECTILINEAR_SPANS -1 #define FORCE_FLUSH 1 /* https://bugs.freedesktop.org/show_bug.cgi?id=55500 */ #define ALWAYS_FLUSH 1 #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_ONE 0 #define NO_FILL_BOXES 0 #define NO_VIDEO 0 #define MAX_FLUSH_VERTICES 1 /* was 6, https://bugs.freedesktop.org/show_bug.cgi?id=55500 */ #define GEN4_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) /* Set up a default static partitioning of the URB, which is supposed to * allow anything we would want to do, at potentially lower performance. */ #define URB_CS_ENTRY_SIZE 1 #define URB_CS_ENTRIES 0 #define URB_VS_ENTRY_SIZE 1 #define URB_VS_ENTRIES 32 #define URB_GS_ENTRY_SIZE 0 #define URB_GS_ENTRIES 0 #define URB_CL_ENTRY_SIZE 0 #define URB_CL_ENTRIES 0 #define URB_SF_ENTRY_SIZE 2 #define URB_SF_ENTRIES 64 /* * this program computes dA/dx and dA/dy for the texture coordinates along * with the base texture coordinate. It was extracted from the Mesa driver */ #define SF_KERNEL_NUM_GRF 16 #define PS_KERNEL_NUM_GRF 32 #define GEN4_MAX_SF_THREADS 24 #define GEN4_MAX_WM_THREADS 32 #define G4X_MAX_WM_THREADS 50 static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_planar.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; #define NOKERNEL(kernel_enum, func, masked) \ [kernel_enum] = {func, 0, masked} #define KERNEL(kernel_enum, kernel, masked) \ [kernel_enum] = {&kernel, sizeof(kernel), masked} static const struct wm_kernel_info { const void *data; unsigned int size; bool has_mask; } wm_kernels[] = { NOKERNEL(WM_KERNEL, brw_wm_kernel__affine, false), NOKERNEL(WM_KERNEL_P, brw_wm_kernel__projective, false), NOKERNEL(WM_KERNEL_MASK, brw_wm_kernel__affine_mask, true), NOKERNEL(WM_KERNEL_MASK_P, brw_wm_kernel__projective_mask, true), NOKERNEL(WM_KERNEL_MASKCA, brw_wm_kernel__affine_mask_ca, true), NOKERNEL(WM_KERNEL_MASKCA_P, brw_wm_kernel__projective_mask_ca, true), NOKERNEL(WM_KERNEL_MASKSA, brw_wm_kernel__affine_mask_sa, true), NOKERNEL(WM_KERNEL_MASKSA_P, brw_wm_kernel__projective_mask_sa, true), NOKERNEL(WM_KERNEL_OPACITY, brw_wm_kernel__affine_opacity, true), NOKERNEL(WM_KERNEL_OPACITY_P, brw_wm_kernel__projective_opacity, true), KERNEL(WM_KERNEL_VIDEO_PLANAR, ps_kernel_planar_static, false), KERNEL(WM_KERNEL_VIDEO_PACKED, ps_kernel_packed_static, false), }; #undef KERNEL static const struct blendinfo { bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen4_blend_op[] = { /* Clear */ {0, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_ZERO}, /* Src */ {0, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_ZERO}, /* Dst */ {0, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_ONE}, /* Over */ {1, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {0, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_ONE}, /* In */ {0, GEN4_BLENDFACTOR_DST_ALPHA, GEN4_BLENDFACTOR_ZERO}, /* InReverse */ {1, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_SRC_ALPHA}, /* Out */ {0, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_ZERO}, /* OutReverse */ {1, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, GEN4_BLENDFACTOR_DST_ALPHA, GEN4_BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in gen4_blend_op. * * This leaves out GEN4_BLENDFACTOR_INV_DST_COLOR, * GEN4_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * GEN4_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define GEN4_BLENDFACTOR_COUNT (GEN4_BLENDFACTOR_INV_DST_ALPHA + 1) #define BLEND_OFFSET(s, d) \ (((s) * GEN4_BLENDFACTOR_COUNT + (d)) * 64) #define SAMPLER_OFFSET(sf, se, mf, me, k) \ ((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * KERNEL_COUNT + (k)) * 64) static void gen4_emit_pipelined_pointers(struct sna *sna, const struct sna_composite_op *op, int blend, int kernel); #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) #define OUT_VERTEX_F(v) vertex_emit(sna, v) #define GEN4_MAX_3D_SIZE 8192 static inline bool too_large(int width, int height) { return width > GEN4_MAX_3D_SIZE || height > GEN4_MAX_3D_SIZE; } static int gen4_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine) { int base; if (has_mask) { if (is_ca) { if (gen4_blend_op[op].src_alpha) base = WM_KERNEL_MASKSA; else base = WM_KERNEL_MASKCA; } else base = WM_KERNEL_MASK; } else base = WM_KERNEL; return base + !is_affine; } static bool gen4_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { struct gen4_render_state *state = &sna->render_state.gen4; if (!op->need_magic_ca_pass) return false; assert(sna->render.vertex_index > sna->render.vertex_start); DBG(("%s: CA fixup\n", __FUNCTION__)); assert(op->mask.bo != NULL); assert(op->has_component_alpha); gen4_emit_pipelined_pointers(sna, op, PictOpAdd, gen4_choose_composite_kernel(PictOpAdd, true, true, op->is_affine)); OUT_BATCH(GEN4_3DPRIMITIVE | GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | 4); OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start); OUT_BATCH(sna->render.vertex_start); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ state->last_primitive = sna->kgem.nbatch; return true; } static uint32_t gen4_get_blend(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t src, dst; src = gen4_blend_op[op].src_blend; dst = gen4_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (src == GEN4_BLENDFACTOR_DST_ALPHA) src = GEN4_BLENDFACTOR_ONE; else if (src == GEN4_BLENDFACTOR_INV_DST_ALPHA) src = GEN4_BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a * case where the source blend factor is 0, and the source blend * value is the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen4_blend_op[op].src_alpha) { if (dst == GEN4_BLENDFACTOR_SRC_ALPHA) dst = GEN4_BLENDFACTOR_SRC_COLOR; else if (dst == GEN4_BLENDFACTOR_INV_SRC_ALPHA) dst = GEN4_BLENDFACTOR_INV_SRC_COLOR; } DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n", op, dst_format, PICT_FORMAT_A(dst_format), src, dst, BLEND_OFFSET(src, dst))); return BLEND_OFFSET(src, dst); } static uint32_t gen4_get_card_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_x8r8g8b8: return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM; case PICT_a8b8g8r8: return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM; case PICT_x8b8g8r8: return GEN4_SURFACEFORMAT_R8G8B8X8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM; case PICT_x2r10g10b10: return GEN4_SURFACEFORMAT_B10G10R10X2_UNORM; #endif case PICT_r8g8b8: return GEN4_SURFACEFORMAT_R8G8B8_UNORM; case PICT_r5g6b5: return GEN4_SURFACEFORMAT_B5G6R5_UNORM; case PICT_a1r5g5b5: return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN4_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM; } } static uint32_t gen4_get_dest_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return GEN4_SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN4_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM; } } static bool gen4_check_dst_format(PictFormat format) { if (gen4_get_dest_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static bool gen4_check_format(uint32_t format) { if (gen4_get_card_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } typedef struct gen4_surface_state_padded { struct gen4_surface_state state; char pad[32 - sizeof(struct gen4_surface_state)]; } gen4_surface_state_padded; static void null_create(struct sna_static_stream *stream) { /* A bunch of zeros useful for legacy border color and depth-stencil */ sna_static_stream_map(stream, 64, 64); } static void sampler_state_init(struct gen4_sampler_state *sampler_state, sampler_filter_t filter, sampler_extend_t extend) { sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.border_color_mode = GEN4_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SAMPLER_FILTER_NEAREST: sampler_state->ss0.min_filter = GEN4_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = GEN4_MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: sampler_state->ss0.min_filter = GEN4_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = GEN4_MAPFILTER_LINEAR; break; } switch (extend) { default: case SAMPLER_EXTEND_NONE: sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_WRAP; sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_WRAP; sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP; sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP; sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_MIRROR; sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_MIRROR; sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_MIRROR; break; } } static uint32_t gen4_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return SAMPLER_FILTER_NEAREST; case PictFilterBilinear: return SAMPLER_FILTER_BILINEAR; } } static uint32_t gen4_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: DBG(("%s: unknown filter: %s [%d]\n", __FUNCTION__, PictureGetFilterName(picture->filter), picture->filter)); return false; } } static uint32_t gen4_repeat(uint32_t repeat) { switch (repeat) { default: assert(0); case RepeatNone: return SAMPLER_EXTEND_NONE; case RepeatNormal: return SAMPLER_EXTEND_REPEAT; case RepeatPad: return SAMPLER_EXTEND_PAD; case RepeatReflect: return SAMPLER_EXTEND_REFLECT; } } static bool gen4_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: DBG(("%s: unknown repeat: %d\n", __FUNCTION__, picture->repeatType)); return false; } } static uint32_t gen4_tiling_bits(uint32_t tiling) { switch (tiling) { default: assert(0); case I915_TILING_NONE: return 0; case I915_TILING_X: return GEN4_SURFACE_TILED; case I915_TILING_Y: return GEN4_SURFACE_TILED | GEN4_SURFACE_TILED_Y; } } /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static uint32_t gen4_bind_bo(struct sna *sna, struct kgem_bo *bo, uint32_t width, uint32_t height, uint32_t format, bool is_dst) { uint32_t domains; uint16_t offset; uint32_t *ss; assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo)); /* After the first bind, we manage the cache domains within the batch */ offset = kgem_bo_get_binding(bo, format | is_dst << 31); if (offset) { assert(offset >= sna->kgem.surface); if (is_dst) kgem_bo_mark_dirty(bo); return offset * sizeof(uint32_t); } offset = sna->kgem.surface -= sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t); ss = sna->kgem.batch + offset; ss[0] = (GEN4_SURFACE_2D << GEN4_SURFACE_TYPE_SHIFT | GEN4_SURFACE_BLEND_ENABLED | format << GEN4_SURFACE_FORMAT_SHIFT); if (is_dst) { ss[0] |= GEN4_SURFACE_RC_READ_WRITE; domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER; } else domains = I915_GEM_DOMAIN_SAMPLER << 16; ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); ss[2] = ((width - 1) << GEN4_SURFACE_WIDTH_SHIFT | (height - 1) << GEN4_SURFACE_HEIGHT_SHIFT); ss[3] = (gen4_tiling_bits(bo->tiling) | (bo->pitch - 1) << GEN4_SURFACE_PITCH_SHIFT); ss[4] = 0; ss[5] = 0; kgem_bo_set_binding(bo, format | is_dst << 31, offset); DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n", offset, bo->handle, ss[1], format, width, height, bo->pitch, bo->tiling, domains & 0xffff ? "render" : "sampler")); return offset * sizeof(uint32_t); } static void gen4_emit_vertex_buffer(struct sna *sna, const struct sna_composite_op *op) { int id = op->u.gen4.ve_id; assert((sna->render.vb_id & (1 << id)) == 0); OUT_BATCH(GEN4_3DSTATE_VERTEX_BUFFERS | 3); OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA | (4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT)); assert(sna->render.nvertex_reloc < ARRAY_SIZE(sna->render.vertex_reloc)); sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch; OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); sna->render.vb_id |= 1 << id; } inline static void gen4_emit_pipe_flush(struct sna *sna) { #if 1 OUT_BATCH(GEN4_PIPE_CONTROL | GEN4_PIPE_CONTROL_WC_FLUSH | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #else OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); #endif } inline static void gen4_emit_pipe_break(struct sna *sna) { #if !ALWAYS_FLUSH OUT_BATCH(GEN4_PIPE_CONTROL | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #else OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); #endif } inline static void gen4_emit_pipe_invalidate(struct sna *sna) { #if 0 OUT_BATCH(GEN4_PIPE_CONTROL | GEN4_PIPE_CONTROL_WC_FLUSH | (sna->kgem.gen >= 045 ? GEN4_PIPE_CONTROL_TC_FLUSH : 0) | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #else OUT_BATCH(MI_FLUSH); #endif } static void gen4_emit_primitive(struct sna *sna) { if (sna->kgem.nbatch == sna->render_state.gen4.last_primitive) { sna->render.vertex_offset = sna->kgem.nbatch - 5; return; } OUT_BATCH(GEN4_3DPRIMITIVE | GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | 4); sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(sna->render.vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ sna->render.vertex_start = sna->render.vertex_index; sna->render_state.gen4.last_primitive = sna->kgem.nbatch; } static bool gen4_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { unsigned int id = 1 << op->u.gen4.ve_id; int ndwords; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; /* 7xpipelined pointers + 6xprimitive + 1xflush */ ndwords = op->need_magic_ca_pass? 19 : 6; if ((sna->render.vb_id & id) == 0) ndwords += 5; ndwords += 8*FORCE_FLUSH; if (!kgem_check_batch(&sna->kgem, ndwords)) return false; if ((sna->render.vb_id & id) == 0) gen4_emit_vertex_buffer(sna, op); if (sna->render.vertex_offset == 0) gen4_emit_primitive(sna); return true; } static int gen4_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, 8*FORCE_FLUSH + (op->need_magic_ca_pass ? 2*19+6 : 6))) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 2)) return 0; if (sna->render.vertex_offset) { gen4_vertex_flush(sna); if (gen4_magic_ca_pass(sna, op)) gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel); } return gen4_vertex_finish(sna); } inline static int gen4_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want, void (*emit_state)(struct sna *sna, const struct sna_composite_op *op)) { int rem; assert(want); #if FORCE_FLUSH rem = sna->render.vertex_offset; if (sna->kgem.nbatch == sna->render_state.gen4.last_primitive) rem = sna->kgem.nbatch - 5; if (rem) { rem = MAX_FLUSH_VERTICES - (sna->render.vertex_index - sna->render.vertex_start) / 3; if (rem <= 0) { if (sna->render.vertex_offset) { gen4_vertex_flush(sna); if (gen4_magic_ca_pass(sna, op)) { if (kgem_check_batch(&sna->kgem, 19+6)) gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel); } } gen4_emit_pipe_break(sna); rem = MAX_FLUSH_VERTICES; } } else rem = MAX_FLUSH_VERTICES; if (want > rem) want = rem; #endif start: rem = vertex_space(sna); if (unlikely(rem < op->floats_per_rect)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen4_get_rectangles__flush(sna, op); if (unlikely(rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen4_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; sna->render.vertex_index += 3*want; return want; flush: if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen4_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); emit_state(sna, op); goto start; } static uint32_t * gen4_composite_get_binding_table(struct sna *sna, uint16_t *offset) { sna->kgem.surface -= sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t); DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface)); /* Clear all surplus entries to zero in case of prefetch */ *offset = sna->kgem.surface; return memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(struct gen4_surface_state_padded)); } static void gen4_emit_urb(struct sna *sna) { int urb_vs_end; int urb_gs_end; int urb_cl_end; int urb_sf_end; int urb_cs_end; if (!sna->render_state.gen4.needs_urb) return; urb_vs_end = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; urb_gs_end = urb_vs_end + URB_GS_ENTRIES * URB_GS_ENTRY_SIZE; urb_cl_end = urb_gs_end + URB_CL_ENTRIES * URB_CL_ENTRY_SIZE; urb_sf_end = urb_cl_end + URB_SF_ENTRIES * URB_SF_ENTRY_SIZE; urb_cs_end = urb_sf_end + URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; assert(urb_cs_end <= 256); while ((sna->kgem.nbatch & 15) > 12) OUT_BATCH(MI_NOOP); OUT_BATCH(GEN4_URB_FENCE | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH(urb_cl_end << UF1_CLIP_FENCE_SHIFT | urb_gs_end << UF1_GS_FENCE_SHIFT | urb_vs_end << UF1_VS_FENCE_SHIFT); OUT_BATCH(urb_cs_end << UF2_CS_FENCE_SHIFT | urb_sf_end << UF2_SF_FENCE_SHIFT); /* Constant buffer state */ OUT_BATCH(GEN4_CS_URB_STATE | 0); OUT_BATCH((URB_CS_ENTRY_SIZE - 1) << 4 | URB_CS_ENTRIES << 0); sna->render_state.gen4.needs_urb = false; } static void gen4_emit_state_base_address(struct sna *sna) { assert(sna->render_state.gen4.general_bo->proxy == NULL); OUT_BATCH(GEN4_STATE_BASE_ADDRESS | 4); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* general */ sna->kgem.nbatch, sna->render_state.gen4.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */ sna->kgem.nbatch, NULL, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(0); /* media */ /* upper bounds, all disabled */ OUT_BATCH(BASE_ADDRESS_MODIFY); OUT_BATCH(0); } static void gen4_emit_invariant(struct sna *sna) { assert(sna->kgem.surface == sna->kgem.batch_size); if (sna->kgem.gen >= 045) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); else OUT_BATCH(GEN4_PIPELINE_SELECT | PIPELINE_SELECT_3D); gen4_emit_state_base_address(sna); sna->render_state.gen4.needs_invariant = false; } static void gen4_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150 + 50*FORCE_FLUSH, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch, 150, 4*8)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen4.needs_invariant) gen4_emit_invariant(sna); } static void gen4_align_vertex(struct sna *sna, const struct sna_composite_op *op) { assert(op->floats_per_rect == 3*op->floats_per_vertex); if (op->floats_per_vertex != sna->render_state.gen4.floats_per_vertex) { DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen4.floats_per_vertex, op->floats_per_vertex)); gen4_vertex_align(sna, op); sna->render_state.gen4.floats_per_vertex = op->floats_per_vertex; } } static void gen4_emit_binding_table(struct sna *sna, uint16_t offset) { if (sna->render_state.gen4.surface_table == offset) return; sna->render_state.gen4.surface_table = offset; /* Binding table pointers */ OUT_BATCH(GEN4_3DSTATE_BINDING_TABLE_POINTERS | 4); OUT_BATCH(0); /* vs */ OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ /* Only the PS uses the binding table */ OUT_BATCH(offset*4); } static void gen4_emit_pipelined_pointers(struct sna *sna, const struct sna_composite_op *op, int blend, int kernel) { uint16_t sp, bp; uint32_t key; DBG(("%s: has_mask=%d, src=(%d, %d), mask=(%d, %d),kernel=%d, blend=%d, ca=%d, format=%x\n", __FUNCTION__, op->u.gen4.ve_id & 2, op->src.filter, op->src.repeat, op->mask.filter, op->mask.repeat, kernel, blend, op->has_component_alpha, (int)op->dst.format)); sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat, op->mask.filter, op->mask.repeat, kernel); bp = gen4_get_blend(blend, op->has_component_alpha, op->dst.format); DBG(("%s: sp=%d, bp=%d\n", __FUNCTION__, sp, bp)); key = sp | (uint32_t)bp << 16; if (key == sna->render_state.gen4.last_pipelined_pointers) return; OUT_BATCH(GEN4_3DSTATE_PIPELINED_POINTERS | 5); OUT_BATCH(sna->render_state.gen4.vs); OUT_BATCH(GEN4_GS_DISABLE); /* passthrough */ OUT_BATCH(GEN4_CLIP_DISABLE); /* passthrough */ OUT_BATCH(sna->render_state.gen4.sf); OUT_BATCH(sna->render_state.gen4.wm + sp); OUT_BATCH(sna->render_state.gen4.cc + bp); sna->render_state.gen4.last_pipelined_pointers = key; gen4_emit_urb(sna); } static bool gen4_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; assert(!too_large(abs(op->dst.x), abs(op->dst.y))); assert(!too_large(op->dst.width, op->dst.height)); if (sna->render_state.gen4.drawrect_limit == limit && sna->render_state.gen4.drawrect_offset == offset) return true; sna->render_state.gen4.drawrect_offset = offset; sna->render_state.gen4.drawrect_limit = limit; OUT_BATCH(GEN4_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(limit); OUT_BATCH(offset); return false; } static void gen4_emit_vertex_elements(struct sna *sna, const struct sna_composite_op *op) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0) * texture coordinate 1 if (has_mask is true): same as above */ struct gen4_render_state *render = &sna->render_state.gen4; uint32_t src_format, dw; int id = op->u.gen4.ve_id; if (render->ve_id == id) return; render->ve_id = id; /* The VUE layout * dword 0-3: position (x, y, 1.0, 1.0), * dword 4-7: texture coordinate 0 (u0, v0, w0, 1.0) * [optional] dword 8-11: texture coordinate 1 (u1, v1, w1, 1.0) */ OUT_BATCH(GEN4_3DSTATE_VERTEX_ELEMENTS | (2 * (1 + 2) - 1)); /* x,y */ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | GEN4_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT | 0 << VE0_OFFSET_SHIFT); OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT | VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT | VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT | VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT | (1*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* u0, v0, w0 */ /* u0, v0, w0 */ DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3)); dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id & 3) { default: assert(0); case 0: src_format = GEN4_SURFACEFORMAT_R16G16_SSCALED; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 1: src_format = GEN4_SURFACEFORMAT_R32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 2: src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | src_format << VE0_FORMAT_SHIFT | 4 << VE0_OFFSET_SHIFT); OUT_BATCH(dw | 8 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); /* u1, v1, w1 */ if (id >> 2) { unsigned src_offset = 4 + ((id & 3) ?: 1) * sizeof(float); DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, src_offset)); dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id >> 2) { case 1: src_format = GEN4_SURFACEFORMAT_R32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; default: assert(0); case 2: src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | src_format << VE0_FORMAT_SHIFT | src_offset << VE0_OFFSET_SHIFT); OUT_BATCH(dw | 12 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); } else { OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | GEN4_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT | 0 << VE0_OFFSET_SHIFT); OUT_BATCH(VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT | VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT | VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT | VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT | 12 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT); } } static void gen4_emit_state(struct sna *sna, const struct sna_composite_op *op, uint16_t wm_binding_table) { bool flush; assert(op->dst.bo->exec); flush = wm_binding_table & 1; wm_binding_table &= ~1; if (ALWAYS_FLUSH || kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { DBG(("%s: flushing dirty (%d, %d), forced? %d\n", __FUNCTION__, kgem_bo_is_dirty(op->src.bo), kgem_bo_is_dirty(op->mask.bo), flush)); gen4_emit_pipe_invalidate(sna); kgem_clear_dirty(&sna->kgem); kgem_bo_mark_dirty(op->dst.bo); flush = false; } flush &= gen4_emit_drawing_rectangle(sna, op); if (flush && op->op > PictOpSrc) gen4_emit_pipe_flush(sna); gen4_emit_binding_table(sna, wm_binding_table); gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel); gen4_emit_vertex_elements(sna, op); } static void gen4_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen4_get_batch(sna, op); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table = gen4_composite_get_binding_table(sna, &offset); binding_table[0] = gen4_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen4_get_dest_format(op->dst.format), true); binding_table[1] = gen4_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (op->mask.bo) { assert(op->u.gen4.ve_id >> 2); binding_table[2] = gen4_bind_bo(sna, op->mask.bo, op->mask.width, op->mask.height, op->mask.card_format, false); } if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table && (op->mask.bo == NULL || sna->kgem.batch[sna->render_state.gen4.surface_table+2] == binding_table[2])) { sna->kgem.surface += sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen4.surface_table; } if (!ALWAYS_FLUSH && sna->kgem.batch[sna->render_state.gen4.surface_table] == binding_table[0]) dirty = 0; gen4_emit_state(sna, op, offset | dirty); } fastcall static void gen4_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, op->src.offset[0], op->src.offset[1], r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1], r->dst.x, r->dst.y, op->dst.x, op->dst.y, r->width, r->height)); gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces); op->prim_emit(sna, op, r); } fastcall static void gen4_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.mask = r.src = r.dst; op->prim_emit(sna, op, &r); } static void gen4_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s(%d) delta=(%d, %d), src=(%d, %d)/(%d, %d), mask=(%d, %d)/(%d, %d)\n", __FUNCTION__, nbox, op->dst.x, op->dst.y, op->src.offset[0], op->src.offset[1], op->src.width, op->src.height, op->mask.offset[0], op->mask.offset[1], op->mask.width, op->mask.height)); do { int nbox_this_time; nbox_this_time = gen4_get_rectangles(sna, op, nbox, gen4_bind_surfaces); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.mask = r.src = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen4_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen4_get_rectangles(sna, op, nbox, gen4_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } #if !FORCE_FLUSH static void gen4_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen4_get_rectangles(sna, op, nbox, gen4_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } #endif #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif static uint32_t gen4_bind_video_source(struct sna *sna, struct kgem_bo *src_bo, uint32_t src_offset, int src_width, int src_height, int src_pitch, uint32_t src_surf_format) { struct gen4_surface_state *ss; sna->kgem.surface -= sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t); ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss)); ss->ss0.surface_type = GEN4_SURFACE_2D; ss->ss0.surface_format = src_surf_format; ss->ss0.color_blend = 1; ss->ss1.base_addr = kgem_add_reloc(&sna->kgem, sna->kgem.surface + 1, src_bo, I915_GEM_DOMAIN_SAMPLER << 16, src_offset); ss->ss2.width = src_width - 1; ss->ss2.height = src_height - 1; ss->ss3.pitch = src_pitch - 1; return sna->kgem.surface * sizeof(uint32_t); } static void gen4_video_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { struct sna_video_frame *frame = op->priv; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; uint32_t *binding_table; uint16_t offset, dirty; int n_src, n; src_surf_base[0] = 0; src_surf_base[1] = 0; src_surf_base[2] = frame->VBufOffset; src_surf_base[3] = frame->VBufOffset; src_surf_base[4] = frame->UBufOffset; src_surf_base[5] = frame->UBufOffset; if (is_planar_fourcc(frame->id)) { src_surf_format = GEN4_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = frame->width; src_height[1] = src_height[0] = frame->height; src_pitch[1] = src_pitch[0] = frame->pitch[1]; src_width[4] = src_width[5] = src_width[2] = src_width[3] = frame->width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = frame->height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = frame->pitch[0]; n_src = 6; } else { if (frame->id == FOURCC_UYVY) src_surf_format = GEN4_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = GEN4_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = frame->width; src_height[0] = frame->height; src_pitch[0] = frame->pitch[0]; n_src = 1; } gen4_get_batch(sna, op); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table = gen4_composite_get_binding_table(sna, &offset); binding_table[0] = gen4_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen4_get_dest_format(op->dst.format), true); for (n = 0; n < n_src; n++) { binding_table[1+n] = gen4_bind_video_source(sna, frame->bo, src_surf_base[n], src_width[n], src_height[n], src_pitch[n], src_surf_format); } if (!ALWAYS_FLUSH && sna->kgem.batch[sna->render_state.gen4.surface_table] == binding_table[0]) dirty = 0; gen4_emit_state(sna, op, offset | dirty); } static bool gen4_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_composite_op tmp; struct sna_pixmap *priv = sna_pixmap(pixmap); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; const BoxRec *box; int nbox; DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_width, src_height, dst_width, dst_height)); assert(priv->gpu_bo); memset(&tmp, 0, sizeof(tmp)); tmp.op = PictOpSrc; tmp.dst.pixmap = pixmap; tmp.dst.width = pixmap->drawable.width; tmp.dst.height = pixmap->drawable.height; tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; if (src_width == dst_width && src_height == dst_height) tmp.src.filter = SAMPLER_FILTER_NEAREST; else tmp.src.filter = SAMPLER_FILTER_BILINEAR; tmp.src.repeat = SAMPLER_EXTEND_PAD; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; tmp.u.gen4.wm_kernel = is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED; tmp.u.gen4.ve_id = 2; tmp.is_affine = true; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; tmp.priv = frame; if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) return false; } gen4_align_vertex(sna, &tmp); gen4_video_bind_surfaces(sna, &tmp); src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; box = region_rects(dstRegion); nbox = region_num_rects(dstRegion); do { int n; n = gen4_get_rectangles(sna, &tmp, nbox, gen4_video_bind_surfaces); assert(n); nbox -= n; do { OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); box++; } while (--n); } while (nbox); gen4_vertex_flush(sna); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } static int gen4_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->is_solid = false; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen4_channel_init_linear(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen4_check_repeat(picture)) { DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen4_check_filter(picture)) { DBG(("%s: unhandled filter fixup\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat && (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen4_channel_init_solid(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; channel->pict_format = picture->format; channel->card_format = gen4_get_card_format(picture->format); if (channel->card_format == -1) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } static void gen4_composite_channel_convert(struct sna_composite_channel *channel) { DBG(("%s: repeat %d -> %d, filter %d -> %d\n", __FUNCTION__, channel->repeat, gen4_repeat(channel->repeat), channel->filter, gen4_repeat(channel->filter))); channel->repeat = gen4_repeat(channel->repeat); channel->filter = gen4_filter(channel->filter); if (channel->card_format == (unsigned)-1) channel->card_format = gen4_get_card_format(channel->pict_format); } static void gen4_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { DBG(("%s()\n", __FUNCTION__)); if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen4_magic_ca_pass(sna, op); } if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } static bool gen4_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned hint; op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; op->dst.format = dst->format; if (w && h) { box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (too_large(op->dst.width, op->dst.height) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool check_gradient(PicturePtr picture, bool precise) { switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(struct sna *sna, PicturePtr p) { return p->pDrawable && untransformed(p) && !is_gpu(sna, p->pDrawable, PREFER_GPU_RENDER); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(struct sna *sna, PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (p->pSourcePict) return check_gradient(p, precise); if (!gen4_check_repeat(p) || !gen4_check_format(p->format)) return true; /* soft errors: perfer to upload/compute rather than readback */ if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen4_check_filter(p) || need_upload(sna, p); } static bool gen4_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen4_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(sna, src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(sna, mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (sna_picture_is_solid(mask, &color)) return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen4_check_repeat(mask)) return false; if (!gen4_check_filter(mask)) return false; if (!gen4_check_format(mask->format)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen4_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen4_filter(mask->filter); mc->pict_format = mask->format; mc->card_format = gen4_get_card_format(mask->format); mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen4_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, width, height, sna->kgem.mode)); if (op >= ARRAY_SIZE(gen4_blend_op)) return false; if (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen4_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, tmp); if (!gen4_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) { DBG(("%s: failed to set composite target\n", __FUNCTION__)); goto fallback; } tmp->op = op; switch (gen4_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: failed to prepare source\n", __FUNCTION__)); goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: if (mask == NULL && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; gen4_composite_channel_convert(&tmp->src); break; } tmp->is_affine = tmp->src.is_affine; tmp->has_component_alpha = false; tmp->need_magic_ca_pass = false; if (mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { tmp->has_component_alpha = true; /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (gen4_blend_op[op].src_alpha && (gen4_blend_op[op].src_blend != GEN4_BLENDFACTOR_ZERO)) { if (op != PictOpOver) { DBG(("%s -- fallback: unhandled component alpha blend\n", __FUNCTION__)); goto cleanup_src; } tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, msk_x, msk_y)) { switch (gen4_composite_picture(sna, mask, &tmp->mask, msk_x, msk_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: failed to prepare mask\n", __FUNCTION__)); goto cleanup_src; case 0: if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: gen4_composite_channel_convert(&tmp->mask); break; } } tmp->is_affine &= tmp->mask.is_affine; } tmp->u.gen4.wm_kernel = gen4_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine); tmp->u.gen4.ve_id = gen4_choose_composite_emitter(sna, tmp); tmp->blt = gen4_render_composite_blt; tmp->box = gen4_render_composite_box; tmp->boxes = gen4_render_composite_boxes__blt; if (tmp->emit_boxes) { tmp->boxes = gen4_render_composite_boxes; #if !FORCE_FLUSH tmp->thread_boxes = gen4_render_composite_boxes__thread; #endif } tmp->done = gen4_render_composite_done; if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; } gen4_align_vertex(sna, tmp); gen4_bind_surfaces(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } #if !NO_COMPOSITE_SPANS fastcall static void gen4_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen4_get_rectangles(sna, &op->base, 1, gen4_bind_surfaces); op->prim_emit(sna, op, box, opacity); } static void gen4_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen4_get_rectangles(sna, &op->base, nbox, gen4_bind_surfaces); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen4_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); assert(nbox); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen4_get_rectangles(sna, &op->base, nbox, gen4_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen4_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen4_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n", __FUNCTION__, op, width, height, flags)); if (op >= ARRAY_SIZE(gen4_blend_op)) return false; if (gen4_composite_fallback(sna, src, NULL, dst)) { DBG(("%s: operation would fallback\n", __FUNCTION__)); return false; } if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } if (FORCE_SPANS) return FORCE_SPANS > 0; if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) { struct sna_pixmap *priv; if (FORCE_NONRECTILINEAR_SPANS) return FORCE_NONRECTILINEAR_SPANS > 0; if ((sna->render.prefer_gpu & PREFER_GPU_SPANS) == 0) return false; priv = sna_pixmap_from_drawable(dst->pDrawable); assert(priv); if (priv->cpu_bo && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) return true; if (flags & COMPOSITE_SPANS_INPLACE_HINT) return false; return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; } static bool gen4_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__, width, height, flags, sna->kgem.ring)); assert(gen4_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; if (!gen4_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) return false; switch (gen4_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: gen4_composite_channel_convert(&tmp->base.src); break; } tmp->base.mask.bo = NULL; tmp->base.mask.filter = SAMPLER_FILTER_NEAREST; tmp->base.mask.repeat = SAMPLER_EXTEND_NONE; tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.has_component_alpha = false; tmp->base.need_magic_ca_pass = false; tmp->base.u.gen4.ve_id = gen4_choose_spans_emitter(sna, tmp); tmp->base.u.gen4.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine; tmp->box = gen4_render_composite_spans_box; tmp->boxes = gen4_render_composite_spans_boxes; if (tmp->emit_boxes) tmp->thread_boxes = gen4_render_composite_spans_boxes__thread; tmp->done = gen4_render_composite_spans_done; if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; } gen4_align_vertex(sna, &tmp->base); gen4_bind_surfaces(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } #endif static void gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen4_get_batch(sna, op); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table = gen4_composite_get_binding_table(sna, &offset); binding_table[0] = gen4_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen4_get_dest_format(op->dst.format), true); binding_table[1] = gen4_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen4.surface_table; } if (!ALWAYS_FLUSH && sna->kgem.batch[sna->render_state.gen4.surface_table] == binding_table[0]) dirty = 0; gen4_emit_state(sna, op, offset | dirty); } static void gen4_render_copy_one(struct sna *sna, const struct sna_composite_op *op, int sx, int sy, int w, int h, int dx, int dy) { gen4_get_rectangles(sna, op, 1, gen4_copy_bind_surfaces); OUT_VERTEX(dx+w, dy+h); OUT_VERTEX_F((sx+w)*op->src.scale[0]); OUT_VERTEX_F((sy+h)*op->src.scale[1]); OUT_VERTEX(dx, dy+h); OUT_VERTEX_F(sx*op->src.scale[0]); OUT_VERTEX_F((sy+h)*op->src.scale[1]); OUT_VERTEX(dx, dy); OUT_VERTEX_F(sx*op->src.scale[0]); OUT_VERTEX_F(sy*op->src.scale[1]); } static bool gen4_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; DBG(("%s x %d\n", __FUNCTION__, n)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo) { fallback_blt: if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } memset(&tmp, 0, sizeof(tmp)); DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); if (dst->depth == src->depth) { tmp.dst.format = sna_render_format_for_depth(dst->depth); tmp.src.pict_format = tmp.dst.format; } else { tmp.dst.format = sna_format_for_depth(dst->depth); tmp.src.pict_format = sna_format_for_depth(src->depth); } if (!gen4_check_format(tmp.src.pict_format)) goto fallback_blt; tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.x = tmp.dst.y = 0; tmp.dst.bo = dst_bo; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height)) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } tmp.src.filter = SAMPLER_FILTER_NEAREST; tmp.src.repeat = SAMPLER_EXTEND_NONE; tmp.src.card_format = gen4_get_card_format(tmp.src.pict_format); if (too_large(src->width, src->height)) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, extents.x1 + src_dx, extents.y1 + src_dy, extents.x2 - extents.x1, extents.y2 - extents.y1)) goto fallback_tiled_dst; } else { tmp.src.bo = kgem_bo_reference(src_bo); tmp.src.width = src->width; tmp.src.height = src->height; tmp.src.offset[0] = tmp.src.offset[1] = 0; tmp.src.scale[0] = 1.f/src->width; tmp.src.scale[1] = 1.f/src->height; } tmp.is_affine = true; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; tmp.u.gen4.wm_kernel = WM_KERNEL; tmp.u.gen4.ve_id = 2; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); goto fallback_blt; } } dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; src_dx += tmp.src.offset[0]; src_dy += tmp.src.offset[1]; gen4_align_vertex(sna, &tmp); gen4_copy_bind_surfaces(sna, &tmp); do { gen4_render_copy_one(sna, &tmp, box->x1 + src_dx, box->y1 + src_dy, box->x2 - box->x1, box->y2 - box->y1, box->x1 + dst_dx, box->y1 + dst_dy); box++; } while (--n); gen4_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; fallback_tiled_dst: if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); fallback_tiled: if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen4_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { gen4_render_copy_one(sna, &op->base, sx, sy, w, h, dx, dy); } static void gen4_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); } static bool gen4_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op) { DBG(("%s: src=%ld, dst=%ld, alu=%d\n", __FUNCTION__, src->drawable.serialNumber, dst->drawable.serialNumber, alu)); if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height)) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); } if (dst->drawable.depth == src->drawable.depth) { op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth); op->base.src.pict_format = op->base.dst.format; } else { op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.src.pict_format = sna_format_for_depth(src->drawable.depth); } if (!gen4_check_format(op->base.src.pict_format)) goto fallback; op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.bo = dst_bo; op->base.src.bo = src_bo; op->base.src.card_format = gen4_get_card_format(op->base.src.pict_format); op->base.src.width = src->drawable.width; op->base.src.height = src->drawable.height; op->base.src.scale[0] = 1.f/src->drawable.width; op->base.src.scale[1] = 1.f/src->drawable.height; op->base.src.filter = SAMPLER_FILTER_NEAREST; op->base.src.repeat = SAMPLER_EXTEND_NONE; op->base.is_affine = true; op->base.floats_per_vertex = 3; op->base.floats_per_rect = 9; op->base.u.gen4.wm_kernel = WM_KERNEL; op->base.u.gen4.ve_id = 2; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; } if (kgem_bo_is_dirty(src_bo)) { if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; } gen4_align_vertex(sna, &op->base); gen4_copy_bind_surfaces(sna, &op->base); op->blt = gen4_render_copy_blt; op->done = gen4_render_copy_done; return true; } static void gen4_render_fill_rectangle(struct sna *sna, const struct sna_composite_op *op, int x, int y, int w, int h) { gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces); OUT_VERTEX(x+w, y+h); OUT_VERTEX_F(.5); OUT_VERTEX(x, y+h); OUT_VERTEX_F(.5); OUT_VERTEX(x, y); OUT_VERTEX_F(.5); } static bool gen4_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; if (op >= ARRAY_SIZE(gen4_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (op <= PictOpSrc) { uint8_t alu = GXinvalid; pixel = 0; if (op == PictOpClear) alu = GXclear; else if (sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) alu = GXcopy; if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n)) return true; if (!gen4_check_dst_format(format)) return false; if (too_large(dst->width, dst->height)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } if (op == PictOpClear) { pixel = 0; op = PictOpSrc; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s(%08x x %d)\n", __FUNCTION__, pixel, n)); memset(&tmp, 0, sizeof(tmp)); tmp.op = op; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; sna_render_composite_redirect_init(&tmp); if (too_large(dst->width, dst->height)) { BoxRec extents; boxes_extents(box, n, &extents); if (!sna_render_composite_redirect(sna, &tmp, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } gen4_channel_init_solid(sna, &tmp.src, pixel); tmp.is_affine = true; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.u.gen4.wm_kernel = WM_KERNEL; tmp.u.gen4.ve_id = 1; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen4_align_vertex(sna, &tmp); gen4_bind_surfaces(sna, &tmp); do { gen4_render_fill_rectangle(sna, &tmp, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); sna_render_composite_redirect_done(sna, &tmp); return true; } static void gen4_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { gen4_render_fill_rectangle(sna, &op->base, x, y, w, h); } fastcall static void gen4_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { gen4_render_fill_rectangle(sna, &op->base, box->x1, box->y1, box->x2-box->x1, box->y2-box->y1); } fastcall static void gen4_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { do { gen4_render_fill_rectangle(sna, &op->base, box->x1, box->y1, box->x2-box->x1, box->y2-box->y1); box++; } while (--nbox); } static void gen4_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, op->base.src.bo); } static bool gen4_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *op) { if (sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op)) return true; if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op); if (alu == GXclear) color = 0; op->base.op = color == 0 ? PictOpClear : PictOpSrc; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.dst.bo = dst_bo; op->base.dst.x = op->base.dst.y = 0; op->base.need_magic_ca_pass = 0; op->base.has_component_alpha = 0; gen4_channel_init_solid(sna, &op->base.src, sna_rgba_for_color(color, dst->drawable.depth)); op->base.mask.bo = NULL; op->base.is_affine = true; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen4.wm_kernel = WM_KERNEL; op->base.u.gen4.ve_id = 1; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, op->base.src.bo); return false; } } gen4_align_vertex(sna, &op->base); gen4_bind_surfaces(sna, &op->base); op->blt = gen4_render_fill_op_blt; op->box = gen4_render_fill_op_box; op->boxes = gen4_render_fill_op_boxes; op->points = NULL; op->done = gen4_render_fill_op_done; return true; } static bool gen4_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; DBG(("%s: color=%08x\n", __FUNCTION__, color)); if (gen4_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return false; if (alu == GXclear) color = 0; tmp.op = color == 0 ? PictOpClear : PictOpSrc; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; gen4_channel_init_solid(sna, &tmp.src, sna_rgba_for_color(color, dst->drawable.depth)); tmp.mask.bo = NULL; tmp.mask.filter = SAMPLER_FILTER_NEAREST; tmp.mask.repeat = SAMPLER_EXTEND_NONE; tmp.is_affine = true; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.has_component_alpha = false; tmp.need_magic_ca_pass = false; tmp.u.gen4.wm_kernel = WM_KERNEL; tmp.u.gen4.ve_id = 1; if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen4_align_vertex(sna, &tmp); gen4_bind_surfaces(sna, &tmp); gen4_render_fill_rectangle(sna, &tmp, x1, y1, x2 - x1, y2 - y1); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static void gen4_render_reset(struct sna *sna) { sna->render_state.gen4.needs_invariant = true; sna->render_state.gen4.needs_urb = true; sna->render_state.gen4.ve_id = -1; sna->render_state.gen4.last_primitive = -1; sna->render_state.gen4.last_pipelined_pointers = -1; sna->render_state.gen4.drawrect_offset = -1; sna->render_state.gen4.drawrect_limit = -1; sna->render_state.gen4.surface_table = 0; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); discard_vbo(sna); } sna->render.vertex_offset = 0; sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; } static void gen4_render_fini(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render_state.gen4.general_bo); } static uint32_t gen4_create_vs_unit_state(struct sna_static_stream *stream) { struct gen4_vs_unit_state *vs = sna_static_stream_map(stream, sizeof(*vs), 32); /* Set up the vertex shader to be disabled (passthrough) */ vs->thread4.nr_urb_entries = URB_VS_ENTRIES; vs->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; vs->vs6.vs_enable = 0; vs->vs6.vert_cache_disable = 1; return sna_static_stream_offsetof(stream, vs); } static uint32_t gen4_create_sf_state(struct sna_static_stream *stream, uint32_t kernel) { struct gen4_sf_unit_state *sf; sf = sna_static_stream_map(stream, sizeof(*sf), 32); sf->thread0.grf_reg_count = GEN4_GRF_BLOCKS(SF_KERNEL_NUM_GRF); sf->thread0.kernel_start_pointer = kernel >> 6; sf->thread3.const_urb_entry_read_length = 0; /* no const URBs */ sf->thread3.const_urb_entry_read_offset = 0; /* no const URBs */ sf->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ /* don't smash vertex header, read start from dw8 */ sf->thread3.urb_entry_read_offset = 1; sf->thread3.dispatch_grf_start_reg = 3; sf->thread4.max_threads = GEN4_MAX_SF_THREADS - 1; sf->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; sf->thread4.nr_urb_entries = URB_SF_ENTRIES; sf->sf5.viewport_transform = false; /* skip viewport */ sf->sf6.cull_mode = GEN4_CULLMODE_NONE; sf->sf6.scissor = 0; sf->sf7.trifan_pv = 2; sf->sf6.dest_org_vbias = 0x8; sf->sf6.dest_org_hbias = 0x8; return sna_static_stream_offsetof(stream, sf); } static uint32_t gen4_create_sampler_state(struct sna_static_stream *stream, sampler_filter_t src_filter, sampler_extend_t src_extend, sampler_filter_t mask_filter, sampler_extend_t mask_extend) { struct gen4_sampler_state *sampler_state; sampler_state = sna_static_stream_map(stream, sizeof(struct gen4_sampler_state) * 2, 32); sampler_state_init(&sampler_state[0], src_filter, src_extend); sampler_state_init(&sampler_state[1], mask_filter, mask_extend); return sna_static_stream_offsetof(stream, sampler_state); } static void gen4_init_wm_state(struct gen4_wm_unit_state *wm, int gen, bool has_mask, uint32_t kernel, uint32_t sampler) { assert((kernel & 63) == 0); wm->thread0.kernel_start_pointer = kernel >> 6; wm->thread0.grf_reg_count = GEN4_GRF_BLOCKS(PS_KERNEL_NUM_GRF); wm->thread1.single_program_flow = 0; wm->thread3.const_urb_entry_read_length = 0; wm->thread3.const_urb_entry_read_offset = 0; wm->thread3.urb_entry_read_offset = 0; wm->thread3.dispatch_grf_start_reg = 3; assert((sampler & 31) == 0); wm->wm4.sampler_state_pointer = sampler >> 5; wm->wm4.sampler_count = 1; wm->wm5.max_threads = gen >= 045 ? G4X_MAX_WM_THREADS - 1 : GEN4_MAX_WM_THREADS - 1; wm->wm5.transposed_urb_read = 0; wm->wm5.thread_dispatch_enable = 1; /* just use 16-pixel dispatch (4 subspans), don't need to change kernel * start point */ wm->wm5.enable_16_pix = 1; wm->wm5.enable_8_pix = 0; wm->wm5.early_depth_test = 1; /* Each pair of attributes (src/mask coords) is two URB entries */ if (has_mask) { wm->thread1.binding_table_entry_count = 3; wm->thread3.urb_entry_read_length = 4; } else { wm->thread1.binding_table_entry_count = 2; wm->thread3.urb_entry_read_length = 2; } } static uint32_t gen4_create_cc_unit_state(struct sna_static_stream *stream) { uint8_t *ptr, *base; int i, j; base = ptr = sna_static_stream_map(stream, GEN4_BLENDFACTOR_COUNT*GEN4_BLENDFACTOR_COUNT*64, 64); for (i = 0; i < GEN4_BLENDFACTOR_COUNT; i++) { for (j = 0; j < GEN4_BLENDFACTOR_COUNT; j++) { struct gen4_cc_unit_state *state = (struct gen4_cc_unit_state *)ptr; state->cc3.blend_enable = !(j == GEN4_BLENDFACTOR_ZERO && i == GEN4_BLENDFACTOR_ONE); state->cc5.logicop_func = 0xc; /* COPY */ state->cc5.ia_blend_function = GEN4_BLENDFUNCTION_ADD; /* Fill in alpha blend factors same as color, for the future. */ state->cc5.ia_src_blend_factor = i; state->cc5.ia_dest_blend_factor = j; state->cc6.blend_function = GEN4_BLENDFUNCTION_ADD; state->cc6.clamp_post_alpha_blend = 1; state->cc6.clamp_pre_alpha_blend = 1; state->cc6.src_blend_factor = i; state->cc6.dest_blend_factor = j; ptr += 64; } } return sna_static_stream_offsetof(stream, base); } static bool gen4_render_setup(struct sna *sna) { struct gen4_render_state *state = &sna->render_state.gen4; struct sna_static_stream general; struct gen4_wm_unit_state_padded *wm_state; uint32_t sf, wm[KERNEL_COUNT]; int i, j, k, l, m; sna_static_stream_init(&general); /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer * dumps, you know it points to zero. */ null_create(&general); sf = sna_static_stream_compile_sf(sna, &general, brw_sf_kernel__mask); for (m = 0; m < KERNEL_COUNT; m++) { if (wm_kernels[m].size) { wm[m] = sna_static_stream_add(&general, wm_kernels[m].data, wm_kernels[m].size, 64); } else { wm[m] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } } state->vs = gen4_create_vs_unit_state(&general); state->sf = gen4_create_sf_state(&general, sf); wm_state = sna_static_stream_map(&general, sizeof(*wm_state) * KERNEL_COUNT * FILTER_COUNT * EXTEND_COUNT * FILTER_COUNT * EXTEND_COUNT, 64); state->wm = sna_static_stream_offsetof(&general, wm_state); for (i = 0; i < FILTER_COUNT; i++) { for (j = 0; j < EXTEND_COUNT; j++) { for (k = 0; k < FILTER_COUNT; k++) { for (l = 0; l < EXTEND_COUNT; l++) { uint32_t sampler_state; sampler_state = gen4_create_sampler_state(&general, i, j, k, l); for (m = 0; m < KERNEL_COUNT; m++) { gen4_init_wm_state(&wm_state->state, sna->kgem.gen, wm_kernels[m].has_mask, wm[m], sampler_state); wm_state++; } } } } } state->cc = gen4_create_cc_unit_state(&general); state->general_bo = sna_static_stream_fini(sna, &general); return state->general_bo != NULL; } const char *gen4_render_init(struct sna *sna, const char *backend) { if (!gen4_render_setup(sna)) return backend; sna->kgem.retire = gen4_render_retire; sna->kgem.expire = gen4_render_expire; #if !NO_COMPOSITE sna->render.composite = gen4_render_composite; sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen4_check_composite_spans; sna->render.composite_spans = gen4_render_composite_spans; if (0) sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif #if !NO_VIDEO sna->render.video = gen4_render_video; #endif #if !NO_COPY_BOXES sna->render.copy_boxes = gen4_render_copy_boxes; #endif #if !NO_COPY sna->render.copy = gen4_render_copy; #endif #if !NO_FILL_BOXES sna->render.fill_boxes = gen4_render_fill_boxes; #endif #if !NO_FILL sna->render.fill = gen4_render_fill; #endif #if !NO_FILL_ONE sna->render.fill_one = gen4_render_fill_one; #endif sna->render.flush = gen4_render_flush; sna->render.reset = gen4_render_reset; sna->render.fini = gen4_render_fini; sna->render.max_3d_size = GEN4_MAX_3D_SIZE; sna->render.max_3d_pitch = 1 << 18; return sna->kgem.gen >= 045 ? "Eaglelake (gen4.5)" : "Broadwater (gen4)"; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_render.h000066400000000000000000002345651267532330400242270ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 GEN4_RENDER_H #define GEN4_RENDER_H #define GEN4_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define GEN4_URB_FENCE GEN4_3D(0, 0, 0) #define GEN4_CS_URB_STATE GEN4_3D(0, 0, 1) #define GEN4_CONSTANT_BUFFER GEN4_3D(0, 0, 2) #define GEN4_STATE_PREFETCH GEN4_3D(0, 0, 3) #define GEN4_STATE_BASE_ADDRESS GEN4_3D(0, 1, 1) #define GEN4_STATE_SIP GEN4_3D(0, 1, 2) #define GEN4_PIPELINE_SELECT GEN4_3D(0, 1, 4) #define NEW_PIPELINE_SELECT GEN4_3D(1, 1, 4) #define GEN4_MEDIA_STATE_POINTERS GEN4_3D(2, 0, 0) #define GEN4_MEDIA_OBJECT GEN4_3D(2, 1, 0) #define GEN4_3DSTATE_PIPELINED_POINTERS GEN4_3D(3, 0, 0) #define GEN4_3DSTATE_BINDING_TABLE_POINTERS GEN4_3D(3, 0, 1) #define GEN4_3DSTATE_VERTEX_BUFFERS GEN4_3D(3, 0, 8) #define GEN4_3DSTATE_VERTEX_ELEMENTS GEN4_3D(3, 0, 9) #define GEN4_3DSTATE_INDEX_BUFFER GEN4_3D(3, 0, 0xa) #define GEN4_3DSTATE_VF_STATISTICS GEN4_3D(3, 0, 0xb) #define GEN4_3DSTATE_DRAWING_RECTANGLE GEN4_3D(3, 1, 0) #define GEN4_3DSTATE_CONSTANT_COLOR GEN4_3D(3, 1, 1) #define GEN4_3DSTATE_SAMPLER_PALETTE_LOAD GEN4_3D(3, 1, 2) #define GEN4_3DSTATE_CHROMA_KEY GEN4_3D(3, 1, 4) #define GEN4_3DSTATE_DEPTH_BUFFER GEN4_3D(3, 1, 5) # define GEN4_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define GEN4_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define GEN4_3DSTATE_POLY_STIPPLE_OFFSET GEN4_3D(3, 1, 6) #define GEN4_3DSTATE_POLY_STIPPLE_PATTERN GEN4_3D(3, 1, 7) #define GEN4_3DSTATE_LINE_STIPPLE GEN4_3D(3, 1, 8) #define GEN4_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP GEN4_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define GEN4_3DSTATE_AA_LINE_PARAMS GEN4_3D(3, 1, 0xa) #define GEN4_3DSTATE_GS_SVB_INDEX GEN4_3D(3, 1, 0xb) #define GEN4_PIPE_CONTROL GEN4_3D(3, 2, 0) #define GEN4_3DPRIMITIVE GEN4_3D(3, 3, 0) #define GEN4_3DSTATE_CLEAR_PARAMS GEN4_3D(3, 1, 0x10) /* DW1 */ # define GEN4_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 #define UF0_CS_REALLOC (1 << 13) #define UF0_VFE_REALLOC (1 << 12) #define UF0_SF_REALLOC (1 << 11) #define UF0_CLIP_REALLOC (1 << 10) #define UF0_GS_REALLOC (1 << 9) #define UF0_VS_REALLOC (1 << 8) #define UF1_CLIP_FENCE_SHIFT 20 #define UF1_GS_FENCE_SHIFT 10 #define UF1_VS_FENCE_SHIFT 0 #define UF2_CS_FENCE_SHIFT 20 #define UF2_VFE_FENCE_SHIFT 10 #define UF2_SF_FENCE_SHIFT 0 /* for GEN4_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for GEN4_3DSTATE_PIPELINED_POINTERS */ #define GEN4_GS_DISABLE 0 #define GEN4_GS_ENABLE 1 #define GEN4_CLIP_DISABLE 0 #define GEN4_CLIP_ENABLE 1 /* for GEN4_PIPE_CONTROL */ #define GEN4_PIPE_CONTROL_NOWRITE (0 << 14) #define GEN4_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define GEN4_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define GEN4_PIPE_CONTROL_WRITE_TIME (3 << 14) #define GEN4_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define GEN4_PIPE_CONTROL_WC_FLUSH (1 << 12) #define GEN4_PIPE_CONTROL_IS_FLUSH (1 << 11) #define GEN4_PIPE_CONTROL_TC_FLUSH (1 << 10) /* ctg+ */ #define GEN4_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define GEN4_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define GEN4_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define GEN4_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define VB0_BUFFER_INDEX_SHIFT 27 #define VB0_VERTEXDATA (0 << 26) #define VB0_INSTANCEDATA (1 << 26) #define VB0_BUFFER_PITCH_SHIFT 0 /* VERTEX_ELEMENT_STATE Structure */ #define VE0_VERTEX_BUFFER_INDEX_SHIFT 27 #define VE0_VALID (1 << 26) #define VE0_FORMAT_SHIFT 16 #define VE0_OFFSET_SHIFT 0 #define VE1_VFCOMPONENT_0_SHIFT 28 #define VE1_VFCOMPONENT_1_SHIFT 24 #define VE1_VFCOMPONENT_2_SHIFT 20 #define VE1_VFCOMPONENT_3_SHIFT 16 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define GEN4_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in gen4_defines.h */ #define GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define GEN4_SVG_CTL 0x7400 #define GEN4_SVG_CTL_GS_BA (0 << 8) #define GEN4_SVG_CTL_SS_BA (1 << 8) #define GEN4_SVG_CTL_IO_BA (2 << 8) #define GEN4_SVG_CTL_GS_AUB (3 << 8) #define GEN4_SVG_CTL_IO_AUB (4 << 8) #define GEN4_SVG_CTL_SIP (5 << 8) #define GEN4_SVG_RDATA 0x7404 #define GEN4_SVG_WORK_CTL 0x7408 #define GEN4_VF_CTL 0x7500 #define GEN4_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN4_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define GEN4_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define GEN4_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define GEN4_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define GEN4_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define GEN4_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define GEN4_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define GEN4_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN4_VF_STRG_VAL 0x7504 #define GEN4_VF_STR_VL_OVR 0x7508 #define GEN4_VF_VC_OVR 0x750c #define GEN4_VF_STR_PSKIP 0x7510 #define GEN4_VF_MAX_PRIM 0x7514 #define GEN4_VF_RDATA 0x7518 #define GEN4_VS_CTL 0x7600 #define GEN4_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN4_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define GEN4_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define GEN4_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define GEN4_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define GEN4_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN4_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN4_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN4_VS_STRG_VAL 0x7604 #define GEN4_VS_RDATA 0x7608 #define GEN4_SF_CTL 0x7b00 #define GEN4_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define GEN4_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define GEN4_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define GEN4_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define GEN4_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN4_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN4_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN4_SF_STRG_VAL 0x7b04 #define GEN4_SF_RDATA 0x7b18 #define GEN4_WIZ_CTL 0x7c00 #define GEN4_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN4_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define GEN4_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define GEN4_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define GEN4_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define GEN4_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define GEN4_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define GEN4_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define GEN4_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define GEN4_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN4_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN4_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN4_WIZ_STRG_VAL 0x7c04 #define GEN4_WIZ_RDATA 0x7c18 #define GEN4_TS_CTL 0x7e00 #define GEN4_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN4_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define GEN4_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define GEN4_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define GEN4_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define GEN4_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN4_TS_STRG_VAL 0x7e04 #define GEN4_TS_RDATA 0x7e08 #define GEN4_TD_CTL 0x8000 #define GEN4_TD_CTL_MUX_SHIFT 8 #define GEN4_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define GEN4_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define GEN4_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define GEN4_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define GEN4_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define GEN4_TD_CTL2 0x8004 #define GEN4_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define GEN4_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define GEN4_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define GEN4_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define GEN4_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define GEN4_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define GEN4_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define GEN4_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define GEN4_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define GEN4_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define GEN4_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define GEN4_TD_VF_VS_EMSK 0x8008 #define GEN4_TD_GS_EMSK 0x800c #define GEN4_TD_CLIP_EMSK 0x8010 #define GEN4_TD_SF_EMSK 0x8014 #define GEN4_TD_WIZ_EMSK 0x8018 #define GEN4_TD_0_6_EHTRG_VAL 0x801c #define GEN4_TD_0_7_EHTRG_VAL 0x8020 #define GEN4_TD_0_6_EHTRG_MSK 0x8024 #define GEN4_TD_0_7_EHTRG_MSK 0x8028 #define GEN4_TD_RDATA 0x802c #define GEN4_TD_TS_EMSK 0x8030 #define GEN4_EU_CTL 0x8800 #define GEN4_EU_CTL_SELECT_SHIFT 16 #define GEN4_EU_CTL_DATA_MUX_SHIFT 8 #define GEN4_EU_ATT_0 0x8810 #define GEN4_EU_ATT_1 0x8814 #define GEN4_EU_ATT_DATA_0 0x8820 #define GEN4_EU_ATT_DATA_1 0x8824 #define GEN4_EU_ATT_CLR_0 0x8830 #define GEN4_EU_ATT_CLR_1 0x8834 #define GEN4_EU_RDATA 0x8840 /* 3D state: */ #define _3DOP_3DSTATE_PIPELINED 0x0 #define _3DOP_3DSTATE_NONPIPELINED 0x1 #define _3DOP_3DCONTROL 0x2 #define _3DOP_3DPRIMITIVE 0x3 #define _3DSTATE_PIPELINED_POINTERS 0x00 #define _3DSTATE_BINDING_TABLE_POINTERS 0x01 #define _3DSTATE_VERTEX_BUFFERS 0x08 #define _3DSTATE_VERTEX_ELEMENTS 0x09 #define _3DSTATE_INDEX_BUFFER 0x0A #define _3DSTATE_VF_STATISTICS 0x0B #define _3DSTATE_DRAWING_RECTANGLE 0x00 #define _3DSTATE_CONSTANT_COLOR 0x01 #define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 #define _3DSTATE_CHROMA_KEY 0x04 #define _3DSTATE_DEPTH_BUFFER 0x05 #define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 #define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 #define _3DSTATE_LINE_STIPPLE 0x08 #define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 #define _3DCONTROL 0x00 #define _3DPRIMITIVE 0x00 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define GEN4_ANISORATIO_2 0 #define GEN4_ANISORATIO_4 1 #define GEN4_ANISORATIO_6 2 #define GEN4_ANISORATIO_8 3 #define GEN4_ANISORATIO_10 4 #define GEN4_ANISORATIO_12 5 #define GEN4_ANISORATIO_14 6 #define GEN4_ANISORATIO_16 7 #define GEN4_BLENDFACTOR_ONE 0x1 #define GEN4_BLENDFACTOR_SRC_COLOR 0x2 #define GEN4_BLENDFACTOR_SRC_ALPHA 0x3 #define GEN4_BLENDFACTOR_DST_ALPHA 0x4 #define GEN4_BLENDFACTOR_DST_COLOR 0x5 #define GEN4_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define GEN4_BLENDFACTOR_CONST_COLOR 0x7 #define GEN4_BLENDFACTOR_CONST_ALPHA 0x8 #define GEN4_BLENDFACTOR_SRC1_COLOR 0x9 #define GEN4_BLENDFACTOR_SRC1_ALPHA 0x0A #define GEN4_BLENDFACTOR_ZERO 0x11 #define GEN4_BLENDFACTOR_INV_SRC_COLOR 0x12 #define GEN4_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define GEN4_BLENDFACTOR_INV_DST_ALPHA 0x14 #define GEN4_BLENDFACTOR_INV_DST_COLOR 0x15 #define GEN4_BLENDFACTOR_INV_CONST_COLOR 0x17 #define GEN4_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define GEN4_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define GEN4_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define GEN4_BLENDFUNCTION_ADD 0 #define GEN4_BLENDFUNCTION_SUBTRACT 1 #define GEN4_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define GEN4_BLENDFUNCTION_MIN 3 #define GEN4_BLENDFUNCTION_MAX 4 #define GEN4_ALPHATEST_FORMAT_UNORM8 0 #define GEN4_ALPHATEST_FORMAT_FLOAT32 1 #define GEN4_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define GEN4_CHROMAKEY_REPLACE_BLACK 1 #define GEN4_CLIP_API_OGL 0 #define GEN4_CLIP_API_DX 1 #define GEN4_CLIPMODE_NORMAL 0 #define GEN4_CLIPMODE_CLIP_ALL 1 #define GEN4_CLIPMODE_CLIP_NON_REJECTED 2 #define GEN4_CLIPMODE_REJECT_ALL 3 #define GEN4_CLIPMODE_ACCEPT_ALL 4 #define GEN4_CLIP_NDCSPACE 0 #define GEN4_CLIP_SCREENSPACE 1 #define GEN4_COMPAREFUNCTION_ALWAYS 0 #define GEN4_COMPAREFUNCTION_NEVER 1 #define GEN4_COMPAREFUNCTION_LESS 2 #define GEN4_COMPAREFUNCTION_EQUAL 3 #define GEN4_COMPAREFUNCTION_LEQUAL 4 #define GEN4_COMPAREFUNCTION_GREATER 5 #define GEN4_COMPAREFUNCTION_NOTEQUAL 6 #define GEN4_COMPAREFUNCTION_GEQUAL 7 #define GEN4_COVERAGE_PIXELS_HALF 0 #define GEN4_COVERAGE_PIXELS_1 1 #define GEN4_COVERAGE_PIXELS_2 2 #define GEN4_COVERAGE_PIXELS_4 3 #define GEN4_CULLMODE_BOTH 0 #define GEN4_CULLMODE_NONE 1 #define GEN4_CULLMODE_FRONT 2 #define GEN4_CULLMODE_BACK 3 #define GEN4_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define GEN4_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define GEN4_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define GEN4_DEPTHFORMAT_D32_FLOAT 1 #define GEN4_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define GEN4_DEPTHFORMAT_D16_UNORM 5 #define GEN4_FLOATING_POINT_IEEE_754 0 #define GEN4_FLOATING_POINT_NON_IEEE_754 1 #define GEN4_FRONTWINDING_CW 0 #define GEN4_FRONTWINDING_CCW 1 #define GEN4_INDEX_BYTE 0 #define GEN4_INDEX_WORD 1 #define GEN4_INDEX_DWORD 2 #define GEN4_LOGICOPFUNCTION_CLEAR 0 #define GEN4_LOGICOPFUNCTION_NOR 1 #define GEN4_LOGICOPFUNCTION_AND_INVERTED 2 #define GEN4_LOGICOPFUNCTION_COPY_INVERTED 3 #define GEN4_LOGICOPFUNCTION_AND_REVERSE 4 #define GEN4_LOGICOPFUNCTION_INVERT 5 #define GEN4_LOGICOPFUNCTION_XOR 6 #define GEN4_LOGICOPFUNCTION_NAND 7 #define GEN4_LOGICOPFUNCTION_AND 8 #define GEN4_LOGICOPFUNCTION_EQUIV 9 #define GEN4_LOGICOPFUNCTION_NOOP 10 #define GEN4_LOGICOPFUNCTION_OR_INVERTED 11 #define GEN4_LOGICOPFUNCTION_COPY 12 #define GEN4_LOGICOPFUNCTION_OR_REVERSE 13 #define GEN4_LOGICOPFUNCTION_OR 14 #define GEN4_LOGICOPFUNCTION_SET 15 #define GEN4_MAPFILTER_NEAREST 0x0 #define GEN4_MAPFILTER_LINEAR 0x1 #define GEN4_MAPFILTER_ANISOTROPIC 0x2 #define GEN4_MIPFILTER_NONE 0 #define GEN4_MIPFILTER_NEAREST 1 #define GEN4_MIPFILTER_LINEAR 3 #define GEN4_POLYGON_FRONT_FACING 0 #define GEN4_POLYGON_BACK_FACING 1 #define GEN4_PREFILTER_ALWAYS 0x0 #define GEN4_PREFILTER_NEVER 0x1 #define GEN4_PREFILTER_LESS 0x2 #define GEN4_PREFILTER_EQUAL 0x3 #define GEN4_PREFILTER_LEQUAL 0x4 #define GEN4_PREFILTER_GREATER 0x5 #define GEN4_PREFILTER_NOTEQUAL 0x6 #define GEN4_PREFILTER_GEQUAL 0x7 #define GEN4_PROVOKING_VERTEX_0 0 #define GEN4_PROVOKING_VERTEX_1 1 #define GEN4_PROVOKING_VERTEX_2 2 #define GEN4_RASTRULE_UPPER_LEFT 0 #define GEN4_RASTRULE_UPPER_RIGHT 1 #define GEN4_RENDERTARGET_CLAMPRANGE_UNORM 0 #define GEN4_RENDERTARGET_CLAMPRANGE_SNORM 1 #define GEN4_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define GEN4_STENCILOP_KEEP 0 #define GEN4_STENCILOP_ZERO 1 #define GEN4_STENCILOP_REPLACE 2 #define GEN4_STENCILOP_INCRSAT 3 #define GEN4_STENCILOP_DECRSAT 4 #define GEN4_STENCILOP_INCR 5 #define GEN4_STENCILOP_DECR 6 #define GEN4_STENCILOP_INVERT 7 #define GEN4_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN4_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN4_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define GEN4_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define GEN4_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define GEN4_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define GEN4_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define GEN4_SURFACEFORMAT_R64G64_FLOAT 0x005 #define GEN4_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define GEN4_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define GEN4_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define GEN4_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define GEN4_SURFACEFORMAT_R32G32B32_SINT 0x041 #define GEN4_SURFACEFORMAT_R32G32B32_UINT 0x042 #define GEN4_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define GEN4_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define GEN4_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define GEN4_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define GEN4_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define GEN4_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define GEN4_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define GEN4_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define GEN4_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define GEN4_SURFACEFORMAT_R32G32_FLOAT 0x085 #define GEN4_SURFACEFORMAT_R32G32_SINT 0x086 #define GEN4_SURFACEFORMAT_R32G32_UINT 0x087 #define GEN4_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define GEN4_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define GEN4_SURFACEFORMAT_L32A32_FLOAT 0x08A #define GEN4_SURFACEFORMAT_R32G32_UNORM 0x08B #define GEN4_SURFACEFORMAT_R32G32_SNORM 0x08C #define GEN4_SURFACEFORMAT_R64_FLOAT 0x08D #define GEN4_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define GEN4_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define GEN4_SURFACEFORMAT_A32X32_FLOAT 0x090 #define GEN4_SURFACEFORMAT_L32X32_FLOAT 0x091 #define GEN4_SURFACEFORMAT_I32X32_FLOAT 0x092 #define GEN4_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define GEN4_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define GEN4_SURFACEFORMAT_R32G32_SSCALED 0x095 #define GEN4_SURFACEFORMAT_R32G32_USCALED 0x096 #define GEN4_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define GEN4_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define GEN4_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define GEN4_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define GEN4_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define GEN4_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define GEN4_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define GEN4_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define GEN4_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define GEN4_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define GEN4_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define GEN4_SURFACEFORMAT_R16G16_UNORM 0x0CC #define GEN4_SURFACEFORMAT_R16G16_SNORM 0x0CD #define GEN4_SURFACEFORMAT_R16G16_SINT 0x0CE #define GEN4_SURFACEFORMAT_R16G16_UINT 0x0CF #define GEN4_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define GEN4_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define GEN4_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define GEN4_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define GEN4_SURFACEFORMAT_R32_SINT 0x0D6 #define GEN4_SURFACEFORMAT_R32_UINT 0x0D7 #define GEN4_SURFACEFORMAT_R32_FLOAT 0x0D8 #define GEN4_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define GEN4_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define GEN4_SURFACEFORMAT_L16A16_UNORM 0x0DF #define GEN4_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define GEN4_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define GEN4_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define GEN4_SURFACEFORMAT_I32_FLOAT 0x0E3 #define GEN4_SURFACEFORMAT_L32_FLOAT 0x0E4 #define GEN4_SURFACEFORMAT_A32_FLOAT 0x0E5 #define GEN4_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define GEN4_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define GEN4_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define GEN4_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define GEN4_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define GEN4_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define GEN4_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define GEN4_SURFACEFORMAT_R32_UNORM 0x0F1 #define GEN4_SURFACEFORMAT_R32_SNORM 0x0F2 #define GEN4_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define GEN4_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define GEN4_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define GEN4_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define GEN4_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define GEN4_SURFACEFORMAT_R32_SSCALED 0x0F8 #define GEN4_SURFACEFORMAT_R32_USCALED 0x0F9 #define GEN4_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define GEN4_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define GEN4_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define GEN4_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define GEN4_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define GEN4_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define GEN4_SURFACEFORMAT_R8G8_UNORM 0x106 #define GEN4_SURFACEFORMAT_R8G8_SNORM 0x107 #define GEN4_SURFACEFORMAT_R8G8_SINT 0x108 #define GEN4_SURFACEFORMAT_R8G8_UINT 0x109 #define GEN4_SURFACEFORMAT_R16_UNORM 0x10A #define GEN4_SURFACEFORMAT_R16_SNORM 0x10B #define GEN4_SURFACEFORMAT_R16_SINT 0x10C #define GEN4_SURFACEFORMAT_R16_UINT 0x10D #define GEN4_SURFACEFORMAT_R16_FLOAT 0x10E #define GEN4_SURFACEFORMAT_I16_UNORM 0x111 #define GEN4_SURFACEFORMAT_L16_UNORM 0x112 #define GEN4_SURFACEFORMAT_A16_UNORM 0x113 #define GEN4_SURFACEFORMAT_L8A8_UNORM 0x114 #define GEN4_SURFACEFORMAT_I16_FLOAT 0x115 #define GEN4_SURFACEFORMAT_L16_FLOAT 0x116 #define GEN4_SURFACEFORMAT_A16_FLOAT 0x117 #define GEN4_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define GEN4_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define GEN4_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define GEN4_SURFACEFORMAT_R8G8_SSCALED 0x11C #define GEN4_SURFACEFORMAT_R8G8_USCALED 0x11D #define GEN4_SURFACEFORMAT_R16_SSCALED 0x11E #define GEN4_SURFACEFORMAT_R16_USCALED 0x11F #define GEN4_SURFACEFORMAT_R8_UNORM 0x140 #define GEN4_SURFACEFORMAT_R8_SNORM 0x141 #define GEN4_SURFACEFORMAT_R8_SINT 0x142 #define GEN4_SURFACEFORMAT_R8_UINT 0x143 #define GEN4_SURFACEFORMAT_A8_UNORM 0x144 #define GEN4_SURFACEFORMAT_I8_UNORM 0x145 #define GEN4_SURFACEFORMAT_L8_UNORM 0x146 #define GEN4_SURFACEFORMAT_P4A4_UNORM 0x147 #define GEN4_SURFACEFORMAT_A4P4_UNORM 0x148 #define GEN4_SURFACEFORMAT_R8_SSCALED 0x149 #define GEN4_SURFACEFORMAT_R8_USCALED 0x14A #define GEN4_SURFACEFORMAT_R1_UINT 0x181 #define GEN4_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define GEN4_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define GEN4_SURFACEFORMAT_BC1_UNORM 0x186 #define GEN4_SURFACEFORMAT_BC2_UNORM 0x187 #define GEN4_SURFACEFORMAT_BC3_UNORM 0x188 #define GEN4_SURFACEFORMAT_BC4_UNORM 0x189 #define GEN4_SURFACEFORMAT_BC5_UNORM 0x18A #define GEN4_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define GEN4_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define GEN4_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define GEN4_SURFACEFORMAT_MONO8 0x18E #define GEN4_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define GEN4_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define GEN4_SURFACEFORMAT_DXT1_RGB 0x191 #define GEN4_SURFACEFORMAT_FXT1 0x192 #define GEN4_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define GEN4_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define GEN4_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define GEN4_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define GEN4_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define GEN4_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define GEN4_SURFACEFORMAT_BC4_SNORM 0x199 #define GEN4_SURFACEFORMAT_BC5_SNORM 0x19A #define GEN4_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define GEN4_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define GEN4_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define GEN4_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define GEN4_SURFACERETURNFORMAT_FLOAT32 0 #define GEN4_SURFACERETURNFORMAT_S1 1 #define GEN4_SURFACE_1D 0 #define GEN4_SURFACE_2D 1 #define GEN4_SURFACE_3D 2 #define GEN4_SURFACE_CUBE 3 #define GEN4_SURFACE_BUFFER 4 #define GEN4_SURFACE_NULL 7 #define GEN4_BORDER_COLOR_MODE_DEFAULT 0 #define GEN4_BORDER_COLOR_MODE_LEGACY 1 #define GEN4_TEXCOORDMODE_WRAP 0 #define GEN4_TEXCOORDMODE_MIRROR 1 #define GEN4_TEXCOORDMODE_CLAMP 2 #define GEN4_TEXCOORDMODE_CUBE 3 #define GEN4_TEXCOORDMODE_CLAMP_BORDER 4 #define GEN4_TEXCOORDMODE_MIRROR_ONCE 5 #define GEN4_THREAD_PRIORITY_NORMAL 0 #define GEN4_THREAD_PRIORITY_HIGH 1 #define GEN4_TILEWALK_XMAJOR 0 #define GEN4_TILEWALK_YMAJOR 1 #define GEN4_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define GEN4_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define GEN4_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define GEN4_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define VFCOMPONENT_NOSTORE 0 #define VFCOMPONENT_STORE_SRC 1 #define VFCOMPONENT_STORE_0 2 #define VFCOMPONENT_STORE_1_FLT 3 #define VFCOMPONENT_STORE_1_INT 4 #define VFCOMPONENT_STORE_VID 5 #define VFCOMPONENT_STORE_IID 6 #define VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define GEN4_ALIGN_1 0 #define GEN4_ALIGN_16 1 #define GEN4_ADDRESS_DIRECT 0 #define GEN4_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define GEN4_CHANNEL_X 0 #define GEN4_CHANNEL_Y 1 #define GEN4_CHANNEL_Z 2 #define GEN4_CHANNEL_W 3 #define GEN4_COMPRESSION_NONE 0 #define GEN4_COMPRESSION_2NDHALF 1 #define GEN4_COMPRESSION_COMPRESSED 2 #define GEN4_CONDITIONAL_NONE 0 #define GEN4_CONDITIONAL_Z 1 #define GEN4_CONDITIONAL_NZ 2 #define GEN4_CONDITIONAL_EQ 1 /* Z */ #define GEN4_CONDITIONAL_NEQ 2 /* NZ */ #define GEN4_CONDITIONAL_G 3 #define GEN4_CONDITIONAL_GE 4 #define GEN4_CONDITIONAL_L 5 #define GEN4_CONDITIONAL_LE 6 #define GEN4_CONDITIONAL_C 7 #define GEN4_CONDITIONAL_O 8 #define GEN4_DEBUG_NONE 0 #define GEN4_DEBUG_BREAKPOINT 1 #define GEN4_DEPENDENCY_NORMAL 0 #define GEN4_DEPENDENCY_NOTCLEARED 1 #define GEN4_DEPENDENCY_NOTCHECKED 2 #define GEN4_DEPENDENCY_DISABLE 3 #define GEN4_EXECUTE_1 0 #define GEN4_EXECUTE_2 1 #define GEN4_EXECUTE_4 2 #define GEN4_EXECUTE_8 3 #define GEN4_EXECUTE_16 4 #define GEN4_EXECUTE_32 5 #define GEN4_HORIZONTAL_STRIDE_0 0 #define GEN4_HORIZONTAL_STRIDE_1 1 #define GEN4_HORIZONTAL_STRIDE_2 2 #define GEN4_HORIZONTAL_STRIDE_4 3 #define GEN4_INSTRUCTION_NORMAL 0 #define GEN4_INSTRUCTION_SATURATE 1 #define _MASK_ENABLE 0 #define _MASK_DISABLE 1 #define GEN4_OPCODE_MOV 1 #define GEN4_OPCODE_SEL 2 #define GEN4_OPCODE_NOT 4 #define GEN4_OPCODE_AND 5 #define GEN4_OPCODE_OR 6 #define GEN4_OPCODE_XOR 7 #define GEN4_OPCODE_SHR 8 #define GEN4_OPCODE_SHL 9 #define GEN4_OPCODE_RSR 10 #define GEN4_OPCODE_RSL 11 #define GEN4_OPCODE_ASR 12 #define GEN4_OPCODE_CMP 16 #define GEN4_OPCODE_JMPI 32 #define GEN4_OPCODE_IF 34 #define GEN4_OPCODE_IFF 35 #define GEN4_OPCODE_ELSE 36 #define GEN4_OPCODE_ENDIF 37 #define GEN4_OPCODE_DO 38 #define GEN4_OPCODE_WHILE 39 #define GEN4_OPCODE_BREAK 40 #define GEN4_OPCODE_CONTINUE 41 #define GEN4_OPCODE_HALT 42 #define GEN4_OPCODE_MSAVE 44 #define GEN4_OPCODE_MRESTORE 45 #define GEN4_OPCODE_PUSH 46 #define GEN4_OPCODE_POP 47 #define GEN4_OPCODE_WAIT 48 #define GEN4_OPCODE_SEND 49 #define GEN4_OPCODE_ADD 64 #define GEN4_OPCODE_MUL 65 #define GEN4_OPCODE_AVG 66 #define GEN4_OPCODE_FRC 67 #define GEN4_OPCODE_RNDU 68 #define GEN4_OPCODE_RNDD 69 #define GEN4_OPCODE_RNDE 70 #define GEN4_OPCODE_RNDZ 71 #define GEN4_OPCODE_MAC 72 #define GEN4_OPCODE_MACH 73 #define GEN4_OPCODE_LZD 74 #define GEN4_OPCODE_SAD2 80 #define GEN4_OPCODE_SADA2 81 #define GEN4_OPCODE_DP4 84 #define GEN4_OPCODE_DPH 85 #define GEN4_OPCODE_DP3 86 #define GEN4_OPCODE_DP2 87 #define GEN4_OPCODE_DPA2 88 #define GEN4_OPCODE_LINE 89 #define GEN4_OPCODE_NOP 126 #define GEN4_PREDICATE_NONE 0 #define GEN4_PREDICATE_NORMAL 1 #define GEN4_PREDICATE_ALIGN1_ANYV 2 #define GEN4_PREDICATE_ALIGN1_ALLV 3 #define GEN4_PREDICATE_ALIGN1_ANY2H 4 #define GEN4_PREDICATE_ALIGN1_ALL2H 5 #define GEN4_PREDICATE_ALIGN1_ANY4H 6 #define GEN4_PREDICATE_ALIGN1_ALL4H 7 #define GEN4_PREDICATE_ALIGN1_ANY8H 8 #define GEN4_PREDICATE_ALIGN1_ALL8H 9 #define GEN4_PREDICATE_ALIGN1_ANY16H 10 #define GEN4_PREDICATE_ALIGN1_ALL16H 11 #define GEN4_PREDICATE_ALIGN16_REPLICATE_X 2 #define GEN4_PREDICATE_ALIGN16_REPLICATE_Y 3 #define GEN4_PREDICATE_ALIGN16_REPLICATE_Z 4 #define GEN4_PREDICATE_ALIGN16_REPLICATE_W 5 #define GEN4_PREDICATE_ALIGN16_ANY4H 6 #define GEN4_PREDICATE_ALIGN16_ALL4H 7 #define GEN4_ARCHITECTURE_REGISTER_FILE 0 #define GEN4_GENERAL_REGISTER_FILE 1 #define GEN4_MESSAGE_REGISTER_FILE 2 #define GEN4_IMMEDIATE_VALUE 3 #define GEN4_REGISTER_TYPE_UD 0 #define GEN4_REGISTER_TYPE_D 1 #define GEN4_REGISTER_TYPE_UW 2 #define GEN4_REGISTER_TYPE_W 3 #define GEN4_REGISTER_TYPE_UB 4 #define GEN4_REGISTER_TYPE_B 5 #define GEN4_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define GEN4_REGISTER_TYPE_HF 6 #define GEN4_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define GEN4_REGISTER_TYPE_F 7 #define GEN4_ARF_NULL 0x00 #define GEN4_ARF_ADDRESS 0x10 #define GEN4_ARF_ACCUMULATOR 0x20 #define GEN4_ARF_FLAG 0x30 #define GEN4_ARF_MASK 0x40 #define GEN4_ARF_MASK_STACK 0x50 #define GEN4_ARF_MASK_STACK_DEPTH 0x60 #define GEN4_ARF_STATE 0x70 #define GEN4_ARF_CONTROL 0x80 #define GEN4_ARF_NOTIFICATION_COUNT 0x90 #define GEN4_ARF_IP 0xA0 #define GEN4_AMASK 0 #define GEN4_IMASK 1 #define GEN4_LMASK 2 #define GEN4_CMASK 3 #define GEN4_THREAD_NORMAL 0 #define GEN4_THREAD_ATOMIC 1 #define GEN4_THREAD_SWITCH 2 #define GEN4_VERTICAL_STRIDE_0 0 #define GEN4_VERTICAL_STRIDE_1 1 #define GEN4_VERTICAL_STRIDE_2 2 #define GEN4_VERTICAL_STRIDE_4 3 #define GEN4_VERTICAL_STRIDE_8 4 #define GEN4_VERTICAL_STRIDE_16 5 #define GEN4_VERTICAL_STRIDE_32 6 #define GEN4_VERTICAL_STRIDE_64 7 #define GEN4_VERTICAL_STRIDE_128 8 #define GEN4_VERTICAL_STRIDE_256 9 #define GEN4_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define GEN4_WIDTH_1 0 #define GEN4_WIDTH_2 1 #define GEN4_WIDTH_4 2 #define GEN4_WIDTH_8 3 #define GEN4_WIDTH_16 4 #define GEN4_STATELESS_BUFFER_BOUNDARY_1K 0 #define GEN4_STATELESS_BUFFER_BOUNDARY_2K 1 #define GEN4_STATELESS_BUFFER_BOUNDARY_4K 2 #define GEN4_STATELESS_BUFFER_BOUNDARY_8K 3 #define GEN4_STATELESS_BUFFER_BOUNDARY_16K 4 #define GEN4_STATELESS_BUFFER_BOUNDARY_32K 5 #define GEN4_STATELESS_BUFFER_BOUNDARY_64K 6 #define GEN4_STATELESS_BUFFER_BOUNDARY_128K 7 #define GEN4_STATELESS_BUFFER_BOUNDARY_256K 8 #define GEN4_STATELESS_BUFFER_BOUNDARY_512K 9 #define GEN4_STATELESS_BUFFER_BOUNDARY_1M 10 #define GEN4_STATELESS_BUFFER_BOUNDARY_2M 11 #define GEN4_POLYGON_FACING_FRONT 0 #define GEN4_POLYGON_FACING_BACK 1 #define GEN4_MESSAGE_TARGET_NULL 0 #define GEN4_MESSAGE_TARGET_MATH 1 #define GEN4_MESSAGE_TARGET_SAMPLER 2 #define GEN4_MESSAGE_TARGET_GATEWAY 3 #define GEN4_MESSAGE_TARGET_DATAPORT_READ 4 #define GEN4_MESSAGE_TARGET_DATAPORT_WRITE 5 #define GEN4_MESSAGE_TARGET_URB 6 #define GEN4_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN4_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define GEN4_SAMPLER_RETURN_FORMAT_UINT32 2 #define GEN4_SAMPLER_RETURN_FORMAT_SINT32 3 #define GEN4_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define GEN4_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define GEN4_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define GEN4_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define GEN4_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define GEN4_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define GEN4_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define GEN4_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define GEN4_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define GEN4_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define GEN4_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define GEN4_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define GEN4_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define GEN4_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define GEN4_SAMPLER_MESSAGE_SIMD8_LD 3 #define GEN4_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN4_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define GEN4_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define GEN4_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define GEN4_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define GEN4_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define GEN4_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define GEN4_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define GEN4_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define GEN4_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define GEN4_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define GEN4_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define GEN4_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define GEN4_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define GEN4_DATAPORT_READ_TARGET_DATA_CACHE 0 #define GEN4_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define GEN4_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define GEN4_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define GEN4_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define GEN4_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define GEN4_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define GEN4_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define GEN4_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define GEN4_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define GEN4_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define GEN4_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define GEN4_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define GEN4_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define GEN4_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define GEN4_MATH_FUNCTION_INV 1 #define GEN4_MATH_FUNCTION_LOG 2 #define GEN4_MATH_FUNCTION_EXP 3 #define GEN4_MATH_FUNCTION_SQRT 4 #define GEN4_MATH_FUNCTION_RSQ 5 #define GEN4_MATH_FUNCTION_SIN 6 /* was 7 */ #define GEN4_MATH_FUNCTION_COS 7 /* was 8 */ #define GEN4_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define GEN4_MATH_FUNCTION_TAN 9 #define GEN4_MATH_FUNCTION_POW 10 #define GEN4_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define GEN4_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define GEN4_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define GEN4_MATH_INTEGER_UNSIGNED 0 #define GEN4_MATH_INTEGER_SIGNED 1 #define GEN4_MATH_PRECISION_FULL 0 #define GEN4_MATH_PRECISION_PARTIAL 1 #define GEN4_MATH_SATURATE_NONE 0 #define GEN4_MATH_SATURATE_SATURATE 1 #define GEN4_MATH_DATA_VECTOR 0 #define GEN4_MATH_DATA_SCALAR 1 #define GEN4_URB_OPCODE_WRITE 0 #define GEN4_URB_SWIZZLE_NONE 0 #define GEN4_URB_SWIZZLE_INTERLEAVE 1 #define GEN4_URB_SWIZZLE_TRANSPOSE 2 #define GEN4_SCRATCH_SPACE_SIZE_1K 0 #define GEN4_SCRATCH_SPACE_SIZE_2K 1 #define GEN4_SCRATCH_SPACE_SIZE_4K 2 #define GEN4_SCRATCH_SPACE_SIZE_8K 3 #define GEN4_SCRATCH_SPACE_SIZE_16K 4 #define GEN4_SCRATCH_SPACE_SIZE_32K 5 #define GEN4_SCRATCH_SPACE_SIZE_64K 6 #define GEN4_SCRATCH_SPACE_SIZE_128K 7 #define GEN4_SCRATCH_SPACE_SIZE_256K 8 #define GEN4_SCRATCH_SPACE_SIZE_512K 9 #define GEN4_SCRATCH_SPACE_SIZE_1M 10 #define GEN4_SCRATCH_SPACE_SIZE_2M 11 #define CMD_URB_FENCE 0x6000 #define CMD_CONST_BUFFER_STATE 0x6001 #define CMD_CONST_BUFFER 0x6002 #define CMD_STATE_BASE_ADDRESS 0x6101 #define CMD_STATE_INSN_POINTER 0x6102 #define CMD_PIPELINE_SELECT 0x6104 #define CMD_PIPELINED_STATE_POINTERS 0x7800 #define CMD_BINDING_TABLE_PTRS 0x7801 #define CMD_VERTEX_BUFFER 0x7808 #define CMD_VERTEX_ELEMENT 0x7809 #define CMD_INDEX_BUFFER 0x780a #define CMD_VF_STATISTICS 0x780b #define CMD_DRAW_RECT 0x7900 #define CMD_BLEND_CONSTANT_COLOR 0x7901 #define CMD_CHROMA_KEY 0x7904 #define CMD_DEPTH_BUFFER 0x7905 #define CMD_POLY_STIPPLE_OFFSET 0x7906 #define CMD_POLY_STIPPLE_PATTERN 0x7907 #define CMD_LINE_STIPPLE_PATTERN 0x7908 #define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908 #define CMD_PIPE_CONTROL 0x7a00 #define CMD_3D_PRIM 0x7b00 #define CMD_MI_FLUSH 0x0200 /* Various values from the R0 vertex header: */ #define R02_PRIM_END 0x1 #define R02_PRIM_START 0x2 /* media pipeline */ #define GEN4_VFE_MODE_GENERIC 0x0 #define GEN4_VFE_MODE_VLD_MPEG2 0x1 #define GEN4_VFE_MODE_IS 0x2 #define GEN4_VFE_MODE_AVC_MC 0x4 #define GEN4_VFE_MODE_AVC_IT 0x7 #define GEN4_VFE_MODE_VC1_IT 0xB #define GEN4_VFE_DEBUG_COUNTER_FREE 0 #define GEN4_VFE_DEBUG_COUNTER_FROZEN 1 #define GEN4_VFE_DEBUG_COUNTER_ONCE 2 #define GEN4_VFE_DEBUG_COUNTER_ALWAYS 3 /* VLD_STATE */ #define GEN4_MPEG_TOP_FIELD 1 #define GEN4_MPEG_BOTTOM_FIELD 2 #define GEN4_MPEG_FRAME 3 #define GEN4_MPEG_QSCALE_LINEAR 0 #define GEN4_MPEG_QSCALE_NONLINEAR 1 #define GEN4_MPEG_ZIGZAG_SCAN 0 #define GEN4_MPEG_ALTER_VERTICAL_SCAN 1 #define GEN4_MPEG_I_PICTURE 1 #define GEN4_MPEG_P_PICTURE 2 #define GEN4_MPEG_B_PICTURE 3 /* Command packets: */ struct header { unsigned int length:16; unsigned int opcode:16; }; union header_union { struct header bits; unsigned int dword; }; struct gen4_3d_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:3; unsigned int wc_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } dest; unsigned int dword2; unsigned int dword3; }; struct gen4_3d_primitive { struct { unsigned int length:8; unsigned int pad:2; unsigned int topology:5; unsigned int indexed:1; unsigned int opcode:16; } header; unsigned int verts_per_instance; unsigned int start_vert_location; unsigned int instance_count; unsigned int start_instance_location; unsigned int base_vert_location; }; /* These seem to be passed around as function args, so it works out * better to keep them as #defines: */ #define GEN4_FLUSH_READ_CACHE 0x1 #define GEN4_FLUSH_STATE_CACHE 0x2 #define GEN4_INHIBIT_FLUSH_RENDER_CACHE 0x4 #define GEN4_FLUSH_SNAPSHOT_COUNTERS 0x8 struct gen4_mi_flush { unsigned int flags:4; unsigned int pad:12; unsigned int opcode:16; }; struct gen4_vf_statistics { unsigned int statistics_enable:1; unsigned int pad:15; unsigned int opcode:16; }; struct gen4_binding_table_pointers { struct header header; unsigned int vs; unsigned int gs; unsigned int clp; unsigned int sf; unsigned int wm; }; struct gen4_blend_constant_color { struct header header; float blend_constant_color[4]; }; struct gen4_depthbuffer { union header_union header; union { struct { unsigned int pitch:18; unsigned int format:3; unsigned int pad:4; unsigned int depth_offset_disable:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad2:1; unsigned int surface_type:3; } bits; unsigned int dword; } dword1; unsigned int dword2_base_addr; union { struct { unsigned int pad:1; unsigned int mipmap_layout:1; unsigned int lod:4; unsigned int width:13; unsigned int height:13; } bits; unsigned int dword; } dword3; union { struct { unsigned int pad:12; unsigned int min_array_element:9; unsigned int depth:11; } bits; unsigned int dword; } dword4; }; struct gen4_drawrect { struct header header; unsigned int xmin:16; unsigned int ymin:16; unsigned int xmax:16; unsigned int ymax:16; unsigned int xorg:16; unsigned int yorg:16; }; struct gen4_global_depth_offset_clamp { struct header header; float depth_offset_clamp; }; struct gen4_indexbuffer { union { struct { unsigned int length:8; unsigned int index_format:2; unsigned int cut_index_enable:1; unsigned int pad:5; unsigned int opcode:16; } bits; unsigned int dword; } header; unsigned int buffer_start; unsigned int buffer_end; }; struct gen4_line_stipple { struct header header; struct { unsigned int pattern:16; unsigned int pad:16; } bits0; struct { unsigned int repeat_count:9; unsigned int pad:7; unsigned int inverse_repeat_count:16; } bits1; }; struct gen4_pipelined_state_pointers { struct header header; struct { unsigned int pad:5; unsigned int offset:27; } vs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } gs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } clp; struct { unsigned int pad:5; unsigned int offset:27; } sf; struct { unsigned int pad:5; unsigned int offset:27; } wm; struct { unsigned int pad:5; unsigned int offset:27; /* KW: check me! */ } cc; }; struct gen4_polygon_stipple_offset { struct header header; struct { unsigned int y_offset:5; unsigned int pad:3; unsigned int x_offset:5; unsigned int pad0:19; } bits0; }; struct gen4_polygon_stipple { struct header header; unsigned int stipple[32]; }; struct gen4_pipeline_select { struct { unsigned int pipeline_select:1; unsigned int pad:15; unsigned int opcode:16; } header; }; struct gen4_pipe_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:2; unsigned int instruction_state_cache_flush_enable:1; unsigned int write_cache_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int post_sync_operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } bits1; unsigned int data0; unsigned int data1; }; struct gen4_urb_fence { struct { unsigned int length:8; unsigned int vs_realloc:1; unsigned int gs_realloc:1; unsigned int clp_realloc:1; unsigned int sf_realloc:1; unsigned int vfe_realloc:1; unsigned int cs_realloc:1; unsigned int pad:2; unsigned int opcode:16; } header; struct { unsigned int vs_fence:10; unsigned int gs_fence:10; unsigned int clp_fence:10; unsigned int pad:2; } bits0; struct { unsigned int sf_fence:10; unsigned int vf_fence:10; unsigned int cs_fence:10; unsigned int pad:2; } bits1; }; struct gen4_constant_buffer_state /* previously gen4_command_streamer */ { struct header header; struct { unsigned int nr_urb_entries:3; unsigned int pad:1; unsigned int urb_entry_size:5; unsigned int pad0:23; } bits0; }; struct gen4_constant_buffer { struct { unsigned int length:8; unsigned int valid:1; unsigned int pad:7; unsigned int opcode:16; } header; struct { unsigned int buffer_length:6; unsigned int buffer_address:26; } bits0; }; struct gen4_state_base_address { struct header header; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int general_state_address:27; } bits0; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int surface_state_address:27; } bits1; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int indirect_object_state_address:27; } bits2; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int general_state_upper_bound:20; } bits3; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int indirect_object_state_upper_bound:20; } bits4; }; struct gen4_state_prefetch { struct header header; struct { unsigned int prefetch_count:3; unsigned int pad:3; unsigned int prefetch_pointer:26; } bits0; }; struct gen4_system_instruction_pointer { struct header header; struct { unsigned int pad:4; unsigned int system_instruction_pointer:28; } bits0; }; /* State structs for the various fixed function units: */ struct thread0 { unsigned int pad0:1; unsigned int grf_reg_count:3; unsigned int pad1:2; unsigned int kernel_start_pointer:26; }; struct thread1 { unsigned int ext_halt_exception_enable:1; unsigned int sw_exception_enable:1; unsigned int mask_stack_exception_enable:1; unsigned int timeout_exception_enable:1; unsigned int illegal_op_exception_enable:1; unsigned int pad0:3; unsigned int depth_coef_urb_read_offset:6; /* WM only */ unsigned int pad1:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad3:5; unsigned int single_program_flow:1; }; struct thread2 { unsigned int per_thread_scratch_space:4; unsigned int pad0:6; unsigned int scratch_space_base_pointer:22; }; struct thread3 { unsigned int dispatch_grf_start_reg:4; unsigned int urb_entry_read_offset:6; unsigned int pad0:1; unsigned int urb_entry_read_length:6; unsigned int pad1:1; unsigned int const_urb_entry_read_offset:6; unsigned int pad2:1; unsigned int const_urb_entry_read_length:6; unsigned int pad3:1; }; struct gen4_clip_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:9; unsigned int gs_output_stats:1; /* not always */ unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; /* may be less */ unsigned int pad3:1; } thread4; struct { unsigned int pad0:13; unsigned int clip_mode:3; unsigned int userclip_enable_flags:8; unsigned int userclip_must_clip:1; unsigned int pad1:1; unsigned int guard_band_enable:1; unsigned int viewport_z_clip_enable:1; unsigned int viewport_xy_clip_enable:1; unsigned int vertex_position_space:1; unsigned int api_mode:1; unsigned int pad2:1; } clip5; struct { unsigned int pad0:5; unsigned int clipper_viewport_state_ptr:27; } clip6; float viewport_xmin; float viewport_xmax; float viewport_ymin; float viewport_ymax; }; struct gen4_cc_unit_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } cc0; struct { unsigned int bf_stencil_ref:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; unsigned int stencil_ref:8; } cc1; struct { unsigned int logicop_enable:1; unsigned int pad0:10; unsigned int depth_write_enable:1; unsigned int depth_test_function:3; unsigned int depth_test:1; unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; } cc2; struct { unsigned int pad0:8; unsigned int alpha_test_func:3; unsigned int alpha_test:1; unsigned int blend_enable:1; unsigned int ia_blend_enable:1; unsigned int pad1:1; unsigned int alpha_test_format:1; unsigned int pad2:16; } cc3; struct { unsigned int pad0:5; unsigned int cc_viewport_state_offset:27; } cc4; struct { unsigned int pad0:2; unsigned int ia_dest_blend_factor:5; unsigned int ia_src_blend_factor:5; unsigned int ia_blend_function:3; unsigned int statistics_enable:1; unsigned int logicop_func:4; unsigned int pad1:11; unsigned int dither_enable:1; } cc5; struct { unsigned int clamp_post_alpha_blend:1; unsigned int clamp_pre_alpha_blend:1; unsigned int clamp_range:2; unsigned int pad0:11; unsigned int y_dither_offset:2; unsigned int x_dither_offset:2; unsigned int dest_blend_factor:5; unsigned int src_blend_factor:5; unsigned int blend_function:3; } cc6; struct { union { float f; unsigned char ub[4]; } alpha_ref; } cc7; }; struct gen4_sf_unit_state { struct thread0 thread0; struct { unsigned int pad0:7; unsigned int sw_exception_enable:1; unsigned int pad1:3; unsigned int mask_stack_exception_enable:1; unsigned int pad2:1; unsigned int illegal_op_exception_enable:1; unsigned int pad3:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad4:5; unsigned int single_program_flow:1; } sf1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; unsigned int pad3:1; } thread4; struct { unsigned int front_winding:1; unsigned int viewport_transform:1; unsigned int pad0:3; unsigned int sf_viewport_state_offset:27; } sf5; struct { unsigned int pad0:9; unsigned int dest_org_vbias:4; unsigned int dest_org_hbias:4; unsigned int scissor:1; unsigned int disable_2x2_trifilter:1; unsigned int disable_zero_pix_trifilter:1; unsigned int point_rast_rule:2; unsigned int line_endcap_aa_region_width:2; unsigned int line_width:4; unsigned int fast_scissor_disable:1; unsigned int cull_mode:2; unsigned int aa_enable:1; } sf6; struct { unsigned int point_size:11; unsigned int use_point_size_state:1; unsigned int subpixel_precision:1; unsigned int sprite_point:1; unsigned int pad0:11; unsigned int trifan_pv:2; unsigned int linestrip_pv:2; unsigned int tristrip_pv:2; unsigned int line_last_pixel_enable:1; } sf7; }; struct gen4_gs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:1; unsigned int pad3:6; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } gs5; struct { unsigned int max_vp_index:4; unsigned int pad0:26; unsigned int reorder_enable:1; unsigned int pad1:1; } gs6; }; struct gen4_vs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:4; unsigned int pad3:3; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } vs5; struct { unsigned int vs_enable:1; unsigned int vert_cache_disable:1; unsigned int pad0:30; } vs6; }; struct gen4_wm_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int stats_enable:1; unsigned int pad0:1; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } wm4; struct { unsigned int enable_8_pix:1; unsigned int enable_16_pix:1; unsigned int enable_32_pix:1; unsigned int pad0:7; unsigned int legacy_global_depth_bias:1; unsigned int line_stipple:1; unsigned int depth_offset:1; unsigned int polygon_stipple:1; unsigned int line_aa_region_width:2; unsigned int line_endcap_aa_region_width:2; unsigned int early_depth_test:1; unsigned int thread_dispatch_enable:1; unsigned int program_uses_depth:1; unsigned int program_computes_depth:1; unsigned int program_uses_killpixel:1; unsigned int legacy_line_rast: 1; unsigned int transposed_urb_read:1; unsigned int max_threads:7; } wm5; float global_depth_offset_constant; float global_depth_offset_scale; struct { unsigned int pad0:1; unsigned int grf_reg_count_1:3; unsigned int pad1:2; unsigned int kernel_start_pointer_1:26; } wm8; struct { unsigned int pad0:1; unsigned int grf_reg_count_2:3; unsigned int pad1:2; unsigned int kernel_start_pointer_2:26; } wm9; struct { unsigned int pad0:1; unsigned int grf_reg_count_3:3; unsigned int pad1:2; unsigned int kernel_start_pointer_3:26; } wm10; }; struct gen4_wm_unit_state_padded { struct gen4_wm_unit_state state; char pad[64 - sizeof(struct gen4_wm_unit_state)]; }; /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct gen4_sampler_default_border_color { float color[4]; }; struct gen4_sampler_legacy_border_color { uint8_t color[4]; }; struct gen4_sampler_state { struct { unsigned int shadow_function:3; unsigned int lod_bias:11; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad:1; unsigned int lod_preclamp:1; unsigned int border_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:3; unsigned int max_lod:10; unsigned int min_lod:10; } ss1; struct { unsigned int pad:5; unsigned int border_color_pointer:27; } ss2; struct { unsigned int pad:19; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int monochrome_filter_width:3; unsigned int monochrome_filter_height:3; } ss3; }; struct gen4_clipper_viewport { float xmin; float xmax; float ymin; float ymax; }; struct gen4_cc_viewport { float min_depth; float max_depth; }; struct gen4_sf_viewport { struct { float m00; float m11; float m22; float m30; float m31; float m32; } viewport; struct { short xmin; short ymin; short xmax; short ymax; } scissor; }; /* Documented in the subsystem/shared-functions/sampler chapter... */ struct gen4_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad:3; unsigned int render_cache_read_mode:1; unsigned int mipmap_layout_mode:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int color_blend:1; unsigned int writedisable_blue:1; unsigned int writedisable_green:1; unsigned int writedisable_red:1; unsigned int writedisable_alpha:1; unsigned int surface_format:9; unsigned int data_return_format:1; unsigned int pad0:1; unsigned int surface_type:3; } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int render_target_rotation:2; unsigned int mip_count:4; unsigned int width:13; unsigned int height:13; } ss2; struct { unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad:1; unsigned int pitch:18; unsigned int depth:11; } ss3; struct { unsigned int pad:19; unsigned int min_array_elt:9; unsigned int min_lod:4; } ss4; struct { unsigned int pad:20; unsigned int y_offset:4; unsigned int pad2:1; unsigned int x_offset:7; } ss5; }; /* Surface state DW0 */ #define GEN4_SURFACE_RC_READ_WRITE (1 << 8) #define GEN4_SURFACE_MIPLAYOUT_SHIFT 10 #define GEN4_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN4_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN4_SURFACE_CUBEFACE_ENABLES 0x3f #define GEN4_SURFACE_BLEND_ENABLED (1 << 13) #define GEN4_SURFACE_WRITEDISABLE_B_SHIFT 14 #define GEN4_SURFACE_WRITEDISABLE_G_SHIFT 15 #define GEN4_SURFACE_WRITEDISABLE_R_SHIFT 16 #define GEN4_SURFACE_WRITEDISABLE_A_SHIFT 17 #define GEN4_SURFACE_FORMAT_SHIFT 18 #define GEN4_SURFACE_FORMAT_MASK _MASK(26, 18) #define GEN4_SURFACE_TYPE_SHIFT 29 #define GEN4_SURFACE_TYPE_MASK _MASK(31, 29) #define GEN4_SURFACE_1D 0 #define GEN4_SURFACE_2D 1 #define GEN4_SURFACE_3D 2 #define GEN4_SURFACE_CUBE 3 #define GEN4_SURFACE_BUFFER 4 #define GEN4_SURFACE_NULL 7 /* Surface state DW2 */ #define GEN4_SURFACE_HEIGHT_SHIFT 19 #define GEN4_SURFACE_HEIGHT_MASK _MASK(31, 19) #define GEN4_SURFACE_WIDTH_SHIFT 6 #define GEN4_SURFACE_WIDTH_MASK _MASK(18, 6) #define GEN4_SURFACE_LOD_SHIFT 2 #define GEN4_SURFACE_LOD_MASK _MASK(5, 2) /* Surface state DW3 */ #define GEN4_SURFACE_DEPTH_SHIFT 21 #define GEN4_SURFACE_DEPTH_MASK _MASK(31, 21) #define GEN4_SURFACE_PITCH_SHIFT 3 #define GEN4_SURFACE_PITCH_MASK _MASK(19, 3) #define GEN4_SURFACE_TILED (1 << 1) #define GEN4_SURFACE_TILED_Y (1 << 0) /* Surface state DW4 */ #define GEN4_SURFACE_MIN_LOD_SHIFT 28 #define GEN4_SURFACE_MIN_LOD_MASK _MASK(31, 28) /* Surface state DW5 */ #define GEN4_SURFACE_X_OFFSET_SHIFT 25 #define GEN4_SURFACE_X_OFFSET_MASK _MASK(31, 25) #define GEN4_SURFACE_Y_OFFSET_SHIFT 20 #define GEN4_SURFACE_Y_OFFSET_MASK _MASK(23, 20) struct gen4_vertex_buffer_state { struct { unsigned int pitch:11; unsigned int pad:15; unsigned int access_type:1; unsigned int vb_index:5; } vb0; unsigned int start_addr; unsigned int max_index; #if 1 unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */ #endif }; #define GEN4_VBP_MAX 17 struct gen4_vb_array_state { struct header header; struct gen4_vertex_buffer_state vb[GEN4_VBP_MAX]; }; struct gen4_vertex_element_state { struct { unsigned int src_offset:11; unsigned int pad:5; unsigned int src_format:9; unsigned int pad0:1; unsigned int valid:1; unsigned int vertex_buffer_index:5; } ve0; struct { unsigned int dst_offset:8; unsigned int pad:8; unsigned int vfcomponent3:4; unsigned int vfcomponent2:4; unsigned int vfcomponent1:4; unsigned int vfcomponent0:4; } ve1; }; #define GEN4_VEP_MAX 18 struct gen4_vertex_element_packet { struct header header; struct gen4_vertex_element_state ve[GEN4_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */ }; struct gen4_urb_immediate { unsigned int opcode:4; unsigned int offset:6; unsigned int swizzle_control:2; unsigned int pad:1; unsigned int allocate:1; unsigned int used:1; unsigned int complete:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; }; /* Instruction format for the execution units: */ struct gen4_instruction { struct { unsigned int opcode:7; unsigned int pad:1; unsigned int access_mode:1; unsigned int mask_control:1; unsigned int dependency_control:2; unsigned int compression_control:2; unsigned int thread_control:2; unsigned int predicate_control:4; unsigned int predicate_inverse:1; unsigned int execution_size:3; unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */ unsigned int pad0:2; unsigned int debug_control:1; unsigned int saturate:1; } header; union { struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad:1; unsigned int dest_subreg_nr:5; unsigned int dest_reg_nr:8; unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } da1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad:6; int dest_indirect_offset:10; /* offset against the deref'd address reg */ unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */ unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } ia1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad0:1; unsigned int dest_writemask:4; unsigned int dest_subreg_nr:1; unsigned int dest_reg_nr:8; unsigned int pad1:2; unsigned int dest_address_mode:1; } da16; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad0:6; unsigned int dest_writemask:4; int dest_indirect_offset:6; unsigned int dest_subreg_nr:3; unsigned int pad1:2; unsigned int dest_address_mode:1; } ia16; } bits1; union { struct { unsigned int src0_subreg_nr:5; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } da1; struct { int src0_indirect_offset:10; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } ia1; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; unsigned int src0_subreg_nr:1; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } da16; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; int src0_indirect_offset:6; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia16; } bits2; union { struct { unsigned int src1_subreg_nr:5; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int pad0:7; } da1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; unsigned int src1_subreg_nr:1; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int pad2:7; } da16; struct { int src1_indirect_offset:10; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; int src1_indirect_offset:6; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad2:6; } ia16; struct { int jump_count:16; /* note: signed */ unsigned int pop_count:4; unsigned int pad0:12; } if_else; struct { unsigned int function:4; unsigned int int_type:1; unsigned int precision:1; unsigned int saturate:1; unsigned int data_type:1; unsigned int pad0:8; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } math; struct { unsigned int binding_table_index:8; unsigned int sampler:4; unsigned int return_format:2; unsigned int msg_type:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } sampler; struct gen4_urb_immediate urb; struct { unsigned int binding_table_index:8; unsigned int msg_control:4; unsigned int msg_type:2; unsigned int target_cache:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_read; struct { unsigned int binding_table_index:8; unsigned int msg_control:3; unsigned int pixel_scoreboard_clear:1; unsigned int msg_type:3; unsigned int send_commit_msg:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_write; struct { unsigned int pad:16; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } generic; unsigned int ud; } bits3; }; /* media pipeline */ struct gen4_vfe_state { struct { unsigned int per_thread_scratch_space:4; unsigned int pad3:3; unsigned int extend_vfe_state_present:1; unsigned int pad2:2; unsigned int scratch_base:22; } vfe0; struct { unsigned int debug_counter_control:2; unsigned int children_present:1; unsigned int vfe_mode:4; unsigned int pad2:2; unsigned int num_urb_entries:7; unsigned int urb_entry_alloc_size:9; unsigned int max_threads:7; } vfe1; struct { unsigned int pad4:4; unsigned int interface_descriptor_base:28; } vfe2; }; struct gen4_vld_state { struct { unsigned int pad6:6; unsigned int scan_order:1; unsigned int intra_vlc_format:1; unsigned int quantizer_scale_type:1; unsigned int concealment_motion_vector:1; unsigned int frame_predict_frame_dct:1; unsigned int top_field_first:1; unsigned int picture_structure:2; unsigned int intra_dc_precision:2; unsigned int f_code_0_0:4; unsigned int f_code_0_1:4; unsigned int f_code_1_0:4; unsigned int f_code_1_1:4; } vld0; struct { unsigned int pad2:9; unsigned int picture_coding_type:2; unsigned int pad:21; } vld1; struct { unsigned int index_0:4; unsigned int index_1:4; unsigned int index_2:4; unsigned int index_3:4; unsigned int index_4:4; unsigned int index_5:4; unsigned int index_6:4; unsigned int index_7:4; } desc_remap_table0; struct { unsigned int index_8:4; unsigned int index_9:4; unsigned int index_10:4; unsigned int index_11:4; unsigned int index_12:4; unsigned int index_13:4; unsigned int index_14:4; unsigned int index_15:4; } desc_remap_table1; }; struct gen4_interface_descriptor { struct { unsigned int grf_reg_blocks:4; unsigned int pad:2; unsigned int kernel_start_pointer:26; } desc0; struct { unsigned int pad:7; unsigned int software_exception:1; unsigned int pad2:3; unsigned int maskstack_exception:1; unsigned int pad3:1; unsigned int illegal_opcode_exception:1; unsigned int pad4:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int single_program_flow:1; unsigned int pad5:1; unsigned int const_urb_entry_read_offset:6; unsigned int const_urb_entry_read_len:6; } desc1; struct { unsigned int pad:2; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } desc2; struct { unsigned int binding_table_entry_count:5; unsigned int binding_table_pointer:27; } desc3; }; struct gen6_blend_state { struct { unsigned int dest_blend_factor:5; unsigned int source_blend_factor:5; unsigned int pad3:1; unsigned int blend_func:3; unsigned int pad2:1; unsigned int ia_dest_blend_factor:5; unsigned int ia_source_blend_factor:5; unsigned int pad1:1; unsigned int ia_blend_func:3; unsigned int pad0:1; unsigned int ia_blend_enable:1; unsigned int blend_enable:1; } blend0; struct { unsigned int post_blend_clamp_enable:1; unsigned int pre_blend_clamp_enable:1; unsigned int clamp_range:2; unsigned int pad0:4; unsigned int x_dither_offset:2; unsigned int y_dither_offset:2; unsigned int dither_enable:1; unsigned int alpha_test_func:3; unsigned int alpha_test_enable:1; unsigned int pad1:1; unsigned int logic_op_func:4; unsigned int logic_op_enable:1; unsigned int pad2:1; unsigned int write_disable_b:1; unsigned int write_disable_g:1; unsigned int write_disable_r:1; unsigned int write_disable_a:1; unsigned int pad3:1; unsigned int alpha_to_coverage_dither:1; unsigned int alpha_to_one:1; unsigned int alpha_to_coverage:1; } blend1; }; struct gen6_color_calc_state { struct { unsigned int alpha_test_format:1; unsigned int pad0:14; unsigned int round_disable:1; unsigned int bf_stencil_ref:8; unsigned int stencil_ref:8; } cc0; union { float alpha_ref_f; struct { unsigned int ui:8; unsigned int pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen6_depth_stencil_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } ds0; struct { unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; } ds1; struct { unsigned int pad0:26; unsigned int depth_write_enable:1; unsigned int depth_test_func:3; unsigned int pad1:1; unsigned int depth_test_enable:1; } ds2; }; typedef enum { SAMPLER_FILTER_NEAREST = 0, SAMPLER_FILTER_BILINEAR, FILTER_COUNT } sampler_filter_t; typedef enum { SAMPLER_EXTEND_NONE = 0, SAMPLER_EXTEND_REPEAT, SAMPLER_EXTEND_PAD, SAMPLER_EXTEND_REFLECT, EXTEND_COUNT } sampler_extend_t; typedef enum { WM_KERNEL = 0, WM_KERNEL_P, WM_KERNEL_MASK, WM_KERNEL_MASK_P, WM_KERNEL_MASKCA, WM_KERNEL_MASKCA_P, WM_KERNEL_MASKSA, WM_KERNEL_MASKSA_P, WM_KERNEL_OPACITY, WM_KERNEL_OPACITY_P, WM_KERNEL_VIDEO_PLANAR, WM_KERNEL_VIDEO_PACKED, KERNEL_COUNT } wm_kernel_t; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_source.c000066400000000000000000000131161267532330400242260ustar00rootroot00000000000000/* * Copyright © 2011,2012,2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "gen4_source.h" #include "gen4_render.h" bool gen4_channel_init_solid(struct sna *sna, struct sna_composite_channel *channel, uint32_t color) { channel->filter = PictFilterNearest; channel->repeat = RepeatNormal; channel->is_affine = true; channel->is_solid = true; channel->is_opaque = (color >> 24) == 0xff; channel->transform = NULL; channel->width = 1; channel->height = 1; channel->pict_format = PICT_a8r8g8b8; channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; channel->bo = sna_render_get_solid(sna, color); channel->scale[0] = channel->scale[1] = 1; channel->offset[0] = channel->offset[1] = 0; return channel->bo != NULL; } bool gen4_channel_init_linear(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y) { PictLinearGradient *linear = (PictLinearGradient *)picture->pSourcePict; pixman_fixed_t tx, ty; float x0, y0, sf; float dx, dy; DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y), pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y), x, y, dst_x, dst_y, w, h)); if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y) return 0; if (!sna_transform_is_affine(picture->transform)) { DBG(("%s: fallback due to projective transform\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear); if (!channel->bo) return 0; channel->filter = PictFilterNearest; channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->width = channel->bo->pitch / 4; channel->height = 1; channel->pict_format = PICT_a8r8g8b8; channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM; channel->is_linear = 1; channel->is_affine = 1; channel->scale[0] = channel->scale[1] = 1; channel->offset[0] = channel->offset[1] = 0; if (sna_transform_is_translation(picture->transform, &tx, &ty)) { dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x); dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y); x0 = pixman_fixed_to_double(linear->p1.x); y0 = pixman_fixed_to_double(linear->p1.y); if (tx | ty) { x0 -= pixman_fixed_to_double(tx); y0 -= pixman_fixed_to_double(ty); } } else { struct pixman_f_vector p1, p2; struct pixman_f_transform m, inv; pixman_f_transform_from_pixman_transform(&m, picture->transform); DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n", __FUNCTION__, m.m[0][0], m.m[0][1], m.m[0][2], m.m[1][0], m.m[1][1], m.m[1][2], m.m[2][0], m.m[2][1], m.m[2][2])); if (!pixman_f_transform_invert(&inv, &m)) return 0; p1.v[0] = pixman_fixed_to_double(linear->p1.x); p1.v[1] = pixman_fixed_to_double(linear->p1.y); p1.v[2] = 1.; pixman_f_transform_point(&inv, &p1); p2.v[0] = pixman_fixed_to_double(linear->p2.x); p2.v[1] = pixman_fixed_to_double(linear->p2.y); p2.v[2] = 1.; pixman_f_transform_point(&inv, &p2); DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n", __FUNCTION__, p1.v[0], p1.v[1], p1.v[2], p2.v[0], p2.v[1], p2.v[2])); dx = p2.v[0] - p1.v[0]; dy = p2.v[1] - p1.v[1]; x0 = p1.v[0]; y0 = p1.v[1]; } sf = dx*dx + dy*dy; dx /= sf; dy /= sf; channel->u.linear.dx = dx; channel->u.linear.dy = dy; channel->u.linear.offset = -dx*(x0+dst_x-x) + -dy*(y0+dst_y-y); channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx); channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy); channel->embedded_transform.matrix[0][2] = pixman_double_to_fixed(channel->u.linear.offset); channel->embedded_transform.matrix[1][0] = 0; channel->embedded_transform.matrix[1][1] = 0; channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5); channel->embedded_transform.matrix[2][0] = 0; channel->embedded_transform.matrix[2][1] = 0; channel->embedded_transform.matrix[2][2] = pixman_fixed_1; channel->transform = &channel->embedded_transform; DBG(("%s: dx=%f, dy=%f, offset=%f\n", __FUNCTION__, dx, dy, channel->u.linear.offset)); return channel->bo != NULL; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_source.h000066400000000000000000000006501267532330400242320ustar00rootroot00000000000000#ifndef GEN4_SOURCE_H #define GEN4_SOURCE_H #include "compiler.h" #include "sna.h" #include "sna_render.h" bool gen4_channel_init_solid(struct sna *sna, struct sna_composite_channel *channel, uint32_t color); bool gen4_channel_init_linear(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y); #endif /* GEN4_SOURCE_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_vertex.c000066400000000000000000002335341267532330400242530ustar00rootroot00000000000000/* * Copyright © 2012 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "gen4_vertex.h" #ifndef sse2 #define sse2 #endif void gen4_vertex_align(struct sna *sna, const struct sna_composite_op *op) { int vertex_index; assert(op->floats_per_vertex); assert(op->floats_per_rect == 3*op->floats_per_vertex); assert(sna->render.vertex_used <= sna->render.vertex_size); vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; if ((int)sna->render.vertex_size - vertex_index * op->floats_per_vertex < 2*op->floats_per_rect) { DBG(("%s: flushing vertex buffer: new index=%d, max=%d\n", __FUNCTION__, vertex_index, sna->render.vertex_size / op->floats_per_vertex)); if (gen4_vertex_finish(sna) < 2*op->floats_per_rect) { kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } assert(sna->render.vertex_used < sna->render.vertex_size); vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; assert(vertex_index * op->floats_per_vertex <= sna->render.vertex_size); } sna->render.vertex_index = vertex_index; sna->render.vertex_used = vertex_index * op->floats_per_vertex; } void gen4_vertex_flush(struct sna *sna) { DBG(("%s[%x] = %d\n", __FUNCTION__, 4*sna->render.vertex_offset, sna->render.vertex_index - sna->render.vertex_start)); assert(sna->render.vertex_offset); assert(sna->render.vertex_offset <= sna->kgem.nbatch); assert(sna->render.vertex_index > sna->render.vertex_start); assert(sna->render.vertex_used <= sna->render.vertex_size); sna->kgem.batch[sna->render.vertex_offset] = sna->render.vertex_index - sna->render.vertex_start; sna->render.vertex_offset = 0; } int gen4_vertex_finish(struct sna *sna) { struct kgem_bo *bo; unsigned int i; unsigned hint, size; DBG(("%s: used=%d / %d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size)); assert(sna->render.vertex_offset == 0); assert(sna->render.vertex_used); assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_wait__locked(&sna->render); /* Note: we only need dword alignment (currently) */ hint = CREATE_GTT_MAP; bo = sna->render.vbo; if (bo) { for (i = 0; i < sna->render.nvertex_reloc; i++) { DBG(("%s: reloc[%d] = %d\n", __FUNCTION__, i, sna->render.vertex_reloc[i])); sna->kgem.batch[sna->render.vertex_reloc[i]] = kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[i], bo, I915_GEM_DOMAIN_VERTEX << 16, 0); } assert(!sna->render.active); sna->render.nvertex_reloc = 0; sna->render.vertex_used = 0; sna->render.vertex_index = 0; sna->render.vbo = NULL; sna->render.vb_id = 0; kgem_bo_destroy(&sna->kgem, bo); hint |= CREATE_CACHED | CREATE_NO_THROTTLE; } else { assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data)); assert(sna->render.vertices == sna->render.vertex_data); if (kgem_is_idle(&sna->kgem)) return 0; } size = 256*1024; assert(!sna->render.active); sna->render.vertices = NULL; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); while (sna->render.vbo == NULL && size > sizeof(sna->render.vertex_data)) { size /= 2; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); } if (sna->render.vbo == NULL) sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024, CREATE_GTT_MAP); if (sna->render.vbo && kgem_check_bo(&sna->kgem, sna->render.vbo, NULL)) sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo); if (sna->render.vertices == NULL) { if (sna->render.vbo) { kgem_bo_destroy(&sna->kgem, sna->render.vbo); sna->render.vbo = NULL; } sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); return 0; } if (sna->render.vertex_used) { DBG(("%s: copying initial buffer x %d to handle=%d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vbo->handle)); assert(sizeof(float)*sna->render.vertex_used <= __kgem_bo_size(sna->render.vbo)); memcpy(sna->render.vertices, sna->render.vertex_data, sizeof(float)*sna->render.vertex_used); } size = __kgem_bo_size(sna->render.vbo)/4; if (size >= UINT16_MAX) size = UINT16_MAX - 1; DBG(("%s: create vbo handle=%d, size=%d floats [%d bytes]\n", __FUNCTION__, sna->render.vbo->handle, size, __kgem_bo_size(sna->render.vbo))); assert(size > sna->render.vertex_used); sna->render.vertex_size = size; return size - sna->render.vertex_used; } void gen4_vertex_close(struct sna *sna) { struct kgem_bo *bo, *free_bo = NULL; unsigned int i, delta = 0; assert(sna->render.vertex_offset == 0); if (!sna->render.vb_id) return; DBG(("%s: used=%d, vbo active? %d, vb=%x, nreloc=%d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0, sna->render.vb_id, sna->render.nvertex_reloc)); assert(!sna->render.active); bo = sna->render.vbo; if (bo) { if (sna->render.vertex_size - sna->render.vertex_used < 64) { DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } else if (!sna->kgem.has_llc && sna->render.vertices == MAP(bo->map__cpu)) { DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, sna->render.vbo); if (sna->render.vertices == NULL) { sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } } } else { int size; size = sna->kgem.nbatch; size += sna->kgem.batch_size - sna->kgem.surface; size += sna->render.vertex_used; if (size <= 1024) { DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__, sna->render.vertex_used, sna->kgem.nbatch)); assert(sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface); memcpy(sna->kgem.batch + sna->kgem.nbatch, sna->render.vertex_data, sna->render.vertex_used * 4); delta = sna->kgem.nbatch * 4; bo = NULL; sna->kgem.nbatch += sna->render.vertex_used; } else { size = 256 * 1024; do { bo = kgem_create_linear(&sna->kgem, size, CREATE_GTT_MAP | CREATE_NO_RETIRE | CREATE_NO_THROTTLE | CREATE_CACHED); } while (bo == NULL && (size>>=1) > sizeof(float)*sna->render.vertex_used); sna->render.vertices = NULL; if (bo) sna->render.vertices = kgem_bo_map(&sna->kgem, bo); if (sna->render.vertices != NULL) { DBG(("%s: new vbo: %d / %d\n", __FUNCTION__, sna->render.vertex_used, __kgem_bo_size(bo)/4)); assert(sizeof(float)*sna->render.vertex_used <= __kgem_bo_size(bo)); memcpy(sna->render.vertices, sna->render.vertex_data, sizeof(float)*sna->render.vertex_used); size = __kgem_bo_size(bo)/4; if (size >= UINT16_MAX) size = UINT16_MAX - 1; sna->render.vbo = bo; sna->render.vertex_size = size; } else { DBG(("%s: tmp vbo: %d\n", __FUNCTION__, sna->render.vertex_used)); if (bo) kgem_bo_destroy(&sna->kgem, bo); bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used, CREATE_NO_THROTTLE); if (bo && !kgem_bo_write(&sna->kgem, bo, sna->render.vertex_data, 4*sna->render.vertex_used)) { kgem_bo_destroy(&sna->kgem, bo); bo = NULL; } assert(sna->render.vbo == NULL); sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } } } assert(sna->render.nvertex_reloc); for (i = 0; i < sna->render.nvertex_reloc; i++) { DBG(("%s: reloc[%d] = %d\n", __FUNCTION__, i, sna->render.vertex_reloc[i])); sna->kgem.batch[sna->render.vertex_reloc[i]] = kgem_add_reloc(&sna->kgem, sna->render.vertex_reloc[i], bo, I915_GEM_DOMAIN_VERTEX << 16, delta); } sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; if (sna->render.vbo == NULL) { assert(!sna->render.active); sna->render.vertex_used = 0; sna->render.vertex_index = 0; assert(sna->render.vertices == sna->render.vertex_data); assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data)); } if (free_bo) kgem_bo_destroy(&sna->kgem, free_bo); } /* specialised vertex emission routines */ #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) /* XXX assert(!too_large(x, y)); */ #define OUT_VERTEX_F(v) vertex_emit(sna, v) force_inline static float compute_linear(const struct sna_composite_channel *channel, int16_t x, int16_t y) { return ((x+channel->offset[0]) * channel->u.linear.dx + (y+channel->offset[1]) * channel->u.linear.dy + channel->u.linear.offset); } sse2 inline static void emit_texcoord(struct sna *sna, const struct sna_composite_channel *channel, int16_t x, int16_t y) { if (channel->is_solid) { OUT_VERTEX_F(0.5); return; } x += channel->offset[0]; y += channel->offset[1]; if (channel->is_affine) { float s, t; sna_get_transformed_coordinates(x, y, channel->transform, &s, &t); OUT_VERTEX_F(s * channel->scale[0]); OUT_VERTEX_F(t * channel->scale[1]); } else { float s, t, w; sna_get_transformed_coordinates_3d(x, y, channel->transform, &s, &t, &w); OUT_VERTEX_F(s * channel->scale[0]); OUT_VERTEX_F(t * channel->scale[1]); OUT_VERTEX_F(w); } } sse2 force_inline static void emit_vertex(struct sna *sna, const struct sna_composite_op *op, int16_t srcX, int16_t srcY, int16_t mskX, int16_t mskY, int16_t dstX, int16_t dstY) { OUT_VERTEX(dstX, dstY); emit_texcoord(sna, &op->src, srcX, srcY); } sse2 fastcall static void emit_primitive(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { emit_vertex(sna, op, r->src.x + r->width, r->src.y + r->height, r->mask.x + r->width, r->mask.y + r->height, r->dst.x + r->width, r->dst.y + r->height); emit_vertex(sna, op, r->src.x, r->src.y + r->height, r->mask.x, r->mask.y + r->height, r->dst.x, r->dst.y + r->height); emit_vertex(sna, op, r->src.x, r->src.y, r->mask.x, r->mask.y, r->dst.x, r->dst.y); } sse2 inline static float * vemit_texcoord(float *v, const struct sna_composite_channel *channel, int16_t x, int16_t y) { if (channel->is_solid) { *v++ = 0.5; } else { x += channel->offset[0]; y += channel->offset[1]; if (channel->is_affine) { float s, t; sna_get_transformed_coordinates(x, y, channel->transform, &s, &t); *v++ = s * channel->scale[0]; *v++ = t * channel->scale[1]; } else { float s, t, w; sna_get_transformed_coordinates_3d(x, y, channel->transform, &s, &t, &w); *v++ = s * channel->scale[0]; *v++ = t * channel->scale[1]; *v++ = w; } } return v; } sse2 force_inline static float * vemit_vertex(float *v, const struct sna_composite_op *op, int16_t x, int16_t y) { *v++ = pack_2s(x, y); return vemit_texcoord(v, &op->src, x, y); } sse2 fastcall static void emit_boxes(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v = vemit_vertex(v, op, box->x2, box->y2); v = vemit_vertex(v, op, box->x1, box->y2); v = vemit_vertex(v, op, box->x1, box->y1); box++; } while (--nbox); } sse2 force_inline static void emit_vertex_mask(struct sna *sna, const struct sna_composite_op *op, int16_t srcX, int16_t srcY, int16_t mskX, int16_t mskY, int16_t dstX, int16_t dstY) { OUT_VERTEX(dstX, dstY); emit_texcoord(sna, &op->src, srcX, srcY); emit_texcoord(sna, &op->mask, mskX, mskY); } sse2 fastcall static void emit_primitive_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { emit_vertex_mask(sna, op, r->src.x + r->width, r->src.y + r->height, r->mask.x + r->width, r->mask.y + r->height, r->dst.x + r->width, r->dst.y + r->height); emit_vertex_mask(sna, op, r->src.x, r->src.y + r->height, r->mask.x, r->mask.y + r->height, r->dst.x, r->dst.y + r->height); emit_vertex_mask(sna, op, r->src.x, r->src.y, r->mask.x, r->mask.y, r->dst.x, r->dst.y); } sse2 force_inline static float * vemit_vertex_mask(float *v, const struct sna_composite_op *op, int16_t x, int16_t y) { *v++ = pack_2s(x, y); v = vemit_texcoord(v, &op->src, x, y); v = vemit_texcoord(v, &op->mask, x, y); return v; } sse2 fastcall static void emit_boxes_mask(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { v = vemit_vertex_mask(v, op, box->x2, box->y2); v = vemit_vertex_mask(v, op, box->x1, box->y2); v = vemit_vertex_mask(v, op, box->x1, box->y1); box++; } while (--nbox); } sse2 fastcall static void emit_primitive_solid(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; assert(op->floats_per_rect == 6); assert((sna->render.vertex_used % 2) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[2] = dst.f; dst.p.y = r->dst.y; v[4] = dst.f; v[5] = v[3] = v[1] = .5; } sse2 fastcall static void emit_boxes_solid(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[2] = dst.f; dst.p.y = box->y1; v[4] = dst.f; v[5] = v[3] = v[1] = .5; box++; v += 6; } while (--nbox); } sse2 fastcall static void emit_primitive_linear(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; assert(op->floats_per_rect == 6); assert((sna->render.vertex_used % 2) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[2] = dst.f; dst.p.y = r->dst.y; v[4] = dst.f; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y); } sse2 fastcall static void emit_boxes_linear(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { union { struct sna_coordinate p; float f; } dst; do { dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[2] = dst.f; dst.p.y = box->y1; v[4] = dst.f; v[1] = compute_linear(&op->src, box->x2, box->y2); v[3] = compute_linear(&op->src, box->x1, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y1); v += 6; box++; } while (--nbox); } sse2 fastcall static void emit_primitive_identity_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[3] = dst.f; dst.p.y = r->dst.y; v[6] = dst.f; v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[1] = v[4] + r->width * op->src.scale[0]; v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[5] = v[2] = v[8] + r->height * op->src.scale[1]; } sse2 fastcall static void emit_boxes_identity_source(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; v += 9; box++; } while (--nbox); } sse2 fastcall static void emit_primitive_simple_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*3; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; dst.p.x = r->dst.x; v[3] = dst.f; v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; dst.p.y = r->dst.y; v[6] = dst.f; v[8] = ((r->src.y + ty) * yy + y0) * sy; } sse2 fastcall static void emit_boxes_simple_source(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[3] = dst.f; v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[6] = dst.f; v[8] = ((box->y1 + ty) * yy + y0) * sy; v += 9; box++; } while (--nbox); } sse2 fastcall static void emit_primitive_affine_source(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x + r->width, op->src.offset[1] + r->src.y + r->height, op->src.transform, op->src.scale, &v[1], &v[2]); dst.p.x = r->dst.x; v[3] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x, op->src.offset[1] + r->src.y + r->height, op->src.transform, op->src.scale, &v[4], &v[5]); dst.p.y = r->dst.y; v[6] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x, op->src.offset[1] + r->src.y, op->src.transform, op->src.scale, &v[7], &v[8]); } sse2 fastcall static void emit_boxes_affine_source(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + box->x2, op->src.offset[1] + box->y2, op->src.transform, op->src.scale, &v[1], &v[2]); dst.p.x = box->x1; v[3] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + box->x1, op->src.offset[1] + box->y2, op->src.transform, op->src.scale, &v[4], &v[5]); dst.p.y = box->y1; v[6] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + box->x1, op->src.offset[1] + box->y1, op->src.transform, op->src.scale, &v[7], &v[8]); box++; v += 9; } while (--nbox); } sse2 fastcall static void emit_primitive_identity_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; } sse2 fastcall static void emit_boxes_identity_mask(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; v += 12; box++; } while (--nbox); } sse2 fastcall static void emit_primitive_linear_identity_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[9] = compute_linear(&op->src, r->src.x, r->src.y); } sse2 fastcall static void emit_boxes_linear_identity_mask(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[1] = compute_linear(&op->src, box->x2, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y2); v[9] = compute_linear(&op->src, box->x1, box->y1); v += 12; box++; } while (--nbox); } sse2 fastcall static void emit_primitive_identity_source_mask(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float src_x, src_y; float msk_x, msk_y; float w, h; float *v; src_x = r->src.x + op->src.offset[0]; src_y = r->src.y + op->src.offset[1]; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; assert(op->floats_per_rect == 15); assert((sna->render.vertex_used % 5) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 15; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[1] = (src_x + w) * op->src.scale[0]; v[2] = (src_y + h) * op->src.scale[1]; v[3] = (msk_x + w) * op->mask.scale[0]; v[4] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[5] = dst.f; v[6] = src_x * op->src.scale[0]; v[7] = v[2]; v[8] = msk_x * op->mask.scale[0]; v[9] = v[4]; dst.p.y = r->dst.y; v[10] = dst.f; v[11] = v[6]; v[12] = src_y * op->src.scale[1]; v[13] = v[8]; v[14] = msk_y * op->mask.scale[1]; } sse2 fastcall static void emit_primitive_simple_source_identity(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; float msk_x = r->mask.x + op->mask.offset[0]; float msk_y = r->mask.y + op->mask.offset[1]; float w = r->width, h = r->height; assert(op->floats_per_rect == 15); assert((sna->render.vertex_used % 5) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*5; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; v[3] = (msk_x + w) * op->mask.scale[0]; v[4] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[5] = dst.f; v[6] = ((r->src.x + tx) * xx + x0) * sx; v[7] = v[2]; v[8] = msk_x * op->mask.scale[0]; v[9] = v[4]; dst.p.y = r->dst.y; v[10] = dst.f; v[11] = v[6]; v[12] = ((r->src.y + ty) * yy + y0) * sy; v[13] = v[8]; v[14] = msk_y * op->mask.scale[1]; } sse2 fastcall static void emit_primitive_affine_source_identity(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; float msk_x = r->mask.x + op->mask.offset[0]; float msk_y = r->mask.y + op->mask.offset[1]; float w = r->width, h = r->height; assert(op->floats_per_rect == 15); assert((sna->render.vertex_used % 5) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*5; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x + r->width, op->src.offset[1] + r->src.y + r->height, op->src.transform, op->src.scale, &v[1], &v[2]); v[3] = (msk_x + w) * op->mask.scale[0]; v[4] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[5] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x, op->src.offset[1] + r->src.y + r->height, op->src.transform, op->src.scale, &v[6], &v[7]); v[8] = msk_x * op->mask.scale[0]; v[9] = v[4]; dst.p.y = r->dst.y; v[10] = dst.f; _sna_get_transformed_scaled(op->src.offset[0] + r->src.x, op->src.offset[1] + r->src.y, op->src.transform, op->src.scale, &v[11], &v[12]); v[13] = v[8]; v[14] = msk_y * op->mask.scale[1]; } /* SSE4_2 */ #if defined(sse4_2) sse4_2 fastcall static void emit_primitive_linear__sse4_2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; assert(op->floats_per_rect == 6); assert((sna->render.vertex_used % 2) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[2] = dst.f; dst.p.y = r->dst.y; v[4] = dst.f; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y); } sse4_2 fastcall static void emit_boxes_linear__sse4_2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { union { struct sna_coordinate p; float f; } dst; do { dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[2] = dst.f; dst.p.y = box->y1; v[4] = dst.f; v[1] = compute_linear(&op->src, box->x2, box->y2); v[3] = compute_linear(&op->src, box->x1, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y1); v += 6; box++; } while (--nbox); } sse4_2 fastcall static void emit_primitive_identity_source__sse4_2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[3] = dst.f; dst.p.y = r->dst.y; v[6] = dst.f; v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[1] = v[4] + r->width * op->src.scale[0]; v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[5] = v[2] = v[8] + r->height * op->src.scale[1]; } sse4_2 fastcall static void emit_boxes_identity_source__sse4_2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; v += 9; box++; } while (--nbox); } sse4_2 fastcall static void emit_primitive_simple_source__sse4_2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*3; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; dst.p.x = r->dst.x; v[3] = dst.f; v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; dst.p.y = r->dst.y; v[6] = dst.f; v[8] = ((r->src.y + ty) * yy + y0) * sy; } sse4_2 fastcall static void emit_boxes_simple_source__sse4_2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[3] = dst.f; v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[6] = dst.f; v[8] = ((box->y1 + ty) * yy + y0) * sy; v += 9; box++; } while (--nbox); } sse4_2 fastcall static void emit_primitive_identity_mask__sse4_2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; } sse4_2 fastcall static void emit_boxes_identity_mask__sse4_2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; v += 12; box++; } while (--nbox); } sse4_2 fastcall static void emit_primitive_linear_identity_mask__sse4_2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[9] = compute_linear(&op->src, r->src.x, r->src.y); } sse4_2 fastcall static void emit_boxes_linear_identity_mask__sse4_2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[1] = compute_linear(&op->src, box->x2, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y2); v[9] = compute_linear(&op->src, box->x1, box->y1); v += 12; box++; } while (--nbox); } #endif /* AVX2 */ #if defined(avx2) avx2 fastcall static void emit_primitive_linear__avx2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; assert(op->floats_per_rect == 6); assert((sna->render.vertex_used % 2) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[2] = dst.f; dst.p.y = r->dst.y; v[4] = dst.f; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[3] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y); } avx2 fastcall static void emit_boxes_linear__avx2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { union { struct sna_coordinate p; float f; } dst; do { dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[2] = dst.f; dst.p.y = box->y1; v[4] = dst.f; v[1] = compute_linear(&op->src, box->x2, box->y2); v[3] = compute_linear(&op->src, box->x1, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y1); v += 6; box++; } while (--nbox); } avx2 fastcall static void emit_primitive_identity_source__avx2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; dst.p.x = r->dst.x; v[3] = dst.f; dst.p.y = r->dst.y; v[6] = dst.f; v[7] = v[4] = (r->src.x + op->src.offset[0]) * op->src.scale[0]; v[1] = v[4] + r->width * op->src.scale[0]; v[8] = (r->src.y + op->src.offset[1]) * op->src.scale[1]; v[5] = v[2] = v[8] + r->height * op->src.scale[1]; } avx2 fastcall static void emit_boxes_identity_source__avx2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[7] = v[4] = (box->x1 + op->src.offset[0]) * op->src.scale[0]; v[1] = (box->x2 + op->src.offset[0]) * op->src.scale[0]; v[8] = (box->y1 + op->src.offset[1]) * op->src.scale[1]; v[2] = v[5] = (box->y2 + op->src.offset[1]) * op->src.scale[1]; v += 9; box++; } while (--nbox); } avx2 fastcall static void emit_primitive_simple_source__avx2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; assert(op->floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*3; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[1] = ((r->src.x + r->width + tx) * xx + x0) * sx; v[5] = v[2] = ((r->src.y + r->height + ty) * yy + y0) * sy; dst.p.x = r->dst.x; v[3] = dst.f; v[7] = v[4] = ((r->src.x + tx) * xx + x0) * sx; dst.p.y = r->dst.y; v[6] = dst.f; v[8] = ((r->src.y + ty) * yy + y0) * sy; } avx2 fastcall static void emit_boxes_simple_source__avx2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float xx = op->src.transform->matrix[0][0]; float x0 = op->src.transform->matrix[0][2]; float yy = op->src.transform->matrix[1][1]; float y0 = op->src.transform->matrix[1][2]; float sx = op->src.scale[0]; float sy = op->src.scale[1]; int16_t tx = op->src.offset[0]; int16_t ty = op->src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[5] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[3] = dst.f; v[7] = v[4] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[6] = dst.f; v[8] = ((box->y1 + ty) * yy + y0) * sy; v += 9; box++; } while (--nbox); } avx2 fastcall static void emit_primitive_identity_mask__avx2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; } avx2 fastcall static void emit_boxes_identity_mask__avx2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[9] = v[5] = v[1] = .5; v += 12; box++; } while (--nbox); } avx2 fastcall static void emit_primitive_linear_identity_mask__avx2(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { union { struct sna_coordinate p; float f; } dst; float msk_x, msk_y; float w, h; float *v; msk_x = r->mask.x + op->mask.offset[0]; msk_y = r->mask.y + op->mask.offset[1]; w = r->width; h = r->height; DBG(("%s: dst=(%d, %d), mask=(%f, %f) x (%f, %f)\n", __FUNCTION__, r->dst.x, r->dst.y, msk_x, msk_y, w, h)); assert(op->floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = r->dst.x + r->width; dst.p.y = r->dst.y + r->height; v[0] = dst.f; v[2] = (msk_x + w) * op->mask.scale[0]; v[7] = v[3] = (msk_y + h) * op->mask.scale[1]; dst.p.x = r->dst.x; v[4] = dst.f; v[10] = v[6] = msk_x * op->mask.scale[0]; dst.p.y = r->dst.y; v[8] = dst.f; v[11] = msk_y * op->mask.scale[1]; v[1] = compute_linear(&op->src, r->src.x+r->width, r->src.y+r->height); v[5] = compute_linear(&op->src, r->src.x, r->src.y+r->height); v[9] = compute_linear(&op->src, r->src.x, r->src.y); } avx2 fastcall static void emit_boxes_linear_identity_mask__avx2(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v) { float msk_x = op->mask.offset[0]; float msk_y = op->mask.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[2] = (msk_x + box->x2) * op->mask.scale[0]; v[7] = v[3] = (msk_y + box->y2) * op->mask.scale[1]; dst.p.x = box->x1; v[4] = dst.f; v[10] = v[6] = (msk_x + box->x1) * op->mask.scale[0]; dst.p.y = box->y1; v[8] = dst.f; v[11] = (msk_y + box->y1) * op->mask.scale[1]; v[1] = compute_linear(&op->src, box->x2, box->y2); v[5] = compute_linear(&op->src, box->x1, box->y2); v[9] = compute_linear(&op->src, box->x1, box->y1); v += 12; box++; } while (--nbox); } #endif unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op *tmp) { unsigned vb; if (tmp->mask.bo) { if (tmp->mask.transform == NULL) { if (tmp->src.is_solid) { DBG(("%s: solid, identity mask\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_primitive_identity_mask__avx2; tmp->emit_boxes = emit_boxes_identity_mask__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_primitive_identity_mask__sse4_2; tmp->emit_boxes = emit_boxes_identity_mask__sse4_2; } else #endif { tmp->prim_emit = emit_primitive_identity_mask; tmp->emit_boxes = emit_boxes_identity_mask; } tmp->floats_per_vertex = 4; vb = 1 | 2 << 2; } else if (tmp->src.is_linear) { DBG(("%s: linear, identity mask\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_primitive_linear_identity_mask__avx2; tmp->emit_boxes = emit_boxes_linear_identity_mask__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_primitive_linear_identity_mask__sse4_2; tmp->emit_boxes = emit_boxes_linear_identity_mask__sse4_2; } else #endif { tmp->prim_emit = emit_primitive_linear_identity_mask; tmp->emit_boxes = emit_boxes_linear_identity_mask; } tmp->floats_per_vertex = 4; vb = 1 | 2 << 2; } else if (tmp->src.transform == NULL) { DBG(("%s: identity source, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_identity_source_mask; tmp->floats_per_vertex = 5; vb = 2 << 2 | 2; } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; if (!sna_affine_transform_is_rotation(tmp->src.transform)) { DBG(("%s: simple src, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_simple_source_identity; } else { DBG(("%s: affine src, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_affine_source_identity; } tmp->floats_per_vertex = 5; vb = 2 << 2 | 2; } else { DBG(("%s: projective source, identity mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_mask; tmp->floats_per_vertex = 6; vb = 2 << 2 | 3; } } else { tmp->prim_emit = emit_primitive_mask; tmp->emit_boxes = emit_boxes_mask; tmp->floats_per_vertex = 1; vb = 0; if (tmp->mask.is_solid) { tmp->floats_per_vertex += 1; vb |= 1 << 2; } else if (tmp->mask.is_affine) { tmp->floats_per_vertex += 2; vb |= 2 << 2; }else { tmp->floats_per_vertex += 3; vb |= 3 << 2; } if (tmp->src.is_solid) { tmp->floats_per_vertex += 1; vb |= 1; } else if (tmp->src.is_affine) { tmp->floats_per_vertex += 2; vb |= 2 ; }else { tmp->floats_per_vertex += 3; vb |= 3; } DBG(("%s: general mask: floats-per-vertex=%d, vb=%x\n", __FUNCTION__,tmp->floats_per_vertex, vb)); } } else { if (tmp->src.is_solid) { DBG(("%s: solid, no mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_solid; tmp->emit_boxes = emit_boxes_solid; if (tmp->src.is_opaque && tmp->op == PictOpOver) tmp->op = PictOpSrc; tmp->floats_per_vertex = 2; vb = 1; } else if (tmp->src.is_linear) { DBG(("%s: linear, no mask\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_primitive_linear__avx2; tmp->emit_boxes = emit_boxes_linear__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_primitive_linear__sse4_2; tmp->emit_boxes = emit_boxes_linear__sse4_2; } else #endif { tmp->prim_emit = emit_primitive_linear; tmp->emit_boxes = emit_boxes_linear; } tmp->floats_per_vertex = 2; vb = 1; } else if (tmp->src.transform == NULL) { DBG(("%s: identity src, no mask\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_primitive_identity_source__avx2; tmp->emit_boxes = emit_boxes_identity_source__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_primitive_identity_source__sse4_2; tmp->emit_boxes = emit_boxes_identity_source__sse4_2; } else #endif { tmp->prim_emit = emit_primitive_identity_source; tmp->emit_boxes = emit_boxes_identity_source; } tmp->floats_per_vertex = 3; vb = 2; } else if (tmp->src.is_affine) { tmp->src.scale[0] /= tmp->src.transform->matrix[2][2]; tmp->src.scale[1] /= tmp->src.transform->matrix[2][2]; if (!sna_affine_transform_is_rotation(tmp->src.transform)) { DBG(("%s: simple src, no mask\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_primitive_simple_source__avx2; tmp->emit_boxes = emit_boxes_simple_source__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_primitive_simple_source__sse4_2; tmp->emit_boxes = emit_boxes_simple_source__sse4_2; } else #endif { tmp->prim_emit = emit_primitive_simple_source; tmp->emit_boxes = emit_boxes_simple_source; } } else { DBG(("%s: affine src, no mask\n", __FUNCTION__)); tmp->prim_emit = emit_primitive_affine_source; tmp->emit_boxes = emit_boxes_affine_source; } tmp->floats_per_vertex = 3; vb = 2; } else { DBG(("%s: projective src, no mask\n", __FUNCTION__)); assert(!tmp->src.is_solid); tmp->prim_emit = emit_primitive; tmp->emit_boxes = emit_boxes; tmp->floats_per_vertex = 4; vb = 3; } } tmp->floats_per_rect = 3 * tmp->floats_per_vertex; return vb; } sse2 force_inline static void emit_span_vertex(struct sna *sna, const struct sna_composite_spans_op *op, int16_t x, int16_t y) { OUT_VERTEX(x, y); emit_texcoord(sna, &op->base.src, x, y); } sse2 fastcall static void emit_span_primitive(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { emit_span_vertex(sna, op, box->x2, box->y2); OUT_VERTEX_F(opacity); emit_span_vertex(sna, op, box->x1, box->y2); OUT_VERTEX_F(opacity); emit_span_vertex(sna, op, box->x1, box->y1); OUT_VERTEX_F(opacity); } sse2 fastcall static void emit_span_boxes(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { v = vemit_vertex(v, &op->base, b->box.x2, b->box.y2); *v++ = b->alpha; v = vemit_vertex(v, &op->base, b->box.x1, b->box.y2); *v++ = b->alpha; v = vemit_vertex(v, &op->base, b->box.x1, b->box.y1); *v++ = b->alpha; b++; } while (--nbox); } sse2 fastcall static void emit_span_solid(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; assert(op->base.floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*3; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[7] = v[4] = v[1] = .5; v[8] = v[5] = v[2] = opacity; } sse2 fastcall static void emit_span_boxes_solid(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; dst.p.x = b->box.x1; v[3] = dst.f; dst.p.y = b->box.y1; v[6] = dst.f; v[7] = v[4] = v[1] = .5; v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } sse2 fastcall static void emit_span_identity(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = (box->x2 + tx) * sx; v[6] = v[2] = (box->y2 + ty) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = (box->x1 + tx) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = (box->y1 + ty) * sy; v[11] = v[7] = v[3] = opacity; } sse2 fastcall static void emit_span_boxes_identity(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = (b->box.x2 + tx) * sx; v[6] = v[2] = (b->box.y2 + ty) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = (b->box.x1 + tx) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = (b->box.y1 + ty) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse2 fastcall static void emit_span_simple(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = ((box->y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = opacity; } sse2 fastcall static void emit_span_boxes_simple(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = ((b->box.x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((b->box.y2 + ty) * yy + y0) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = ((b->box.x1 + tx) * xx + x0) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = ((b->box.y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse2 fastcall static void emit_span_affine(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x2, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = box->x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = box->y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = opacity; } sse2 fastcall static void emit_span_boxes_affine(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x2, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = b->box.x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = b->box.y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse2 fastcall static void emit_span_linear(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, box->x2, box->y2); v[4] = compute_linear(&op->base.src, box->x1, box->y2); v[7] = compute_linear(&op->base.src, box->x1, box->y1); v[8] = v[5] = v[2] = opacity; } sse2 fastcall static void emit_span_boxes_linear(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; dst.p.x = b->box.x1; v[3] = dst.f; dst.p.y = b->box.y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, b->box.x2, b->box.y2); v[4] = compute_linear(&op->base.src, b->box.x1, b->box.y2); v[7] = compute_linear(&op->base.src, b->box.x1, b->box.y1); v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } /* SSE4_2 */ #if defined(sse4_2) sse4_2 fastcall static void emit_span_identity__sse4_2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = (box->x2 + tx) * sx; v[6] = v[2] = (box->y2 + ty) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = (box->x1 + tx) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = (box->y1 + ty) * sy; v[11] = v[7] = v[3] = opacity; } sse4_2 fastcall static void emit_span_boxes_identity__sse4_2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = (b->box.x2 + tx) * sx; v[6] = v[2] = (b->box.y2 + ty) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = (b->box.x1 + tx) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = (b->box.y1 + ty) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse4_2 fastcall static void emit_span_simple__sse4_2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = ((box->y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = opacity; } sse4_2 fastcall static void emit_span_boxes_simple__sse4_2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = ((b->box.x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((b->box.y2 + ty) * yy + y0) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = ((b->box.x1 + tx) * xx + x0) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = ((b->box.y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse4_2 fastcall static void emit_span_affine__sse4_2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x2, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = box->x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = box->y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = opacity; } sse4_2 fastcall static void emit_span_boxes_affine__sse4_2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x2, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = b->box.x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = b->box.y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } sse4_2 fastcall static void emit_span_linear__sse4_2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, box->x2, box->y2); v[4] = compute_linear(&op->base.src, box->x1, box->y2); v[7] = compute_linear(&op->base.src, box->x1, box->y1); v[8] = v[5] = v[2] = opacity; } sse4_2 fastcall static void emit_span_boxes_linear__sse4_2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; dst.p.x = b->box.x1; v[3] = dst.f; dst.p.y = b->box.y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, b->box.x2, b->box.y2); v[4] = compute_linear(&op->base.src, b->box.x1, b->box.y2); v[7] = compute_linear(&op->base.src, b->box.x1, b->box.y1); v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } #endif /* AVX2 */ #if defined(avx2) avx2 fastcall static void emit_span_identity__avx2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = (box->x2 + tx) * sx; v[6] = v[2] = (box->y2 + ty) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = (box->x1 + tx) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = (box->y1 + ty) * sy; v[11] = v[7] = v[3] = opacity; } avx2 fastcall static void emit_span_boxes_identity__avx2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = (b->box.x2 + tx) * sx; v[6] = v[2] = (b->box.y2 + ty) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = (b->box.x1 + tx) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = (b->box.y1 + ty) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } avx2 fastcall static void emit_span_simple__avx2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { float *v; union { struct sna_coordinate p; float f; } dst; float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 3*4; assert(sna->render.vertex_used <= sna->render.vertex_size); dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; v[1] = ((box->x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((box->y2 + ty) * yy + y0) * sy; dst.p.x = box->x1; v[4] = dst.f; v[9] = v[5] = ((box->x1 + tx) * xx + x0) * sx; dst.p.y = box->y1; v[8] = dst.f; v[10] = ((box->y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = opacity; } avx2 fastcall static void emit_span_boxes_simple__avx2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { float xx = op->base.src.transform->matrix[0][0]; float x0 = op->base.src.transform->matrix[0][2]; float yy = op->base.src.transform->matrix[1][1]; float y0 = op->base.src.transform->matrix[1][2]; float sx = op->base.src.scale[0]; float sy = op->base.src.scale[1]; int16_t tx = op->base.src.offset[0]; int16_t ty = op->base.src.offset[1]; do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; v[1] = ((b->box.x2 + tx) * xx + x0) * sx; v[6] = v[2] = ((b->box.y2 + ty) * yy + y0) * sy; dst.p.x = b->box.x1; v[4] = dst.f; v[9] = v[5] = ((b->box.x1 + tx) * xx + x0) * sx; dst.p.y = b->box.y1; v[8] = dst.f; v[10] = ((b->box.y1 + ty) * yy + y0) * sy; v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } avx2 fastcall static void emit_span_affine__avx2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 12); assert((sna->render.vertex_used % 4) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 12; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x2, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = box->x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = box->y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + box->x1, op->base.src.offset[1] + box->y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = opacity; } avx2 fastcall static void emit_span_boxes_affine__avx2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x2, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[1], &v[2]); dst.p.x = b->box.x1; v[4] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y2, op->base.src.transform, op->base.src.scale, &v[5], &v[6]); dst.p.y = b->box.y1; v[8] = dst.f; _sna_get_transformed_scaled(op->base.src.offset[0] + b->box.x1, op->base.src.offset[1] + b->box.y1, op->base.src.transform, op->base.src.scale, &v[9], &v[10]); v[11] = v[7] = v[3] = b->alpha; v += 12; b++; } while (--nbox); } avx2 fastcall static void emit_span_linear__avx2(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { union { struct sna_coordinate p; float f; } dst; float *v; assert(op->base.floats_per_rect == 9); assert((sna->render.vertex_used % 3) == 0); v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += 9; dst.p.x = box->x2; dst.p.y = box->y2; v[0] = dst.f; dst.p.x = box->x1; v[3] = dst.f; dst.p.y = box->y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, box->x2, box->y2); v[4] = compute_linear(&op->base.src, box->x1, box->y2); v[7] = compute_linear(&op->base.src, box->x1, box->y1); v[8] = v[5] = v[2] = opacity; } avx2 fastcall static void emit_span_boxes_linear__avx2(const struct sna_composite_spans_op *op, const struct sna_opacity_box *b, int nbox, float *v) { do { union { struct sna_coordinate p; float f; } dst; dst.p.x = b->box.x2; dst.p.y = b->box.y2; v[0] = dst.f; dst.p.x = b->box.x1; v[3] = dst.f; dst.p.y = b->box.y1; v[6] = dst.f; v[1] = compute_linear(&op->base.src, b->box.x2, b->box.y2); v[4] = compute_linear(&op->base.src, b->box.x1, b->box.y2); v[7] = compute_linear(&op->base.src, b->box.x1, b->box.y1); v[8] = v[5] = v[2] = b->alpha; v += 9; b++; } while (--nbox); } #endif unsigned gen4_choose_spans_emitter(struct sna *sna, struct sna_composite_spans_op *tmp) { unsigned vb; if (tmp->base.src.is_solid) { DBG(("%s: solid source\n", __FUNCTION__)); tmp->prim_emit = emit_span_solid; tmp->emit_boxes = emit_span_boxes_solid; tmp->base.floats_per_vertex = 3; vb = 1 << 2 | 1; } else if (tmp->base.src.is_linear) { DBG(("%s: linear source\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_span_linear__avx2; tmp->emit_boxes = emit_span_boxes_linear__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_span_linear__sse4_2; tmp->emit_boxes = emit_span_boxes_linear__sse4_2; } else #endif { tmp->prim_emit = emit_span_linear; tmp->emit_boxes = emit_span_boxes_linear; } tmp->base.floats_per_vertex = 3; vb = 1 << 2 | 1; } else if (tmp->base.src.transform == NULL) { DBG(("%s: identity transform\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_span_identity__avx2; tmp->emit_boxes = emit_span_boxes_identity__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_span_identity__sse4_2; tmp->emit_boxes = emit_span_boxes_identity__sse4_2; } else #endif { tmp->prim_emit = emit_span_identity; tmp->emit_boxes = emit_span_boxes_identity; } tmp->base.floats_per_vertex = 4; vb = 1 << 2 | 2; } else if (tmp->base.is_affine) { tmp->base.src.scale[0] /= tmp->base.src.transform->matrix[2][2]; tmp->base.src.scale[1] /= tmp->base.src.transform->matrix[2][2]; if (!sna_affine_transform_is_rotation(tmp->base.src.transform)) { DBG(("%s: simple (unrotated affine) transform\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_span_simple__avx2; tmp->emit_boxes = emit_span_boxes_simple__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_span_simple__sse4_2; tmp->emit_boxes = emit_span_boxes_simple__sse4_2; } else #endif { tmp->prim_emit = emit_span_simple; tmp->emit_boxes = emit_span_boxes_simple; } } else { DBG(("%s: affine transform\n", __FUNCTION__)); #if defined(avx2) if (sna->cpu_features & AVX2) { tmp->prim_emit = emit_span_affine__avx2; tmp->emit_boxes = emit_span_boxes_affine__avx2; } else #endif #if defined(sse4_2) if (sna->cpu_features & SSE4_2) { tmp->prim_emit = emit_span_affine__sse4_2; tmp->emit_boxes = emit_span_boxes_affine__sse4_2; } else #endif { tmp->prim_emit = emit_span_affine; tmp->emit_boxes = emit_span_boxes_affine; } } tmp->base.floats_per_vertex = 4; vb = 1 << 2 | 2; } else { DBG(("%s: projective transform\n", __FUNCTION__)); tmp->prim_emit = emit_span_primitive; tmp->emit_boxes = emit_span_boxes; tmp->base.floats_per_vertex = 5; vb = 1 << 2 | 3; } tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex; return vb; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen4_vertex.h000066400000000000000000000010021267532330400242370ustar00rootroot00000000000000#ifndef GEN4_VERTEX_H #define GEN4_VERTEX_H #include "compiler.h" #include "sna.h" #include "sna_render.h" void gen4_vertex_align(struct sna *sna, const struct sna_composite_op *op); void gen4_vertex_flush(struct sna *sna); int gen4_vertex_finish(struct sna *sna); void gen4_vertex_close(struct sna *sna); unsigned gen4_choose_composite_emitter(struct sna *sna, struct sna_composite_op *tmp); unsigned gen4_choose_spans_emitter(struct sna *sna, struct sna_composite_spans_op *tmp); #endif /* GEN4_VERTEX_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen5_render.c000066400000000000000000002657431267532330400242250ustar00rootroot00000000000000/* * Copyright © 2006,2008,2011 Intel Corporation * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Carl Worth * Keith Packard * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_video.h" #include "brw/brw.h" #include "gen5_render.h" #include "gen4_common.h" #include "gen4_source.h" #include "gen4_vertex.h" #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define PREFER_BLT_FILL 1 #define DBG_NO_STATE_CACHE 0 #define DBG_NO_SURFACE_CACHE 0 #define ALWAYS_FLUSH 0 #define MAX_3D_SIZE 8192 #define GEN5_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) /* Set up a default static partitioning of the URB, which is supposed to * allow anything we would want to do, at potentially lower performance. */ #define URB_CS_ENTRY_SIZE 1 #define URB_CS_ENTRIES 0 #define URB_VS_ENTRY_SIZE 1 #define URB_VS_ENTRIES 256 /* minimum of 8 */ #define URB_GS_ENTRY_SIZE 0 #define URB_GS_ENTRIES 0 #define URB_CLIP_ENTRY_SIZE 0 #define URB_CLIP_ENTRIES 0 #define URB_SF_ENTRY_SIZE 2 #define URB_SF_ENTRIES 64 /* * this program computes dA/dx and dA/dy for the texture coordinates along * with the base texture coordinate. It was extracted from the Mesa driver */ #define SF_KERNEL_NUM_GRF 16 #define SF_MAX_THREADS 48 #define PS_KERNEL_NUM_GRF 32 #define PS_MAX_THREADS 72 static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_argb.g5b" #include "exa_wm_yuv_rgb.g5b" #include "exa_wm_write.g5b" }; static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_xy.g5b" #include "exa_wm_src_affine.g5b" #include "exa_wm_src_sample_planar.g5b" #include "exa_wm_yuv_rgb.g5b" #include "exa_wm_write.g5b" }; #define NOKERNEL(kernel_enum, func, masked) \ [kernel_enum] = {func, 0, masked} #define KERNEL(kernel_enum, kernel, masked) \ [kernel_enum] = {&kernel, sizeof(kernel), masked} static const struct wm_kernel_info { const void *data; unsigned int size; bool has_mask; } wm_kernels[] = { NOKERNEL(WM_KERNEL, brw_wm_kernel__affine, false), NOKERNEL(WM_KERNEL_P, brw_wm_kernel__projective, false), NOKERNEL(WM_KERNEL_MASK, brw_wm_kernel__affine_mask, true), NOKERNEL(WM_KERNEL_MASK_P, brw_wm_kernel__projective_mask, true), NOKERNEL(WM_KERNEL_MASKCA, brw_wm_kernel__affine_mask_ca, true), NOKERNEL(WM_KERNEL_MASKCA_P, brw_wm_kernel__projective_mask_ca, true), NOKERNEL(WM_KERNEL_MASKSA, brw_wm_kernel__affine_mask_sa, true), NOKERNEL(WM_KERNEL_MASKSA_P, brw_wm_kernel__projective_mask_sa, true), NOKERNEL(WM_KERNEL_OPACITY, brw_wm_kernel__affine_opacity, true), NOKERNEL(WM_KERNEL_OPACITY_P, brw_wm_kernel__projective_opacity, true), KERNEL(WM_KERNEL_VIDEO_PLANAR, ps_kernel_planar_static, false), KERNEL(WM_KERNEL_VIDEO_PACKED, ps_kernel_packed_static, false), }; #undef KERNEL static const struct blendinfo { bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen5_blend_op[] = { /* Clear */ {0, GEN5_BLENDFACTOR_ZERO, GEN5_BLENDFACTOR_ZERO}, /* Src */ {0, GEN5_BLENDFACTOR_ONE, GEN5_BLENDFACTOR_ZERO}, /* Dst */ {0, GEN5_BLENDFACTOR_ZERO, GEN5_BLENDFACTOR_ONE}, /* Over */ {1, GEN5_BLENDFACTOR_ONE, GEN5_BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {0, GEN5_BLENDFACTOR_INV_DST_ALPHA, GEN5_BLENDFACTOR_ONE}, /* In */ {0, GEN5_BLENDFACTOR_DST_ALPHA, GEN5_BLENDFACTOR_ZERO}, /* InReverse */ {1, GEN5_BLENDFACTOR_ZERO, GEN5_BLENDFACTOR_SRC_ALPHA}, /* Out */ {0, GEN5_BLENDFACTOR_INV_DST_ALPHA, GEN5_BLENDFACTOR_ZERO}, /* OutReverse */ {1, GEN5_BLENDFACTOR_ZERO, GEN5_BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, GEN5_BLENDFACTOR_DST_ALPHA, GEN5_BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, GEN5_BLENDFACTOR_INV_DST_ALPHA, GEN5_BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, GEN5_BLENDFACTOR_INV_DST_ALPHA, GEN5_BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, GEN5_BLENDFACTOR_ONE, GEN5_BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in gen5_blend_op. * * This leaves out GEN5_BLENDFACTOR_INV_DST_COLOR, * GEN5_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * GEN5_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define GEN5_BLENDFACTOR_COUNT (GEN5_BLENDFACTOR_INV_DST_ALPHA + 1) #define BLEND_OFFSET(s, d) \ (((s) * GEN5_BLENDFACTOR_COUNT + (d)) * 64) #define SAMPLER_OFFSET(sf, se, mf, me, k) \ ((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * KERNEL_COUNT + (k)) * 64) static bool gen5_emit_pipelined_pointers(struct sna *sna, const struct sna_composite_op *op, int blend, int kernel); #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) #define OUT_VERTEX_F(v) vertex_emit(sna, v) static inline bool too_large(int width, int height) { return width > MAX_3D_SIZE || height > MAX_3D_SIZE; } static int gen5_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine) { int base; if (has_mask) { if (is_ca) { if (gen5_blend_op[op].src_alpha) base = WM_KERNEL_MASKSA; else base = WM_KERNEL_MASKCA; } else base = WM_KERNEL_MASK; } else base = WM_KERNEL; return base + !is_affine; } static bool gen5_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { struct gen5_render_state *state = &sna->render_state.gen5; if (!op->need_magic_ca_pass) return false; assert(sna->render.vertex_index > sna->render.vertex_start); DBG(("%s: CA fixup\n", __FUNCTION__)); assert(op->mask.bo != NULL); assert(op->has_component_alpha); gen5_emit_pipelined_pointers (sna, op, PictOpAdd, gen5_choose_composite_kernel(PictOpAdd, true, true, op->is_affine)); OUT_BATCH(GEN5_3DPRIMITIVE | GEN5_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << GEN5_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | 4); OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start); OUT_BATCH(sna->render.vertex_start); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ state->last_primitive = sna->kgem.nbatch; return true; } static uint32_t gen5_get_blend(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t src, dst; src = gen5_blend_op[op].src_blend; dst = gen5_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (src == GEN5_BLENDFACTOR_DST_ALPHA) src = GEN5_BLENDFACTOR_ONE; else if (src == GEN5_BLENDFACTOR_INV_DST_ALPHA) src = GEN5_BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a * case where the source blend factor is 0, and the source blend * value is the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen5_blend_op[op].src_alpha) { if (dst == GEN5_BLENDFACTOR_SRC_ALPHA) dst = GEN5_BLENDFACTOR_SRC_COLOR; else if (dst == GEN5_BLENDFACTOR_INV_SRC_ALPHA) dst = GEN5_BLENDFACTOR_INV_SRC_COLOR; } DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n", op, dst_format, PICT_FORMAT_A(dst_format), src, dst, BLEND_OFFSET(src, dst))); return BLEND_OFFSET(src, dst); } static uint32_t gen5_get_card_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_x8r8g8b8: return GEN5_SURFACEFORMAT_B8G8R8X8_UNORM; case PICT_a8b8g8r8: return GEN5_SURFACEFORMAT_R8G8B8A8_UNORM; case PICT_x8b8g8r8: return GEN5_SURFACEFORMAT_R8G8B8X8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM; case PICT_x2r10g10b10: return GEN5_SURFACEFORMAT_B10G10R10X2_UNORM; #endif case PICT_r8g8b8: return GEN5_SURFACEFORMAT_R8G8B8_UNORM; case PICT_r5g6b5: return GEN5_SURFACEFORMAT_B5G6R5_UNORM; case PICT_a1r5g5b5: return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN5_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: return GEN5_SURFACEFORMAT_B4G4R4A4_UNORM; } } static uint32_t gen5_get_dest_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return GEN5_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return GEN5_SURFACEFORMAT_R8G8B8A8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return GEN5_SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return GEN5_SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return GEN5_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN5_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return GEN5_SURFACEFORMAT_B4G4R4A4_UNORM; } } static bool gen5_check_dst_format(PictFormat format) { if (gen5_get_dest_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static bool gen5_check_format(uint32_t format) { if (gen5_get_card_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } typedef struct gen5_surface_state_padded { struct gen5_surface_state state; char pad[32 - sizeof(struct gen5_surface_state)]; } gen5_surface_state_padded; static void null_create(struct sna_static_stream *stream) { /* A bunch of zeros useful for legacy border color and depth-stencil */ sna_static_stream_map(stream, 64, 64); } static void sampler_state_init(struct gen5_sampler_state *sampler_state, sampler_filter_t filter, sampler_extend_t extend) { sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.border_color_mode = GEN5_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SAMPLER_FILTER_NEAREST: sampler_state->ss0.min_filter = GEN5_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = GEN5_MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: sampler_state->ss0.min_filter = GEN5_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = GEN5_MAPFILTER_LINEAR; break; } switch (extend) { default: case SAMPLER_EXTEND_NONE: sampler_state->ss1.r_wrap_mode = GEN5_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.s_wrap_mode = GEN5_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.t_wrap_mode = GEN5_TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: sampler_state->ss1.r_wrap_mode = GEN5_TEXCOORDMODE_WRAP; sampler_state->ss1.s_wrap_mode = GEN5_TEXCOORDMODE_WRAP; sampler_state->ss1.t_wrap_mode = GEN5_TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: sampler_state->ss1.r_wrap_mode = GEN5_TEXCOORDMODE_CLAMP; sampler_state->ss1.s_wrap_mode = GEN5_TEXCOORDMODE_CLAMP; sampler_state->ss1.t_wrap_mode = GEN5_TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: sampler_state->ss1.r_wrap_mode = GEN5_TEXCOORDMODE_MIRROR; sampler_state->ss1.s_wrap_mode = GEN5_TEXCOORDMODE_MIRROR; sampler_state->ss1.t_wrap_mode = GEN5_TEXCOORDMODE_MIRROR; break; } } static uint32_t gen5_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return SAMPLER_FILTER_NEAREST; case PictFilterBilinear: return SAMPLER_FILTER_BILINEAR; } } static uint32_t gen5_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: DBG(("%s: unknown filter: %x\n", __FUNCTION__, picture->filter)); return false; } } static uint32_t gen5_repeat(uint32_t repeat) { switch (repeat) { default: assert(0); case RepeatNone: return SAMPLER_EXTEND_NONE; case RepeatNormal: return SAMPLER_EXTEND_REPEAT; case RepeatPad: return SAMPLER_EXTEND_PAD; case RepeatReflect: return SAMPLER_EXTEND_REFLECT; } } static bool gen5_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: DBG(("%s: unknown repeat: %x\n", __FUNCTION__, picture->repeatType)); return false; } } static uint32_t gen5_tiling_bits(uint32_t tiling) { switch (tiling) { default: assert(0); case I915_TILING_NONE: return 0; case I915_TILING_X: return GEN5_SURFACE_TILED; case I915_TILING_Y: return GEN5_SURFACE_TILED | GEN5_SURFACE_TILED_Y; } } /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static uint32_t gen5_bind_bo(struct sna *sna, struct kgem_bo *bo, uint32_t width, uint32_t height, uint32_t format, bool is_dst) { uint32_t domains; uint16_t offset; uint32_t *ss; /* After the first bind, we manage the cache domains within the batch */ if (!DBG_NO_SURFACE_CACHE) { offset = kgem_bo_get_binding(bo, format | is_dst << 31); if (offset) { if (is_dst) kgem_bo_mark_dirty(bo); assert(offset >= sna->kgem.surface); return offset * sizeof(uint32_t); } } offset = sna->kgem.surface -= sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); ss = sna->kgem.batch + offset; ss[0] = (GEN5_SURFACE_2D << GEN5_SURFACE_TYPE_SHIFT | GEN5_SURFACE_BLEND_ENABLED | format << GEN5_SURFACE_FORMAT_SHIFT); if (is_dst) { ss[0] |= GEN5_SURFACE_RC_READ_WRITE; domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER; } else domains = I915_GEM_DOMAIN_SAMPLER << 16; ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); ss[2] = ((width - 1) << GEN5_SURFACE_WIDTH_SHIFT | (height - 1) << GEN5_SURFACE_HEIGHT_SHIFT); ss[3] = (gen5_tiling_bits(bo->tiling) | (bo->pitch - 1) << GEN5_SURFACE_PITCH_SHIFT); ss[4] = 0; ss[5] = 0; kgem_bo_set_binding(bo, format | is_dst << 31, offset); DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n", offset, bo->handle, ss[1], format, width, height, bo->pitch, bo->tiling, domains & 0xffff ? "render" : "sampler")); return offset * sizeof(uint32_t); } static void gen5_emit_vertex_buffer(struct sna *sna, const struct sna_composite_op *op) { int id = op->u.gen5.ve_id; assert((sna->render.vb_id & (1 << id)) == 0); OUT_BATCH(GEN5_3DSTATE_VERTEX_BUFFERS | 3); OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA | (4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT)); assert(sna->render.nvertex_reloc < ARRAY_SIZE(sna->render.vertex_reloc)); sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch; OUT_BATCH(0); OUT_BATCH(~0); /* max address: disabled */ OUT_BATCH(0); sna->render.vb_id |= 1 << id; } static void gen5_emit_primitive(struct sna *sna) { if (sna->kgem.nbatch == sna->render_state.gen5.last_primitive) { sna->render.vertex_offset = sna->kgem.nbatch - 5; return; } OUT_BATCH(GEN5_3DPRIMITIVE | GEN5_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << GEN5_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | 4); sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(sna->render.vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ sna->render.vertex_start = sna->render.vertex_index; sna->render_state.gen5.last_primitive = sna->kgem.nbatch; } static bool gen5_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { int id = op->u.gen5.ve_id; int ndwords; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; ndwords = op->need_magic_ca_pass ? 20 : 6; if ((sna->render.vb_id & (1 << id)) == 0) ndwords += 5; if (!kgem_check_batch(&sna->kgem, ndwords)) return false; if ((sna->render.vb_id & (1 << id)) == 0) gen5_emit_vertex_buffer(sna, op); if (sna->render.vertex_offset == 0) gen5_emit_primitive(sna); return true; } static int gen5_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 40 : 6)) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 2)) return 0; if (sna->render.vertex_offset) { gen4_vertex_flush(sna); if (gen5_magic_ca_pass(sna, op)) gen5_emit_pipelined_pointers(sna, op, op->op, op->u.gen5.wm_kernel); } return gen4_vertex_finish(sna); } inline static int gen5_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want, void (*emit_state)(struct sna *sna, const struct sna_composite_op *op)) { int rem; assert(want); start: rem = vertex_space(sna); if (unlikely(rem < op->floats_per_rect)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen5_get_rectangles__flush(sna, op); if (unlikely (rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen5_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; sna->render.vertex_index += 3*want; return want; flush: if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen5_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); emit_state(sna, op); goto start; } static uint32_t * gen5_composite_get_binding_table(struct sna *sna, uint16_t *offset) { sna->kgem.surface -= sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface)); /* Clear all surplus entries to zero in case of prefetch */ *offset = sna->kgem.surface; return memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(struct gen5_surface_state_padded)); } static void gen5_emit_urb(struct sna *sna) { int urb_vs_start, urb_vs_size; int urb_gs_start, urb_gs_size; int urb_clip_start, urb_clip_size; int urb_sf_start, urb_sf_size; int urb_cs_start, urb_cs_size; urb_vs_start = 0; urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; urb_gs_start = urb_vs_start + urb_vs_size; urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE; urb_clip_start = urb_gs_start + urb_gs_size; urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE; urb_sf_start = urb_clip_start + urb_clip_size; urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE; urb_cs_start = urb_sf_start + urb_sf_size; urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; OUT_BATCH(GEN5_URB_FENCE | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) | ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) | ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT)); OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) | ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT)); /* Constant buffer state */ OUT_BATCH(GEN5_CS_URB_STATE | 0); OUT_BATCH((URB_CS_ENTRY_SIZE - 1) << 4 | URB_CS_ENTRIES << 0); } static void gen5_emit_state_base_address(struct sna *sna) { assert(sna->render_state.gen5.general_bo->proxy == NULL); OUT_BATCH(GEN5_STATE_BASE_ADDRESS | 6); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* general */ sna->kgem.nbatch, sna->render_state.gen5.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */ sna->kgem.nbatch, NULL, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(0); /* media */ OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */ sna->kgem.nbatch, sna->render_state.gen5.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); /* upper bounds, all disabled */ OUT_BATCH(BASE_ADDRESS_MODIFY); OUT_BATCH(0); OUT_BATCH(BASE_ADDRESS_MODIFY); } static void gen5_emit_invariant(struct sna *sna) { /* Ironlake errata workaround: Before disabling the clipper, * you have to MI_FLUSH to get the pipeline idle. * * However, the kernel flushes the pipeline between batches, * so we should be safe.... * * On the other hand, after using BLT we must use a non-pipelined * operation... */ if (sna->kgem.nreloc) OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); OUT_BATCH(GEN5_PIPELINE_SELECT | PIPELINE_SELECT_3D); gen5_emit_state_base_address(sna); sna->render_state.gen5.needs_invariant = false; } static void gen5_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch, 150, 4*8)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen5.needs_invariant) gen5_emit_invariant(sna); } static void gen5_align_vertex(struct sna *sna, const struct sna_composite_op *op) { assert(op->floats_per_rect == 3*op->floats_per_vertex); if (op->floats_per_vertex != sna->render_state.gen5.floats_per_vertex) { DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen5.floats_per_vertex, op->floats_per_vertex)); gen4_vertex_align(sna, op); sna->render_state.gen5.floats_per_vertex = op->floats_per_vertex; } } static void gen5_emit_binding_table(struct sna *sna, uint16_t offset) { if (!DBG_NO_STATE_CACHE && sna->render_state.gen5.surface_table == offset) return; sna->render_state.gen5.surface_table = offset; /* Binding table pointers */ OUT_BATCH(GEN5_3DSTATE_BINDING_TABLE_POINTERS | 4); OUT_BATCH(0); /* vs */ OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ /* Only the PS uses the binding table */ OUT_BATCH(offset*4); } static bool gen5_emit_pipelined_pointers(struct sna *sna, const struct sna_composite_op *op, int blend, int kernel) { uint16_t sp, bp; uint32_t key; DBG(("%s: has_mask=%d, src=(%d, %d), mask=(%d, %d),kernel=%d, blend=%d, ca=%d, format=%x\n", __FUNCTION__, op->u.gen5.ve_id & 2, op->src.filter, op->src.repeat, op->mask.filter, op->mask.repeat, kernel, blend, op->has_component_alpha, (int)op->dst.format)); sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat, op->mask.filter, op->mask.repeat, kernel); bp = gen5_get_blend(blend, op->has_component_alpha, op->dst.format); key = sp | (uint32_t)bp << 16 | (op->mask.bo != NULL) << 31; DBG(("%s: sp=%d, bp=%d, key=%08x (current sp=%d, bp=%d, key=%08x)\n", __FUNCTION__, sp, bp, key, sna->render_state.gen5.last_pipelined_pointers & 0xffff, (sna->render_state.gen5.last_pipelined_pointers >> 16) & 0x7fff, sna->render_state.gen5.last_pipelined_pointers)); if (key == sna->render_state.gen5.last_pipelined_pointers) return false; OUT_BATCH(GEN5_3DSTATE_PIPELINED_POINTERS | 5); OUT_BATCH(sna->render_state.gen5.vs); OUT_BATCH(GEN5_GS_DISABLE); /* passthrough */ OUT_BATCH(GEN5_CLIP_DISABLE); /* passthrough */ OUT_BATCH(sna->render_state.gen5.sf[op->mask.bo != NULL]); OUT_BATCH(sna->render_state.gen5.wm + sp); OUT_BATCH(sna->render_state.gen5.cc + bp); bp = (sna->render_state.gen5.last_pipelined_pointers & 0x7fff0000) != ((uint32_t)bp << 16); sna->render_state.gen5.last_pipelined_pointers = key; gen5_emit_urb(sna); return bp; } static bool gen5_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; assert(!too_large(abs(op->dst.x), abs(op->dst.y))); assert(!too_large(op->dst.width, op->dst.height)); if (!DBG_NO_STATE_CACHE && sna->render_state.gen5.drawrect_limit == limit && sna->render_state.gen5.drawrect_offset == offset) return false; sna->render_state.gen5.drawrect_offset = offset; sna->render_state.gen5.drawrect_limit = limit; OUT_BATCH(GEN5_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0x00000000); OUT_BATCH(limit); OUT_BATCH(offset); return true; } static void gen5_emit_vertex_elements(struct sna *sna, const struct sna_composite_op *op) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0) * texture coordinate 1 if (has_mask is true): same as above */ struct gen5_render_state *render = &sna->render_state.gen5; int id = op->u.gen5.ve_id; bool has_mask = id >> 2; uint32_t format, dw; if (!DBG_NO_STATE_CACHE && render->ve_id == id) return; DBG(("%s: changing %d -> %d\n", __FUNCTION__, render->ve_id, id)); render->ve_id = id; /* The VUE layout * dword 0-3: pad (0.0, 0.0, 0.0. 0.0) * dword 4-7: position (x, y, 1.0, 1.0), * dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0) * dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0) * * dword 4-15 are fetched from vertex buffer */ OUT_BATCH(GEN5_3DSTATE_VERTEX_ELEMENTS | ((2 * (has_mask ? 4 : 3)) + 1 - 2)); OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) | (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) | (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) | (VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT)); /* x,y */ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT | 0 << VE0_OFFSET_SHIFT); OUT_BATCH(VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT | VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT | VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT | VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT); /* u0, v0, w0 */ DBG(("%s: id=%d, first channel %d floats, offset=4b\n", __FUNCTION__, id, id & 3)); dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id & 3) { default: assert(0); case 0: format = GEN5_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 1: format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 2: format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 3: format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | format | 4 << VE0_OFFSET_SHIFT); OUT_BATCH(dw); /* u1, v1, w1 */ if (has_mask) { unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float); DBG(("%s: id=%x, second channel %d floats, offset=%db\n", __FUNCTION__, id, id >> 2, offset)); dw = VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id >> 2) { case 1: format = GEN5_SURFACEFORMAT_R32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; default: assert(0); case 2: format = GEN5_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT; break; case 3: format = GEN5_SURFACEFORMAT_R32G32B32_FLOAT << VE0_FORMAT_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | format | offset << VE0_OFFSET_SHIFT); OUT_BATCH(dw); } } inline static void gen5_emit_pipe_flush(struct sna *sna) { #if 1 OUT_BATCH(GEN5_PIPE_CONTROL | GEN5_PIPE_CONTROL_WC_FLUSH | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #else OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); #endif } static void gen5_emit_state(struct sna *sna, const struct sna_composite_op *op, uint16_t offset) { bool flush = false; assert(op->dst.bo->exec); /* drawrect must be first for Ironlake BLT workaround */ if (gen5_emit_drawing_rectangle(sna, op)) offset &= ~1; gen5_emit_binding_table(sna, offset & ~1); if (gen5_emit_pipelined_pointers(sna, op, op->op, op->u.gen5.wm_kernel)){ DBG(("%s: changed blend state, flush required? %d\n", __FUNCTION__, (offset & 1) && op->op > PictOpSrc)); flush = (offset & 1) && op->op > PictOpSrc; } gen5_emit_vertex_elements(sna, op); if (ALWAYS_FLUSH || kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { DBG(("%s: flushing dirty (%d, %d)\n", __FUNCTION__, kgem_bo_is_dirty(op->src.bo), kgem_bo_is_dirty(op->mask.bo))); OUT_BATCH(MI_FLUSH); kgem_clear_dirty(&sna->kgem); kgem_bo_mark_dirty(op->dst.bo); flush = false; } if (flush) { DBG(("%s: forcing flush\n", __FUNCTION__)); gen5_emit_pipe_flush(sna); } } static void gen5_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { bool dirty = kgem_bo_is_dirty(op->dst.bo); uint32_t *binding_table; uint16_t offset; gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); binding_table[0] = gen5_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen5_get_dest_format(op->dst.format), true); binding_table[1] = gen5_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (op->mask.bo) { assert(op->u.gen5.ve_id >> 2); binding_table[2] = gen5_bind_bo(sna, op->mask.bo, op->mask.width, op->mask.height, op->mask.card_format, false); } if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen5.surface_table) == *(uint64_t*)binding_table && (op->mask.bo == NULL || sna->kgem.batch[sna->render_state.gen5.surface_table+2] == binding_table[2])) { sna->kgem.surface += sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen5.surface_table; } gen5_emit_state(sna, op, offset | dirty); } fastcall static void gen5_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, op->src.offset[0], op->src.offset[1], r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1], r->dst.x, r->dst.y, op->dst.x, op->dst.y, r->width, r->height)); gen5_get_rectangles(sna, op, 1, gen5_bind_surfaces); op->prim_emit(sna, op, r); } fastcall static void gen5_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen5_get_rectangles(sna, op, 1, gen5_bind_surfaces); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.mask = r.src = r.dst; op->prim_emit(sna, op, &r); } static void gen5_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s(%d) delta=(%d, %d), src=(%d, %d)/(%d, %d), mask=(%d, %d)/(%d, %d)\n", __FUNCTION__, nbox, op->dst.x, op->dst.y, op->src.offset[0], op->src.offset[1], op->src.width, op->src.height, op->mask.offset[0], op->mask.offset[1], op->mask.width, op->mask.height)); do { int nbox_this_time; nbox_this_time = gen5_get_rectangles(sna, op, nbox, gen5_bind_surfaces); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.mask = r.src = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen5_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen5_get_rectangles(sna, op, nbox, gen5_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } static void gen5_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen5_get_rectangles(sna, op, nbox, gen5_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif static uint32_t gen5_bind_video_source(struct sna *sna, struct kgem_bo *src_bo, uint32_t src_offset, int src_width, int src_height, int src_pitch, uint32_t src_surf_format) { struct gen5_surface_state *ss; sna->kgem.surface -= sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss)); ss->ss0.surface_type = GEN5_SURFACE_2D; ss->ss0.surface_format = src_surf_format; ss->ss0.color_blend = 1; ss->ss1.base_addr = kgem_add_reloc(&sna->kgem, sna->kgem.surface + 1, src_bo, I915_GEM_DOMAIN_SAMPLER << 16, src_offset); ss->ss2.width = src_width - 1; ss->ss2.height = src_height - 1; ss->ss3.pitch = src_pitch - 1; return sna->kgem.surface * sizeof(uint32_t); } static void gen5_video_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { bool dirty = kgem_bo_is_dirty(op->dst.bo); struct sna_video_frame *frame = op->priv; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; uint32_t *binding_table; uint16_t offset; int n_src, n; src_surf_base[0] = 0; src_surf_base[1] = 0; src_surf_base[2] = frame->VBufOffset; src_surf_base[3] = frame->VBufOffset; src_surf_base[4] = frame->UBufOffset; src_surf_base[5] = frame->UBufOffset; if (is_planar_fourcc(frame->id)) { src_surf_format = GEN5_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = frame->width; src_height[1] = src_height[0] = frame->height; src_pitch[1] = src_pitch[0] = frame->pitch[1]; src_width[4] = src_width[5] = src_width[2] = src_width[3] = frame->width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = frame->height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = frame->pitch[0]; n_src = 6; } else { if (frame->id == FOURCC_UYVY) src_surf_format = GEN5_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = GEN5_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = frame->width; src_height[0] = frame->height; src_pitch[0] = frame->pitch[0]; n_src = 1; } gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); binding_table[0] = gen5_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen5_get_dest_format(op->dst.format), true); for (n = 0; n < n_src; n++) { binding_table[1+n] = gen5_bind_video_source(sna, frame->bo, src_surf_base[n], src_width[n], src_height[n], src_pitch[n], src_surf_format); } gen5_emit_state(sna, op, offset | dirty); } static bool gen5_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_composite_op tmp; struct sna_pixmap *priv = sna_pixmap(pixmap); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; const BoxRec *box; int nbox; DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_width, src_height, dst_width, dst_height)); assert(priv->gpu_bo); memset(&tmp, 0, sizeof(tmp)); tmp.op = PictOpSrc; tmp.dst.pixmap = pixmap; tmp.dst.width = pixmap->drawable.width; tmp.dst.height = pixmap->drawable.height; tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; if (src_width == dst_width && src_height == dst_height) tmp.src.filter = SAMPLER_FILTER_NEAREST; else tmp.src.filter = SAMPLER_FILTER_BILINEAR; tmp.src.repeat = SAMPLER_EXTEND_PAD; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; tmp.u.gen5.wm_kernel = is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED; tmp.u.gen5.ve_id = 2; tmp.is_affine = true; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; tmp.priv = frame; if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) return false; } gen5_align_vertex(sna, &tmp); gen5_video_bind_surfaces(sna, &tmp); src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; box = region_rects(dstRegion); nbox = region_num_rects(dstRegion); while (nbox--) { gen5_get_rectangles(sna, &tmp, 1, gen5_video_bind_surfaces); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); box++; } gen4_vertex_flush(sna); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } static int gen5_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->is_solid = false; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen4_channel_init_linear(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen5_check_repeat(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (!gen5_check_filter(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat || (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen4_channel_init_solid(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; channel->pict_format = picture->format; channel->card_format = gen5_get_card_format(picture->format); if (channel->card_format == -1) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s: pixmap, repeat=%d, filter=%d, transform?=%d [affine? %d], format=%08x\n", __FUNCTION__, channel->repeat, channel->filter, channel->transform != NULL, channel->is_affine, channel->pict_format)); if (channel->transform) { DBG(("%s: transform=[%f %f %f, %f %f %f, %f %f %f]\n", __FUNCTION__, channel->transform->matrix[0][0] / 65536., channel->transform->matrix[0][1] / 65536., channel->transform->matrix[0][2] / 65536., channel->transform->matrix[1][0] / 65536., channel->transform->matrix[1][1] / 65536., channel->transform->matrix[1][2] / 65536., channel->transform->matrix[2][0] / 65536., channel->transform->matrix[2][1] / 65536., channel->transform->matrix[2][2] / 65536.)); } return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } static void gen5_composite_channel_convert(struct sna_composite_channel *channel) { channel->repeat = gen5_repeat(channel->repeat); channel->filter = gen5_filter(channel->filter); if (channel->card_format == (unsigned)-1) channel->card_format = gen5_get_card_format(channel->pict_format); } static void gen5_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen5_magic_ca_pass(sna,op); } DBG(("%s()\n", __FUNCTION__)); if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } static bool gen5_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned hint; op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; op->dst.format = dst->format; if (w && h) { box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (too_large(op->dst.width, op->dst.height) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool is_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(struct sna *sna, PicturePtr p) { return p->pDrawable && untransformed(p) && !is_gpu(sna, p->pDrawable, PREFER_GPU_RENDER); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(struct sna *sna, PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (is_gradient(p, precise) || !gen5_check_repeat(p) || !gen5_check_format(p->format)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen5_check_filter(p) || need_upload(sna, p); } static bool gen5_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen5_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(sna, src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(sna, mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (sna_picture_is_solid(mask, &color)) return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen5_check_repeat(mask)) return false; if (!gen5_check_filter(mask)) return false; if (!gen5_check_format(mask->format)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen5_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen5_filter(mask->filter); mc->pict_format = mask->format; mc->card_format = gen5_get_card_format(mask->format); mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen5_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, width, height, sna->kgem.mode)); if (op >= ARRAY_SIZE(gen5_blend_op)) { DBG(("%s: unhandled blend op %d\n", __FUNCTION__, op)); return false; } if (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen5_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, tmp); if (!gen5_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) { DBG(("%s: failed to set composite target\n", __FUNCTION__)); goto fallback; } DBG(("%s: preparing source\n", __FUNCTION__)); tmp->op = op; switch (gen5_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: failed to prepare source picture\n", __FUNCTION__)); goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: if (mask == NULL && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; gen5_composite_channel_convert(&tmp->src); break; } tmp->is_affine = tmp->src.is_affine; tmp->has_component_alpha = false; tmp->need_magic_ca_pass = false; if (mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { tmp->has_component_alpha = true; /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (gen5_blend_op[op].src_alpha && (gen5_blend_op[op].src_blend != GEN5_BLENDFACTOR_ZERO)) { if (op != PictOpOver) { DBG(("%s: unhandled CA blend op %d\n", __FUNCTION__, op)); goto cleanup_src; } tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, msk_x, msk_y)) { DBG(("%s: preparing mask\n", __FUNCTION__)); switch (gen5_composite_picture(sna, mask, &tmp->mask, msk_x, msk_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: DBG(("%s: failed to prepare mask picture\n", __FUNCTION__)); goto cleanup_src; case 0: if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: gen5_composite_channel_convert(&tmp->mask); break; } } tmp->is_affine &= tmp->mask.is_affine; } tmp->u.gen5.wm_kernel = gen5_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine); tmp->u.gen5.ve_id = gen4_choose_composite_emitter(sna, tmp); tmp->blt = gen5_render_composite_blt; tmp->box = gen5_render_composite_box; tmp->boxes = gen5_render_composite_boxes__blt; if (tmp->emit_boxes) { tmp->boxes = gen5_render_composite_boxes; tmp->thread_boxes = gen5_render_composite_boxes__thread; } tmp->done = gen5_render_composite_done; if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; } gen5_align_vertex(sna, tmp); gen5_bind_surfaces(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } #if !NO_COMPOSITE_SPANS fastcall static void gen5_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen5_get_rectangles(sna, &op->base, 1, gen5_bind_surfaces); op->prim_emit(sna, op, box, opacity); } static void gen5_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen5_get_rectangles(sna, &op->base, nbox, gen5_bind_surfaces); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen5_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen5_get_rectangles(sna, &op->base, nbox, gen5_bind_surfaces); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen5_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen5_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n", __FUNCTION__, op, width, height, flags)); if (op >= ARRAY_SIZE(gen5_blend_op)) return false; if (gen5_composite_fallback(sna, src, NULL, dst)) { DBG(("%s: operation would fallback\n", __FUNCTION__)); return false; } if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) { struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); assert(priv); if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; if (flags & COMPOSITE_SPANS_INPLACE_HINT) return false; if ((sna->render.prefer_gpu & PREFER_GPU_SPANS) == 0 && dst->format == PICT_a8) return false; return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; } static bool gen5_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__, width, height, flags, sna->kgem.ring)); assert(gen5_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; if (!gen5_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) return false; switch (gen5_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: gen5_composite_channel_convert(&tmp->base.src); break; } tmp->base.mask.bo = NULL; tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.has_component_alpha = false; tmp->base.need_magic_ca_pass = false; tmp->base.u.gen5.ve_id = gen4_choose_spans_emitter(sna, tmp); tmp->base.u.gen5.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine; tmp->box = gen5_render_composite_spans_box; tmp->boxes = gen5_render_composite_spans_boxes; if (tmp->emit_boxes) tmp->thread_boxes = gen5_render_composite_spans_boxes__thread; tmp->done = gen5_render_composite_spans_done; if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; } gen5_align_vertex(sna, &tmp->base); gen5_bind_surfaces(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } #endif static void gen5_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { bool dirty = kgem_bo_is_dirty(op->dst.bo); uint32_t *binding_table; uint16_t offset; gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); binding_table[0] = gen5_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen5_get_dest_format(op->dst.format), true); binding_table[1] = gen5_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen5.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen5_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen5.surface_table; } gen5_emit_state(sna, op, offset | dirty); } static bool gen5_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; DBG(("%s alu=%d, src=%ld:handle=%d, dst=%ld:handle=%d boxes=%d x [((%d, %d), (%d, %d))...], flags=%x\n", __FUNCTION__, alu, src->serialNumber, src_bo->handle, dst->serialNumber, dst_bo->handle, n, box->x1, box->y1, box->x2, box->y2, flags)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo) { fallback_blt: if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } memset(&tmp, 0, sizeof(tmp)); if (dst->depth == src->depth) { tmp.dst.format = sna_render_format_for_depth(dst->depth); tmp.src.pict_format = tmp.dst.format; } else { tmp.dst.format = sna_format_for_depth(dst->depth); tmp.src.pict_format = sna_format_for_depth(src->depth); } if (!gen5_check_format(tmp.src.pict_format)) { DBG(("%s: unsupported source format, %x, use BLT\n", __FUNCTION__, tmp.src.pict_format)); goto fallback_blt; } DBG(("%s (%d, %d)->(%d, %d) x %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n)); tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.x = tmp.dst.y = 0; tmp.dst.bo = dst_bo; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height)) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } tmp.src.filter = SAMPLER_FILTER_NEAREST; tmp.src.repeat = SAMPLER_EXTEND_NONE; tmp.src.card_format = gen5_get_card_format(tmp.src.pict_format); if (too_large(src->width, src->height)) { BoxRec extents = box[0]; int i; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, extents.x1 + src_dx, extents.y1 + src_dy, extents.x2 - extents.x1, extents.y2 - extents.y1)) goto fallback_tiled_dst; } else { tmp.src.bo = kgem_bo_reference(src_bo); tmp.src.width = src->width; tmp.src.height = src->height; tmp.src.offset[0] = tmp.src.offset[1] = 0; tmp.src.scale[0] = 1.f/src->width; tmp.src.scale[1] = 1.f/src->height; } tmp.is_affine = true; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; tmp.u.gen5.wm_kernel = WM_KERNEL; tmp.u.gen5.ve_id = 2; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { DBG(("%s: aperture check failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); goto fallback_blt; } } dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; src_dx += tmp.src.offset[0]; src_dy += tmp.src.offset[1]; gen5_align_vertex(sna, &tmp); gen5_copy_bind_surfaces(sna, &tmp); do { int n_this_time; n_this_time = gen5_get_rectangles(sna, &tmp, n, gen5_copy_bind_surfaces); n -= n_this_time; do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); OUT_VERTEX(box->x2 + dst_dx, box->y2 + dst_dy); OUT_VERTEX_F((box->x2 + src_dx) * tmp.src.scale[0]); OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]); OUT_VERTEX(box->x1 + dst_dx, box->y2 + dst_dy); OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]); OUT_VERTEX_F((box->y2 + src_dy) * tmp.src.scale[1]); OUT_VERTEX(box->x1 + dst_dx, box->y1 + dst_dy); OUT_VERTEX_F((box->x1 + src_dx) * tmp.src.scale[0]); OUT_VERTEX_F((box->y1 + src_dy) * tmp.src.scale[1]); box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; fallback_tiled_dst: if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); fallback_tiled: if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; DBG(("%s: tiled fallback\n", __FUNCTION__)); return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen5_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, sx, sy, dx, dy, w, h)); gen5_get_rectangles(sna, &op->base, 1, gen5_copy_bind_surfaces); OUT_VERTEX(dx+w, dy+h); OUT_VERTEX_F((sx+w)*op->base.src.scale[0]); OUT_VERTEX_F((sy+h)*op->base.src.scale[1]); OUT_VERTEX(dx, dy+h); OUT_VERTEX_F(sx*op->base.src.scale[0]); OUT_VERTEX_F((sy+h)*op->base.src.scale[1]); OUT_VERTEX(dx, dy); OUT_VERTEX_F(sx*op->base.src.scale[0]); OUT_VERTEX_F(sy*op->base.src.scale[1]); } static void gen5_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); } static bool gen5_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op) { DBG(("%s (alu=%d)\n", __FUNCTION__, alu)); if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height)) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); } if (dst->drawable.depth == src->drawable.depth) { op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth); op->base.src.pict_format = op->base.dst.format; } else { op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.src.pict_format = sna_format_for_depth(src->drawable.depth); } if (!gen5_check_format(op->base.src.pict_format)) goto fallback; op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.bo = dst_bo; op->base.src.bo = src_bo; op->base.src.card_format = gen5_get_card_format(op->base.src.pict_format); op->base.src.width = src->drawable.width; op->base.src.height = src->drawable.height; op->base.src.scale[0] = 1.f/src->drawable.width; op->base.src.scale[1] = 1.f/src->drawable.height; op->base.src.filter = SAMPLER_FILTER_NEAREST; op->base.src.repeat = SAMPLER_EXTEND_NONE; op->base.is_affine = true; op->base.floats_per_vertex = 3; op->base.floats_per_rect = 9; op->base.u.gen5.wm_kernel = WM_KERNEL; op->base.u.gen5.ve_id = 2; if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; } if (kgem_bo_is_dirty(src_bo)) { if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; } gen5_align_vertex(sna, &op->base); gen5_copy_bind_surfaces(sna, &op->base); op->blt = gen5_render_copy_blt; op->done = gen5_render_copy_done; return true; } static void gen5_fill_bind_surfaces(struct sna *sna, const struct sna_composite_op *op) { bool dirty = kgem_bo_is_dirty(op->dst.bo); uint32_t *binding_table; uint16_t offset; gen5_get_batch(sna, op); binding_table = gen5_composite_get_binding_table(sna, &offset); binding_table[0] = gen5_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen5_get_dest_format(op->dst.format), true); binding_table[1] = gen5_bind_bo(sna, op->src.bo, 1, 1, GEN5_SURFACEFORMAT_B8G8R8A8_UNORM, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen5.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen5_surface_state_padded)/sizeof(uint32_t); offset = sna->render_state.gen5.surface_table; } gen5_emit_state(sna, op, offset | dirty); } static inline bool prefer_blt_fill(struct sna *sna) { #if PREFER_BLT_FILL return true; #else return sna->kgem.mode != KGEM_RENDER; #endif } static bool gen5_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; DBG(("%s op=%x, color=(%04x,%04x,%04x,%04x), boxes=%d x [((%d, %d), (%d, %d))...]\n", __FUNCTION__, op, color->red, color->green, color->blue, color->alpha, n, box->x1, box->y1, box->x2, box->y2)); if (op >= ARRAY_SIZE(gen5_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (op <= PictOpSrc && (prefer_blt_fill(sna) || too_large(dst->width, dst->height) || !gen5_check_dst_format(format))) { uint8_t alu = GXinvalid; pixel = 0; if (op == PictOpClear) alu = GXclear; else if (sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) alu = GXcopy; if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n)) return true; if (!gen5_check_dst_format(format)) return false; if (too_large(dst->width, dst->height)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } if (op == PictOpClear) { pixel = 0; op = PictOpSrc; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s(%08x x %d)\n", __FUNCTION__, pixel, n)); memset(&tmp, 0, sizeof(tmp)); tmp.op = op; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; if (too_large(dst->width, dst->height)) { BoxRec extents; boxes_extents(box, n, &extents); if (!sna_render_composite_redirect(sna, &tmp, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.src.filter = SAMPLER_FILTER_NEAREST; tmp.src.repeat = SAMPLER_EXTEND_REPEAT; tmp.is_affine = true; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.u.gen5.wm_kernel = WM_KERNEL; tmp.u.gen5.ve_id = 1; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen5_align_vertex(sna, &tmp); gen5_fill_bind_surfaces(sna, &tmp); do { int n_this_time; n_this_time = gen5_get_rectangles(sna, &tmp, n, gen5_fill_bind_surfaces); n -= n_this_time; do { DBG((" (%d, %d), (%d, %d)\n", box->x1, box->y1, box->x2, box->y2)); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(.5); box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); sna_render_composite_redirect_done(sna, &tmp); return true; } static void gen5_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x,y,w,h)); gen5_get_rectangles(sna, &op->base, 1, gen5_fill_bind_surfaces); OUT_VERTEX(x+w, y+h); OUT_VERTEX_F(.5); OUT_VERTEX(x, y+h); OUT_VERTEX_F(.5); OUT_VERTEX(x, y); OUT_VERTEX_F(.5); } fastcall static void gen5_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen5_get_rectangles(sna, &op->base, 1, gen5_fill_bind_surfaces); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(.5); } fastcall static void gen5_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time; nbox_this_time = gen5_get_rectangles(sna, &op->base, nbox, gen5_fill_bind_surfaces); nbox -= nbox_this_time; do { OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(.5); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(.5); box++; } while (--nbox_this_time); } while (nbox); } static void gen5_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, op->base.src.bo); DBG(("%s()\n", __FUNCTION__)); } static bool gen5_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *op) { DBG(("%s(alu=%d, color=%08x)\n", __FUNCTION__, alu, color)); if (prefer_blt_fill(sna) && sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op)) return true; if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op); if (alu == GXclear) color = 0; op->base.op = color == 0 ? PictOpClear : PictOpSrc; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.dst.bo = dst_bo; op->base.dst.x = op->base.dst.y = 0; op->base.need_magic_ca_pass = 0; op->base.has_component_alpha = 0; op->base.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); op->base.src.filter = SAMPLER_FILTER_NEAREST; op->base.src.repeat = SAMPLER_EXTEND_REPEAT; op->base.mask.bo = NULL; op->base.mask.filter = SAMPLER_FILTER_NEAREST; op->base.mask.repeat = SAMPLER_EXTEND_NONE; op->base.is_affine = true; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen5.wm_kernel = WM_KERNEL; op->base.u.gen5.ve_id = 1; if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, op->base.src.bo); return false; } } gen5_align_vertex(sna, &op->base); gen5_fill_bind_surfaces(sna, &op->base); op->blt = gen5_render_fill_op_blt; op->box = gen5_render_fill_op_box; op->boxes = gen5_render_fill_op_boxes; op->points = NULL; op->done = gen5_render_fill_op_done; return true; } static bool gen5_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen5_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; #if NO_FILL_ONE return gen5_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); #endif /* Prefer to use the BLT if already engaged */ if (prefer_blt_fill(sna) && gen5_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return gen5_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); if (alu == GXclear) color = 0; tmp.op = color == 0 ? PictOpClear : PictOpSrc; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); tmp.src.filter = SAMPLER_FILTER_NEAREST; tmp.src.repeat = SAMPLER_EXTEND_REPEAT; tmp.mask.bo = NULL; tmp.mask.filter = SAMPLER_FILTER_NEAREST; tmp.mask.repeat = SAMPLER_EXTEND_NONE; tmp.is_affine = true; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.has_component_alpha = 0; tmp.need_magic_ca_pass = false; tmp.u.gen5.wm_kernel = WM_KERNEL; tmp.u.gen5.ve_id = 1; if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen5_align_vertex(sna, &tmp); gen5_fill_bind_surfaces(sna, &tmp); gen5_get_rectangles(sna, &tmp, 1, gen5_fill_bind_surfaces); DBG((" (%d, %d), (%d, %d)\n", x1, y1, x2, y2)); OUT_VERTEX(x2, y2); OUT_VERTEX_F(.5); OUT_VERTEX(x1, y2); OUT_VERTEX_F(.5); OUT_VERTEX(x1, y1); OUT_VERTEX_F(.5); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static void gen5_render_context_switch(struct kgem *kgem, int new_mode) { if (!kgem->nbatch) return; /* WaNonPipelinedStateCommandFlush * * Ironlake has a limitation that a 3D or Media command can't * be the first command after a BLT, unless it's * non-pipelined. * * We do this by ensuring that the non-pipelined drawrect * is always emitted first following a switch from BLT. */ if (kgem->mode == KGEM_BLT) { struct sna *sna = to_sna_from_kgem(kgem); DBG(("%s: forcing drawrect on next state emission\n", __FUNCTION__)); sna->render_state.gen5.drawrect_limit = -1; } if (kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: GPU idle, flushing\n", __FUNCTION__)); _kgem_submit(kgem); } } static void gen5_render_reset(struct sna *sna) { sna->render_state.gen5.needs_invariant = true; sna->render_state.gen5.ve_id = -1; sna->render_state.gen5.last_primitive = -1; sna->render_state.gen5.last_pipelined_pointers = 0; sna->render_state.gen5.drawrect_offset = -1; sna->render_state.gen5.drawrect_limit = -1; sna->render_state.gen5.surface_table = -1; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); discard_vbo(sna); } sna->render.vertex_offset = 0; sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; } static void gen5_render_fini(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render_state.gen5.general_bo); } static uint32_t gen5_create_vs_unit_state(struct sna_static_stream *stream) { struct gen5_vs_unit_state *vs = sna_static_stream_map(stream, sizeof(*vs), 32); /* Set up the vertex shader to be disabled (passthrough) */ vs->thread4.nr_urb_entries = URB_VS_ENTRIES >> 2; vs->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; vs->vs6.vs_enable = 0; vs->vs6.vert_cache_disable = 1; return sna_static_stream_offsetof(stream, vs); } static uint32_t gen5_create_sf_state(struct sna_static_stream *stream, uint32_t kernel) { struct gen5_sf_unit_state *sf_state; sf_state = sna_static_stream_map(stream, sizeof(*sf_state), 32); sf_state->thread0.grf_reg_count = GEN5_GRF_BLOCKS(SF_KERNEL_NUM_GRF); sf_state->thread0.kernel_start_pointer = kernel >> 6; sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */ sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */ sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ /* don't smash vertex header, read start from dw8 */ sf_state->thread3.urb_entry_read_offset = 1; sf_state->thread3.dispatch_grf_start_reg = 3; sf_state->thread4.max_threads = SF_MAX_THREADS - 1; sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES; sf_state->sf5.viewport_transform = false; /* skip viewport */ sf_state->sf6.cull_mode = GEN5_CULLMODE_NONE; sf_state->sf6.scissor = 0; sf_state->sf7.trifan_pv = 2; sf_state->sf6.dest_org_vbias = 0x8; sf_state->sf6.dest_org_hbias = 0x8; return sna_static_stream_offsetof(stream, sf_state); } static uint32_t gen5_create_sampler_state(struct sna_static_stream *stream, sampler_filter_t src_filter, sampler_extend_t src_extend, sampler_filter_t mask_filter, sampler_extend_t mask_extend) { struct gen5_sampler_state *sampler_state; sampler_state = sna_static_stream_map(stream, sizeof(struct gen5_sampler_state) * 2, 32); sampler_state_init(&sampler_state[0], src_filter, src_extend); sampler_state_init(&sampler_state[1], mask_filter, mask_extend); return sna_static_stream_offsetof(stream, sampler_state); } static void gen5_init_wm_state(struct gen5_wm_unit_state *state, bool has_mask, uint32_t kernel, uint32_t sampler) { state->thread0.grf_reg_count = GEN5_GRF_BLOCKS(PS_KERNEL_NUM_GRF); state->thread0.kernel_start_pointer = kernel >> 6; state->thread1.single_program_flow = 0; /* scratch space is not used in our kernel */ state->thread2.scratch_space_base_pointer = 0; state->thread2.per_thread_scratch_space = 0; state->thread3.const_urb_entry_read_length = 0; state->thread3.const_urb_entry_read_offset = 0; state->thread3.urb_entry_read_offset = 0; /* wm kernel use urb from 3, see wm_program in compiler module */ state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */ state->wm4.sampler_count = 0; /* hardware requirement */ state->wm4.sampler_state_pointer = sampler >> 5; state->wm5.max_threads = PS_MAX_THREADS - 1; state->wm5.transposed_urb_read = 0; state->wm5.thread_dispatch_enable = 1; /* just use 16-pixel dispatch (4 subspans), don't need to change kernel * start point */ state->wm5.enable_16_pix = 1; state->wm5.enable_8_pix = 0; state->wm5.early_depth_test = 1; /* Each pair of attributes (src/mask coords) is two URB entries */ if (has_mask) { state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */ state->thread3.urb_entry_read_length = 4; } else { state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */ state->thread3.urb_entry_read_length = 2; } /* binding table entry count is only used for prefetching, * and it has to be set 0 for Ironlake */ state->thread1.binding_table_entry_count = 0; } static uint32_t gen5_create_cc_unit_state(struct sna_static_stream *stream) { uint8_t *ptr, *base; int i, j; base = ptr = sna_static_stream_map(stream, GEN5_BLENDFACTOR_COUNT*GEN5_BLENDFACTOR_COUNT*64, 64); for (i = 0; i < GEN5_BLENDFACTOR_COUNT; i++) { for (j = 0; j < GEN5_BLENDFACTOR_COUNT; j++) { struct gen5_cc_unit_state *state = (struct gen5_cc_unit_state *)ptr; state->cc3.blend_enable = !(j == GEN5_BLENDFACTOR_ZERO && i == GEN5_BLENDFACTOR_ONE); state->cc5.logicop_func = 0xc; /* COPY */ state->cc5.ia_blend_function = GEN5_BLENDFUNCTION_ADD; /* Fill in alpha blend factors same as color, for the future. */ state->cc5.ia_src_blend_factor = i; state->cc5.ia_dest_blend_factor = j; state->cc6.blend_function = GEN5_BLENDFUNCTION_ADD; state->cc6.clamp_post_alpha_blend = 1; state->cc6.clamp_pre_alpha_blend = 1; state->cc6.src_blend_factor = i; state->cc6.dest_blend_factor = j; ptr += 64; } } return sna_static_stream_offsetof(stream, base); } static bool gen5_render_setup(struct sna *sna) { struct gen5_render_state *state = &sna->render_state.gen5; struct sna_static_stream general; struct gen5_wm_unit_state_padded *wm_state; uint32_t sf[2], wm[KERNEL_COUNT]; int i, j, k, l, m; sna_static_stream_init(&general); /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer * dumps, you know it points to zero. */ null_create(&general); /* Set up the two SF states (one for blending with a mask, one without) */ sf[0] = sna_static_stream_compile_sf(sna, &general, brw_sf_kernel__nomask); sf[1] = sna_static_stream_compile_sf(sna, &general, brw_sf_kernel__mask); for (m = 0; m < KERNEL_COUNT; m++) { if (wm_kernels[m].size) { wm[m] = sna_static_stream_add(&general, wm_kernels[m].data, wm_kernels[m].size, 64); } else { wm[m] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } assert(wm[m]); } state->vs = gen5_create_vs_unit_state(&general); state->sf[0] = gen5_create_sf_state(&general, sf[0]); state->sf[1] = gen5_create_sf_state(&general, sf[1]); /* Set up the WM states: each filter/extend type for source and mask, per * kernel. */ wm_state = sna_static_stream_map(&general, sizeof(*wm_state) * KERNEL_COUNT * FILTER_COUNT * EXTEND_COUNT * FILTER_COUNT * EXTEND_COUNT, 64); state->wm = sna_static_stream_offsetof(&general, wm_state); for (i = 0; i < FILTER_COUNT; i++) { for (j = 0; j < EXTEND_COUNT; j++) { for (k = 0; k < FILTER_COUNT; k++) { for (l = 0; l < EXTEND_COUNT; l++) { uint32_t sampler_state; sampler_state = gen5_create_sampler_state(&general, i, j, k, l); for (m = 0; m < KERNEL_COUNT; m++) { gen5_init_wm_state(&wm_state->state, wm_kernels[m].has_mask, wm[m], sampler_state); wm_state++; } } } } } state->cc = gen5_create_cc_unit_state(&general); state->general_bo = sna_static_stream_fini(sna, &general); return state->general_bo != NULL; } const char *gen5_render_init(struct sna *sna, const char *backend) { if (!gen5_render_setup(sna)) return backend; sna->kgem.context_switch = gen5_render_context_switch; sna->kgem.retire = gen4_render_retire; sna->kgem.expire = gen4_render_expire; #if !NO_COMPOSITE sna->render.composite = gen5_render_composite; sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen5_check_composite_spans; sna->render.composite_spans = gen5_render_composite_spans; if (intel_get_device_id(sna->dev) == 0x0044) sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen5_render_video; sna->render.copy_boxes = gen5_render_copy_boxes; sna->render.copy = gen5_render_copy; sna->render.fill_boxes = gen5_render_fill_boxes; sna->render.fill = gen5_render_fill; sna->render.fill_one = gen5_render_fill_one; sna->render.flush = gen4_render_flush; sna->render.reset = gen5_render_reset; sna->render.fini = gen5_render_fini; sna->render.max_3d_size = MAX_3D_SIZE; sna->render.max_3d_pitch = 1 << 18; return "Ironlake (gen5)"; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen5_render.h000066400000000000000000002433531267532330400242230ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 GEN5_RENDER_H #define GEN5_RENDER_H #define GEN5_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define GEN5_URB_FENCE GEN5_3D(0, 0, 0) #define GEN5_CS_URB_STATE GEN5_3D(0, 0, 1) #define GEN5_CONSTANT_BUFFER GEN5_3D(0, 0, 2) #define GEN5_STATE_PREFETCH GEN5_3D(0, 0, 3) #define GEN5_STATE_BASE_ADDRESS GEN5_3D(0, 1, 1) #define GEN5_STATE_SIP GEN5_3D(0, 1, 2) #define GEN5_PIPELINE_SELECT GEN5_3D(1, 1, 4) #define GEN5_MEDIA_STATE_POINTERS GEN5_3D(2, 0, 0) #define GEN5_MEDIA_OBJECT GEN5_3D(2, 1, 0) #define GEN5_3DSTATE_PIPELINED_POINTERS GEN5_3D(3, 0, 0) #define GEN5_3DSTATE_BINDING_TABLE_POINTERS GEN5_3D(3, 0, 1) # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS (1 << 12)/* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_GS (1 << 9) /* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_VS (1 << 8) /* for GEN6 */ #define GEN5_3DSTATE_VERTEX_BUFFERS GEN5_3D(3, 0, 8) #define GEN5_3DSTATE_VERTEX_ELEMENTS GEN5_3D(3, 0, 9) #define GEN5_3DSTATE_INDEX_BUFFER GEN5_3D(3, 0, 0xa) #define GEN5_3DSTATE_VF_STATISTICS GEN5_3D(3, 0, 0xb) #define GEN5_3DSTATE_DRAWING_RECTANGLE GEN5_3D(3, 1, 0) #define GEN5_3DSTATE_CONSTANT_COLOR GEN5_3D(3, 1, 1) #define GEN5_3DSTATE_SAMPLER_PALETTE_LOAD GEN5_3D(3, 1, 2) #define GEN5_3DSTATE_CHROMA_KEY GEN5_3D(3, 1, 4) #define GEN5_3DSTATE_DEPTH_BUFFER GEN5_3D(3, 1, 5) # define GEN5_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define GEN5_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define GEN5_3DSTATE_POLY_STIPPLE_OFFSET GEN5_3D(3, 1, 6) #define GEN5_3DSTATE_POLY_STIPPLE_PATTERN GEN5_3D(3, 1, 7) #define GEN5_3DSTATE_LINE_STIPPLE GEN5_3D(3, 1, 8) #define GEN5_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP GEN5_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define GEN5_3DSTATE_AA_LINE_PARAMS GEN5_3D(3, 1, 0xa) #define GEN5_3DSTATE_GS_SVB_INDEX GEN5_3D(3, 1, 0xb) #define GEN5_PIPE_CONTROL GEN5_3D(3, 2, 0) #define GEN5_3DPRIMITIVE GEN5_3D(3, 3, 0) #define GEN5_3DSTATE_CLEAR_PARAMS GEN5_3D(3, 1, 0x10) /* DW1 */ # define GEN5_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) /* for GEN6+ */ #define GEN6_3DSTATE_SAMPLER_STATE_POINTERS GEN5_3D(3, 0, 0x02) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN6_3DSTATE_URB GEN5_3D(3, 0, 0x05) /* DW1 */ # define GEN6_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN6_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN6_3DSTATE_VIEWPORT_STATE_POINTERS GEN5_3D(3, 0, 0x0d) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN6_3DSTATE_CC_STATE_POINTERS GEN5_3D(3, 0, 0x0e) #define GEN6_3DSTATE_VS GEN5_3D(3, 0, 0x10) #define GEN6_3DSTATE_GS GEN5_3D(3, 0, 0x11) /* DW4 */ # define GEN6_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN6_3DSTATE_CLIP GEN5_3D(3, 0, 0x12) #define GEN6_3DSTATE_SF GEN5_3D(3, 0, 0x13) /* DW1 */ # define GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN6_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN6_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN6_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN6_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN6_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN6_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN6_3DSTATE_WM GEN5_3D(3, 0, 0x14) /* DW2 */ # define GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF 27 # define GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 /* DW4 */ # define GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT 16 /* DW5 */ # define GEN6_3DSTATE_WM_MAX_THREADS_SHIFT 25 # define GEN6_3DSTATE_WM_DISPATCH_ENABLE (1 << 19) # define GEN6_3DSTATE_WM_16_DISPATCH_ENABLE (1 << 1) # define GEN6_3DSTATE_WM_8_DISPATCH_ENABLE (1 << 0) /* DW6 */ # define GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT 20 # define GEN6_3DSTATE_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 15) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 14) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 13) # define GEN6_3DSTATE_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_3DSTATE_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) #define GEN6_3DSTATE_CONSTANT_VS GEN5_3D(3, 0, 0x15) #define GEN6_3DSTATE_CONSTANT_GS GEN5_3D(3, 0, 0x16) #define GEN6_3DSTATE_CONSTANT_PS GEN5_3D(3, 0, 0x17) #define GEN6_3DSTATE_SAMPLE_MASK GEN5_3D(3, 0, 0x18) #define GEN6_3DSTATE_MULTISAMPLE GEN5_3D(3, 1, 0x0d) /* DW1 */ # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 #define UF0_CS_REALLOC (1 << 13) #define UF0_VFE_REALLOC (1 << 12) #define UF0_SF_REALLOC (1 << 11) #define UF0_CLIP_REALLOC (1 << 10) #define UF0_GS_REALLOC (1 << 9) #define UF0_VS_REALLOC (1 << 8) #define UF1_CLIP_FENCE_SHIFT 20 #define UF1_GS_FENCE_SHIFT 10 #define UF1_VS_FENCE_SHIFT 0 #define UF2_CS_FENCE_SHIFT 20 #define UF2_VFE_FENCE_SHIFT 10 #define UF2_SF_FENCE_SHIFT 0 /* for GEN5_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for GEN5_3DSTATE_PIPELINED_POINTERS */ #define GEN5_GS_DISABLE 0 #define GEN5_GS_ENABLE 1 #define GEN5_CLIP_DISABLE 0 #define GEN5_CLIP_ENABLE 1 /* for GEN5_PIPE_CONTROL */ #define GEN5_PIPE_CONTROL_NOWRITE (0 << 14) #define GEN5_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define GEN5_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define GEN5_PIPE_CONTROL_WRITE_TIME (3 << 14) #define GEN5_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define GEN5_PIPE_CONTROL_WC_FLUSH (1 << 12) #define GEN5_PIPE_CONTROL_IS_FLUSH (1 << 11) #define GEN5_PIPE_CONTROL_TC_FLUSH (1 << 10) #define GEN5_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define GEN5_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define GEN5_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define GEN5_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define VB0_BUFFER_INDEX_SHIFT 27 #define GEN6_VB0_BUFFER_INDEX_SHIFT 26 #define VB0_VERTEXDATA (0 << 26) #define VB0_INSTANCEDATA (1 << 26) #define GEN6_VB0_VERTEXDATA (0 << 20) #define GEN6_VB0_INSTANCEDATA (1 << 20) #define VB0_BUFFER_PITCH_SHIFT 0 /* VERTEX_ELEMENT_STATE Structure */ #define VE0_VERTEX_BUFFER_INDEX_SHIFT 27 #define GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT 26 /* for GEN6 */ #define VE0_VALID (1 << 26) #define GEN6_VE0_VALID (1 << 25) /* for GEN6 */ #define VE0_FORMAT_SHIFT 16 #define VE0_OFFSET_SHIFT 0 #define VE1_VFCOMPONENT_0_SHIFT 28 #define VE1_VFCOMPONENT_1_SHIFT 24 #define VE1_VFCOMPONENT_2_SHIFT 20 #define VE1_VFCOMPONENT_3_SHIFT 16 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define GEN5_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define GEN5_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in gen5_defines.h */ #define GEN5_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define GEN5_SVG_CTL 0x7400 #define GEN5_SVG_CTL_GS_BA (0 << 8) #define GEN5_SVG_CTL_SS_BA (1 << 8) #define GEN5_SVG_CTL_IO_BA (2 << 8) #define GEN5_SVG_CTL_GS_AUB (3 << 8) #define GEN5_SVG_CTL_IO_AUB (4 << 8) #define GEN5_SVG_CTL_SIP (5 << 8) #define GEN5_SVG_RDATA 0x7404 #define GEN5_SVG_WORK_CTL 0x7408 #define GEN5_VF_CTL 0x7500 #define GEN5_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN5_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define GEN5_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define GEN5_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define GEN5_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define GEN5_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define GEN5_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define GEN5_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define GEN5_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN5_VF_STRG_VAL 0x7504 #define GEN5_VF_STR_VL_OVR 0x7508 #define GEN5_VF_VC_OVR 0x750c #define GEN5_VF_STR_PSKIP 0x7510 #define GEN5_VF_MAX_PRIM 0x7514 #define GEN5_VF_RDATA 0x7518 #define GEN5_VS_CTL 0x7600 #define GEN5_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN5_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define GEN5_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define GEN5_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define GEN5_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define GEN5_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN5_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN5_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN5_VS_STRG_VAL 0x7604 #define GEN5_VS_RDATA 0x7608 #define GEN5_SF_CTL 0x7b00 #define GEN5_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define GEN5_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define GEN5_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define GEN5_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define GEN5_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN5_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN5_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN5_SF_STRG_VAL 0x7b04 #define GEN5_SF_RDATA 0x7b18 #define GEN5_WIZ_CTL 0x7c00 #define GEN5_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN5_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define GEN5_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define GEN5_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define GEN5_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define GEN5_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define GEN5_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define GEN5_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define GEN5_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define GEN5_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN5_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN5_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN5_WIZ_STRG_VAL 0x7c04 #define GEN5_WIZ_RDATA 0x7c18 #define GEN5_TS_CTL 0x7e00 #define GEN5_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN5_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define GEN5_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define GEN5_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define GEN5_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define GEN5_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN5_TS_STRG_VAL 0x7e04 #define GEN5_TS_RDATA 0x7e08 #define GEN5_TD_CTL 0x8000 #define GEN5_TD_CTL_MUX_SHIFT 8 #define GEN5_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define GEN5_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define GEN5_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define GEN5_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define GEN5_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define GEN5_TD_CTL2 0x8004 #define GEN5_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define GEN5_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define GEN5_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define GEN5_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define GEN5_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define GEN5_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define GEN5_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define GEN5_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define GEN5_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define GEN5_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define GEN5_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define GEN5_TD_VF_VS_EMSK 0x8008 #define GEN5_TD_GS_EMSK 0x800c #define GEN5_TD_CLIP_EMSK 0x8010 #define GEN5_TD_SF_EMSK 0x8014 #define GEN5_TD_WIZ_EMSK 0x8018 #define GEN5_TD_0_6_EHTRG_VAL 0x801c #define GEN5_TD_0_7_EHTRG_VAL 0x8020 #define GEN5_TD_0_6_EHTRG_MSK 0x8024 #define GEN5_TD_0_7_EHTRG_MSK 0x8028 #define GEN5_TD_RDATA 0x802c #define GEN5_TD_TS_EMSK 0x8030 #define GEN5_EU_CTL 0x8800 #define GEN5_EU_CTL_SELECT_SHIFT 16 #define GEN5_EU_CTL_DATA_MUX_SHIFT 8 #define GEN5_EU_ATT_0 0x8810 #define GEN5_EU_ATT_1 0x8814 #define GEN5_EU_ATT_DATA_0 0x8820 #define GEN5_EU_ATT_DATA_1 0x8824 #define GEN5_EU_ATT_CLR_0 0x8830 #define GEN5_EU_ATT_CLR_1 0x8834 #define GEN5_EU_RDATA 0x8840 /* 3D state: */ #define _3DOP_3DSTATE_PIPELINED 0x0 #define _3DOP_3DSTATE_NONPIPELINED 0x1 #define _3DOP_3DCONTROL 0x2 #define _3DOP_3DPRIMITIVE 0x3 #define _3DSTATE_PIPELINED_POINTERS 0x00 #define _3DSTATE_BINDING_TABLE_POINTERS 0x01 #define _3DSTATE_VERTEX_BUFFERS 0x08 #define _3DSTATE_VERTEX_ELEMENTS 0x09 #define _3DSTATE_INDEX_BUFFER 0x0A #define _3DSTATE_VF_STATISTICS 0x0B #define _3DSTATE_DRAWING_RECTANGLE 0x00 #define _3DSTATE_CONSTANT_COLOR 0x01 #define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 #define _3DSTATE_CHROMA_KEY 0x04 #define _3DSTATE_DEPTH_BUFFER 0x05 #define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 #define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 #define _3DSTATE_LINE_STIPPLE 0x08 #define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 #define _3DCONTROL 0x00 #define _3DPRIMITIVE 0x00 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define GEN5_ANISORATIO_2 0 #define GEN5_ANISORATIO_4 1 #define GEN5_ANISORATIO_6 2 #define GEN5_ANISORATIO_8 3 #define GEN5_ANISORATIO_10 4 #define GEN5_ANISORATIO_12 5 #define GEN5_ANISORATIO_14 6 #define GEN5_ANISORATIO_16 7 #define GEN5_BLENDFACTOR_ONE 0x1 #define GEN5_BLENDFACTOR_SRC_COLOR 0x2 #define GEN5_BLENDFACTOR_SRC_ALPHA 0x3 #define GEN5_BLENDFACTOR_DST_ALPHA 0x4 #define GEN5_BLENDFACTOR_DST_COLOR 0x5 #define GEN5_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define GEN5_BLENDFACTOR_CONST_COLOR 0x7 #define GEN5_BLENDFACTOR_CONST_ALPHA 0x8 #define GEN5_BLENDFACTOR_SRC1_COLOR 0x9 #define GEN5_BLENDFACTOR_SRC1_ALPHA 0x0A #define GEN5_BLENDFACTOR_ZERO 0x11 #define GEN5_BLENDFACTOR_INV_SRC_COLOR 0x12 #define GEN5_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define GEN5_BLENDFACTOR_INV_DST_ALPHA 0x14 #define GEN5_BLENDFACTOR_INV_DST_COLOR 0x15 #define GEN5_BLENDFACTOR_INV_CONST_COLOR 0x17 #define GEN5_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define GEN5_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define GEN5_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define GEN5_BLENDFUNCTION_ADD 0 #define GEN5_BLENDFUNCTION_SUBTRACT 1 #define GEN5_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define GEN5_BLENDFUNCTION_MIN 3 #define GEN5_BLENDFUNCTION_MAX 4 #define GEN5_ALPHATEST_FORMAT_UNORM8 0 #define GEN5_ALPHATEST_FORMAT_FLOAT32 1 #define GEN5_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define GEN5_CHROMAKEY_REPLACE_BLACK 1 #define GEN5_CLIP_API_OGL 0 #define GEN5_CLIP_API_DX 1 #define GEN5_CLIPMODE_NORMAL 0 #define GEN5_CLIPMODE_CLIP_ALL 1 #define GEN5_CLIPMODE_CLIP_NON_REJECTED 2 #define GEN5_CLIPMODE_REJECT_ALL 3 #define GEN5_CLIPMODE_ACCEPT_ALL 4 #define GEN5_CLIP_NDCSPACE 0 #define GEN5_CLIP_SCREENSPACE 1 #define GEN5_COMPAREFUNCTION_ALWAYS 0 #define GEN5_COMPAREFUNCTION_NEVER 1 #define GEN5_COMPAREFUNCTION_LESS 2 #define GEN5_COMPAREFUNCTION_EQUAL 3 #define GEN5_COMPAREFUNCTION_LEQUAL 4 #define GEN5_COMPAREFUNCTION_GREATER 5 #define GEN5_COMPAREFUNCTION_NOTEQUAL 6 #define GEN5_COMPAREFUNCTION_GEQUAL 7 #define GEN5_COVERAGE_PIXELS_HALF 0 #define GEN5_COVERAGE_PIXELS_1 1 #define GEN5_COVERAGE_PIXELS_2 2 #define GEN5_COVERAGE_PIXELS_4 3 #define GEN5_CULLMODE_BOTH 0 #define GEN5_CULLMODE_NONE 1 #define GEN5_CULLMODE_FRONT 2 #define GEN5_CULLMODE_BACK 3 #define GEN5_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define GEN5_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define GEN5_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define GEN5_DEPTHFORMAT_D32_FLOAT 1 #define GEN5_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define GEN5_DEPTHFORMAT_D16_UNORM 5 #define GEN5_FLOATING_POINT_IEEE_754 0 #define GEN5_FLOATING_POINT_NON_IEEE_754 1 #define GEN5_FRONTWINDING_CW 0 #define GEN5_FRONTWINDING_CCW 1 #define GEN5_INDEX_BYTE 0 #define GEN5_INDEX_WORD 1 #define GEN5_INDEX_DWORD 2 #define GEN5_LOGICOPFUNCTION_CLEAR 0 #define GEN5_LOGICOPFUNCTION_NOR 1 #define GEN5_LOGICOPFUNCTION_AND_INVERTED 2 #define GEN5_LOGICOPFUNCTION_COPY_INVERTED 3 #define GEN5_LOGICOPFUNCTION_AND_REVERSE 4 #define GEN5_LOGICOPFUNCTION_INVERT 5 #define GEN5_LOGICOPFUNCTION_XOR 6 #define GEN5_LOGICOPFUNCTION_NAND 7 #define GEN5_LOGICOPFUNCTION_AND 8 #define GEN5_LOGICOPFUNCTION_EQUIV 9 #define GEN5_LOGICOPFUNCTION_NOOP 10 #define GEN5_LOGICOPFUNCTION_OR_INVERTED 11 #define GEN5_LOGICOPFUNCTION_COPY 12 #define GEN5_LOGICOPFUNCTION_OR_REVERSE 13 #define GEN5_LOGICOPFUNCTION_OR 14 #define GEN5_LOGICOPFUNCTION_SET 15 #define GEN5_MAPFILTER_NEAREST 0x0 #define GEN5_MAPFILTER_LINEAR 0x1 #define GEN5_MAPFILTER_ANISOTROPIC 0x2 #define GEN5_MIPFILTER_NONE 0 #define GEN5_MIPFILTER_NEAREST 1 #define GEN5_MIPFILTER_LINEAR 3 #define GEN5_POLYGON_FRONT_FACING 0 #define GEN5_POLYGON_BACK_FACING 1 #define GEN5_PREFILTER_ALWAYS 0x0 #define GEN5_PREFILTER_NEVER 0x1 #define GEN5_PREFILTER_LESS 0x2 #define GEN5_PREFILTER_EQUAL 0x3 #define GEN5_PREFILTER_LEQUAL 0x4 #define GEN5_PREFILTER_GREATER 0x5 #define GEN5_PREFILTER_NOTEQUAL 0x6 #define GEN5_PREFILTER_GEQUAL 0x7 #define GEN5_PROVOKING_VERTEX_0 0 #define GEN5_PROVOKING_VERTEX_1 1 #define GEN5_PROVOKING_VERTEX_2 2 #define GEN5_RASTRULE_UPPER_LEFT 0 #define GEN5_RASTRULE_UPPER_RIGHT 1 #define GEN5_RENDERTARGET_CLAMPRANGE_UNORM 0 #define GEN5_RENDERTARGET_CLAMPRANGE_SNORM 1 #define GEN5_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define GEN5_STENCILOP_KEEP 0 #define GEN5_STENCILOP_ZERO 1 #define GEN5_STENCILOP_REPLACE 2 #define GEN5_STENCILOP_INCRSAT 3 #define GEN5_STENCILOP_DECRSAT 4 #define GEN5_STENCILOP_INCR 5 #define GEN5_STENCILOP_DECR 6 #define GEN5_STENCILOP_INVERT 7 #define GEN5_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN5_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define GEN5_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define GEN5_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define GEN5_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define GEN5_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define GEN5_SURFACEFORMAT_R64G64_FLOAT 0x005 #define GEN5_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define GEN5_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define GEN5_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define GEN5_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define GEN5_SURFACEFORMAT_R32G32B32_SINT 0x041 #define GEN5_SURFACEFORMAT_R32G32B32_UINT 0x042 #define GEN5_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define GEN5_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define GEN5_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define GEN5_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define GEN5_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define GEN5_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define GEN5_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define GEN5_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define GEN5_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define GEN5_SURFACEFORMAT_R32G32_FLOAT 0x085 #define GEN5_SURFACEFORMAT_R32G32_SINT 0x086 #define GEN5_SURFACEFORMAT_R32G32_UINT 0x087 #define GEN5_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define GEN5_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define GEN5_SURFACEFORMAT_L32A32_FLOAT 0x08A #define GEN5_SURFACEFORMAT_R32G32_UNORM 0x08B #define GEN5_SURFACEFORMAT_R32G32_SNORM 0x08C #define GEN5_SURFACEFORMAT_R64_FLOAT 0x08D #define GEN5_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define GEN5_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define GEN5_SURFACEFORMAT_A32X32_FLOAT 0x090 #define GEN5_SURFACEFORMAT_L32X32_FLOAT 0x091 #define GEN5_SURFACEFORMAT_I32X32_FLOAT 0x092 #define GEN5_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define GEN5_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define GEN5_SURFACEFORMAT_R32G32_SSCALED 0x095 #define GEN5_SURFACEFORMAT_R32G32_USCALED 0x096 #define GEN5_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define GEN5_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define GEN5_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define GEN5_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define GEN5_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define GEN5_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define GEN5_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define GEN5_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define GEN5_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define GEN5_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define GEN5_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define GEN5_SURFACEFORMAT_R16G16_UNORM 0x0CC #define GEN5_SURFACEFORMAT_R16G16_SNORM 0x0CD #define GEN5_SURFACEFORMAT_R16G16_SINT 0x0CE #define GEN5_SURFACEFORMAT_R16G16_UINT 0x0CF #define GEN5_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define GEN5_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define GEN5_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define GEN5_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define GEN5_SURFACEFORMAT_R32_SINT 0x0D6 #define GEN5_SURFACEFORMAT_R32_UINT 0x0D7 #define GEN5_SURFACEFORMAT_R32_FLOAT 0x0D8 #define GEN5_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define GEN5_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define GEN5_SURFACEFORMAT_L16A16_UNORM 0x0DF #define GEN5_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define GEN5_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define GEN5_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define GEN5_SURFACEFORMAT_I32_FLOAT 0x0E3 #define GEN5_SURFACEFORMAT_L32_FLOAT 0x0E4 #define GEN5_SURFACEFORMAT_A32_FLOAT 0x0E5 #define GEN5_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define GEN5_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define GEN5_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define GEN5_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define GEN5_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define GEN5_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define GEN5_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define GEN5_SURFACEFORMAT_R32_UNORM 0x0F1 #define GEN5_SURFACEFORMAT_R32_SNORM 0x0F2 #define GEN5_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define GEN5_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define GEN5_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define GEN5_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define GEN5_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define GEN5_SURFACEFORMAT_R32_SSCALED 0x0F8 #define GEN5_SURFACEFORMAT_R32_USCALED 0x0F9 #define GEN5_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define GEN5_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define GEN5_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define GEN5_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define GEN5_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define GEN5_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define GEN5_SURFACEFORMAT_R8G8_UNORM 0x106 #define GEN5_SURFACEFORMAT_R8G8_SNORM 0x107 #define GEN5_SURFACEFORMAT_R8G8_SINT 0x108 #define GEN5_SURFACEFORMAT_R8G8_UINT 0x109 #define GEN5_SURFACEFORMAT_R16_UNORM 0x10A #define GEN5_SURFACEFORMAT_R16_SNORM 0x10B #define GEN5_SURFACEFORMAT_R16_SINT 0x10C #define GEN5_SURFACEFORMAT_R16_UINT 0x10D #define GEN5_SURFACEFORMAT_R16_FLOAT 0x10E #define GEN5_SURFACEFORMAT_I16_UNORM 0x111 #define GEN5_SURFACEFORMAT_L16_UNORM 0x112 #define GEN5_SURFACEFORMAT_A16_UNORM 0x113 #define GEN5_SURFACEFORMAT_L8A8_UNORM 0x114 #define GEN5_SURFACEFORMAT_I16_FLOAT 0x115 #define GEN5_SURFACEFORMAT_L16_FLOAT 0x116 #define GEN5_SURFACEFORMAT_A16_FLOAT 0x117 #define GEN5_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define GEN5_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define GEN5_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define GEN5_SURFACEFORMAT_R8G8_SSCALED 0x11C #define GEN5_SURFACEFORMAT_R8G8_USCALED 0x11D #define GEN5_SURFACEFORMAT_R16_SSCALED 0x11E #define GEN5_SURFACEFORMAT_R16_USCALED 0x11F #define GEN5_SURFACEFORMAT_R8_UNORM 0x140 #define GEN5_SURFACEFORMAT_R8_SNORM 0x141 #define GEN5_SURFACEFORMAT_R8_SINT 0x142 #define GEN5_SURFACEFORMAT_R8_UINT 0x143 #define GEN5_SURFACEFORMAT_A8_UNORM 0x144 #define GEN5_SURFACEFORMAT_I8_UNORM 0x145 #define GEN5_SURFACEFORMAT_L8_UNORM 0x146 #define GEN5_SURFACEFORMAT_P4A4_UNORM 0x147 #define GEN5_SURFACEFORMAT_A4P4_UNORM 0x148 #define GEN5_SURFACEFORMAT_R8_SSCALED 0x149 #define GEN5_SURFACEFORMAT_R8_USCALED 0x14A #define GEN5_SURFACEFORMAT_R1_UINT 0x181 #define GEN5_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define GEN5_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define GEN5_SURFACEFORMAT_BC1_UNORM 0x186 #define GEN5_SURFACEFORMAT_BC2_UNORM 0x187 #define GEN5_SURFACEFORMAT_BC3_UNORM 0x188 #define GEN5_SURFACEFORMAT_BC4_UNORM 0x189 #define GEN5_SURFACEFORMAT_BC5_UNORM 0x18A #define GEN5_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define GEN5_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define GEN5_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define GEN5_SURFACEFORMAT_MONO8 0x18E #define GEN5_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define GEN5_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define GEN5_SURFACEFORMAT_DXT1_RGB 0x191 #define GEN5_SURFACEFORMAT_FXT1 0x192 #define GEN5_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define GEN5_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define GEN5_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define GEN5_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define GEN5_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define GEN5_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define GEN5_SURFACEFORMAT_BC4_SNORM 0x199 #define GEN5_SURFACEFORMAT_BC5_SNORM 0x19A #define GEN5_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define GEN5_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define GEN5_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define GEN5_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define GEN5_SURFACERETURNFORMAT_FLOAT32 0 #define GEN5_SURFACERETURNFORMAT_S1 1 #define GEN5_SURFACE_1D 0 #define GEN5_SURFACE_2D 1 #define GEN5_SURFACE_3D 2 #define GEN5_SURFACE_CUBE 3 #define GEN5_SURFACE_BUFFER 4 #define GEN5_SURFACE_NULL 7 #define GEN5_BORDER_COLOR_MODE_DEFAULT 0 #define GEN5_BORDER_COLOR_MODE_LEGACY 1 #define GEN5_TEXCOORDMODE_WRAP 0 #define GEN5_TEXCOORDMODE_MIRROR 1 #define GEN5_TEXCOORDMODE_CLAMP 2 #define GEN5_TEXCOORDMODE_CUBE 3 #define GEN5_TEXCOORDMODE_CLAMP_BORDER 4 #define GEN5_TEXCOORDMODE_MIRROR_ONCE 5 #define GEN5_THREAD_PRIORITY_NORMAL 0 #define GEN5_THREAD_PRIORITY_HIGH 1 #define GEN5_TILEWALK_XMAJOR 0 #define GEN5_TILEWALK_YMAJOR 1 #define GEN5_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define GEN5_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define GEN5_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define GEN5_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define VFCOMPONENT_NOSTORE 0 #define VFCOMPONENT_STORE_SRC 1 #define VFCOMPONENT_STORE_0 2 #define VFCOMPONENT_STORE_1_FLT 3 #define VFCOMPONENT_STORE_1_INT 4 #define VFCOMPONENT_STORE_VID 5 #define VFCOMPONENT_STORE_IID 6 #define VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define GEN5_ALIGN_1 0 #define GEN5_ALIGN_16 1 #define GEN5_ADDRESS_DIRECT 0 #define GEN5_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define GEN5_CHANNEL_X 0 #define GEN5_CHANNEL_Y 1 #define GEN5_CHANNEL_Z 2 #define GEN5_CHANNEL_W 3 #define GEN5_COMPRESSION_NONE 0 #define GEN5_COMPRESSION_2NDHALF 1 #define GEN5_COMPRESSION_COMPRESSED 2 #define GEN5_CONDITIONAL_NONE 0 #define GEN5_CONDITIONAL_Z 1 #define GEN5_CONDITIONAL_NZ 2 #define GEN5_CONDITIONAL_EQ 1 /* Z */ #define GEN5_CONDITIONAL_NEQ 2 /* NZ */ #define GEN5_CONDITIONAL_G 3 #define GEN5_CONDITIONAL_GE 4 #define GEN5_CONDITIONAL_L 5 #define GEN5_CONDITIONAL_LE 6 #define GEN5_CONDITIONAL_C 7 #define GEN5_CONDITIONAL_O 8 #define GEN5_DEBUG_NONE 0 #define GEN5_DEBUG_BREAKPOINT 1 #define GEN5_DEPENDENCY_NORMAL 0 #define GEN5_DEPENDENCY_NOTCLEARED 1 #define GEN5_DEPENDENCY_NOTCHECKED 2 #define GEN5_DEPENDENCY_DISABLE 3 #define GEN5_EXECUTE_1 0 #define GEN5_EXECUTE_2 1 #define GEN5_EXECUTE_4 2 #define GEN5_EXECUTE_8 3 #define GEN5_EXECUTE_16 4 #define GEN5_EXECUTE_32 5 #define GEN5_HORIZONTAL_STRIDE_0 0 #define GEN5_HORIZONTAL_STRIDE_1 1 #define GEN5_HORIZONTAL_STRIDE_2 2 #define GEN5_HORIZONTAL_STRIDE_4 3 #define GEN5_INSTRUCTION_NORMAL 0 #define GEN5_INSTRUCTION_SATURATE 1 #define GEN5_MASK_ENABLE 0 #define GEN5_MASK_DISABLE 1 #define GEN5_OPCODE_MOV 1 #define GEN5_OPCODE_SEL 2 #define GEN5_OPCODE_NOT 4 #define GEN5_OPCODE_AND 5 #define GEN5_OPCODE_OR 6 #define GEN5_OPCODE_XOR 7 #define GEN5_OPCODE_SHR 8 #define GEN5_OPCODE_SHL 9 #define GEN5_OPCODE_RSR 10 #define GEN5_OPCODE_RSL 11 #define GEN5_OPCODE_ASR 12 #define GEN5_OPCODE_CMP 16 #define GEN5_OPCODE_JMPI 32 #define GEN5_OPCODE_IF 34 #define GEN5_OPCODE_IFF 35 #define GEN5_OPCODE_ELSE 36 #define GEN5_OPCODE_ENDIF 37 #define GEN5_OPCODE_DO 38 #define GEN5_OPCODE_WHILE 39 #define GEN5_OPCODE_BREAK 40 #define GEN5_OPCODE_CONTINUE 41 #define GEN5_OPCODE_HALT 42 #define GEN5_OPCODE_MSAVE 44 #define GEN5_OPCODE_MRESTORE 45 #define GEN5_OPCODE_PUSH 46 #define GEN5_OPCODE_POP 47 #define GEN5_OPCODE_WAIT 48 #define GEN5_OPCODE_SEND 49 #define GEN5_OPCODE_ADD 64 #define GEN5_OPCODE_MUL 65 #define GEN5_OPCODE_AVG 66 #define GEN5_OPCODE_FRC 67 #define GEN5_OPCODE_RNDU 68 #define GEN5_OPCODE_RNDD 69 #define GEN5_OPCODE_RNDE 70 #define GEN5_OPCODE_RNDZ 71 #define GEN5_OPCODE_MAC 72 #define GEN5_OPCODE_MACH 73 #define GEN5_OPCODE_LZD 74 #define GEN5_OPCODE_SAD2 80 #define GEN5_OPCODE_SADA2 81 #define GEN5_OPCODE_DP4 84 #define GEN5_OPCODE_DPH 85 #define GEN5_OPCODE_DP3 86 #define GEN5_OPCODE_DP2 87 #define GEN5_OPCODE_DPA2 88 #define GEN5_OPCODE_LINE 89 #define GEN5_OPCODE_NOP 126 #define GEN5_PREDICATE_NONE 0 #define GEN5_PREDICATE_NORMAL 1 #define GEN5_PREDICATE_ALIGN1_ANYV 2 #define GEN5_PREDICATE_ALIGN1_ALLV 3 #define GEN5_PREDICATE_ALIGN1_ANY2H 4 #define GEN5_PREDICATE_ALIGN1_ALL2H 5 #define GEN5_PREDICATE_ALIGN1_ANY4H 6 #define GEN5_PREDICATE_ALIGN1_ALL4H 7 #define GEN5_PREDICATE_ALIGN1_ANY8H 8 #define GEN5_PREDICATE_ALIGN1_ALL8H 9 #define GEN5_PREDICATE_ALIGN1_ANY16H 10 #define GEN5_PREDICATE_ALIGN1_ALL16H 11 #define GEN5_PREDICATE_ALIGN16_REPLICATE_X 2 #define GEN5_PREDICATE_ALIGN16_REPLICATE_Y 3 #define GEN5_PREDICATE_ALIGN16_REPLICATE_Z 4 #define GEN5_PREDICATE_ALIGN16_REPLICATE_W 5 #define GEN5_PREDICATE_ALIGN16_ANY4H 6 #define GEN5_PREDICATE_ALIGN16_ALL4H 7 #define GEN5_ARCHITECTURE_REGISTER_FILE 0 #define GEN5_GENERAL_REGISTER_FILE 1 #define GEN5_MESSAGE_REGISTER_FILE 2 #define GEN5_IMMEDIATE_VALUE 3 #define GEN5_REGISTER_TYPE_UD 0 #define GEN5_REGISTER_TYPE_D 1 #define GEN5_REGISTER_TYPE_UW 2 #define GEN5_REGISTER_TYPE_W 3 #define GEN5_REGISTER_TYPE_UB 4 #define GEN5_REGISTER_TYPE_B 5 #define GEN5_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define GEN5_REGISTER_TYPE_HF 6 #define GEN5_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define GEN5_REGISTER_TYPE_F 7 #define GEN5_ARF_NULL 0x00 #define GEN5_ARF_ADDRESS 0x10 #define GEN5_ARF_ACCUMULATOR 0x20 #define GEN5_ARF_FLAG 0x30 #define GEN5_ARF_MASK 0x40 #define GEN5_ARF_MASK_STACK 0x50 #define GEN5_ARF_MASK_STACK_DEPTH 0x60 #define GEN5_ARF_STATE 0x70 #define GEN5_ARF_CONTROL 0x80 #define GEN5_ARF_NOTIFICATION_COUNT 0x90 #define GEN5_ARF_IP 0xA0 #define GEN5_AMASK 0 #define GEN5_IMASK 1 #define GEN5_LMASK 2 #define GEN5_CMASK 3 #define GEN5_THREAD_NORMAL 0 #define GEN5_THREAD_ATOMIC 1 #define GEN5_THREAD_SWITCH 2 #define GEN5_VERTICAL_STRIDE_0 0 #define GEN5_VERTICAL_STRIDE_1 1 #define GEN5_VERTICAL_STRIDE_2 2 #define GEN5_VERTICAL_STRIDE_4 3 #define GEN5_VERTICAL_STRIDE_8 4 #define GEN5_VERTICAL_STRIDE_16 5 #define GEN5_VERTICAL_STRIDE_32 6 #define GEN5_VERTICAL_STRIDE_64 7 #define GEN5_VERTICAL_STRIDE_128 8 #define GEN5_VERTICAL_STRIDE_256 9 #define GEN5_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define GEN5_WIDTH_1 0 #define GEN5_WIDTH_2 1 #define GEN5_WIDTH_4 2 #define GEN5_WIDTH_8 3 #define GEN5_WIDTH_16 4 #define GEN5_STATELESS_BUFFER_BOUNDARY_1K 0 #define GEN5_STATELESS_BUFFER_BOUNDARY_2K 1 #define GEN5_STATELESS_BUFFER_BOUNDARY_4K 2 #define GEN5_STATELESS_BUFFER_BOUNDARY_8K 3 #define GEN5_STATELESS_BUFFER_BOUNDARY_16K 4 #define GEN5_STATELESS_BUFFER_BOUNDARY_32K 5 #define GEN5_STATELESS_BUFFER_BOUNDARY_64K 6 #define GEN5_STATELESS_BUFFER_BOUNDARY_128K 7 #define GEN5_STATELESS_BUFFER_BOUNDARY_256K 8 #define GEN5_STATELESS_BUFFER_BOUNDARY_512K 9 #define GEN5_STATELESS_BUFFER_BOUNDARY_1M 10 #define GEN5_STATELESS_BUFFER_BOUNDARY_2M 11 #define GEN5_POLYGON_FACING_FRONT 0 #define GEN5_POLYGON_FACING_BACK 1 #define GEN5_MESSAGE_TARGET_NULL 0 #define GEN5_MESSAGE_TARGET_MATH 1 #define GEN5_MESSAGE_TARGET_SAMPLER 2 #define GEN5_MESSAGE_TARGET_GATEWAY 3 #define GEN5_MESSAGE_TARGET_DATAPORT_READ 4 #define GEN5_MESSAGE_TARGET_DATAPORT_WRITE 5 #define GEN5_MESSAGE_TARGET_URB 6 #define GEN5_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN5_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define GEN5_SAMPLER_RETURN_FORMAT_UINT32 2 #define GEN5_SAMPLER_RETURN_FORMAT_SINT32 3 #define GEN5_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define GEN5_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define GEN5_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define GEN5_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define GEN5_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define GEN5_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define GEN5_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define GEN5_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define GEN5_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define GEN5_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define GEN5_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define GEN5_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define GEN5_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define GEN5_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define GEN5_SAMPLER_MESSAGE_SIMD8_LD 3 #define GEN5_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN5_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define GEN5_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define GEN5_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define GEN5_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define GEN5_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define GEN5_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define GEN5_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define GEN5_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define GEN5_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define GEN5_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define GEN5_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define GEN5_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define GEN5_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define GEN5_DATAPORT_READ_TARGET_DATA_CACHE 0 #define GEN5_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define GEN5_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define GEN5_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define GEN5_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define GEN5_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define GEN5_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define GEN5_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define GEN5_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define GEN5_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define GEN5_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define GEN5_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define GEN5_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define GEN5_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define GEN5_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define GEN5_MATH_FUNCTION_INV 1 #define GEN5_MATH_FUNCTION_LOG 2 #define GEN5_MATH_FUNCTION_EXP 3 #define GEN5_MATH_FUNCTION_SQRT 4 #define GEN5_MATH_FUNCTION_RSQ 5 #define GEN5_MATH_FUNCTION_SIN 6 /* was 7 */ #define GEN5_MATH_FUNCTION_COS 7 /* was 8 */ #define GEN5_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define GEN5_MATH_FUNCTION_TAN 9 #define GEN5_MATH_FUNCTION_POW 10 #define GEN5_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define GEN5_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define GEN5_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define GEN5_MATH_INTEGER_UNSIGNED 0 #define GEN5_MATH_INTEGER_SIGNED 1 #define GEN5_MATH_PRECISION_FULL 0 #define GEN5_MATH_PRECISION_PARTIAL 1 #define GEN5_MATH_SATURATE_NONE 0 #define GEN5_MATH_SATURATE_SATURATE 1 #define GEN5_MATH_DATA_VECTOR 0 #define GEN5_MATH_DATA_SCALAR 1 #define GEN5_URB_OPCODE_WRITE 0 #define GEN5_URB_SWIZZLE_NONE 0 #define GEN5_URB_SWIZZLE_INTERLEAVE 1 #define GEN5_URB_SWIZZLE_TRANSPOSE 2 #define GEN5_SCRATCH_SPACE_SIZE_1K 0 #define GEN5_SCRATCH_SPACE_SIZE_2K 1 #define GEN5_SCRATCH_SPACE_SIZE_4K 2 #define GEN5_SCRATCH_SPACE_SIZE_8K 3 #define GEN5_SCRATCH_SPACE_SIZE_16K 4 #define GEN5_SCRATCH_SPACE_SIZE_32K 5 #define GEN5_SCRATCH_SPACE_SIZE_64K 6 #define GEN5_SCRATCH_SPACE_SIZE_128K 7 #define GEN5_SCRATCH_SPACE_SIZE_256K 8 #define GEN5_SCRATCH_SPACE_SIZE_512K 9 #define GEN5_SCRATCH_SPACE_SIZE_1M 10 #define GEN5_SCRATCH_SPACE_SIZE_2M 11 #define CMD_URB_FENCE 0x6000 #define CMD_CONST_BUFFER_STATE 0x6001 #define CMD_CONST_BUFFER 0x6002 #define CMD_STATE_BASE_ADDRESS 0x6101 #define CMD_STATE_INSN_POINTER 0x6102 #define CMD_PIPELINE_SELECT 0x6104 #define CMD_PIPELINED_STATE_POINTERS 0x7800 #define CMD_BINDING_TABLE_PTRS 0x7801 #define CMD_VERTEX_BUFFER 0x7808 #define CMD_VERTEX_ELEMENT 0x7809 #define CMD_INDEX_BUFFER 0x780a #define CMD_VF_STATISTICS 0x780b #define CMD_DRAW_RECT 0x7900 #define CMD_BLEND_CONSTANT_COLOR 0x7901 #define CMD_CHROMA_KEY 0x7904 #define CMD_DEPTH_BUFFER 0x7905 #define CMD_POLY_STIPPLE_OFFSET 0x7906 #define CMD_POLY_STIPPLE_PATTERN 0x7907 #define CMD_LINE_STIPPLE_PATTERN 0x7908 #define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908 #define CMD_PIPE_CONTROL 0x7a00 #define CMD_3D_PRIM 0x7b00 #define CMD_MI_FLUSH 0x0200 /* Various values from the R0 vertex header: */ #define R02_PRIM_END 0x1 #define R02_PRIM_START 0x2 /* media pipeline */ #define GEN5_VFE_MODE_GENERIC 0x0 #define GEN5_VFE_MODE_VLD_MPEG2 0x1 #define GEN5_VFE_MODE_IS 0x2 #define GEN5_VFE_MODE_AVC_MC 0x4 #define GEN5_VFE_MODE_AVC_IT 0x7 #define GEN5_VFE_MODE_VC1_IT 0xB #define GEN5_VFE_DEBUG_COUNTER_FREE 0 #define GEN5_VFE_DEBUG_COUNTER_FROZEN 1 #define GEN5_VFE_DEBUG_COUNTER_ONCE 2 #define GEN5_VFE_DEBUG_COUNTER_ALWAYS 3 /* VLD_STATE */ #define GEN5_MPEG_TOP_FIELD 1 #define GEN5_MPEG_BOTTOM_FIELD 2 #define GEN5_MPEG_FRAME 3 #define GEN5_MPEG_QSCALE_LINEAR 0 #define GEN5_MPEG_QSCALE_NONLINEAR 1 #define GEN5_MPEG_ZIGZAG_SCAN 0 #define GEN5_MPEG_ALTER_VERTICAL_SCAN 1 #define GEN5_MPEG_I_PICTURE 1 #define GEN5_MPEG_P_PICTURE 2 #define GEN5_MPEG_B_PICTURE 3 /* Command packets: */ struct header { unsigned int length:16; unsigned int opcode:16; }; union header_union { struct header bits; unsigned int dword; }; struct gen5_3d_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:3; unsigned int wc_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } dest; unsigned int dword2; unsigned int dword3; }; struct gen5_3d_primitive { struct { unsigned int length:8; unsigned int pad:2; unsigned int topology:5; unsigned int indexed:1; unsigned int opcode:16; } header; unsigned int verts_per_instance; unsigned int start_vert_location; unsigned int instance_count; unsigned int start_instance_location; unsigned int base_vert_location; }; /* These seem to be passed around as function args, so it works out * better to keep them as #defines: */ #define GEN5_FLUSH_READ_CACHE 0x1 #define GEN5_FLUSH_STATE_CACHE 0x2 #define GEN5_INHIBIT_FLUSH_RENDER_CACHE 0x4 #define GEN5_FLUSH_SNAPSHOT_COUNTERS 0x8 struct gen5_mi_flush { unsigned int flags:4; unsigned int pad:12; unsigned int opcode:16; }; struct gen5_vf_statistics { unsigned int statistics_enable:1; unsigned int pad:15; unsigned int opcode:16; }; struct gen5_binding_table_pointers { struct header header; unsigned int vs; unsigned int gs; unsigned int clp; unsigned int sf; unsigned int wm; }; struct gen5_blend_constant_color { struct header header; float blend_constant_color[4]; }; struct gen5_depthbuffer { union header_union header; union { struct { unsigned int pitch:18; unsigned int format:3; unsigned int pad:4; unsigned int depth_offset_disable:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad2:1; unsigned int surface_type:3; } bits; unsigned int dword; } dword1; unsigned int dword2_base_addr; union { struct { unsigned int pad:1; unsigned int mipmap_layout:1; unsigned int lod:4; unsigned int width:13; unsigned int height:13; } bits; unsigned int dword; } dword3; union { struct { unsigned int pad:12; unsigned int min_array_element:9; unsigned int depth:11; } bits; unsigned int dword; } dword4; }; struct gen5_drawrect { struct header header; unsigned int xmin:16; unsigned int ymin:16; unsigned int xmax:16; unsigned int ymax:16; unsigned int xorg:16; unsigned int yorg:16; }; struct gen5_global_depth_offset_clamp { struct header header; float depth_offset_clamp; }; struct gen5_indexbuffer { union { struct { unsigned int length:8; unsigned int index_format:2; unsigned int cut_index_enable:1; unsigned int pad:5; unsigned int opcode:16; } bits; unsigned int dword; } header; unsigned int buffer_start; unsigned int buffer_end; }; struct gen5_line_stipple { struct header header; struct { unsigned int pattern:16; unsigned int pad:16; } bits0; struct { unsigned int repeat_count:9; unsigned int pad:7; unsigned int inverse_repeat_count:16; } bits1; }; struct gen5_pipelined_state_pointers { struct header header; struct { unsigned int pad:5; unsigned int offset:27; } vs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } gs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } clp; struct { unsigned int pad:5; unsigned int offset:27; } sf; struct { unsigned int pad:5; unsigned int offset:27; } wm; struct { unsigned int pad:5; unsigned int offset:27; /* KW: check me! */ } cc; }; struct gen5_polygon_stipple_offset { struct header header; struct { unsigned int y_offset:5; unsigned int pad:3; unsigned int x_offset:5; unsigned int pad0:19; } bits0; }; struct gen5_polygon_stipple { struct header header; unsigned int stipple[32]; }; struct gen5_pipeline_select { struct { unsigned int pipeline_select:1; unsigned int pad:15; unsigned int opcode:16; } header; }; struct gen5_pipe_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:2; unsigned int instruction_state_cache_flush_enable:1; unsigned int write_cache_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int post_sync_operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } bits1; unsigned int data0; unsigned int data1; }; struct gen5_urb_fence { struct { unsigned int length:8; unsigned int vs_realloc:1; unsigned int gs_realloc:1; unsigned int clp_realloc:1; unsigned int sf_realloc:1; unsigned int vfe_realloc:1; unsigned int cs_realloc:1; unsigned int pad:2; unsigned int opcode:16; } header; struct { unsigned int vs_fence:10; unsigned int gs_fence:10; unsigned int clp_fence:10; unsigned int pad:2; } bits0; struct { unsigned int sf_fence:10; unsigned int vf_fence:10; unsigned int cs_fence:10; unsigned int pad:2; } bits1; }; struct gen5_constant_buffer_state /* previously gen5_command_streamer */ { struct header header; struct { unsigned int nr_urb_entries:3; unsigned int pad:1; unsigned int urb_entry_size:5; unsigned int pad0:23; } bits0; }; struct gen5_constant_buffer { struct { unsigned int length:8; unsigned int valid:1; unsigned int pad:7; unsigned int opcode:16; } header; struct { unsigned int buffer_length:6; unsigned int buffer_address:26; } bits0; }; struct gen5_state_base_address { struct header header; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int general_state_address:27; } bits0; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int surface_state_address:27; } bits1; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int indirect_object_state_address:27; } bits2; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int general_state_upper_bound:20; } bits3; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int indirect_object_state_upper_bound:20; } bits4; }; struct gen5_state_prefetch { struct header header; struct { unsigned int prefetch_count:3; unsigned int pad:3; unsigned int prefetch_pointer:26; } bits0; }; struct gen5_system_instruction_pointer { struct header header; struct { unsigned int pad:4; unsigned int system_instruction_pointer:28; } bits0; }; /* State structs for the various fixed function units: */ struct thread0 { unsigned int pad0:1; unsigned int grf_reg_count:3; unsigned int pad1:2; unsigned int kernel_start_pointer:26; }; struct thread1 { unsigned int ext_halt_exception_enable:1; unsigned int sw_exception_enable:1; unsigned int mask_stack_exception_enable:1; unsigned int timeout_exception_enable:1; unsigned int illegal_op_exception_enable:1; unsigned int pad0:3; unsigned int depth_coef_urb_read_offset:6; /* WM only */ unsigned int pad1:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad3:5; unsigned int single_program_flow:1; }; struct thread2 { unsigned int per_thread_scratch_space:4; unsigned int pad0:6; unsigned int scratch_space_base_pointer:22; }; struct thread3 { unsigned int dispatch_grf_start_reg:4; unsigned int urb_entry_read_offset:6; unsigned int pad0:1; unsigned int urb_entry_read_length:6; unsigned int pad1:1; unsigned int const_urb_entry_read_offset:6; unsigned int pad2:1; unsigned int const_urb_entry_read_length:6; unsigned int pad3:1; }; struct gen5_clip_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:9; unsigned int gs_output_stats:1; /* not always */ unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; /* may be less */ unsigned int pad3:1; } thread4; struct { unsigned int pad0:13; unsigned int clip_mode:3; unsigned int userclip_enable_flags:8; unsigned int userclip_must_clip:1; unsigned int pad1:1; unsigned int guard_band_enable:1; unsigned int viewport_z_clip_enable:1; unsigned int viewport_xy_clip_enable:1; unsigned int vertex_position_space:1; unsigned int api_mode:1; unsigned int pad2:1; } clip5; struct { unsigned int pad0:5; unsigned int clipper_viewport_state_ptr:27; } clip6; float viewport_xmin; float viewport_xmax; float viewport_ymin; float viewport_ymax; }; struct gen5_cc_unit_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } cc0; struct { unsigned int bf_stencil_ref:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; unsigned int stencil_ref:8; } cc1; struct { unsigned int logicop_enable:1; unsigned int pad0:10; unsigned int depth_write_enable:1; unsigned int depth_test_function:3; unsigned int depth_test:1; unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; } cc2; struct { unsigned int pad0:8; unsigned int alpha_test_func:3; unsigned int alpha_test:1; unsigned int blend_enable:1; unsigned int ia_blend_enable:1; unsigned int pad1:1; unsigned int alpha_test_format:1; unsigned int pad2:16; } cc3; struct { unsigned int pad0:5; unsigned int cc_viewport_state_offset:27; } cc4; struct { unsigned int pad0:2; unsigned int ia_dest_blend_factor:5; unsigned int ia_src_blend_factor:5; unsigned int ia_blend_function:3; unsigned int statistics_enable:1; unsigned int logicop_func:4; unsigned int pad1:11; unsigned int dither_enable:1; } cc5; struct { unsigned int clamp_post_alpha_blend:1; unsigned int clamp_pre_alpha_blend:1; unsigned int clamp_range:2; unsigned int pad0:11; unsigned int y_dither_offset:2; unsigned int x_dither_offset:2; unsigned int dest_blend_factor:5; unsigned int src_blend_factor:5; unsigned int blend_function:3; } cc6; struct { union { float f; unsigned char ub[4]; } alpha_ref; } cc7; }; struct gen5_sf_unit_state { struct thread0 thread0; struct { unsigned int pad0:7; unsigned int sw_exception_enable:1; unsigned int pad1:3; unsigned int mask_stack_exception_enable:1; unsigned int pad2:1; unsigned int illegal_op_exception_enable:1; unsigned int pad3:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad4:5; unsigned int single_program_flow:1; } sf1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; unsigned int pad3:1; } thread4; struct { unsigned int front_winding:1; unsigned int viewport_transform:1; unsigned int pad0:3; unsigned int sf_viewport_state_offset:27; } sf5; struct { unsigned int pad0:9; unsigned int dest_org_vbias:4; unsigned int dest_org_hbias:4; unsigned int scissor:1; unsigned int disable_2x2_trifilter:1; unsigned int disable_zero_pix_trifilter:1; unsigned int point_rast_rule:2; unsigned int line_endcap_aa_region_width:2; unsigned int line_width:4; unsigned int fast_scissor_disable:1; unsigned int cull_mode:2; unsigned int aa_enable:1; } sf6; struct { unsigned int point_size:11; unsigned int use_point_size_state:1; unsigned int subpixel_precision:1; unsigned int sprite_point:1; unsigned int pad0:11; unsigned int trifan_pv:2; unsigned int linestrip_pv:2; unsigned int tristrip_pv:2; unsigned int line_last_pixel_enable:1; } sf7; }; struct gen5_gs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:1; unsigned int pad3:6; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } gs5; struct { unsigned int max_vp_index:4; unsigned int pad0:26; unsigned int reorder_enable:1; unsigned int pad1:1; } gs6; }; struct gen5_vs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:4; unsigned int pad3:3; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } vs5; struct { unsigned int vs_enable:1; unsigned int vert_cache_disable:1; unsigned int pad0:30; } vs6; }; struct gen5_wm_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int stats_enable:1; unsigned int pad0:1; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } wm4; struct { unsigned int enable_8_pix:1; unsigned int enable_16_pix:1; unsigned int enable_32_pix:1; unsigned int pad0:7; unsigned int legacy_global_depth_bias:1; unsigned int line_stipple:1; unsigned int depth_offset:1; unsigned int polygon_stipple:1; unsigned int line_aa_region_width:2; unsigned int line_endcap_aa_region_width:2; unsigned int early_depth_test:1; unsigned int thread_dispatch_enable:1; unsigned int program_uses_depth:1; unsigned int program_computes_depth:1; unsigned int program_uses_killpixel:1; unsigned int legacy_line_rast: 1; unsigned int transposed_urb_read:1; unsigned int max_threads:7; } wm5; float global_depth_offset_constant; float global_depth_offset_scale; struct { unsigned int pad0:1; unsigned int grf_reg_count_1:3; unsigned int pad1:2; unsigned int kernel_start_pointer_1:26; } wm8; struct { unsigned int pad0:1; unsigned int grf_reg_count_2:3; unsigned int pad1:2; unsigned int kernel_start_pointer_2:26; } wm9; struct { unsigned int pad0:1; unsigned int grf_reg_count_3:3; unsigned int pad1:2; unsigned int kernel_start_pointer_3:26; } wm10; }; struct gen5_wm_unit_state_padded { struct gen5_wm_unit_state state; char pad[64 - sizeof(struct gen5_wm_unit_state)]; }; /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct gen5_sampler_default_border_color { float color[4]; }; struct gen5_sampler_legacy_border_color { uint8_t color[4]; }; struct gen5_sampler_state { struct { unsigned int shadow_function:3; unsigned int lod_bias:11; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad:1; unsigned int lod_preclamp:1; unsigned int border_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:3; unsigned int max_lod:10; unsigned int min_lod:10; } ss1; struct { unsigned int pad:5; unsigned int border_color_pointer:27; } ss2; struct { uint32_t pad:13; uint32_t address_round:6; uint32_t max_aniso:3; uint32_t chroma_key_mode:1; uint32_t chroma_key_index:2; uint32_t chroma_key_enable:1; uint32_t mbz:6; } ss3; }; struct gen5_clipper_viewport { float xmin; float xmax; float ymin; float ymax; }; struct gen5_cc_viewport { float min_depth; float max_depth; }; struct gen5_sf_viewport { struct { float m00; float m11; float m22; float m30; float m31; float m32; } viewport; struct { short xmin; short ymin; short xmax; short ymax; } scissor; }; /* Documented in the subsystem/shared-functions/sampler chapter... */ struct gen5_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad:3; unsigned int render_cache_read_mode:1; unsigned int mipmap_layout_mode:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int color_blend:1; unsigned int writedisable_blue:1; unsigned int writedisable_green:1; unsigned int writedisable_red:1; unsigned int writedisable_alpha:1; unsigned int surface_format:9; unsigned int data_return_format:1; unsigned int pad0:1; unsigned int surface_type:3; } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int render_target_rotation:2; unsigned int mip_count:4; unsigned int width:13; unsigned int height:13; } ss2; struct { unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad:1; unsigned int pitch:18; unsigned int depth:11; } ss3; struct { unsigned int pad:19; unsigned int min_array_elt:9; unsigned int min_lod:4; } ss4; struct { unsigned int pad:20; unsigned int y_offset:4; unsigned int pad2:1; unsigned int x_offset:7; } ss5; }; /* Surface state DW0 */ #define GEN5_SURFACE_RC_READ_WRITE (1 << 8) #define GEN5_SURFACE_MIPLAYOUT_SHIFT 10 #define GEN5_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN5_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN5_SURFACE_CUBEFACE_ENABLES 0x3f #define GEN5_SURFACE_BLEND_ENABLED (1 << 13) #define GEN5_SURFACE_WRITEDISABLE_B_SHIFT 14 #define GEN5_SURFACE_WRITEDISABLE_G_SHIFT 15 #define GEN5_SURFACE_WRITEDISABLE_R_SHIFT 16 #define GEN5_SURFACE_WRITEDISABLE_A_SHIFT 17 #define GEN5_SURFACE_FORMAT_SHIFT 18 #define GEN5_SURFACE_FORMAT_MASK INTEL_MASK(26, 18) #define GEN5_SURFACE_TYPE_SHIFT 29 #define GEN5_SURFACE_TYPE_MASK GEN5_MASK(31, 29) #define GEN5_SURFACE_1D 0 #define GEN5_SURFACE_2D 1 #define GEN5_SURFACE_3D 2 #define GEN5_SURFACE_CUBE 3 #define GEN5_SURFACE_BUFFER 4 #define GEN5_SURFACE_NULL 7 /* Surface state DW2 */ #define GEN5_SURFACE_HEIGHT_SHIFT 19 #define GEN5_SURFACE_HEIGHT_MASK GEN5_MASK(31, 19) #define GEN5_SURFACE_WIDTH_SHIFT 6 #define GEN5_SURFACE_WIDTH_MASK GEN5_MASK(18, 6) #define GEN5_SURFACE_LOD_SHIFT 2 #define GEN5_SURFACE_LOD_MASK GEN5_MASK(5, 2) /* Surface state DW3 */ #define GEN5_SURFACE_DEPTH_SHIFT 21 #define GEN5_SURFACE_DEPTH_MASK GEN5_MASK(31, 21) #define GEN5_SURFACE_PITCH_SHIFT 3 #define GEN5_SURFACE_PITCH_MASK GEN5_MASK(19, 3) #define GEN5_SURFACE_TILED (1 << 1) #define GEN5_SURFACE_TILED_Y (1 << 0) /* Surface state DW4 */ #define GEN5_SURFACE_MIN_LOD_SHIFT 28 #define GEN5_SURFACE_MIN_LOD_MASK GEN5_MASK(31, 28) /* Surface state DW5 */ #define GEN5_SURFACE_X_OFFSET_SHIFT 25 #define GEN5_SURFACE_X_OFFSET_MASK GEN5_MASK(31, 25) #define GEN5_SURFACE_Y_OFFSET_SHIFT 20 #define GEN5_SURFACE_Y_OFFSET_MASK GEN5_MASK(23, 20) struct gen5_vertex_buffer_state { struct { unsigned int pitch:11; unsigned int pad:15; unsigned int access_type:1; unsigned int vb_index:5; } vb0; unsigned int start_addr; unsigned int max_index; #if 1 unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */ #endif }; #define GEN5_VBP_MAX 17 struct gen5_vb_array_state { struct header header; struct gen5_vertex_buffer_state vb[GEN5_VBP_MAX]; }; struct gen5_vertex_element_state { struct { unsigned int src_offset:11; unsigned int pad:5; unsigned int src_format:9; unsigned int pad0:1; unsigned int valid:1; unsigned int vertex_buffer_index:5; } ve0; struct { unsigned int dst_offset:8; unsigned int pad:8; unsigned int vfcomponent3:4; unsigned int vfcomponent2:4; unsigned int vfcomponent1:4; unsigned int vfcomponent0:4; } ve1; }; #define GEN5_VEP_MAX 18 struct gen5_vertex_element_packet { struct header header; struct gen5_vertex_element_state ve[GEN5_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */ }; struct gen5_urb_immediate { unsigned int opcode:4; unsigned int offset:6; unsigned int swizzle_control:2; unsigned int pad:1; unsigned int allocate:1; unsigned int used:1; unsigned int complete:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; }; /* Instruction format for the execution units: */ struct gen5_instruction { struct { unsigned int opcode:7; unsigned int pad:1; unsigned int access_mode:1; unsigned int mask_control:1; unsigned int dependency_control:2; unsigned int compression_control:2; unsigned int thread_control:2; unsigned int predicate_control:4; unsigned int predicate_inverse:1; unsigned int execution_size:3; unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */ unsigned int pad0:2; unsigned int debug_control:1; unsigned int saturate:1; } header; union { struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad:1; unsigned int dest_subreg_nr:5; unsigned int dest_reg_nr:8; unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } da1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad:6; int dest_indirect_offset:10; /* offset against the deref'd address reg */ unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */ unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } ia1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad0:1; unsigned int dest_writemask:4; unsigned int dest_subreg_nr:1; unsigned int dest_reg_nr:8; unsigned int pad1:2; unsigned int dest_address_mode:1; } da16; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad0:6; unsigned int dest_writemask:4; int dest_indirect_offset:6; unsigned int dest_subreg_nr:3; unsigned int pad1:2; unsigned int dest_address_mode:1; } ia16; } bits1; union { struct { unsigned int src0_subreg_nr:5; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } da1; struct { int src0_indirect_offset:10; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } ia1; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; unsigned int src0_subreg_nr:1; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } da16; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; int src0_indirect_offset:6; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia16; } bits2; union { struct { unsigned int src1_subreg_nr:5; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int pad0:7; } da1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; unsigned int src1_subreg_nr:1; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int pad2:7; } da16; struct { int src1_indirect_offset:10; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; int src1_indirect_offset:6; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad2:6; } ia16; struct { int jump_count:16; /* note: signed */ unsigned int pop_count:4; unsigned int pad0:12; } if_else; struct { unsigned int function:4; unsigned int int_type:1; unsigned int precision:1; unsigned int saturate:1; unsigned int data_type:1; unsigned int pad0:8; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } math; struct { unsigned int binding_table_index:8; unsigned int sampler:4; unsigned int return_format:2; unsigned int msg_type:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } sampler; struct gen5_urb_immediate urb; struct { unsigned int binding_table_index:8; unsigned int msg_control:4; unsigned int msg_type:2; unsigned int target_cache:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_read; struct { unsigned int binding_table_index:8; unsigned int msg_control:3; unsigned int pixel_scoreboard_clear:1; unsigned int msg_type:3; unsigned int send_commit_msg:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_write; struct { unsigned int pad:16; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } generic; unsigned int ud; } bits3; }; /* media pipeline */ struct gen5_vfe_state { struct { unsigned int per_thread_scratch_space:4; unsigned int pad3:3; unsigned int extend_vfe_state_present:1; unsigned int pad2:2; unsigned int scratch_base:22; } vfe0; struct { unsigned int debug_counter_control:2; unsigned int children_present:1; unsigned int vfe_mode:4; unsigned int pad2:2; unsigned int num_urb_entries:7; unsigned int urb_entry_alloc_size:9; unsigned int max_threads:7; } vfe1; struct { unsigned int pad4:4; unsigned int interface_descriptor_base:28; } vfe2; }; struct gen5_vld_state { struct { unsigned int pad6:6; unsigned int scan_order:1; unsigned int intra_vlc_format:1; unsigned int quantizer_scale_type:1; unsigned int concealment_motion_vector:1; unsigned int frame_predict_frame_dct:1; unsigned int top_field_first:1; unsigned int picture_structure:2; unsigned int intra_dc_precision:2; unsigned int f_code_0_0:4; unsigned int f_code_0_1:4; unsigned int f_code_1_0:4; unsigned int f_code_1_1:4; } vld0; struct { unsigned int pad2:9; unsigned int picture_coding_type:2; unsigned int pad:21; } vld1; struct { unsigned int index_0:4; unsigned int index_1:4; unsigned int index_2:4; unsigned int index_3:4; unsigned int index_4:4; unsigned int index_5:4; unsigned int index_6:4; unsigned int index_7:4; } desc_remap_table0; struct { unsigned int index_8:4; unsigned int index_9:4; unsigned int index_10:4; unsigned int index_11:4; unsigned int index_12:4; unsigned int index_13:4; unsigned int index_14:4; unsigned int index_15:4; } desc_remap_table1; }; struct gen5_interface_descriptor { struct { unsigned int grf_reg_blocks:4; unsigned int pad:2; unsigned int kernel_start_pointer:26; } desc0; struct { unsigned int pad:7; unsigned int software_exception:1; unsigned int pad2:3; unsigned int maskstack_exception:1; unsigned int pad3:1; unsigned int illegal_opcode_exception:1; unsigned int pad4:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int single_program_flow:1; unsigned int pad5:1; unsigned int const_urb_entry_read_offset:6; unsigned int const_urb_entry_read_len:6; } desc1; struct { unsigned int pad:2; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } desc2; struct { unsigned int binding_table_entry_count:5; unsigned int binding_table_pointer:27; } desc3; }; struct gen6_blend_state { struct { unsigned int dest_blend_factor:5; unsigned int source_blend_factor:5; unsigned int pad3:1; unsigned int blend_func:3; unsigned int pad2:1; unsigned int ia_dest_blend_factor:5; unsigned int ia_source_blend_factor:5; unsigned int pad1:1; unsigned int ia_blend_func:3; unsigned int pad0:1; unsigned int ia_blend_enable:1; unsigned int blend_enable:1; } blend0; struct { unsigned int post_blend_clamp_enable:1; unsigned int pre_blend_clamp_enable:1; unsigned int clamp_range:2; unsigned int pad0:4; unsigned int x_dither_offset:2; unsigned int y_dither_offset:2; unsigned int dither_enable:1; unsigned int alpha_test_func:3; unsigned int alpha_test_enable:1; unsigned int pad1:1; unsigned int logic_op_func:4; unsigned int logic_op_enable:1; unsigned int pad2:1; unsigned int write_disable_b:1; unsigned int write_disable_g:1; unsigned int write_disable_r:1; unsigned int write_disable_a:1; unsigned int pad3:1; unsigned int alpha_to_coverage_dither:1; unsigned int alpha_to_one:1; unsigned int alpha_to_coverage:1; } blend1; }; struct gen6_color_calc_state { struct { unsigned int alpha_test_format:1; unsigned int pad0:14; unsigned int round_disable:1; unsigned int bf_stencil_ref:8; unsigned int stencil_ref:8; } cc0; union { float alpha_ref_f; struct { unsigned int ui:8; unsigned int pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen6_depth_stencil_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } ds0; struct { unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; } ds1; struct { unsigned int pad0:26; unsigned int depth_write_enable:1; unsigned int depth_test_func:3; unsigned int pad1:1; unsigned int depth_test_enable:1; } ds2; }; typedef enum { SAMPLER_FILTER_NEAREST = 0, SAMPLER_FILTER_BILINEAR, FILTER_COUNT } sampler_filter_t; typedef enum { SAMPLER_EXTEND_NONE = 0, SAMPLER_EXTEND_REPEAT, SAMPLER_EXTEND_PAD, SAMPLER_EXTEND_REFLECT, EXTEND_COUNT } sampler_extend_t; typedef enum { WM_KERNEL = 0, WM_KERNEL_P, WM_KERNEL_MASK, WM_KERNEL_MASK_P, WM_KERNEL_MASKCA, WM_KERNEL_MASKCA_P, WM_KERNEL_MASKSA, WM_KERNEL_MASKSA_P, WM_KERNEL_OPACITY, WM_KERNEL_OPACITY_P, WM_KERNEL_VIDEO_PLANAR, WM_KERNEL_VIDEO_PACKED, KERNEL_COUNT } wm_kernel_t; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen6_common.c000066400000000000000000000042311267532330400242160ustar00rootroot00000000000000/* * Copyright © 2011-2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "gen6_common.h" #include "gen4_vertex.h" void gen6_render_context_switch(struct kgem *kgem, int new_mode) { if (kgem->nbatch) { DBG(("%s: from %d to %d, submit batch\n", __FUNCTION__, kgem->mode, new_mode)); _kgem_submit(kgem); } if (kgem->nexec) { DBG(("%s: from %d to %d, reset incomplete batch\n", __FUNCTION__, kgem->mode, new_mode)); kgem_reset(kgem); } assert(kgem->nbatch == 0); assert(kgem->nreloc == 0); assert(kgem->nexec == 0); kgem->ring = new_mode; } void gen6_render_retire(struct kgem *kgem) { struct sna *sna; if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire)) kgem->ring = kgem->mode; sna = container_of(kgem, struct sna, kgem); if (sna->render.nvertex_reloc == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) { DBG(("%s: resetting idle vbo\n", __FUNCTION__)); sna->render.vertex_used = 0; sna->render.vertex_index = 0; } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen6_common.h000066400000000000000000000117071267532330400242310ustar00rootroot00000000000000/* * Copyright © 2011-2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef GEN6_COMMON_H #define GEN6_COMMON_H #include "sna.h" #define NO_RING_SWITCH(sna) (!(sna)->kgem.has_semaphores) #define PREFER_RENDER 0 /* -1 -> BLT, 1 -> RENDER */ static inline bool is_uncached(struct sna *sna, struct kgem_bo *bo) { return bo->io || (bo->scanout && !sna->kgem.has_wt); } inline static bool can_switch_to_blt(struct sna *sna, struct kgem_bo *bo, unsigned flags) { if (sna->kgem.ring != KGEM_RENDER) return true; if (NO_RING_SWITCH(sna)) return false; if (bo && RQ_IS_BLT(bo->rq)) return true; if (bo && bo->tiling == I915_TILING_Y) return false; if (sna->render_state.gt < 2) return true; if (bo && RQ_IS_RENDER(bo->rq)) return false; if (flags & COPY_LAST) return true; return kgem_ring_is_idle(&sna->kgem, KGEM_BLT); } static inline bool untiled_tlb_miss(struct kgem_bo *bo) { if (kgem_bo_is_render(bo)) return false; return bo->tiling == I915_TILING_NONE && bo->pitch >= 4096; } static int prefer_blt_bo(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst) { assert(dst != NULL); if (PREFER_RENDER) return PREFER_RENDER < 0; if (dst->rq) return RQ_IS_BLT(dst->rq); if (sna->flags & SNA_POWERSAVE) return true; if (src) { if (sna->render_state.gt > 1) return false; if (src->rq) return RQ_IS_BLT(src->rq); if (src->tiling == I915_TILING_Y) return false; } else { if (sna->render_state.gt > 2) return false; } if (sna->render_state.gt < 2) return true; return dst->tiling == I915_TILING_NONE || is_uncached(sna, dst); } inline static bool force_blt_ring(struct sna *sna, struct kgem_bo *bo) { if (sna->kgem.mode == KGEM_RENDER) return false; if (NO_RING_SWITCH(sna)) return sna->kgem.ring == KGEM_BLT; if (bo->tiling == I915_TILING_Y) return false; if (sna->flags & SNA_POWERSAVE) return true; if (sna->render_state.gt < 2) return true; return false; } nonnull inline static bool prefer_blt_ring(struct sna *sna, struct kgem_bo *bo, unsigned flags) { if (PREFER_RENDER) return PREFER_RENDER < 0; assert(!force_blt_ring(sna, bo)); assert(!kgem_bo_is_render(bo) || NO_RING_SWITCH(sna)); if (kgem_bo_is_blt(bo)) return true; return can_switch_to_blt(sna, bo, flags); } nonnull inline static bool prefer_render_ring(struct sna *sna, struct kgem_bo *bo) { if (sna->kgem.ring == KGEM_RENDER) return true; if (sna->kgem.ring != KGEM_NONE && NO_RING_SWITCH(sna)) return false; if (kgem_bo_is_render(bo)) return true; if (sna->flags & SNA_POWERSAVE) return false; if (!prefer_blt_bo(sna, NULL, bo)) return true; return !kgem_ring_is_idle(&sna->kgem, KGEM_RENDER); } inline static bool prefer_blt_composite(struct sna *sna, struct sna_composite_op *tmp) { if (PREFER_RENDER) return PREFER_RENDER < 0; if (untiled_tlb_miss(tmp->dst.bo) || untiled_tlb_miss(tmp->src.bo)) return true; if (force_blt_ring(sna, tmp->dst.bo)) return true; if (prefer_render_ring(sna, tmp->dst.bo)) return false; if (!prefer_blt_ring(sna, tmp->dst.bo, 0)) return false; return prefer_blt_bo(sna, tmp->src.bo, tmp->dst.bo); } nonnull static inline bool prefer_blt_fill(struct sna *sna, struct kgem_bo *bo, unsigned flags) { if (PREFER_RENDER) return PREFER_RENDER < 0; if (untiled_tlb_miss(bo)) return true; if (force_blt_ring(sna, bo)) return true; if ((flags & (FILL_POINTS | FILL_SPANS)) == 0) { if (prefer_render_ring(sna, bo)) return false; if (!prefer_blt_ring(sna, bo, 0)) return false; } else { if (can_switch_to_blt(sna, bo, 0)) return true; } return prefer_blt_bo(sna, NULL, bo); } void gen6_render_context_switch(struct kgem *kgem, int new_mode); void gen6_render_retire(struct kgem *kgem); #endif /* GEN6_COMMON_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen6_render.c000066400000000000000000003065401267532330400242150ustar00rootroot00000000000000/* * Copyright © 2006,2008,2011 Intel Corporation * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Carl Worth * Keith Packard * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_video.h" #include "brw/brw.h" #include "gen6_render.h" #include "gen6_common.h" #include "gen4_common.h" #include "gen4_source.h" #include "gen4_vertex.h" #define ALWAYS_INVALIDATE 0 #define ALWAYS_FLUSH 0 #define ALWAYS_STALL 0 #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_BOXES 0 #define NO_FILL_ONE 0 #define NO_FILL_CLEAR 0 #define USE_8_PIXEL_DISPATCH 1 #define USE_16_PIXEL_DISPATCH 1 #define USE_32_PIXEL_DISPATCH 0 #if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH #error "Must select at least 8, 16 or 32 pixel dispatch" #endif #define GEN6_MAX_SIZE 8192 struct gt_info { const char *name; int max_vs_threads; int max_gs_threads; int max_wm_threads; struct { int size; int max_vs_entries; int max_gs_entries; } urb; int gt; }; static const struct gt_info gt1_info = { .name = "Sandybridge (gen6, gt1)", .max_vs_threads = 24, .max_gs_threads = 21, .max_wm_threads = 40, .urb = { 32, 256, 256 }, .gt = 1, }; static const struct gt_info gt2_info = { .name = "Sandybridge (gen6, gt2)", .max_vs_threads = 60, .max_gs_threads = 60, .max_wm_threads = 80, .urb = { 64, 256, 256 }, .gt = 2, }; static const uint32_t ps_kernel_packed[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_planar[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_planar.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; #define NOKERNEL(kernel_enum, func, ns) \ [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, func, 0, ns} #define KERNEL(kernel_enum, kernel, ns) \ [GEN6_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), ns} static const struct wm_kernel_info { const char *name; const void *data; unsigned int size; unsigned int num_surfaces; } wm_kernels[] = { NOKERNEL(NOMASK, brw_wm_kernel__affine, 2), NOKERNEL(NOMASK_P, brw_wm_kernel__projective, 2), NOKERNEL(MASK, brw_wm_kernel__affine_mask, 3), NOKERNEL(MASK_P, brw_wm_kernel__projective_mask, 3), NOKERNEL(MASKCA, brw_wm_kernel__affine_mask_ca, 3), NOKERNEL(MASKCA_P, brw_wm_kernel__projective_mask_ca, 3), NOKERNEL(MASKSA, brw_wm_kernel__affine_mask_sa, 3), NOKERNEL(MASKSA_P, brw_wm_kernel__projective_mask_sa, 3), NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2), NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2), KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), }; #undef KERNEL static const struct blendinfo { bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen6_blend_op[] = { /* Clear */ {0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO}, /* Src */ {0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO}, /* Dst */ {0, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ONE}, /* Over */ {1, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ONE}, /* In */ {0, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_ZERO}, /* InReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_SRC_ALPHA}, /* Out */ {0, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_ZERO}, /* OutReverse */ {1, GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, GEN6_BLENDFACTOR_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, GEN6_BLENDFACTOR_INV_DST_ALPHA, GEN6_BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in gen6_blend_op. * * This leaves out GEN6_BLENDFACTOR_INV_DST_COLOR, * GEN6_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * GEN6_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define GEN6_BLENDFACTOR_COUNT (GEN6_BLENDFACTOR_INV_DST_ALPHA + 1) #define GEN6_BLEND_STATE_PADDED_SIZE ALIGN(sizeof(struct gen6_blend_state), 64) #define BLEND_OFFSET(s, d) \ (((s) * GEN6_BLENDFACTOR_COUNT + (d)) * GEN6_BLEND_STATE_PADDED_SIZE) #define NO_BLEND BLEND_OFFSET(GEN6_BLENDFACTOR_ONE, GEN6_BLENDFACTOR_ZERO) #define CLEAR BLEND_OFFSET(GEN6_BLENDFACTOR_ZERO, GEN6_BLENDFACTOR_ZERO) #define SAMPLER_OFFSET(sf, se, mf, me) \ (((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me) + 2) * 2 * sizeof(struct gen6_sampler_state)) #define VERTEX_2s2s 0 #define COPY_SAMPLER 0 #define COPY_VERTEX VERTEX_2s2s #define COPY_FLAGS(a) GEN6_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN6_WM_KERNEL_NOMASK, COPY_VERTEX) #define FILL_SAMPLER (2 * sizeof(struct gen6_sampler_state)) #define FILL_VERTEX VERTEX_2s2s #define FILL_FLAGS(op, format) GEN6_SET_FLAGS(FILL_SAMPLER, gen6_get_blend((op), false, (format)), GEN6_WM_KERNEL_NOMASK, FILL_VERTEX) #define FILL_FLAGS_NOBLEND GEN6_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN6_WM_KERNEL_NOMASK, FILL_VERTEX) #define GEN6_SAMPLER(f) (((f) >> 16) & 0xfff0) #define GEN6_BLEND(f) (((f) >> 0) & 0xfff0) #define GEN6_KERNEL(f) (((f) >> 16) & 0xf) #define GEN6_VERTEX(f) (((f) >> 0) & 0xf) #define GEN6_SET_FLAGS(S, B, K, V) (((S) | (K)) << 16 | ((B) | (V))) #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) #define OUT_VERTEX_F(v) vertex_emit(sna, v) static inline bool too_large(int width, int height) { return width > GEN6_MAX_SIZE || height > GEN6_MAX_SIZE; } static uint32_t gen6_get_blend(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t src, dst; src = gen6_blend_op[op].src_blend; dst = gen6_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that * we'll treat it always as 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (src == GEN6_BLENDFACTOR_DST_ALPHA) src = GEN6_BLENDFACTOR_ONE; else if (src == GEN6_BLENDFACTOR_INV_DST_ALPHA) src = GEN6_BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a * case where the source blend factor is 0, and the source blend * value is the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen6_blend_op[op].src_alpha) { if (dst == GEN6_BLENDFACTOR_SRC_ALPHA) dst = GEN6_BLENDFACTOR_SRC_COLOR; else if (dst == GEN6_BLENDFACTOR_INV_SRC_ALPHA) dst = GEN6_BLENDFACTOR_INV_SRC_COLOR; } DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n", op, dst_format, PICT_FORMAT_A(dst_format), src, dst, (int)BLEND_OFFSET(src, dst))); return BLEND_OFFSET(src, dst); } static uint32_t gen6_get_card_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_x8r8g8b8: return GEN6_SURFACEFORMAT_B8G8R8X8_UNORM; case PICT_a8b8g8r8: return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM; case PICT_x8b8g8r8: return GEN6_SURFACEFORMAT_R8G8B8X8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM; case PICT_x2r10g10b10: return GEN6_SURFACEFORMAT_B10G10R10X2_UNORM; #endif case PICT_r8g8b8: return GEN6_SURFACEFORMAT_R8G8B8_UNORM; case PICT_r5g6b5: return GEN6_SURFACEFORMAT_B5G6R5_UNORM; case PICT_a1r5g5b5: return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN6_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM; } } static uint32_t gen6_get_dest_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return GEN6_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return GEN6_SURFACEFORMAT_R8G8B8A8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return GEN6_SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return GEN6_SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return GEN6_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN6_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return GEN6_SURFACEFORMAT_B4G4R4A4_UNORM; } } static bool gen6_check_dst_format(PictFormat format) { if (gen6_get_dest_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static bool gen6_check_format(uint32_t format) { if (gen6_get_card_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static uint32_t gen6_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return SAMPLER_FILTER_NEAREST; case PictFilterBilinear: return SAMPLER_FILTER_BILINEAR; } } static uint32_t gen6_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: return false; } } static uint32_t gen6_repeat(uint32_t repeat) { switch (repeat) { default: assert(0); case RepeatNone: return SAMPLER_EXTEND_NONE; case RepeatNormal: return SAMPLER_EXTEND_REPEAT; case RepeatPad: return SAMPLER_EXTEND_PAD; case RepeatReflect: return SAMPLER_EXTEND_REFLECT; } } static bool gen6_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: return false; } } static int gen6_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine) { int base; if (has_mask) { if (is_ca) { if (gen6_blend_op[op].src_alpha) base = GEN6_WM_KERNEL_MASKSA; else base = GEN6_WM_KERNEL_MASKCA; } else base = GEN6_WM_KERNEL_MASK; } else base = GEN6_WM_KERNEL_NOMASK; return base + !is_affine; } inline static void gen6_emit_pipe_invalidate(struct sna *sna) { OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH | GEN6_PIPE_CONTROL_TC_FLUSH | GEN6_PIPE_CONTROL_CS_STALL); OUT_BATCH(0); OUT_BATCH(0); } inline static void gen6_emit_pipe_flush(struct sna *sna, bool need_stall) { unsigned stall; stall = 0; if (need_stall) stall = GEN6_PIPE_CONTROL_CS_STALL; OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN6_PIPE_CONTROL_WC_FLUSH | stall); OUT_BATCH(0); OUT_BATCH(0); } inline static void gen6_emit_pipe_stall(struct sna *sna) { OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN6_PIPE_CONTROL_CS_STALL | GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH(0); OUT_BATCH(0); } static void gen6_emit_urb(struct sna *sna) { OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2)); OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) | (sna->render_state.gen6.info->urb.max_vs_entries << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */ OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) | (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */ } static void gen6_emit_state_base_address(struct sna *sna) { OUT_BATCH(GEN6_STATE_BASE_ADDRESS | (10 - 2)); OUT_BATCH(0); /* general */ OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */ sna->kgem.nbatch, NULL, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */ sna->kgem.nbatch, sna->render_state.gen6.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(0); /* indirect */ OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, sna->render_state.gen6.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); /* upper bounds, disable */ OUT_BATCH(0); OUT_BATCH(BASE_ADDRESS_MODIFY); OUT_BATCH(0); OUT_BATCH(BASE_ADDRESS_MODIFY); } static void gen6_emit_viewports(struct sna *sna) { OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS | GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen6_emit_vs(struct sna *sna) { /* disable VS constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2)); OUT_BATCH(0); /* no VS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ } static void gen6_emit_gs(struct sna *sna) { /* disable GS constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2)); OUT_BATCH(0); /* no GS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ } static void gen6_emit_clip(struct sna *sna) { OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(0); } static void gen6_emit_wm_constants(struct sna *sna) { /* disable WM constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen6_emit_null_depth_buffer(struct sna *sna) { OUT_BATCH(GEN6_3DSTATE_DEPTH_BUFFER | (7 - 2)); OUT_BATCH(GEN6_SURFACE_NULL << GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT | GEN6_DEPTHFORMAT_D32_FLOAT << GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_CLEAR_PARAMS | (2 - 2)); OUT_BATCH(0); } static void gen6_emit_invariant(struct sna *sna) { OUT_BATCH(GEN6_PIPELINE_SELECT | PIPELINE_SELECT_3D); OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | (3 - 2)); OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER | GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */ OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2)); OUT_BATCH(1); gen6_emit_urb(sna); gen6_emit_state_base_address(sna); gen6_emit_viewports(sna); gen6_emit_vs(sna); gen6_emit_gs(sna); gen6_emit_clip(sna); gen6_emit_wm_constants(sna); gen6_emit_null_depth_buffer(sna); sna->render_state.gen6.needs_invariant = false; } static void gen6_emit_cc(struct sna *sna, int blend) { struct gen6_render_state *render = &sna->render_state.gen6; if (render->blend == blend) return; DBG(("%s: blend = %x\n", __FUNCTION__, blend)); OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2)); OUT_BATCH((render->cc_blend + blend) | 1); if (render->blend == (unsigned)-1) { OUT_BATCH(1); OUT_BATCH(1); } else { OUT_BATCH(0); OUT_BATCH(0); } render->blend = blend; } static void gen6_emit_sampler(struct sna *sna, uint32_t state) { if (sna->render_state.gen6.samplers == state) return; sna->render_state.gen6.samplers = state; DBG(("%s: sampler = %x\n", __FUNCTION__, state)); OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS | GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS | (4 - 2)); OUT_BATCH(0); /* VS */ OUT_BATCH(0); /* GS */ OUT_BATCH(sna->render_state.gen6.wm_state + state); } static void gen6_emit_sf(struct sna *sna, bool has_mask) { int num_sf_outputs = has_mask ? 2 : 1; if (sna->render_state.gen6.num_sf_outputs == num_sf_outputs) return; DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n", __FUNCTION__, num_sf_outputs, 1, 0)); sna->render_state.gen6.num_sf_outputs = num_sf_outputs; OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2)); OUT_BATCH(num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT | 1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT | 1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE); OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW9 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW14 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW19 */ } static void gen6_emit_wm(struct sna *sna, unsigned int kernel, bool has_mask) { const uint32_t *kernels; if (sna->render_state.gen6.kernel == kernel) return; sna->render_state.gen6.kernel = kernel; kernels = sna->render_state.gen6.wm_kernel[kernel]; DBG(("%s: switching to %s, num_surfaces=%d (8-pixel? %d, 16-pixel? %d,32-pixel? %d)\n", __FUNCTION__, wm_kernels[kernel].name, wm_kernels[kernel].num_surfaces, kernels[0], kernels[1], kernels[2])); OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2)); OUT_BATCH(kernels[0] ?: kernels[1] ?: kernels[2]); OUT_BATCH(1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT | wm_kernels[kernel].num_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT); OUT_BATCH(0); /* scratch space */ OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << GEN6_3DSTATE_WM_DISPATCH_0_START_GRF_SHIFT | 8 << GEN6_3DSTATE_WM_DISPATCH_1_START_GRF_SHIFT | 6 << GEN6_3DSTATE_WM_DISPATCH_2_START_GRF_SHIFT); OUT_BATCH((sna->render_state.gen6.info->max_wm_threads - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT | (kernels[0] ? GEN6_3DSTATE_WM_8_DISPATCH_ENABLE : 0) | (kernels[1] ? GEN6_3DSTATE_WM_16_DISPATCH_ENABLE : 0) | (kernels[2] ? GEN6_3DSTATE_WM_32_DISPATCH_ENABLE : 0) | GEN6_3DSTATE_WM_DISPATCH_ENABLE); OUT_BATCH((1 + has_mask) << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT | GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(kernels[2]); OUT_BATCH(kernels[1]); } static bool gen6_emit_binding_table(struct sna *sna, uint16_t offset) { if (sna->render_state.gen6.surface_table == offset) return false; /* Binding table pointers */ OUT_BATCH(GEN6_3DSTATE_BINDING_TABLE_POINTERS | GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS | (4 - 2)); OUT_BATCH(0); /* vs */ OUT_BATCH(0); /* gs */ /* Only the PS uses the binding table */ OUT_BATCH(offset*4); sna->render_state.gen6.surface_table = offset; return true; } static bool gen6_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; assert(!too_large(abs(op->dst.x), abs(op->dst.y))); assert(!too_large(op->dst.width, op->dst.height)); if (sna->render_state.gen6.drawrect_limit == limit && sna->render_state.gen6.drawrect_offset == offset) return true; /* [DevSNB-C+{W/A}] Before any depth stall flush (including those * produced by non-pipelined state commands), software needs to first * send a PIPE_CONTROL with no bits set except Post-Sync Operation != * 0. * * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent * BEFORE the pipe-control with a post-sync op and no write-cache * flushes. */ if (!sna->render_state.gen6.first_state_packet) gen6_emit_pipe_stall(sna); OUT_BATCH(GEN6_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN6_PIPE_CONTROL_WRITE_TIME); OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch, sna->render_state.gen6.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16 | I915_GEM_DOMAIN_INSTRUCTION, 64)); OUT_BATCH(0); DBG(("%s: offset=(%d, %d), limit=(%d, %d)\n", __FUNCTION__, op->dst.x, op->dst.y, op->dst.width, op->dst.height)); OUT_BATCH(GEN6_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(limit); OUT_BATCH(offset); sna->render_state.gen6.drawrect_offset = offset; sna->render_state.gen6.drawrect_limit = limit; return false; } static void gen6_emit_vertex_elements(struct sna *sna, const struct sna_composite_op *op) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0) * texture coordinate 1 if (has_mask is true): same as above */ struct gen6_render_state *render = &sna->render_state.gen6; uint32_t src_format, dw; int id = GEN6_VERTEX(op->u.gen6.flags); bool has_mask; DBG(("%s: setup id=%d\n", __FUNCTION__, id)); if (render->ve_id == id) return; render->ve_id = id; /* The VUE layout * dword 0-3: pad (0.0, 0.0, 0.0. 0.0) * dword 4-7: position (x, y, 1.0, 1.0), * dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0) * dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0) * * dword 4-15 are fetched from vertex buffer */ has_mask = (id >> 2) != 0; OUT_BATCH(GEN6_3DSTATE_VERTEX_ELEMENTS | ((2 * (3 + has_mask)) + 1 - 2)); OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT << VE0_FORMAT_SHIFT | 0 << VE0_OFFSET_SHIFT); OUT_BATCH(GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT | GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT | GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT | GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT); /* x,y */ OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | GEN6_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT | 0 << VE0_OFFSET_SHIFT); OUT_BATCH(GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT | GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT | GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT | GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT); /* u0, v0, w0 */ DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3)); dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id & 3) { default: assert(0); case 0: src_format = GEN6_SURFACEFORMAT_R16G16_SSCALED; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT; break; case 1: src_format = GEN6_SURFACEFORMAT_R32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT; break; case 2: src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | src_format << VE0_FORMAT_SHIFT | 4 << VE0_OFFSET_SHIFT); OUT_BATCH(dw); /* u1, v1, w1 */ if (has_mask) { unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float); DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, offset)); dw = GEN6_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT; switch (id >> 2) { case 1: src_format = GEN6_SURFACEFORMAT_R32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT; break; default: assert(0); case 2: src_format = GEN6_SURFACEFORMAT_R32G32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN6_SURFACEFORMAT_R32G32B32_FLOAT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT; dw |= GEN6_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID | src_format << VE0_FORMAT_SHIFT | offset << VE0_OFFSET_SHIFT); OUT_BATCH(dw); } } static void gen6_emit_state(struct sna *sna, const struct sna_composite_op *op, uint16_t wm_binding_table) { bool need_invalidate; bool need_flush; bool need_stall; assert(op->dst.bo->exec); need_flush = wm_binding_table & 1; if (ALWAYS_FLUSH) need_flush = true; wm_binding_table &= ~1; need_stall = sna->render_state.gen6.surface_table != wm_binding_table; if (ALWAYS_STALL) need_stall = true; need_invalidate = kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo); if (ALWAYS_INVALIDATE) need_invalidate = true; if (need_invalidate) { gen6_emit_pipe_invalidate(sna); kgem_clear_dirty(&sna->kgem); assert(op->dst.bo->exec); kgem_bo_mark_dirty(op->dst.bo); need_flush = false; need_stall = false; sna->render_state.gen6.first_state_packet = true; } if (need_flush) { gen6_emit_pipe_flush(sna, need_stall); need_stall = false; sna->render_state.gen6.first_state_packet = true; } need_stall &= gen6_emit_drawing_rectangle(sna, op); if (need_stall) gen6_emit_pipe_stall(sna); gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)); gen6_emit_sampler(sna, GEN6_SAMPLER(op->u.gen6.flags)); gen6_emit_sf(sna, GEN6_VERTEX(op->u.gen6.flags) >> 2); gen6_emit_wm(sna, GEN6_KERNEL(op->u.gen6.flags), GEN6_VERTEX(op->u.gen6.flags) >> 2); gen6_emit_vertex_elements(sna, op); gen6_emit_binding_table(sna, wm_binding_table); sna->render_state.gen6.first_state_packet = false; } static bool gen6_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { struct gen6_render_state *state = &sna->render_state.gen6; if (!op->need_magic_ca_pass) return false; DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__, sna->render.vertex_start, sna->render.vertex_index)); gen6_emit_pipe_stall(sna); gen6_emit_cc(sna, gen6_get_blend(PictOpAdd, true, op->dst.format)); gen6_emit_wm(sna, gen6_choose_composite_kernel(PictOpAdd, true, true, op->is_affine), true); OUT_BATCH(GEN6_3DPRIMITIVE | GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT | 0 << 9 | 4); OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start); OUT_BATCH(sna->render.vertex_start); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ state->last_primitive = sna->kgem.nbatch; return true; } typedef struct gen6_surface_state_padded { struct gen6_surface_state state; char pad[32 - sizeof(struct gen6_surface_state)]; } gen6_surface_state_padded; static void null_create(struct sna_static_stream *stream) { /* A bunch of zeros useful for legacy border color and depth-stencil */ sna_static_stream_map(stream, 64, 64); } static void scratch_create(struct sna_static_stream *stream) { /* 64 bytes of scratch space for random writes, such as * the pipe-control w/a. */ sna_static_stream_map(stream, 64, 64); } static void sampler_state_init(struct gen6_sampler_state *sampler_state, sampler_filter_t filter, sampler_extend_t extend) { sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.border_color_mode = GEN6_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SAMPLER_FILTER_NEAREST: sampler_state->ss0.min_filter = GEN6_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = GEN6_MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: sampler_state->ss0.min_filter = GEN6_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = GEN6_MAPFILTER_LINEAR; break; } switch (extend) { default: case SAMPLER_EXTEND_NONE: sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_WRAP; sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_WRAP; sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: sampler_state->ss1.r_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; sampler_state->ss1.s_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; sampler_state->ss1.t_wrap_mode = GEN6_TEXCOORDMODE_MIRROR; break; } } static void sampler_copy_init(struct gen6_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static void sampler_fill_init(struct gen6_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static uint32_t gen6_tiling_bits(uint32_t tiling) { switch (tiling) { default: assert(0); case I915_TILING_NONE: return 0; case I915_TILING_X: return GEN6_SURFACE_TILED; case I915_TILING_Y: return GEN6_SURFACE_TILED | GEN6_SURFACE_TILED_Y; } } /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static int gen6_bind_bo(struct sna *sna, struct kgem_bo *bo, uint32_t width, uint32_t height, uint32_t format, bool is_dst) { uint32_t *ss; uint32_t domains; uint16_t offset; uint32_t is_scanout = is_dst && bo->scanout; /* After the first bind, we manage the cache domains within the batch */ offset = kgem_bo_get_binding(bo, format | is_dst << 30 | is_scanout << 31); if (offset) { DBG(("[%x] bo(handle=%d), format=%d, reuse %s binding\n", offset, bo->handle, format, is_dst ? "render" : "sampler")); assert(offset >= sna->kgem.surface); if (is_dst) kgem_bo_mark_dirty(bo); return offset * sizeof(uint32_t); } offset = sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t); ss = sna->kgem.batch + offset; ss[0] = (GEN6_SURFACE_2D << GEN6_SURFACE_TYPE_SHIFT | GEN6_SURFACE_BLEND_ENABLED | format << GEN6_SURFACE_FORMAT_SHIFT); if (is_dst) { ss[0] |= GEN6_SURFACE_RC_READ_WRITE; domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER; } else domains = I915_GEM_DOMAIN_SAMPLER << 16; ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); ss[2] = ((width - 1) << GEN6_SURFACE_WIDTH_SHIFT | (height - 1) << GEN6_SURFACE_HEIGHT_SHIFT); assert(bo->pitch <= (1 << 18)); ss[3] = (gen6_tiling_bits(bo->tiling) | (bo->pitch - 1) << GEN6_SURFACE_PITCH_SHIFT); ss[4] = 0; ss[5] = (is_scanout || bo->io) ? 0 : 3 << 16; kgem_bo_set_binding(bo, format | is_dst << 30 | is_scanout << 31, offset); DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n", offset, bo->handle, ss[1], format, width, height, bo->pitch, bo->tiling, domains & 0xffff ? "render" : "sampler")); return offset * sizeof(uint32_t); } static void gen6_emit_vertex_buffer(struct sna *sna, const struct sna_composite_op *op) { int id = GEN6_VERTEX(op->u.gen6.flags); OUT_BATCH(GEN6_3DSTATE_VERTEX_BUFFERS | 3); OUT_BATCH(id << VB0_BUFFER_INDEX_SHIFT | VB0_VERTEXDATA | 4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT); sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch; OUT_BATCH(0); OUT_BATCH(~0); /* max address: disabled */ OUT_BATCH(0); sna->render.vb_id |= 1 << id; } static void gen6_emit_primitive(struct sna *sna) { if (sna->kgem.nbatch == sna->render_state.gen6.last_primitive) { DBG(("%s: continuing previous primitive, start=%d, index=%d\n", __FUNCTION__, sna->render.vertex_start, sna->render.vertex_index)); sna->render.vertex_offset = sna->kgem.nbatch - 5; return; } OUT_BATCH(GEN6_3DPRIMITIVE | GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST << GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT | 0 << 9 | 4); sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(sna->render.vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ sna->render.vertex_start = sna->render.vertex_index; DBG(("%s: started new primitive: index=%d\n", __FUNCTION__, sna->render.vertex_start)); sna->render_state.gen6.last_primitive = sna->kgem.nbatch; } static bool gen6_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { int id = 1 << GEN6_VERTEX(op->u.gen6.flags); int ndwords; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; ndwords = op->need_magic_ca_pass ? 60 : 6; if ((sna->render.vb_id & id) == 0) ndwords += 5; if (!kgem_check_batch(&sna->kgem, ndwords)) return false; if ((sna->render.vb_id & id) == 0) gen6_emit_vertex_buffer(sna, op); gen6_emit_primitive(sna); return true; } static int gen6_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5)) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 2)) return 0; if (sna->render.vertex_offset) { gen4_vertex_flush(sna); if (gen6_magic_ca_pass(sna, op)) { gen6_emit_pipe_stall(sna); gen6_emit_cc(sna, GEN6_BLEND(op->u.gen6.flags)); gen6_emit_wm(sna, GEN6_KERNEL(op->u.gen6.flags), GEN6_VERTEX(op->u.gen6.flags) >> 2); } } return gen4_vertex_finish(sna); } inline static int gen6_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want, void (*emit_state)(struct sna *, const struct sna_composite_op *op)) { int rem; assert(want); start: rem = vertex_space(sna); if (unlikely(rem < op->floats_per_rect)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen6_get_rectangles__flush(sna, op); if (unlikely(rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen6_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; assert(want > 0); sna->render.vertex_index += 3*want; return want; flush: if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen6_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); emit_state(sna, op); goto start; } inline static uint32_t *gen6_composite_get_binding_table(struct sna *sna, uint16_t *offset) { uint32_t *table; sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t); /* Clear all surplus entries to zero in case of prefetch */ table = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(struct gen6_surface_state_padded)); DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface)); *offset = sna->kgem.surface; return table; } static bool gen6_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch, 150, 4*8)); kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } if (sna->render_state.gen6.needs_invariant) gen6_emit_invariant(sna); return kgem_bo_is_dirty(op->dst.bo); } static void gen6_emit_composite_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset; bool dirty; dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); binding_table[0] = gen6_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen6_get_dest_format(op->dst.format), true); binding_table[1] = gen6_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (op->mask.bo) { binding_table[2] = gen6_bind_bo(sna, op->mask.bo, op->mask.width, op->mask.height, op->mask.card_format, false); } if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table && (op->mask.bo == NULL || sna->kgem.batch[sna->render_state.gen6.surface_table+2] == binding_table[2])) { sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen6.surface_table; } gen6_emit_state(sna, op, offset | dirty); } static void gen6_align_vertex(struct sna *sna, const struct sna_composite_op *op) { assert (sna->render.vertex_offset == 0); if (op->floats_per_vertex != sna->render_state.gen6.floats_per_vertex) { DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen6.floats_per_vertex, op->floats_per_vertex)); gen4_vertex_align(sna, op); sna->render_state.gen6.floats_per_vertex = op->floats_per_vertex; } assert((sna->render.vertex_used % op->floats_per_vertex) == 0); } fastcall static void gen6_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state); op->prim_emit(sna, op, r); } fastcall static void gen6_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; gen6_get_rectangles(sna, op, 1, gen6_emit_composite_state); DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); } static void gen6_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("composite_boxes(%d)\n", nbox)); do { int nbox_this_time; nbox_this_time = gen6_get_rectangles(sna, op, nbox, gen6_emit_composite_state); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen6_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen6_get_rectangles(sna, op, nbox, gen6_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } static void gen6_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen6_get_rectangles(sna, op, nbox, gen6_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif static uint32_t gen6_composite_create_blend_state(struct sna_static_stream *stream) { char *base, *ptr; int src, dst; base = sna_static_stream_map(stream, GEN6_BLENDFACTOR_COUNT * GEN6_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE, 64); ptr = base; for (src = 0; src < GEN6_BLENDFACTOR_COUNT; src++) { for (dst= 0; dst < GEN6_BLENDFACTOR_COUNT; dst++) { struct gen6_blend_state *blend = (struct gen6_blend_state *)ptr; blend->blend0.dest_blend_factor = dst; blend->blend0.source_blend_factor = src; blend->blend0.blend_func = GEN6_BLENDFUNCTION_ADD; blend->blend0.blend_enable = !(dst == GEN6_BLENDFACTOR_ZERO && src == GEN6_BLENDFACTOR_ONE); blend->blend1.post_blend_clamp_enable = 1; blend->blend1.pre_blend_clamp_enable = 1; ptr += GEN6_BLEND_STATE_PADDED_SIZE; } } return sna_static_stream_offsetof(stream, base); } static uint32_t gen6_bind_video_source(struct sna *sna, struct kgem_bo *src_bo, uint32_t src_offset, int src_width, int src_height, int src_pitch, uint32_t src_surf_format) { struct gen6_surface_state *ss; sna->kgem.surface -= sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t); ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss)); ss->ss0.surface_type = GEN6_SURFACE_2D; ss->ss0.surface_format = src_surf_format; ss->ss1.base_addr = kgem_add_reloc(&sna->kgem, sna->kgem.surface + 1, src_bo, I915_GEM_DOMAIN_SAMPLER << 16, src_offset); ss->ss2.width = src_width - 1; ss->ss2.height = src_height - 1; ss->ss3.pitch = src_pitch - 1; return sna->kgem.surface * sizeof(uint32_t); } static void gen6_emit_video_state(struct sna *sna, const struct sna_composite_op *op) { struct sna_video_frame *frame = op->priv; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; uint32_t *binding_table; uint16_t offset; bool dirty; int n_src, n; dirty = gen6_get_batch(sna, op); src_surf_base[0] = 0; src_surf_base[1] = 0; src_surf_base[2] = frame->VBufOffset; src_surf_base[3] = frame->VBufOffset; src_surf_base[4] = frame->UBufOffset; src_surf_base[5] = frame->UBufOffset; if (is_planar_fourcc(frame->id)) { src_surf_format = GEN6_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = frame->width; src_height[1] = src_height[0] = frame->height; src_pitch[1] = src_pitch[0] = frame->pitch[1]; src_width[4] = src_width[5] = src_width[2] = src_width[3] = frame->width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = frame->height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = frame->pitch[0]; n_src = 6; } else { if (frame->id == FOURCC_UYVY) src_surf_format = GEN6_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = GEN6_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = frame->width; src_height[0] = frame->height; src_pitch[0] = frame->pitch[0]; n_src = 1; } binding_table = gen6_composite_get_binding_table(sna, &offset); binding_table[0] = gen6_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen6_get_dest_format(op->dst.format), true); for (n = 0; n < n_src; n++) { binding_table[1+n] = gen6_bind_video_source(sna, frame->bo, src_surf_base[n], src_width[n], src_height[n], src_pitch[n], src_surf_format); } gen6_emit_state(sna, op, offset | dirty); } static bool gen6_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_composite_op tmp; struct sna_pixmap *priv = sna_pixmap(pixmap); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; unsigned filter; const BoxRec *box; int nbox; DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n", __FUNCTION__, src_width, src_height, dst_width, dst_height, region_num_rects(dstRegion), REGION_EXTENTS(NULL, dstRegion)->x1, REGION_EXTENTS(NULL, dstRegion)->y1, REGION_EXTENTS(NULL, dstRegion)->x2, REGION_EXTENTS(NULL, dstRegion)->y2)); assert(priv->gpu_bo); memset(&tmp, 0, sizeof(tmp)); tmp.dst.pixmap = pixmap; tmp.dst.width = pixmap->drawable.width; tmp.dst.height = pixmap->drawable.height; tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; if (src_width == dst_width && src_height == dst_height) filter = SAMPLER_FILTER_NEAREST; else filter = SAMPLER_FILTER_BILINEAR; tmp.u.gen6.flags = GEN6_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, is_planar_fourcc(frame->id) ? GEN6_WM_KERNEL_VIDEO_PLANAR : GEN6_WM_KERNEL_VIDEO_PACKED, 2); tmp.priv = frame; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen6_align_vertex(sna, &tmp); gen6_emit_video_state(sna, &tmp); src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; box = region_rects(dstRegion); nbox = region_num_rects(dstRegion); while (nbox--) { gen6_get_rectangles(sna, &tmp, 1, gen6_emit_video_state); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); box++; } gen4_vertex_flush(sna); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } static int gen6_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d), precise=%d\n", __FUNCTION__, x, y, w, h, dst_x, dst_y, precise)); channel->is_solid = false; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen4_channel_init_linear(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fixup, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen6_check_repeat(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (!gen6_check_filter(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat && (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen4_channel_init_solid(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; channel->pict_format = picture->format; channel->card_format = gen6_get_card_format(picture->format); if (channel->card_format == (unsigned)-1) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); } DBG(("%s: pixmap, repeat=%d, filter=%d, transform?=%d [affine? %d], format=%08x\n", __FUNCTION__, channel->repeat, channel->filter, channel->transform != NULL, channel->is_affine, channel->pict_format)); if (channel->transform) { #define f2d(x) (((double)(x))/65536.) DBG(("%s: transform=[%f %f %f, %f %f %f, %f %f %f] (raw [%x %x %x, %x %x %x, %x %x %x])\n", __FUNCTION__, f2d(channel->transform->matrix[0][0]), f2d(channel->transform->matrix[0][1]), f2d(channel->transform->matrix[0][2]), f2d(channel->transform->matrix[1][0]), f2d(channel->transform->matrix[1][1]), f2d(channel->transform->matrix[1][2]), f2d(channel->transform->matrix[2][0]), f2d(channel->transform->matrix[2][1]), f2d(channel->transform->matrix[2][2]), channel->transform->matrix[0][0], channel->transform->matrix[0][1], channel->transform->matrix[0][2], channel->transform->matrix[1][0], channel->transform->matrix[1][1], channel->transform->matrix[1][2], channel->transform->matrix[2][0], channel->transform->matrix[2][1], channel->transform->matrix[2][2])); #undef f2d } return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } inline static void gen6_composite_channel_convert(struct sna_composite_channel *channel) { channel->repeat = gen6_repeat(channel->repeat); channel->filter = gen6_filter(channel->filter); if (channel->card_format == (unsigned)-1) channel->card_format = gen6_get_card_format(channel->pict_format); assert(channel->card_format != (unsigned)-1); } static void gen6_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { DBG(("%s\n", __FUNCTION__)); assert(!sna->render.active); if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen6_magic_ca_pass(sna, op); } if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } inline static bool gen6_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned int hint; DBG(("%s: (%d, %d)x(%d, %d), partial?=%d\n", __FUNCTION__, x, y, w, h, partial)); op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.format = dst->format; op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; if (w && h) { box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (too_large(op->dst.width, op->dst.height) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool try_blt(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) goto execute; if (untiled_tlb_miss(bo)) goto execute; if (bo->rq) { if (RQ_IS_BLT(bo->rq)) goto execute; return false; } if (bo->tiling == I915_TILING_Y) goto upload; if (src->pDrawable == dst->pDrawable && can_switch_to_blt(sna, bo, 0)) goto execute; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) goto execute; if (prefer_blt_bo(sna, s, bo)) goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } upload: flags |= COMPOSITE_UPLOAD; execute: return sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } static bool check_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(PicturePtr p) { return p->pDrawable && unattached(p->pDrawable) && untransformed(p); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL || priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (p->pSourcePict) return check_gradient(p, precise); if (!gen6_check_repeat(p) || !gen6_check_format(p->format)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen6_check_filter(p) || need_upload(p); } static bool gen6_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen6_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (sna_picture_is_solid(mask, &color)) return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen6_check_repeat(mask)) return false; if (!gen6_check_filter(mask)) return false; if (!gen6_check_format(mask->format)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen6_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen6_filter(mask->filter); mc->pict_format = mask->format; mc->card_format = gen6_get_card_format(mask->format); mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen6_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { if (op >= ARRAY_SIZE(gen6_blend_op)) return false; DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__, width, height, sna->kgem.ring)); if (mask == NULL && try_blt(sna, op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen6_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, tmp); if (op == PictOpClear && src == sna->clear) op = PictOpSrc; tmp->op = op; if (!gen6_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) goto fallback; switch (gen6_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: /* Did we just switch rings to prepare the source? */ if (mask == NULL && prefer_blt_composite(sna, tmp) && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; gen6_composite_channel_convert(&tmp->src); break; } tmp->is_affine = tmp->src.is_affine; tmp->has_component_alpha = false; tmp->need_magic_ca_pass = false; tmp->mask.bo = NULL; tmp->mask.filter = SAMPLER_FILTER_NEAREST; tmp->mask.repeat = SAMPLER_EXTEND_NONE; if (mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { tmp->has_component_alpha = true; /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (gen6_blend_op[op].src_alpha && (gen6_blend_op[op].src_blend != GEN6_BLENDFACTOR_ZERO)) { if (op != PictOpOver) goto cleanup_src; tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, msk_x, msk_y)) { switch (gen6_composite_picture(sna, mask, &tmp->mask, msk_x, msk_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_src; case 0: if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: gen6_composite_channel_convert(&tmp->mask); break; } } tmp->is_affine &= tmp->mask.is_affine; } tmp->u.gen6.flags = GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter, tmp->src.repeat, tmp->mask.filter, tmp->mask.repeat), gen6_get_blend(tmp->op, tmp->has_component_alpha, tmp->dst.format), gen6_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine), gen4_choose_composite_emitter(sna, tmp)); tmp->blt = gen6_render_composite_blt; tmp->box = gen6_render_composite_box; tmp->boxes = gen6_render_composite_boxes__blt; if (tmp->emit_boxes) { tmp->boxes = gen6_render_composite_boxes; tmp->thread_boxes = gen6_render_composite_boxes__thread; } tmp->done = gen6_render_composite_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen6_align_vertex(sna, tmp); gen6_emit_composite_state(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } #if !NO_COMPOSITE_SPANS fastcall static void gen6_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen6_get_rectangles(sna, &op->base, 1, gen6_emit_composite_state); op->prim_emit(sna, op, box, opacity); } static void gen6_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox, gen6_emit_composite_state); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen6_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox, gen6_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen6_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { DBG(("%s()\n", __FUNCTION__)); assert(!sna->render.active); if (sna->render.vertex_offset) gen4_vertex_flush(sna); if (op->base.src.bo) kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen6_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n", __FUNCTION__, op, width, height, flags)); if (op >= ARRAY_SIZE(gen6_blend_op)) return false; if (gen6_composite_fallback(sna, src, NULL, dst)) { DBG(("%s: operation would fallback\n", __FUNCTION__)); return false; } if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) { struct sna_pixmap *priv = sna_pixmap_from_drawable(dst->pDrawable); assert(priv); if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; if (flags & COMPOSITE_SPANS_INPLACE_HINT) return false; return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } return true; } static bool gen6_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__, width, height, flags, sna->kgem.ring)); assert(gen6_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; if (!gen6_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) return false; switch (gen6_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: gen6_composite_channel_convert(&tmp->base.src); break; } tmp->base.mask.bo = NULL; tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.need_magic_ca_pass = false; tmp->base.u.gen6.flags = GEN6_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_PAD), gen6_get_blend(tmp->base.op, false, tmp->base.dst.format), GEN6_WM_KERNEL_OPACITY | !tmp->base.is_affine, gen4_choose_spans_emitter(sna, tmp)); tmp->box = gen6_render_composite_spans_box; tmp->boxes = gen6_render_composite_spans_boxes; if (tmp->emit_boxes) tmp->thread_boxes = gen6_render_composite_spans_boxes__thread; tmp->done = gen6_render_composite_spans_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen6_align_vertex(sna, &tmp->base); gen6_emit_composite_state(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } #endif static void gen6_emit_copy_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset; bool dirty; dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); binding_table[0] = gen6_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen6_get_dest_format(op->dst.format), true); binding_table[1] = gen6_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen6_surface_state_padded) / sizeof(uint32_t); offset = sna->render_state.gen6.surface_table; } gen6_emit_state(sna, op, offset | dirty); } static inline bool prefer_blt_copy(struct sna *sna, struct kgem_bo *src_bo, struct kgem_bo *dst_bo, unsigned flags) { if (flags & COPY_SYNC) return false; if (PREFER_RENDER) return PREFER_RENDER > 0; if (sna->kgem.ring == KGEM_BLT) return true; if (flags & COPY_DRI && !sna->kgem.has_semaphores) return false; if ((flags & COPY_SMALL || src_bo == dst_bo) && can_switch_to_blt(sna, dst_bo, flags)) return true; if (untiled_tlb_miss(src_bo) || untiled_tlb_miss(dst_bo)) return true; if (force_blt_ring(sna, dst_bo)) return true; if (kgem_bo_is_render(dst_bo) || kgem_bo_is_render(src_bo)) return false; if (flags & COPY_LAST && can_switch_to_blt(sna, dst_bo, flags)) return true; if (prefer_render_ring(sna, dst_bo)) return false; if (!prefer_blt_ring(sna, dst_bo, flags)) return false; return prefer_blt_bo(sna, src_bo, dst_bo); } static bool gen6_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; BoxRec extents; DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, self-copy=%d, overlaps? %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu, src_bo == dst_bo, overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents))); if (prefer_blt_copy(sna, src_bo, dst_bo, flags) && sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear)) { fallback_blt: if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } if (overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents)) { bool big = too_large(extents.x2-extents.x1, extents.y2-extents.y1); if ((big || can_switch_to_blt(sna, dst_bo, flags)) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (big) goto fallback_blt; assert(src_bo == dst_bo); assert(src->depth == dst->depth); assert(src->width == dst->width); assert(src->height == dst->height); return sna_render_copy_boxes__overlap(sna, alu, dst, dst_bo, src_dx, src_dy, dst_dx, dst_dy, box, n, &extents); } if (dst->depth == src->depth) { tmp.dst.format = sna_render_format_for_depth(dst->depth); tmp.src.pict_format = tmp.dst.format; } else { tmp.dst.format = sna_format_for_depth(dst->depth); tmp.src.pict_format = sna_format_for_depth(src->depth); } if (!gen6_check_format(tmp.src.pict_format)) goto fallback_blt; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } tmp.src.card_format = gen6_get_card_format(tmp.src.pict_format); if (too_large(src->width, src->height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, extents.x1 + src_dx, extents.y1 + src_dy, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: unable to extract partial pixmap\n", __FUNCTION__)); goto fallback_tiled_dst; } } else { tmp.src.bo = src_bo; tmp.src.width = src->width; tmp.src.height = src->height; tmp.src.offset[0] = tmp.src.offset[1] = 0; } tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = 0; tmp.u.gen6.flags = COPY_FLAGS(alu); assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(tmp.u.gen6.flags) == COPY_SAMPLER); assert(GEN6_VERTEX(tmp.u.gen6.flags) == COPY_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { DBG(("%s: too large for a single operation\n", __FUNCTION__)); if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); goto fallback_blt; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } src_dx += tmp.src.offset[0]; src_dy += tmp.src.offset[1]; dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; gen6_align_vertex(sna, &tmp); gen6_emit_copy_state(sna, &tmp); do { int16_t *v; int n_this_time; n_this_time = gen6_get_rectangles(sna, &tmp, n, gen6_emit_copy_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); v[0] = box->x2 + dst_dx; v[2] = box->x2 + src_dx; v[1] = v[5] = box->y2 + dst_dy; v[3] = v[7] = box->y2 + src_dy; v[8] = v[4] = box->x1 + dst_dx; v[10] = v[6] = box->x1 + src_dx; v[9] = box->y1 + dst_dy; v[11] = box->y1 + src_dy; v += 12; box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; fallback_tiled_dst: if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); fallback_tiled: if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen6_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { int16_t *v; gen6_get_rectangles(sna, &op->base, 1, gen6_emit_copy_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dx+w; v[1] = dy+h; v[2] = sx+w; v[3] = sy+h; v[4] = dx; v[5] = dy+h; v[6] = sx; v[7] = sy+h; v[8] = dx; v[9] = dy; v[10] = sx; v[11] = sy; } static void gen6_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { DBG(("%s()\n", __FUNCTION__)); assert(!sna->render.active); if (sna->render.vertex_offset) gen4_vertex_flush(sna); } static bool gen6_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op) { DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n", __FUNCTION__, alu, src->drawable.width, src->drawable.height, dst->drawable.width, dst->drawable.height)); if (prefer_blt_copy(sna, src_bo, dst_bo, 0) && sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height)) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); } if (dst->drawable.depth == src->drawable.depth) { op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth); op->base.src.pict_format = op->base.dst.format; } else { op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.src.pict_format = sna_format_for_depth(src->drawable.depth); } if (!gen6_check_format(op->base.src.pict_format)) goto fallback; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.bo = dst_bo; op->base.src.bo = src_bo; op->base.src.card_format = gen6_get_card_format(op->base.src.pict_format); op->base.src.width = src->drawable.width; op->base.src.height = src->drawable.height; op->base.mask.bo = NULL; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen6.flags = COPY_FLAGS(alu); assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER); assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen6_align_vertex(sna, &op->base); gen6_emit_copy_state(sna, &op->base); op->blt = gen6_render_copy_blt; op->done = gen6_render_copy_done; return true; } static void gen6_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset; bool dirty; dirty = gen6_get_batch(sna, op); binding_table = gen6_composite_get_binding_table(sna, &offset); binding_table[0] = gen6_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen6_get_dest_format(op->dst.format), true); binding_table[1] = gen6_bind_bo(sna, op->src.bo, 1, 1, GEN6_SURFACEFORMAT_B8G8R8A8_UNORM, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen6.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen6_surface_state_padded)/sizeof(uint32_t); offset = sna->render_state.gen6.surface_table; } gen6_emit_state(sna, op, offset | dirty); } static bool gen6_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; DBG(("%s (op=%d, color=(%04x, %04x, %04x, %04x) [%08x])\n", __FUNCTION__, op, color->red, color->green, color->blue, color->alpha, (int)format)); if (op >= ARRAY_SIZE(gen6_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (prefer_blt_fill(sna, dst_bo, FILL_BOXES) || !gen6_check_dst_format(format)) { uint8_t alu = GXinvalid; if (op <= PictOpSrc) { pixel = 0; if (op == PictOpClear) alu = GXclear; else if (sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) alu = GXcopy; } if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n)) return true; if (!gen6_check_dst_format(format)) return false; } if (op == PictOpClear) { pixel = 0; op = PictOpSrc; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s(%08x x %d [(%d, %d), (%d, %d) ...])\n", __FUNCTION__, pixel, n, box[0].x1, box[0].y1, box[0].x2, box[0].y2)); tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(dst->width, dst->height)) { BoxRec extents; boxes_extents(box, n, &extents); if (!sna_render_composite_redirect(sna, &tmp, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen6.flags = FILL_FLAGS(op, format); assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER); assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); assert(kgem_check_bo(&sna->kgem, dst_bo, NULL)); } gen6_align_vertex(sna, &tmp); gen6_emit_fill_state(sna, &tmp); do { int n_this_time; int16_t *v; n_this_time = gen6_get_rectangles(sna, &tmp, n, gen6_emit_fill_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d), (%d, %d)\n", box->x1, box->y1, box->x2, box->y2)); v[0] = box->x2; v[5] = v[1] = box->y2; v[8] = v[4] = box->x1; v[9] = box->y1; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; v += 12; box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); sna_render_composite_redirect_done(sna, &tmp); return true; } static void gen6_render_op_fill_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { int16_t *v; DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x+w; v[4] = v[8] = x; v[1] = v[5] = y+h; v[9] = y; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen6_render_op_fill_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { int16_t *v; DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen6_get_rectangles(sna, &op->base, 1, gen6_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen6_render_op_fill_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time; int16_t *v; nbox_this_time = gen6_get_rectangles(sna, &op->base, nbox, gen6_emit_fill_state); nbox -= nbox_this_time; v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6 * nbox_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; box++; v += 12; } while (--nbox_this_time); } while (nbox); } static void gen6_render_op_fill_done(struct sna *sna, const struct sna_fill_op *op) { DBG(("%s()\n", __FUNCTION__)); assert(!sna->render.active); if (sna->render.vertex_offset) gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, op->base.src.bo); } static bool gen6_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *op) { DBG(("%s: (alu=%d, color=%x)\n", __FUNCTION__, alu, color)); if (prefer_blt_fill(sna, dst_bo, flags) && sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op)) return true; if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op); if (alu == GXclear) color = 0; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.dst.bo = dst_bo; op->base.dst.x = op->base.dst.y = 0; op->base.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); op->base.mask.bo = NULL; op->base.need_magic_ca_pass = false; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen6.flags = FILL_FLAGS_NOBLEND; assert(GEN6_KERNEL(op->base.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(op->base.u.gen6.flags) == FILL_SAMPLER); assert(GEN6_VERTEX(op->base.u.gen6.flags) == FILL_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); assert(kgem_check_bo(&sna->kgem, dst_bo, NULL)); } gen6_align_vertex(sna, &op->base); gen6_emit_fill_state(sna, &op->base); op->blt = gen6_render_op_fill_blt; op->box = gen6_render_op_fill_box; op->boxes = gen6_render_op_fill_boxes; op->points = NULL; op->done = gen6_render_op_fill_done; return true; } static bool gen6_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; int16_t *v; /* Prefer to use the BLT if already engaged */ if (prefer_blt_fill(sna, bo, FILL_BOXES) && gen6_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return gen6_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); if (alu == GXclear) color = 0; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen6.flags = FILL_FLAGS_NOBLEND; assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER); assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen6_align_vertex(sna, &tmp); gen6_emit_fill_state(sna, &tmp); gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state); DBG((" (%d, %d), (%d, %d)\n", x1, y1, x2, y2)); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x2; v[8] = v[4] = x1; v[5] = v[1] = y2; v[9] = y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static bool gen6_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = dst->drawable.width; box.y2 = dst->drawable.height; return sna_blt_fill_boxes(sna, GXclear, bo, dst->drawable.bitsPerPixel, 0, &box, 1); } static bool gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { struct sna_composite_op tmp; int16_t *v; DBG(("%s: %dx%d\n", __FUNCTION__, dst->drawable.width, dst->drawable.height)); /* Prefer to use the BLT if, and only if, already engaged */ if (sna->kgem.ring == KGEM_BLT && gen6_render_clear_try_blt(sna, dst, bo)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(dst->drawable.width, dst->drawable.height)) return gen6_render_clear_try_blt(sna, dst, bo); tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, 0); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen6.flags = FILL_FLAGS_NOBLEND; assert(GEN6_KERNEL(tmp.u.gen6.flags) == GEN6_WM_KERNEL_NOMASK); assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER); assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX); kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } } gen6_align_vertex(sna, &tmp); gen6_emit_fill_state(sna, &tmp); gen6_get_rectangles(sna, &tmp, 1, gen6_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst->drawable.width; v[5] = v[1] = dst->drawable.height; v[8] = v[4] = 0; v[9] = 0; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static void gen6_render_reset(struct sna *sna) { sna->render_state.gen6.needs_invariant = true; sna->render_state.gen6.first_state_packet = true; sna->render_state.gen6.ve_id = 3 << 2; sna->render_state.gen6.last_primitive = -1; sna->render_state.gen6.num_sf_outputs = 0; sna->render_state.gen6.samplers = -1; sna->render_state.gen6.blend = -1; sna->render_state.gen6.kernel = -1; sna->render_state.gen6.drawrect_offset = -1; sna->render_state.gen6.drawrect_limit = -1; sna->render_state.gen6.surface_table = -1; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); discard_vbo(sna); } sna->render.vertex_offset = 0; sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; } static void gen6_render_fini(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render_state.gen6.general_bo); } static bool is_gt2(struct sna *sna, int devid) { return devid & 0x30; } static bool is_mobile(struct sna *sna, int devid) { return (devid & 0xf) == 0x6; } static bool gen6_render_setup(struct sna *sna, int devid) { struct gen6_render_state *state = &sna->render_state.gen6; struct sna_static_stream general; struct gen6_sampler_state *ss; int i, j, k, l, m; state->info = >1_info; if (is_gt2(sna, devid)) state->info = >2_info; /* XXX requires GT_MODE WiZ disabled */ state->gt = state->info->gt; sna_static_stream_init(&general); /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer * dumps, you know it points to zero. */ null_create(&general); scratch_create(&general); for (m = 0; m < GEN6_KERNEL_COUNT; m++) { if (wm_kernels[m].size) { state->wm_kernel[m][1] = sna_static_stream_add(&general, wm_kernels[m].data, wm_kernels[m].size, 64); } else { if (USE_8_PIXEL_DISPATCH) { state->wm_kernel[m][0] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 8); } if (USE_16_PIXEL_DISPATCH) { state->wm_kernel[m][1] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } if (USE_32_PIXEL_DISPATCH) { state->wm_kernel[m][2] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 32); } } if ((state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]) == 0) { state->wm_kernel[m][1] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } } ss = sna_static_stream_map(&general, 2 * sizeof(*ss) * (2 + FILTER_COUNT * EXTEND_COUNT * FILTER_COUNT * EXTEND_COUNT), 32); state->wm_state = sna_static_stream_offsetof(&general, ss); sampler_copy_init(ss); ss += 2; sampler_fill_init(ss); ss += 2; for (i = 0; i < FILTER_COUNT; i++) { for (j = 0; j < EXTEND_COUNT; j++) { for (k = 0; k < FILTER_COUNT; k++) { for (l = 0; l < EXTEND_COUNT; l++) { sampler_state_init(ss++, i, j); sampler_state_init(ss++, k, l); } } } } state->cc_blend = gen6_composite_create_blend_state(&general); state->general_bo = sna_static_stream_fini(sna, &general); return state->general_bo != NULL; } const char *gen6_render_init(struct sna *sna, const char *backend) { int devid = intel_get_device_id(sna->dev); if (!gen6_render_setup(sna, devid)) return backend; sna->kgem.context_switch = gen6_render_context_switch; sna->kgem.retire = gen6_render_retire; sna->kgem.expire = gen4_render_expire; #if !NO_COMPOSITE sna->render.composite = gen6_render_composite; sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen6_check_composite_spans; sna->render.composite_spans = gen6_render_composite_spans; if (is_mobile(sna, devid)) sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen6_render_video; #if !NO_COPY_BOXES sna->render.copy_boxes = gen6_render_copy_boxes; #endif #if !NO_COPY sna->render.copy = gen6_render_copy; #endif #if !NO_FILL_BOXES sna->render.fill_boxes = gen6_render_fill_boxes; #endif #if !NO_FILL sna->render.fill = gen6_render_fill; #endif #if !NO_FILL_ONE sna->render.fill_one = gen6_render_fill_one; #endif #if !NO_FILL_CLEAR sna->render.clear = gen6_render_clear; #endif sna->render.flush = gen4_render_flush; sna->render.reset = gen6_render_reset; sna->render.fini = gen6_render_fini; sna->render.max_3d_size = GEN6_MAX_SIZE; sna->render.max_3d_pitch = 1 << 18; return sna->render_state.gen6.info->name; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen6_render.h000066400000000000000000001653651267532330400242320ustar00rootroot00000000000000#ifndef GEN6_RENDER_H #define GEN6_RENDER_H #define GEN6_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low)) #define GEN6_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define GEN6_STATE_BASE_ADDRESS GEN6_3D(0, 1, 1) #define GEN6_STATE_SIP GEN6_3D(0, 1, 2) #define GEN6_PIPELINE_SELECT GEN6_3D(1, 1, 4) #define GEN6_MEDIA_STATE_POINTERS GEN6_3D(2, 0, 0) #define GEN6_MEDIA_OBJECT GEN6_3D(2, 1, 0) #define GEN6_3DSTATE_BINDING_TABLE_POINTERS GEN6_3D(3, 0, 1) # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS (1 << 12)/* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_GS (1 << 9) /* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_VS (1 << 8) /* for GEN6 */ #define GEN6_3DSTATE_VERTEX_BUFFERS GEN6_3D(3, 0, 8) #define GEN6_3DSTATE_VERTEX_ELEMENTS GEN6_3D(3, 0, 9) #define GEN6_3DSTATE_INDEX_BUFFER GEN6_3D(3, 0, 0xa) #define GEN6_3DSTATE_VF_STATISTICS GEN6_3D(3, 0, 0xb) #define GEN6_3DSTATE_DRAWING_RECTANGLE GEN6_3D(3, 1, 0) #define GEN6_3DSTATE_CONSTANT_COLOR GEN6_3D(3, 1, 1) #define GEN6_3DSTATE_SAMPLER_PALETTE_LOAD GEN6_3D(3, 1, 2) #define GEN6_3DSTATE_CHROMA_KEY GEN6_3D(3, 1, 4) #define GEN6_3DSTATE_DEPTH_BUFFER GEN6_3D(3, 1, 5) # define GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define GEN6_3DSTATE_POLY_STIPPLE_OFFSET GEN6_3D(3, 1, 6) #define GEN6_3DSTATE_POLY_STIPPLE_PATTERN GEN6_3D(3, 1, 7) #define GEN6_3DSTATE_LINE_STIPPLE GEN6_3D(3, 1, 8) #define GEN6_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP GEN6_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define GEN6_3DSTATE_AA_LINE_PARAMS GEN6_3D(3, 1, 0xa) #define GEN6_3DSTATE_GS_SVB_INDEX GEN6_3D(3, 1, 0xb) #define GEN6_3DPRIMITIVE GEN6_3D(3, 3, 0) #define GEN6_3DSTATE_CLEAR_PARAMS GEN6_3D(3, 1, 0x10) /* DW1 */ # define GEN6_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) #define GEN6_3DSTATE_SAMPLER_STATE_POINTERS GEN6_3D(3, 0, 0x02) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN6_3DSTATE_URB GEN6_3D(3, 0, 0x05) /* DW1 */ # define GEN6_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN6_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN6_3DSTATE_VIEWPORT_STATE_POINTERS GEN6_3D(3, 0, 0x0d) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN6_3DSTATE_CC_STATE_POINTERS GEN6_3D(3, 0, 0x0e) #define GEN6_3DSTATE_VS GEN6_3D(3, 0, 0x10) #define GEN6_3DSTATE_GS GEN6_3D(3, 0, 0x11) /* DW4 */ # define GEN6_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN6_3DSTATE_CLIP GEN6_3D(3, 0, 0x12) #define GEN6_3DSTATE_SF GEN6_3D(3, 0, 0x13) /* DW1 */ # define GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN6_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN6_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN6_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN6_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN6_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN6_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN6_3DSTATE_WM GEN6_3D(3, 0, 0x14) /* DW2 */ # define GEN6_3DSTATE_WM_SAMPLER_COUNT_SHIFT 27 # define GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 /* DW4 */ # define GEN6_3DSTATE_WM_DISPATCH_0_START_GRF_SHIFT 16 # define GEN6_3DSTATE_WM_DISPATCH_1_START_GRF_SHIFT 8 # define GEN6_3DSTATE_WM_DISPATCH_2_START_GRF_SHIFT 0 /* DW5 */ # define GEN6_3DSTATE_WM_MAX_THREADS_SHIFT 25 # define GEN6_3DSTATE_WM_DISPATCH_ENABLE (1 << 19) # define GEN6_3DSTATE_WM_32_DISPATCH_ENABLE (1 << 2) # define GEN6_3DSTATE_WM_16_DISPATCH_ENABLE (1 << 1) # define GEN6_3DSTATE_WM_8_DISPATCH_ENABLE (1 << 0) /* DW6 */ # define GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT 20 # define GEN6_3DSTATE_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 15) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 14) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 13) # define GEN6_3DSTATE_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_3DSTATE_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) #define GEN6_3DSTATE_CONSTANT_VS GEN6_3D(3, 0, 0x15) #define GEN6_3DSTATE_CONSTANT_GS GEN6_3D(3, 0, 0x16) #define GEN6_3DSTATE_CONSTANT_PS GEN6_3D(3, 0, 0x17) #define GEN6_3DSTATE_SAMPLE_MASK GEN6_3D(3, 0, 0x18) #define GEN6_3DSTATE_MULTISAMPLE GEN6_3D(3, 1, 0x0d) /* DW1 */ # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 /* for GEN6_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define VB0_BUFFER_INDEX_SHIFT 26 #define VB0_VERTEXDATA (0 << 20) #define VB0_INSTANCEDATA (1 << 20) #define VB0_BUFFER_PITCH_SHIFT 0 /* VERTEX_ELEMENT_STATE Structure */ #define VE0_VERTEX_BUFFER_INDEX_SHIFT 26 /* for GEN6 */ #define VE0_VALID (1 << 25) /* for GEN6 */ #define VE0_FORMAT_SHIFT 16 #define VE0_OFFSET_SHIFT 0 #define VE1_VFCOMPONENT_0_SHIFT 28 #define VE1_VFCOMPONENT_1_SHIFT 24 #define VE1_VFCOMPONENT_2_SHIFT 20 #define VE1_VFCOMPONENT_3_SHIFT 16 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define GEN6_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in gen6_defines.h */ #define GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define GEN6_SVG_CTL 0x7400 #define GEN6_SVG_CTL_GS_BA (0 << 8) #define GEN6_SVG_CTL_SS_BA (1 << 8) #define GEN6_SVG_CTL_IO_BA (2 << 8) #define GEN6_SVG_CTL_GS_AUB (3 << 8) #define GEN6_SVG_CTL_IO_AUB (4 << 8) #define GEN6_SVG_CTL_SIP (5 << 8) #define GEN6_SVG_RDATA 0x7404 #define GEN6_SVG_WORK_CTL 0x7408 #define GEN6_VF_CTL 0x7500 #define GEN6_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define GEN6_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define GEN6_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define GEN6_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define GEN6_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define GEN6_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define GEN6_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define GEN6_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_VF_STRG_VAL 0x7504 #define GEN6_VF_STR_VL_OVR 0x7508 #define GEN6_VF_VC_OVR 0x750c #define GEN6_VF_STR_PSKIP 0x7510 #define GEN6_VF_MAX_PRIM 0x7514 #define GEN6_VF_RDATA 0x7518 #define GEN6_VS_CTL 0x7600 #define GEN6_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define GEN6_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_VS_STRG_VAL 0x7604 #define GEN6_VS_RDATA 0x7608 #define GEN6_SF_CTL 0x7b00 #define GEN6_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define GEN6_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define GEN6_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define GEN6_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_SF_STRG_VAL 0x7b04 #define GEN6_SF_RDATA 0x7b18 #define GEN6_WIZ_CTL 0x7c00 #define GEN6_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define GEN6_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define GEN6_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define GEN6_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define GEN6_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define GEN6_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define GEN6_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define GEN6_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define GEN6_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_WIZ_STRG_VAL 0x7c04 #define GEN6_WIZ_RDATA 0x7c18 #define GEN6_TS_CTL 0x7e00 #define GEN6_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define GEN6_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define GEN6_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define GEN6_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define GEN6_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_TS_STRG_VAL 0x7e04 #define GEN6_TS_RDATA 0x7e08 #define GEN6_TD_CTL 0x8000 #define GEN6_TD_CTL_MUX_SHIFT 8 #define GEN6_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define GEN6_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define GEN6_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define GEN6_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define GEN6_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define GEN6_TD_CTL2 0x8004 #define GEN6_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define GEN6_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define GEN6_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define GEN6_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define GEN6_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define GEN6_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define GEN6_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define GEN6_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define GEN6_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define GEN6_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define GEN6_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define GEN6_TD_VF_VS_EMSK 0x8008 #define GEN6_TD_GS_EMSK 0x800c #define GEN6_TD_CLIP_EMSK 0x8010 #define GEN6_TD_SF_EMSK 0x8014 #define GEN6_TD_WIZ_EMSK 0x8018 #define GEN6_TD_0_6_EHTRG_VAL 0x801c #define GEN6_TD_0_7_EHTRG_VAL 0x8020 #define GEN6_TD_0_6_EHTRG_MSK 0x8024 #define GEN6_TD_0_7_EHTRG_MSK 0x8028 #define GEN6_TD_RDATA 0x802c #define GEN6_TD_TS_EMSK 0x8030 #define GEN6_EU_CTL 0x8800 #define GEN6_EU_CTL_SELECT_SHIFT 16 #define GEN6_EU_CTL_DATA_MUX_SHIFT 8 #define GEN6_EU_ATT_0 0x8810 #define GEN6_EU_ATT_1 0x8814 #define GEN6_EU_ATT_DATA_0 0x8820 #define GEN6_EU_ATT_DATA_1 0x8824 #define GEN6_EU_ATT_CLR_0 0x8830 #define GEN6_EU_ATT_CLR_1 0x8834 #define GEN6_EU_RDATA 0x8840 #define GEN6_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define GEN6_STATE_BASE_ADDRESS GEN6_3D(0, 1, 1) #define GEN6_STATE_SIP GEN6_3D(0, 1, 2) #define GEN6_PIPELINE_SELECT GEN6_3D(1, 1, 4) #define GEN6_MEDIA_STATE_POINTERS GEN6_3D(2, 0, 0) #define GEN6_MEDIA_OBJECT GEN6_3D(2, 1, 0) #define GEN6_3DSTATE_BINDING_TABLE_POINTERS GEN6_3D(3, 0, 1) # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS (1 << 12)/* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_GS (1 << 9) /* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_VS (1 << 8) /* for GEN6 */ #define GEN6_3DSTATE_VERTEX_BUFFERS GEN6_3D(3, 0, 8) #define GEN6_3DSTATE_VERTEX_ELEMENTS GEN6_3D(3, 0, 9) #define GEN6_3DSTATE_INDEX_BUFFER GEN6_3D(3, 0, 0xa) #define GEN6_3DSTATE_VF_STATISTICS GEN6_3D(3, 0, 0xb) #define GEN6_3DSTATE_DRAWING_RECTANGLE GEN6_3D(3, 1, 0) #define GEN6_3DSTATE_CONSTANT_COLOR GEN6_3D(3, 1, 1) #define GEN6_3DSTATE_SAMPLER_PALETTE_LOAD GEN6_3D(3, 1, 2) #define GEN6_3DSTATE_CHROMA_KEY GEN6_3D(3, 1, 4) #define GEN6_3DSTATE_DEPTH_BUFFER GEN6_3D(3, 1, 5) # define GEN6_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define GEN6_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define GEN6_3DSTATE_POLY_STIPPLE_OFFSET GEN6_3D(3, 1, 6) #define GEN6_3DSTATE_POLY_STIPPLE_PATTERN GEN6_3D(3, 1, 7) #define GEN6_3DSTATE_LINE_STIPPLE GEN6_3D(3, 1, 8) #define GEN6_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP GEN6_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define GEN6_3DSTATE_AA_LINE_PARAMS GEN6_3D(3, 1, 0xa) #define GEN6_3DSTATE_GS_SVB_INDEX GEN6_3D(3, 1, 0xb) #define GEN6_3DPRIMITIVE GEN6_3D(3, 3, 0) #define GEN6_3DSTATE_CLEAR_PARAMS GEN6_3D(3, 1, 0x10) /* DW1 */ # define GEN6_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) /* for GEN6+ */ #define GEN6_3DSTATE_SAMPLER_STATE_POINTERS GEN6_3D(3, 0, 0x02) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN6_3DSTATE_URB GEN6_3D(3, 0, 0x05) /* DW1 */ # define GEN6_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN6_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN6_3DSTATE_VIEWPORT_STATE_POINTERS GEN6_3D(3, 0, 0x0d) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN6_3DSTATE_CC_STATE_POINTERS GEN6_3D(3, 0, 0x0e) #define GEN6_3DSTATE_VS GEN6_3D(3, 0, 0x10) #define GEN6_3DSTATE_GS GEN6_3D(3, 0, 0x11) /* DW4 */ # define GEN6_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN6_3DSTATE_CLIP GEN6_3D(3, 0, 0x12) #define GEN6_3DSTATE_SF GEN6_3D(3, 0, 0x13) /* DW1 */ # define GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN6_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN6_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN6_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN6_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN6_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN6_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN6_3DSTATE_WM GEN6_3D(3, 0, 0x14) /* DW2 */ # define GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF 27 # define GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 /* DW4 */ # define GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT 16 /* DW5 */ # define GEN6_3DSTATE_WM_MAX_THREADS_SHIFT 25 # define GEN6_3DSTATE_WM_DISPATCH_ENABLE (1 << 19) # define GEN6_3DSTATE_WM_16_DISPATCH_ENABLE (1 << 1) # define GEN6_3DSTATE_WM_8_DISPATCH_ENABLE (1 << 0) /* DW6 */ # define GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT 20 # define GEN6_3DSTATE_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 15) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 14) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 13) # define GEN6_3DSTATE_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_3DSTATE_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) #define GEN6_3DSTATE_CONSTANT_VS GEN6_3D(3, 0, 0x15) #define GEN6_3DSTATE_CONSTANT_GS GEN6_3D(3, 0, 0x16) #define GEN6_3DSTATE_CONSTANT_PS GEN6_3D(3, 0, 0x17) #define GEN6_3DSTATE_SAMPLE_MASK GEN6_3D(3, 0, 0x18) #define GEN6_3DSTATE_MULTISAMPLE GEN6_3D(3, 1, 0x0d) /* DW1 */ # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 #define UF0_CS_REALLOC (1 << 13) #define UF0_VFE_REALLOC (1 << 12) #define UF0_SF_REALLOC (1 << 11) #define UF0_CLIP_REALLOC (1 << 10) #define UF0_GS_REALLOC (1 << 9) #define UF0_VS_REALLOC (1 << 8) #define UF1_CLIP_FENCE_SHIFT 20 #define UF1_GS_FENCE_SHIFT 10 #define UF1_VS_FENCE_SHIFT 0 #define UF2_CS_FENCE_SHIFT 20 #define UF2_VFE_FENCE_SHIFT 10 #define UF2_SF_FENCE_SHIFT 0 /* for GEN6_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for GEN6_3DSTATE_PIPELINED_POINTERS */ #define GEN6_GS_DISABLE 0 #define GEN6_GS_ENABLE 1 #define GEN6_CLIP_DISABLE 0 #define GEN6_CLIP_ENABLE 1 /* for GEN6_PIPE_CONTROL */ #define GEN6_PIPE_CONTROL GEN6_3D(3, 2, 0) #define GEN6_PIPE_CONTROL_CS_STALL (1 << 20) #define GEN6_PIPE_CONTROL_NOWRITE (0 << 14) #define GEN6_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define GEN6_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define GEN6_PIPE_CONTROL_WRITE_TIME (3 << 14) #define GEN6_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define GEN6_PIPE_CONTROL_WC_FLUSH (1 << 12) #define GEN6_PIPE_CONTROL_IS_FLUSH (1 << 11) #define GEN6_PIPE_CONTROL_TC_FLUSH (1 << 10) #define GEN6_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define GEN6_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define GEN6_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define GEN6_PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) #define GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* 3DPRIMITIVE bits */ #define GEN6_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define GEN6_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in gen6_defines.h */ #define GEN6_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define GEN6_SVG_CTL 0x7400 #define GEN6_SVG_CTL_GS_BA (0 << 8) #define GEN6_SVG_CTL_SS_BA (1 << 8) #define GEN6_SVG_CTL_IO_BA (2 << 8) #define GEN6_SVG_CTL_GS_AUB (3 << 8) #define GEN6_SVG_CTL_IO_AUB (4 << 8) #define GEN6_SVG_CTL_SIP (5 << 8) #define GEN6_SVG_RDATA 0x7404 #define GEN6_SVG_WORK_CTL 0x7408 #define GEN6_VF_CTL 0x7500 #define GEN6_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define GEN6_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define GEN6_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define GEN6_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define GEN6_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define GEN6_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define GEN6_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define GEN6_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_VF_STRG_VAL 0x7504 #define GEN6_VF_STR_VL_OVR 0x7508 #define GEN6_VF_VC_OVR 0x750c #define GEN6_VF_STR_PSKIP 0x7510 #define GEN6_VF_MAX_PRIM 0x7514 #define GEN6_VF_RDATA 0x7518 #define GEN6_VS_CTL 0x7600 #define GEN6_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define GEN6_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define GEN6_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_VS_STRG_VAL 0x7604 #define GEN6_VS_RDATA 0x7608 #define GEN6_SF_CTL 0x7b00 #define GEN6_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define GEN6_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define GEN6_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define GEN6_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define GEN6_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_SF_STRG_VAL 0x7b04 #define GEN6_SF_RDATA 0x7b18 #define GEN6_WIZ_CTL 0x7c00 #define GEN6_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define GEN6_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define GEN6_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define GEN6_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define GEN6_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define GEN6_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define GEN6_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define GEN6_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define GEN6_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN6_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN6_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_WIZ_STRG_VAL 0x7c04 #define GEN6_WIZ_RDATA 0x7c18 #define GEN6_TS_CTL 0x7e00 #define GEN6_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN6_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define GEN6_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define GEN6_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define GEN6_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define GEN6_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN6_TS_STRG_VAL 0x7e04 #define GEN6_TS_RDATA 0x7e08 #define GEN6_TD_CTL 0x8000 #define GEN6_TD_CTL_MUX_SHIFT 8 #define GEN6_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define GEN6_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define GEN6_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define GEN6_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define GEN6_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define GEN6_TD_CTL2 0x8004 #define GEN6_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define GEN6_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define GEN6_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define GEN6_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define GEN6_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define GEN6_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define GEN6_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define GEN6_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define GEN6_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define GEN6_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define GEN6_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define GEN6_TD_VF_VS_EMSK 0x8008 #define GEN6_TD_GS_EMSK 0x800c #define GEN6_TD_CLIP_EMSK 0x8010 #define GEN6_TD_SF_EMSK 0x8014 #define GEN6_TD_WIZ_EMSK 0x8018 #define GEN6_TD_0_6_EHTRG_VAL 0x801c #define GEN6_TD_0_7_EHTRG_VAL 0x8020 #define GEN6_TD_0_6_EHTRG_MSK 0x8024 #define GEN6_TD_0_7_EHTRG_MSK 0x8028 #define GEN6_TD_RDATA 0x802c #define GEN6_TD_TS_EMSK 0x8030 #define GEN6_EU_CTL 0x8800 #define GEN6_EU_CTL_SELECT_SHIFT 16 #define GEN6_EU_CTL_DATA_MUX_SHIFT 8 #define GEN6_EU_ATT_0 0x8810 #define GEN6_EU_ATT_1 0x8814 #define GEN6_EU_ATT_DATA_0 0x8820 #define GEN6_EU_ATT_DATA_1 0x8824 #define GEN6_EU_ATT_CLR_0 0x8830 #define GEN6_EU_ATT_CLR_1 0x8834 #define GEN6_EU_RDATA 0x8840 /* 3D state: */ #define _3DOP_3DSTATE_PIPELINED 0x0 #define _3DOP_3DSTATE_NONPIPELINED 0x1 #define _3DOP_3DCONTROL 0x2 #define _3DOP_3DPRIMITIVE 0x3 #define _3DSTATE_PIPELINED_POINTERS 0x00 #define _3DSTATE_BINDING_TABLE_POINTERS 0x01 #define _3DSTATE_VERTEX_BUFFERS 0x08 #define _3DSTATE_VERTEX_ELEMENTS 0x09 #define _3DSTATE_INDEX_BUFFER 0x0A #define _3DSTATE_VF_STATISTICS 0x0B #define _3DSTATE_DRAWING_RECTANGLE 0x00 #define _3DSTATE_CONSTANT_COLOR 0x01 #define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 #define _3DSTATE_CHROMA_KEY 0x04 #define _3DSTATE_DEPTH_BUFFER 0x05 #define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 #define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 #define _3DSTATE_LINE_STIPPLE 0x08 #define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 #define _3DCONTROL 0x00 #define _3DPRIMITIVE 0x00 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define GEN6_ANISORATIO_2 0 #define GEN6_ANISORATIO_4 1 #define GEN6_ANISORATIO_6 2 #define GEN6_ANISORATIO_8 3 #define GEN6_ANISORATIO_10 4 #define GEN6_ANISORATIO_12 5 #define GEN6_ANISORATIO_14 6 #define GEN6_ANISORATIO_16 7 #define GEN6_BLENDFACTOR_ONE 0x1 #define GEN6_BLENDFACTOR_SRC_COLOR 0x2 #define GEN6_BLENDFACTOR_SRC_ALPHA 0x3 #define GEN6_BLENDFACTOR_DST_ALPHA 0x4 #define GEN6_BLENDFACTOR_DST_COLOR 0x5 #define GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define GEN6_BLENDFACTOR_CONST_COLOR 0x7 #define GEN6_BLENDFACTOR_CONST_ALPHA 0x8 #define GEN6_BLENDFACTOR_SRC1_COLOR 0x9 #define GEN6_BLENDFACTOR_SRC1_ALPHA 0x0A #define GEN6_BLENDFACTOR_ZERO 0x11 #define GEN6_BLENDFACTOR_INV_SRC_COLOR 0x12 #define GEN6_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define GEN6_BLENDFACTOR_INV_DST_ALPHA 0x14 #define GEN6_BLENDFACTOR_INV_DST_COLOR 0x15 #define GEN6_BLENDFACTOR_INV_CONST_COLOR 0x17 #define GEN6_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define GEN6_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define GEN6_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define GEN6_BLENDFUNCTION_ADD 0 #define GEN6_BLENDFUNCTION_SUBTRACT 1 #define GEN6_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define GEN6_BLENDFUNCTION_MIN 3 #define GEN6_BLENDFUNCTION_MAX 4 #define GEN6_ALPHATEST_FORMAT_UNORM8 0 #define GEN6_ALPHATEST_FORMAT_FLOAT32 1 #define GEN6_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define GEN6_CHROMAKEY_REPLACE_BLACK 1 #define GEN6_CLIP_API_OGL 0 #define GEN6_CLIP_API_DX 1 #define GEN6_CLIPMODE_NORMAL 0 #define GEN6_CLIPMODE_CLIP_ALL 1 #define GEN6_CLIPMODE_CLIP_NON_REJECTED 2 #define GEN6_CLIPMODE_REJECT_ALL 3 #define GEN6_CLIPMODE_ACCEPT_ALL 4 #define GEN6_CLIP_NDCSPACE 0 #define GEN6_CLIP_SCREENSPACE 1 #define GEN6_COMPAREFUNCTION_ALWAYS 0 #define GEN6_COMPAREFUNCTION_NEVER 1 #define GEN6_COMPAREFUNCTION_LESS 2 #define GEN6_COMPAREFUNCTION_EQUAL 3 #define GEN6_COMPAREFUNCTION_LEQUAL 4 #define GEN6_COMPAREFUNCTION_GREATER 5 #define GEN6_COMPAREFUNCTION_NOTEQUAL 6 #define GEN6_COMPAREFUNCTION_GEQUAL 7 #define GEN6_COVERAGE_PIXELS_HALF 0 #define GEN6_COVERAGE_PIXELS_1 1 #define GEN6_COVERAGE_PIXELS_2 2 #define GEN6_COVERAGE_PIXELS_4 3 #define GEN6_CULLMODE_BOTH 0 #define GEN6_CULLMODE_NONE 1 #define GEN6_CULLMODE_FRONT 2 #define GEN6_CULLMODE_BACK 3 #define GEN6_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define GEN6_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define GEN6_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define GEN6_DEPTHFORMAT_D32_FLOAT 1 #define GEN6_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define GEN6_DEPTHFORMAT_D16_UNORM 5 #define GEN6_FLOATING_POINT_IEEE_754 0 #define GEN6_FLOATING_POINT_NON_IEEE_754 1 #define GEN6_FRONTWINDING_CW 0 #define GEN6_FRONTWINDING_CCW 1 #define GEN6_INDEX_BYTE 0 #define GEN6_INDEX_WORD 1 #define GEN6_INDEX_DWORD 2 #define GEN6_LOGICOPFUNCTION_CLEAR 0 #define GEN6_LOGICOPFUNCTION_NOR 1 #define GEN6_LOGICOPFUNCTION_AND_INVERTED 2 #define GEN6_LOGICOPFUNCTION_COPY_INVERTED 3 #define GEN6_LOGICOPFUNCTION_AND_REVERSE 4 #define GEN6_LOGICOPFUNCTION_INVERT 5 #define GEN6_LOGICOPFUNCTION_XOR 6 #define GEN6_LOGICOPFUNCTION_NAND 7 #define GEN6_LOGICOPFUNCTION_AND 8 #define GEN6_LOGICOPFUNCTION_EQUIV 9 #define GEN6_LOGICOPFUNCTION_NOOP 10 #define GEN6_LOGICOPFUNCTION_OR_INVERTED 11 #define GEN6_LOGICOPFUNCTION_COPY 12 #define GEN6_LOGICOPFUNCTION_OR_REVERSE 13 #define GEN6_LOGICOPFUNCTION_OR 14 #define GEN6_LOGICOPFUNCTION_SET 15 #define GEN6_MAPFILTER_NEAREST 0x0 #define GEN6_MAPFILTER_LINEAR 0x1 #define GEN6_MAPFILTER_ANISOTROPIC 0x2 #define GEN6_MIPFILTER_NONE 0 #define GEN6_MIPFILTER_NEAREST 1 #define GEN6_MIPFILTER_LINEAR 3 #define GEN6_POLYGON_FRONT_FACING 0 #define GEN6_POLYGON_BACK_FACING 1 #define GEN6_PREFILTER_ALWAYS 0x0 #define GEN6_PREFILTER_NEVER 0x1 #define GEN6_PREFILTER_LESS 0x2 #define GEN6_PREFILTER_EQUAL 0x3 #define GEN6_PREFILTER_LEQUAL 0x4 #define GEN6_PREFILTER_GREATER 0x5 #define GEN6_PREFILTER_NOTEQUAL 0x6 #define GEN6_PREFILTER_GEQUAL 0x7 #define GEN6_PROVOKING_VERTEX_0 0 #define GEN6_PROVOKING_VERTEX_1 1 #define GEN6_PROVOKING_VERTEX_2 2 #define GEN6_RASTRULE_UPPER_LEFT 0 #define GEN6_RASTRULE_UPPER_RIGHT 1 #define GEN6_RENDERTARGET_CLAMPRANGE_UNORM 0 #define GEN6_RENDERTARGET_CLAMPRANGE_SNORM 1 #define GEN6_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define GEN6_STENCILOP_KEEP 0 #define GEN6_STENCILOP_ZERO 1 #define GEN6_STENCILOP_REPLACE 2 #define GEN6_STENCILOP_INCRSAT 3 #define GEN6_STENCILOP_DECRSAT 4 #define GEN6_STENCILOP_INCR 5 #define GEN6_STENCILOP_DECR 6 #define GEN6_STENCILOP_INVERT 7 #define GEN6_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN6_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define GEN6_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define GEN6_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define GEN6_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define GEN6_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define GEN6_SURFACEFORMAT_R64G64_FLOAT 0x005 #define GEN6_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define GEN6_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define GEN6_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define GEN6_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define GEN6_SURFACEFORMAT_R32G32B32_SINT 0x041 #define GEN6_SURFACEFORMAT_R32G32B32_UINT 0x042 #define GEN6_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define GEN6_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define GEN6_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define GEN6_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define GEN6_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define GEN6_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define GEN6_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define GEN6_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define GEN6_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define GEN6_SURFACEFORMAT_R32G32_FLOAT 0x085 #define GEN6_SURFACEFORMAT_R32G32_SINT 0x086 #define GEN6_SURFACEFORMAT_R32G32_UINT 0x087 #define GEN6_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define GEN6_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define GEN6_SURFACEFORMAT_L32A32_FLOAT 0x08A #define GEN6_SURFACEFORMAT_R32G32_UNORM 0x08B #define GEN6_SURFACEFORMAT_R32G32_SNORM 0x08C #define GEN6_SURFACEFORMAT_R64_FLOAT 0x08D #define GEN6_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define GEN6_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define GEN6_SURFACEFORMAT_A32X32_FLOAT 0x090 #define GEN6_SURFACEFORMAT_L32X32_FLOAT 0x091 #define GEN6_SURFACEFORMAT_I32X32_FLOAT 0x092 #define GEN6_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define GEN6_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define GEN6_SURFACEFORMAT_R32G32_SSCALED 0x095 #define GEN6_SURFACEFORMAT_R32G32_USCALED 0x096 #define GEN6_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define GEN6_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define GEN6_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define GEN6_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define GEN6_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define GEN6_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define GEN6_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define GEN6_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define GEN6_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define GEN6_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define GEN6_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define GEN6_SURFACEFORMAT_R16G16_UNORM 0x0CC #define GEN6_SURFACEFORMAT_R16G16_SNORM 0x0CD #define GEN6_SURFACEFORMAT_R16G16_SINT 0x0CE #define GEN6_SURFACEFORMAT_R16G16_UINT 0x0CF #define GEN6_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define GEN6_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define GEN6_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define GEN6_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define GEN6_SURFACEFORMAT_R32_SINT 0x0D6 #define GEN6_SURFACEFORMAT_R32_UINT 0x0D7 #define GEN6_SURFACEFORMAT_R32_FLOAT 0x0D8 #define GEN6_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define GEN6_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define GEN6_SURFACEFORMAT_L16A16_UNORM 0x0DF #define GEN6_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define GEN6_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define GEN6_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define GEN6_SURFACEFORMAT_I32_FLOAT 0x0E3 #define GEN6_SURFACEFORMAT_L32_FLOAT 0x0E4 #define GEN6_SURFACEFORMAT_A32_FLOAT 0x0E5 #define GEN6_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define GEN6_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define GEN6_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define GEN6_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define GEN6_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define GEN6_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define GEN6_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define GEN6_SURFACEFORMAT_R32_UNORM 0x0F1 #define GEN6_SURFACEFORMAT_R32_SNORM 0x0F2 #define GEN6_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define GEN6_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define GEN6_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define GEN6_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define GEN6_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define GEN6_SURFACEFORMAT_R32_SSCALED 0x0F8 #define GEN6_SURFACEFORMAT_R32_USCALED 0x0F9 #define GEN6_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define GEN6_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define GEN6_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define GEN6_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define GEN6_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define GEN6_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define GEN6_SURFACEFORMAT_R8G8_UNORM 0x106 #define GEN6_SURFACEFORMAT_R8G8_SNORM 0x107 #define GEN6_SURFACEFORMAT_R8G8_SINT 0x108 #define GEN6_SURFACEFORMAT_R8G8_UINT 0x109 #define GEN6_SURFACEFORMAT_R16_UNORM 0x10A #define GEN6_SURFACEFORMAT_R16_SNORM 0x10B #define GEN6_SURFACEFORMAT_R16_SINT 0x10C #define GEN6_SURFACEFORMAT_R16_UINT 0x10D #define GEN6_SURFACEFORMAT_R16_FLOAT 0x10E #define GEN6_SURFACEFORMAT_I16_UNORM 0x111 #define GEN6_SURFACEFORMAT_L16_UNORM 0x112 #define GEN6_SURFACEFORMAT_A16_UNORM 0x113 #define GEN6_SURFACEFORMAT_L8A8_UNORM 0x114 #define GEN6_SURFACEFORMAT_I16_FLOAT 0x115 #define GEN6_SURFACEFORMAT_L16_FLOAT 0x116 #define GEN6_SURFACEFORMAT_A16_FLOAT 0x117 #define GEN6_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define GEN6_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define GEN6_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define GEN6_SURFACEFORMAT_R8G8_SSCALED 0x11C #define GEN6_SURFACEFORMAT_R8G8_USCALED 0x11D #define GEN6_SURFACEFORMAT_R16_SSCALED 0x11E #define GEN6_SURFACEFORMAT_R16_USCALED 0x11F #define GEN6_SURFACEFORMAT_R8_UNORM 0x140 #define GEN6_SURFACEFORMAT_R8_SNORM 0x141 #define GEN6_SURFACEFORMAT_R8_SINT 0x142 #define GEN6_SURFACEFORMAT_R8_UINT 0x143 #define GEN6_SURFACEFORMAT_A8_UNORM 0x144 #define GEN6_SURFACEFORMAT_I8_UNORM 0x145 #define GEN6_SURFACEFORMAT_L8_UNORM 0x146 #define GEN6_SURFACEFORMAT_P4A4_UNORM 0x147 #define GEN6_SURFACEFORMAT_A4P4_UNORM 0x148 #define GEN6_SURFACEFORMAT_R8_SSCALED 0x149 #define GEN6_SURFACEFORMAT_R8_USCALED 0x14A #define GEN6_SURFACEFORMAT_R1_UINT 0x181 #define GEN6_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define GEN6_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define GEN6_SURFACEFORMAT_BC1_UNORM 0x186 #define GEN6_SURFACEFORMAT_BC2_UNORM 0x187 #define GEN6_SURFACEFORMAT_BC3_UNORM 0x188 #define GEN6_SURFACEFORMAT_BC4_UNORM 0x189 #define GEN6_SURFACEFORMAT_BC5_UNORM 0x18A #define GEN6_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define GEN6_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define GEN6_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define GEN6_SURFACEFORMAT_MONO8 0x18E #define GEN6_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define GEN6_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define GEN6_SURFACEFORMAT_DXT1_RGB 0x191 #define GEN6_SURFACEFORMAT_FXT1 0x192 #define GEN6_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define GEN6_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define GEN6_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define GEN6_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define GEN6_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define GEN6_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define GEN6_SURFACEFORMAT_BC4_SNORM 0x199 #define GEN6_SURFACEFORMAT_BC5_SNORM 0x19A #define GEN6_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define GEN6_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define GEN6_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define GEN6_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define GEN6_SURFACERETURNFORMAT_FLOAT32 0 #define GEN6_SURFACERETURNFORMAT_S1 1 #define GEN6_SURFACE_1D 0 #define GEN6_SURFACE_2D 1 #define GEN6_SURFACE_3D 2 #define GEN6_SURFACE_CUBE 3 #define GEN6_SURFACE_BUFFER 4 #define GEN6_SURFACE_NULL 7 #define GEN6_BORDER_COLOR_MODE_DEFAULT 0 #define GEN6_BORDER_COLOR_MODE_LEGACY 1 #define GEN6_TEXCOORDMODE_WRAP 0 #define GEN6_TEXCOORDMODE_MIRROR 1 #define GEN6_TEXCOORDMODE_CLAMP 2 #define GEN6_TEXCOORDMODE_CUBE 3 #define GEN6_TEXCOORDMODE_CLAMP_BORDER 4 #define GEN6_TEXCOORDMODE_MIRROR_ONCE 5 #define GEN6_THREAD_PRIORITY_NORMAL 0 #define GEN6_THREAD_PRIORITY_HIGH 1 #define GEN6_TILEWALK_XMAJOR 0 #define GEN6_TILEWALK_YMAJOR 1 #define GEN6_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define GEN6_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define GEN6_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define GEN6_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define GEN6_VFCOMPONENT_NOSTORE 0 #define GEN6_VFCOMPONENT_STORE_SRC 1 #define GEN6_VFCOMPONENT_STORE_0 2 #define GEN6_VFCOMPONENT_STORE_1_FLT 3 #define GEN6_VFCOMPONENT_STORE_1_INT 4 #define GEN6_VFCOMPONENT_STORE_VID 5 #define GEN6_VFCOMPONENT_STORE_IID 6 #define GEN6_VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define GEN6_ALIGN_1 0 #define GEN6_ALIGN_16 1 #define GEN6_ADDRESS_DIRECT 0 #define GEN6_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define GEN6_CHANNEL_X 0 #define GEN6_CHANNEL_Y 1 #define GEN6_CHANNEL_Z 2 #define GEN6_CHANNEL_W 3 #define GEN6_COMPRESSION_NONE 0 #define GEN6_COMPRESSION_2NDHALF 1 #define GEN6_COMPRESSION_COMPRESSED 2 #define GEN6_CONDITIONAL_NONE 0 #define GEN6_CONDITIONAL_Z 1 #define GEN6_CONDITIONAL_NZ 2 #define GEN6_CONDITIONAL_EQ 1 /* Z */ #define GEN6_CONDITIONAL_NEQ 2 /* NZ */ #define GEN6_CONDITIONAL_G 3 #define GEN6_CONDITIONAL_GE 4 #define GEN6_CONDITIONAL_L 5 #define GEN6_CONDITIONAL_LE 6 #define GEN6_CONDITIONAL_C 7 #define GEN6_CONDITIONAL_O 8 #define GEN6_DEBUG_NONE 0 #define GEN6_DEBUG_BREAKPOINT 1 #define GEN6_DEPENDENCY_NORMAL 0 #define GEN6_DEPENDENCY_NOTCLEARED 1 #define GEN6_DEPENDENCY_NOTCHECKED 2 #define GEN6_DEPENDENCY_DISABLE 3 #define GEN6_EXECUTE_1 0 #define GEN6_EXECUTE_2 1 #define GEN6_EXECUTE_4 2 #define GEN6_EXECUTE_8 3 #define GEN6_EXECUTE_16 4 #define GEN6_EXECUTE_32 5 #define GEN6_HORIZONTAL_STRIDE_0 0 #define GEN6_HORIZONTAL_STRIDE_1 1 #define GEN6_HORIZONTAL_STRIDE_2 2 #define GEN6_HORIZONTAL_STRIDE_4 3 #define GEN6_INSTRUCTION_NORMAL 0 #define GEN6_INSTRUCTION_SATURATE 1 #define GEN6_MASK_ENABLE 0 #define GEN6_MASK_DISABLE 1 #define GEN6_OPCODE_MOV 1 #define GEN6_OPCODE_SEL 2 #define GEN6_OPCODE_NOT 4 #define GEN6_OPCODE_AND 5 #define GEN6_OPCODE_OR 6 #define GEN6_OPCODE_XOR 7 #define GEN6_OPCODE_SHR 8 #define GEN6_OPCODE_SHL 9 #define GEN6_OPCODE_RSR 10 #define GEN6_OPCODE_RSL 11 #define GEN6_OPCODE_ASR 12 #define GEN6_OPCODE_CMP 16 #define GEN6_OPCODE_JMPI 32 #define GEN6_OPCODE_IF 34 #define GEN6_OPCODE_IFF 35 #define GEN6_OPCODE_ELSE 36 #define GEN6_OPCODE_ENDIF 37 #define GEN6_OPCODE_DO 38 #define GEN6_OPCODE_WHILE 39 #define GEN6_OPCODE_BREAK 40 #define GEN6_OPCODE_CONTINUE 41 #define GEN6_OPCODE_HALT 42 #define GEN6_OPCODE_MSAVE 44 #define GEN6_OPCODE_MRESTORE 45 #define GEN6_OPCODE_PUSH 46 #define GEN6_OPCODE_POP 47 #define GEN6_OPCODE_WAIT 48 #define GEN6_OPCODE_SEND 49 #define GEN6_OPCODE_ADD 64 #define GEN6_OPCODE_MUL 65 #define GEN6_OPCODE_AVG 66 #define GEN6_OPCODE_FRC 67 #define GEN6_OPCODE_RNDU 68 #define GEN6_OPCODE_RNDD 69 #define GEN6_OPCODE_RNDE 70 #define GEN6_OPCODE_RNDZ 71 #define GEN6_OPCODE_MAC 72 #define GEN6_OPCODE_MACH 73 #define GEN6_OPCODE_LZD 74 #define GEN6_OPCODE_SAD2 80 #define GEN6_OPCODE_SADA2 81 #define GEN6_OPCODE_DP4 84 #define GEN6_OPCODE_DPH 85 #define GEN6_OPCODE_DP3 86 #define GEN6_OPCODE_DP2 87 #define GEN6_OPCODE_DPA2 88 #define GEN6_OPCODE_LINE 89 #define GEN6_OPCODE_NOP 126 #define GEN6_PREDICATE_NONE 0 #define GEN6_PREDICATE_NORMAL 1 #define GEN6_PREDICATE_ALIGN1_ANYV 2 #define GEN6_PREDICATE_ALIGN1_ALLV 3 #define GEN6_PREDICATE_ALIGN1_ANY2H 4 #define GEN6_PREDICATE_ALIGN1_ALL2H 5 #define GEN6_PREDICATE_ALIGN1_ANY4H 6 #define GEN6_PREDICATE_ALIGN1_ALL4H 7 #define GEN6_PREDICATE_ALIGN1_ANY8H 8 #define GEN6_PREDICATE_ALIGN1_ALL8H 9 #define GEN6_PREDICATE_ALIGN1_ANY16H 10 #define GEN6_PREDICATE_ALIGN1_ALL16H 11 #define GEN6_PREDICATE_ALIGN16_REPLICATE_X 2 #define GEN6_PREDICATE_ALIGN16_REPLICATE_Y 3 #define GEN6_PREDICATE_ALIGN16_REPLICATE_Z 4 #define GEN6_PREDICATE_ALIGN16_REPLICATE_W 5 #define GEN6_PREDICATE_ALIGN16_ANY4H 6 #define GEN6_PREDICATE_ALIGN16_ALL4H 7 #define GEN6_ARCHITECTURE_REGISTER_FILE 0 #define GEN6_GENERAL_REGISTER_FILE 1 #define GEN6_MESSAGE_REGISTER_FILE 2 #define GEN6_IMMEDIATE_VALUE 3 #define GEN6_REGISTER_TYPE_UD 0 #define GEN6_REGISTER_TYPE_D 1 #define GEN6_REGISTER_TYPE_UW 2 #define GEN6_REGISTER_TYPE_W 3 #define GEN6_REGISTER_TYPE_UB 4 #define GEN6_REGISTER_TYPE_B 5 #define GEN6_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define GEN6_REGISTER_TYPE_HF 6 #define GEN6_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define GEN6_REGISTER_TYPE_F 7 #define GEN6_ARF_NULL 0x00 #define GEN6_ARF_ADDRESS 0x10 #define GEN6_ARF_ACCUMULATOR 0x20 #define GEN6_ARF_FLAG 0x30 #define GEN6_ARF_MASK 0x40 #define GEN6_ARF_MASK_STACK 0x50 #define GEN6_ARF_MASK_STACK_DEPTH 0x60 #define GEN6_ARF_STATE 0x70 #define GEN6_ARF_CONTROL 0x80 #define GEN6_ARF_NOTIFICATION_COUNT 0x90 #define GEN6_ARF_IP 0xA0 #define GEN6_AMASK 0 #define GEN6_IMASK 1 #define GEN6_LMASK 2 #define GEN6_CMASK 3 #define GEN6_THREAD_NORMAL 0 #define GEN6_THREAD_ATOMIC 1 #define GEN6_THREAD_SWITCH 2 #define GEN6_VERTICAL_STRIDE_0 0 #define GEN6_VERTICAL_STRIDE_1 1 #define GEN6_VERTICAL_STRIDE_2 2 #define GEN6_VERTICAL_STRIDE_4 3 #define GEN6_VERTICAL_STRIDE_8 4 #define GEN6_VERTICAL_STRIDE_16 5 #define GEN6_VERTICAL_STRIDE_32 6 #define GEN6_VERTICAL_STRIDE_64 7 #define GEN6_VERTICAL_STRIDE_128 8 #define GEN6_VERTICAL_STRIDE_256 9 #define GEN6_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define GEN6_WIDTH_1 0 #define GEN6_WIDTH_2 1 #define GEN6_WIDTH_4 2 #define GEN6_WIDTH_8 3 #define GEN6_WIDTH_16 4 #define GEN6_STATELESS_BUFFER_BOUNDARY_1K 0 #define GEN6_STATELESS_BUFFER_BOUNDARY_2K 1 #define GEN6_STATELESS_BUFFER_BOUNDARY_4K 2 #define GEN6_STATELESS_BUFFER_BOUNDARY_8K 3 #define GEN6_STATELESS_BUFFER_BOUNDARY_16K 4 #define GEN6_STATELESS_BUFFER_BOUNDARY_32K 5 #define GEN6_STATELESS_BUFFER_BOUNDARY_64K 6 #define GEN6_STATELESS_BUFFER_BOUNDARY_128K 7 #define GEN6_STATELESS_BUFFER_BOUNDARY_256K 8 #define GEN6_STATELESS_BUFFER_BOUNDARY_512K 9 #define GEN6_STATELESS_BUFFER_BOUNDARY_1M 10 #define GEN6_STATELESS_BUFFER_BOUNDARY_2M 11 #define GEN6_POLYGON_FACING_FRONT 0 #define GEN6_POLYGON_FACING_BACK 1 #define GEN6_MESSAGE_TARGET_NULL 0 #define GEN6_MESSAGE_TARGET_MATH 1 #define GEN6_MESSAGE_TARGET_SAMPLER 2 #define GEN6_MESSAGE_TARGET_GATEWAY 3 #define GEN6_MESSAGE_TARGET_DATAPORT_READ 4 #define GEN6_MESSAGE_TARGET_DATAPORT_WRITE 5 #define GEN6_MESSAGE_TARGET_URB 6 #define GEN6_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN6_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define GEN6_SAMPLER_RETURN_FORMAT_UINT32 2 #define GEN6_SAMPLER_RETURN_FORMAT_SINT32 3 #define GEN6_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define GEN6_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define GEN6_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define GEN6_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define GEN6_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define GEN6_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define GEN6_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define GEN6_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define GEN6_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define GEN6_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define GEN6_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define GEN6_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define GEN6_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define GEN6_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define GEN6_SAMPLER_MESSAGE_SIMD8_LD 3 #define GEN6_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN6_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define GEN6_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define GEN6_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define GEN6_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define GEN6_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define GEN6_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define GEN6_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define GEN6_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define GEN6_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define GEN6_DATAPORT_READ_TARGET_DATA_CACHE 0 #define GEN6_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define GEN6_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define GEN6_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define GEN6_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define GEN6_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define GEN6_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define GEN6_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define GEN6_MATH_INTEGER_UNSIGNED 0 #define GEN6_MATH_INTEGER_SIGNED 1 #define GEN6_MATH_PRECISION_FULL 0 #define GEN6_MATH_PRECISION_PARTIAL 1 #define GEN6_MATH_SATURATE_NONE 0 #define GEN6_MATH_SATURATE_SATURATE 1 #define GEN6_MATH_DATA_VECTOR 0 #define GEN6_MATH_DATA_SCALAR 1 #define GEN6_URB_OPCODE_WRITE 0 #define GEN6_URB_SWIZZLE_NONE 0 #define GEN6_URB_SWIZZLE_INTERLEAVE 1 #define GEN6_URB_SWIZZLE_TRANSPOSE 2 #define GEN6_SCRATCH_SPACE_SIZE_1K 0 #define GEN6_SCRATCH_SPACE_SIZE_2K 1 #define GEN6_SCRATCH_SPACE_SIZE_4K 2 #define GEN6_SCRATCH_SPACE_SIZE_8K 3 #define GEN6_SCRATCH_SPACE_SIZE_16K 4 #define GEN6_SCRATCH_SPACE_SIZE_32K 5 #define GEN6_SCRATCH_SPACE_SIZE_64K 6 #define GEN6_SCRATCH_SPACE_SIZE_128K 7 #define GEN6_SCRATCH_SPACE_SIZE_256K 8 #define GEN6_SCRATCH_SPACE_SIZE_512K 9 #define GEN6_SCRATCH_SPACE_SIZE_1M 10 #define GEN6_SCRATCH_SPACE_SIZE_2M 11 /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct gen6_sampler_default_border_color { float color[4]; }; struct gen6_sampler_legacy_border_color { uint8_t color[4]; }; struct gen6_sampler_state { struct { uint32_t shadow_function:3; uint32_t lod_bias:11; uint32_t min_filter:3; uint32_t mag_filter:3; uint32_t mip_filter:2; uint32_t base_level:5; uint32_t pad:1; uint32_t lod_preclamp:1; uint32_t border_color_mode:1; uint32_t pad0:1; uint32_t disable:1; } ss0; struct { uint32_t r_wrap_mode:3; uint32_t t_wrap_mode:3; uint32_t s_wrap_mode:3; uint32_t pad:3; uint32_t max_lod:10; uint32_t min_lod:10; } ss1; struct { uint32_t border_color; } ss2; struct { uint32_t non_normalized_coord:1; uint32_t pad:12; uint32_t address_round:6; uint32_t max_aniso:3; uint32_t chroma_key_mode:1; uint32_t chroma_key_index:2; uint32_t chroma_key_enable:1; uint32_t monochrome_filter_width:3; uint32_t monochrome_filter_height:3; } ss3; }; struct gen6_blend_state { struct { uint32_t dest_blend_factor:5; uint32_t source_blend_factor:5; uint32_t pad3:1; uint32_t blend_func:3; uint32_t pad2:1; uint32_t ia_dest_blend_factor:5; uint32_t ia_source_blend_factor:5; uint32_t pad1:1; uint32_t ia_blend_func:3; uint32_t pad0:1; uint32_t ia_blend_enable:1; uint32_t blend_enable:1; } blend0; struct { uint32_t post_blend_clamp_enable:1; uint32_t pre_blend_clamp_enable:1; uint32_t clamp_range:2; uint32_t pad0:4; uint32_t x_dither_offset:2; uint32_t y_dither_offset:2; uint32_t dither_enable:1; uint32_t alpha_test_func:3; uint32_t alpha_test_enable:1; uint32_t pad1:1; uint32_t logic_op_func:4; uint32_t logic_op_enable:1; uint32_t pad2:1; uint32_t write_disable_b:1; uint32_t write_disable_g:1; uint32_t write_disable_r:1; uint32_t write_disable_a:1; uint32_t pad3:1; uint32_t alpha_to_coverage_dither:1; uint32_t alpha_to_one:1; uint32_t alpha_to_coverage:1; } blend1; }; struct gen6_color_calc_state { struct { uint32_t alpha_test_format:1; uint32_t pad0:14; uint32_t round_disable:1; uint32_t bf_stencil_ref:8; uint32_t stencil_ref:8; } cc0; union { float alpha_ref_f; struct { uint32_t ui:8; uint32_t pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen6_depth_stencil_state { struct { uint32_t pad0:3; uint32_t bf_stencil_pass_depth_pass_op:3; uint32_t bf_stencil_pass_depth_fail_op:3; uint32_t bf_stencil_fail_op:3; uint32_t bf_stencil_func:3; uint32_t bf_stencil_enable:1; uint32_t pad1:2; uint32_t stencil_write_enable:1; uint32_t stencil_pass_depth_pass_op:3; uint32_t stencil_pass_depth_fail_op:3; uint32_t stencil_fail_op:3; uint32_t stencil_func:3; uint32_t stencil_enable:1; } ds0; struct { uint32_t bf_stencil_write_mask:8; uint32_t bf_stencil_test_mask:8; uint32_t stencil_write_mask:8; uint32_t stencil_test_mask:8; } ds1; struct { uint32_t pad0:26; uint32_t depth_write_enable:1; uint32_t depth_test_func:3; uint32_t pad1:1; uint32_t depth_test_enable:1; } ds2; }; struct gen6_surface_state { struct { uint32_t cube_pos_z:1; uint32_t cube_neg_z:1; uint32_t cube_pos_y:1; uint32_t cube_neg_y:1; uint32_t cube_pos_x:1; uint32_t cube_neg_x:1; uint32_t pad:3; uint32_t render_cache_read_mode:1; uint32_t mipmap_layout_mode:1; uint32_t vert_line_stride_ofs:1; uint32_t vert_line_stride:1; uint32_t color_blend:1; uint32_t writedisable_blue:1; uint32_t writedisable_green:1; uint32_t writedisable_red:1; uint32_t writedisable_alpha:1; uint32_t surface_format:9; uint32_t data_return_format:1; uint32_t pad0:1; uint32_t surface_type:3; } ss0; struct { uint32_t base_addr; } ss1; struct { uint32_t render_target_rotation:2; uint32_t mip_count:4; uint32_t width:13; uint32_t height:13; } ss2; struct { uint32_t tile_walk:1; uint32_t tiled_surface:1; uint32_t pad:1; uint32_t pitch:18; uint32_t depth:11; } ss3; struct { uint32_t pad:19; uint32_t min_array_elt:9; uint32_t min_lod:4; } ss4; struct { uint32_t pad:20; uint32_t y_offset:4; uint32_t pad2:1; uint32_t x_offset:7; } ss5; }; /* Surface state DW0 */ #define GEN6_SURFACE_RC_READ_WRITE (1 << 8) #define GEN6_SURFACE_MIPLAYOUT_SHIFT 10 #define GEN6_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN6_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN6_SURFACE_CUBEFACE_ENABLES 0x3f #define GEN6_SURFACE_BLEND_ENABLED (1 << 13) #define GEN6_SURFACE_WRITEDISABLE_B_SHIFT 14 #define GEN6_SURFACE_WRITEDISABLE_G_SHIFT 15 #define GEN6_SURFACE_WRITEDISABLE_R_SHIFT 16 #define GEN6_SURFACE_WRITEDISABLE_A_SHIFT 17 #define GEN6_SURFACE_FORMAT_SHIFT 18 #define GEN6_SURFACE_FORMAT_MASK INTEL_MASK(26, 18) #define GEN6_SURFACE_TYPE_SHIFT 29 #define GEN6_SURFACE_TYPE_MASK GEN6_MASK(31, 29) #define GEN6_SURFACE_1D 0 #define GEN6_SURFACE_2D 1 #define GEN6_SURFACE_3D 2 #define GEN6_SURFACE_CUBE 3 #define GEN6_SURFACE_BUFFER 4 #define GEN6_SURFACE_NULL 7 /* Surface state DW2 */ #define GEN6_SURFACE_HEIGHT_SHIFT 19 #define GEN6_SURFACE_HEIGHT_MASK GEN6_MASK(31, 19) #define GEN6_SURFACE_WIDTH_SHIFT 6 #define GEN6_SURFACE_WIDTH_MASK GEN6_MASK(18, 6) #define GEN6_SURFACE_LOD_SHIFT 2 #define GEN6_SURFACE_LOD_MASK GEN6_MASK(5, 2) /* Surface state DW3 */ #define GEN6_SURFACE_DEPTH_SHIFT 21 #define GEN6_SURFACE_DEPTH_MASK GEN6_MASK(31, 21) #define GEN6_SURFACE_PITCH_SHIFT 3 #define GEN6_SURFACE_PITCH_MASK GEN6_MASK(19, 3) #define GEN6_SURFACE_TILED (1 << 1) #define GEN6_SURFACE_TILED_Y (1 << 0) /* Surface state DW4 */ #define GEN6_SURFACE_MIN_LOD_SHIFT 28 #define GEN6_SURFACE_MIN_LOD_MASK GEN6_MASK(31, 28) /* Surface state DW5 */ #define GEN6_SURFACE_X_OFFSET_SHIFT 25 #define GEN6_SURFACE_X_OFFSET_MASK GEN6_MASK(31, 25) #define GEN6_SURFACE_Y_OFFSET_SHIFT 20 #define GEN6_SURFACE_Y_OFFSET_MASK GEN6_MASK(23, 20) struct gen6_cc_viewport { float min_depth; float max_depth; }; typedef enum { SAMPLER_FILTER_NEAREST = 0, SAMPLER_FILTER_BILINEAR, FILTER_COUNT } sampler_filter_t; typedef enum { SAMPLER_EXTEND_NONE = 0, SAMPLER_EXTEND_REPEAT, SAMPLER_EXTEND_PAD, SAMPLER_EXTEND_REFLECT, EXTEND_COUNT } sampler_extend_t; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen7_render.c000066400000000000000000003173121267532330400242150ustar00rootroot00000000000000/* * Copyright © 2006,2008,2011 Intel Corporation * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Carl Worth * Keith Packard * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_video.h" #include "brw/brw.h" #include "gen7_render.h" #include "gen4_common.h" #include "gen4_source.h" #include "gen4_vertex.h" #include "gen6_common.h" #define ALWAYS_INVALIDATE 0 #define ALWAYS_FLUSH 0 #define ALWAYS_STALL 0 #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_BOXES 0 #define NO_FILL_ONE 0 #define NO_FILL_CLEAR 0 #define USE_8_PIXEL_DISPATCH 1 #define USE_16_PIXEL_DISPATCH 1 #define USE_32_PIXEL_DISPATCH 0 #if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH #error "Must select at least 8, 16 or 32 pixel dispatch" #endif #define GEN7_MAX_SIZE 16384 /* XXX Todo * * STR (software tiled rendering) mode. No, really. * 64x32 pixel blocks align with the rendering cache. Worth considering. */ #define is_aligned(x, y) (((x) & ((y) - 1)) == 0) struct gt_info { const char *name; uint32_t max_vs_threads; uint32_t max_gs_threads; uint32_t max_wm_threads; struct { int size; int max_vs_entries; int max_gs_entries; int push_ps_size; /* in 1KBs */ } urb; int gt; uint32_t mocs; }; static const struct gt_info ivb_gt_info = { .name = "Ivybridge (gen7)", .max_vs_threads = 16, .max_gs_threads = 16, .max_wm_threads = (16-1) << IVB_PS_MAX_THREADS_SHIFT, .urb = { 128, 64, 64, 8 }, .gt = 0, }; static const struct gt_info ivb_gt1_info = { .name = "Ivybridge (gen7, gt1)", .max_vs_threads = 36, .max_gs_threads = 36, .max_wm_threads = (48-1) << IVB_PS_MAX_THREADS_SHIFT, .urb = { 128, 512, 192, 8 }, .gt = 1, .mocs = 3, }; static const struct gt_info ivb_gt2_info = { .name = "Ivybridge (gen7, gt2)", .max_vs_threads = 128, .max_gs_threads = 128, .max_wm_threads = (172-1) << IVB_PS_MAX_THREADS_SHIFT, .urb = { 256, 704, 320, 8 }, .gt = 2, .mocs = 3, }; static const struct gt_info byt_gt_info = { .name = "Baytrail (gen7)", .max_vs_threads = 36, .max_gs_threads = 36, .max_wm_threads = (48-1) << IVB_PS_MAX_THREADS_SHIFT, .urb = { 128, 512, 192, 8 }, .gt = 1, }; static const struct gt_info hsw_gt_info = { .name = "Haswell (gen7.5)", .max_vs_threads = 8, .max_gs_threads = 8, .max_wm_threads = (8 - 1) << HSW_PS_MAX_THREADS_SHIFT | 1 << HSW_PS_SAMPLE_MASK_SHIFT, .urb = { 128, 64, 64, 8 }, .gt = 0, }; static const struct gt_info hsw_gt1_info = { .name = "Haswell (gen7.5, gt1)", .max_vs_threads = 70, .max_gs_threads = 70, .max_wm_threads = (70 - 1) << HSW_PS_MAX_THREADS_SHIFT | 1 << HSW_PS_SAMPLE_MASK_SHIFT, .urb = { 128, 640, 256, 8 }, .gt = 1, .mocs = 5, }; static const struct gt_info hsw_gt2_info = { .name = "Haswell (gen7.5, gt2)", .max_vs_threads = 140, .max_gs_threads = 140, .max_wm_threads = (140 - 1) << HSW_PS_MAX_THREADS_SHIFT | 1 << HSW_PS_SAMPLE_MASK_SHIFT, .urb = { 256, 1664, 640, 8 }, .gt = 2, .mocs = 5, }; static const struct gt_info hsw_gt3_info = { .name = "Haswell (gen7.5, gt3)", .max_vs_threads = 280, .max_gs_threads = 280, .max_wm_threads = (280 - 1) << HSW_PS_MAX_THREADS_SHIFT | 1 << HSW_PS_SAMPLE_MASK_SHIFT, .urb = { 512, 3328, 1280, 16 }, .gt = 3, .mocs = 5, }; inline static bool is_ivb(struct sna *sna) { return sna->kgem.gen == 070; } inline static bool is_byt(struct sna *sna) { return sna->kgem.gen == 071; } inline static bool is_hsw(struct sna *sna) { return sna->kgem.gen == 075; } static const uint32_t ps_kernel_packed[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_planar[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_planar.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; #define KERNEL(kernel_enum, kernel, num_surfaces) \ [GEN7_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), num_surfaces} #define NOKERNEL(kernel_enum, func, num_surfaces) \ [GEN7_WM_KERNEL_##kernel_enum] = {#kernel_enum, (void *)func, 0, num_surfaces} static const struct wm_kernel_info { const char *name; const void *data; unsigned int size; int num_surfaces; } wm_kernels[] = { NOKERNEL(NOMASK, brw_wm_kernel__affine, 2), NOKERNEL(NOMASK_P, brw_wm_kernel__projective, 2), NOKERNEL(MASK, brw_wm_kernel__affine_mask, 3), NOKERNEL(MASK_P, brw_wm_kernel__projective_mask, 3), NOKERNEL(MASKCA, brw_wm_kernel__affine_mask_ca, 3), NOKERNEL(MASKCA_P, brw_wm_kernel__projective_mask_ca, 3), NOKERNEL(MASKSA, brw_wm_kernel__affine_mask_sa, 3), NOKERNEL(MASKSA_P, brw_wm_kernel__projective_mask_sa, 3), NOKERNEL(OPACITY, brw_wm_kernel__affine_opacity, 2), NOKERNEL(OPACITY_P, brw_wm_kernel__projective_opacity, 2), KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), }; #undef KERNEL static const struct blendinfo { bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } gen7_blend_op[] = { /* Clear */ {0, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ZERO}, /* Src */ {0, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ZERO}, /* Dst */ {0, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ONE}, /* Over */ {1, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {0, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_ONE}, /* In */ {0, GEN7_BLENDFACTOR_DST_ALPHA, GEN7_BLENDFACTOR_ZERO}, /* InReverse */ {1, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_SRC_ALPHA}, /* Out */ {0, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_ZERO}, /* OutReverse */ {1, GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, GEN7_BLENDFACTOR_DST_ALPHA, GEN7_BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, GEN7_BLENDFACTOR_INV_DST_ALPHA, GEN7_BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in gen7_blend_op. * * This leaves out GEN7_BLENDFACTOR_INV_DST_COLOR, * GEN7_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * GEN7_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define GEN7_BLENDFACTOR_COUNT (GEN7_BLENDFACTOR_INV_DST_ALPHA + 1) #define GEN7_BLEND_STATE_PADDED_SIZE ALIGN(sizeof(struct gen7_blend_state), 64) #define BLEND_OFFSET(s, d) \ ((d != GEN7_BLENDFACTOR_ZERO) << 15 | \ (((s) * GEN7_BLENDFACTOR_COUNT + (d)) * GEN7_BLEND_STATE_PADDED_SIZE)) #define NO_BLEND BLEND_OFFSET(GEN7_BLENDFACTOR_ONE, GEN7_BLENDFACTOR_ZERO) #define CLEAR BLEND_OFFSET(GEN7_BLENDFACTOR_ZERO, GEN7_BLENDFACTOR_ZERO) #define SAMPLER_OFFSET(sf, se, mf, me) \ ((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) + 2) * 2 * sizeof(struct gen7_sampler_state)) #define VERTEX_2s2s 0 #define COPY_SAMPLER 0 #define COPY_VERTEX VERTEX_2s2s #define COPY_FLAGS(a) GEN7_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN7_WM_KERNEL_NOMASK, COPY_VERTEX) #define FILL_SAMPLER (2 * sizeof(struct gen7_sampler_state)) #define FILL_VERTEX VERTEX_2s2s #define FILL_FLAGS(op, format) GEN7_SET_FLAGS(FILL_SAMPLER, gen7_get_blend((op), false, (format)), GEN7_WM_KERNEL_NOMASK, FILL_VERTEX) #define FILL_FLAGS_NOBLEND GEN7_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN7_WM_KERNEL_NOMASK, FILL_VERTEX) #define GEN7_SAMPLER(f) (((f) >> 16) & 0xfff0) #define GEN7_BLEND(f) (((f) >> 0) & 0x7ff0) #define GEN7_READS_DST(f) (((f) >> 15) & 1) #define GEN7_KERNEL(f) (((f) >> 16) & 0xf) #define GEN7_VERTEX(f) (((f) >> 0) & 0xf) #define GEN7_SET_FLAGS(S, B, K, V) (((S) | (K)) << 16 | ((B) | (V))) #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) #define OUT_VERTEX_F(v) vertex_emit(sna, v) static inline bool too_large(int width, int height) { return width > GEN7_MAX_SIZE || height > GEN7_MAX_SIZE; } static uint32_t gen7_get_blend(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t src, dst; src = gen7_blend_op[op].src_blend; dst = gen7_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that * we'll treat it always as 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (src == GEN7_BLENDFACTOR_DST_ALPHA) src = GEN7_BLENDFACTOR_ONE; else if (src == GEN7_BLENDFACTOR_INV_DST_ALPHA) src = GEN7_BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a * case where the source blend factor is 0, and the source blend * value is the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen7_blend_op[op].src_alpha) { if (dst == GEN7_BLENDFACTOR_SRC_ALPHA) dst = GEN7_BLENDFACTOR_SRC_COLOR; else if (dst == GEN7_BLENDFACTOR_INV_SRC_ALPHA) dst = GEN7_BLENDFACTOR_INV_SRC_COLOR; } DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n", op, dst_format, PICT_FORMAT_A(dst_format), src, dst, (int)BLEND_OFFSET(src, dst))); return BLEND_OFFSET(src, dst); } static uint32_t gen7_get_card_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_x8r8g8b8: return GEN7_SURFACEFORMAT_B8G8R8X8_UNORM; case PICT_a8b8g8r8: return GEN7_SURFACEFORMAT_R8G8B8A8_UNORM; case PICT_x8b8g8r8: return GEN7_SURFACEFORMAT_R8G8B8X8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: return GEN7_SURFACEFORMAT_B10G10R10A2_UNORM; case PICT_x2r10g10b10: return GEN7_SURFACEFORMAT_B10G10R10X2_UNORM; #endif case PICT_r8g8b8: return GEN7_SURFACEFORMAT_R8G8B8_UNORM; case PICT_r5g6b5: return GEN7_SURFACEFORMAT_B5G6R5_UNORM; case PICT_a1r5g5b5: return GEN7_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN7_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: return GEN7_SURFACEFORMAT_B4G4R4A4_UNORM; } } static uint32_t gen7_get_dest_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return GEN7_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return GEN7_SURFACEFORMAT_R8G8B8A8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return GEN7_SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return GEN7_SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return GEN7_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return GEN7_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return GEN7_SURFACEFORMAT_B4G4R4A4_UNORM; } } static bool gen7_check_dst_format(PictFormat format) { if (gen7_get_dest_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static bool gen7_check_format(uint32_t format) { if (gen7_get_card_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static uint32_t gen7_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return SAMPLER_FILTER_NEAREST; case PictFilterBilinear: return SAMPLER_FILTER_BILINEAR; } } static uint32_t gen7_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: return false; } } static uint32_t gen7_repeat(uint32_t repeat) { switch (repeat) { default: assert(0); case RepeatNone: return SAMPLER_EXTEND_NONE; case RepeatNormal: return SAMPLER_EXTEND_REPEAT; case RepeatPad: return SAMPLER_EXTEND_PAD; case RepeatReflect: return SAMPLER_EXTEND_REFLECT; } } static bool gen7_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: return false; } } static int gen7_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine) { int base; if (has_mask) { if (is_ca) { if (gen7_blend_op[op].src_alpha) base = GEN7_WM_KERNEL_MASKSA; else base = GEN7_WM_KERNEL_MASKCA; } else base = GEN7_WM_KERNEL_MASK; } else base = GEN7_WM_KERNEL_NOMASK; return base + !is_affine; } static void gen7_emit_urb(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2)); OUT_BATCH(sna->render_state.gen7.info->urb.push_ps_size); /* num of VS entries must be divisible by 8 if size < 9 */ OUT_BATCH(GEN7_3DSTATE_URB_VS | (2 - 2)); OUT_BATCH((sna->render_state.gen7.info->urb.max_vs_entries << GEN7_URB_ENTRY_NUMBER_SHIFT) | (2 - 1) << GEN7_URB_ENTRY_SIZE_SHIFT | (1 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_HS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (2 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_DS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (2 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_GS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (1 << GEN7_URB_STARTING_ADDRESS_SHIFT)); } static void gen7_emit_state_base_address(struct sna *sna) { uint32_t mocs = sna->render_state.gen7.info->mocs << 8; OUT_BATCH(GEN7_STATE_BASE_ADDRESS | (10 - 2)); OUT_BATCH(0); /* general */ OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */ sna->kgem.nbatch, NULL, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH(kgem_add_reloc(&sna->kgem, /* dynamic */ sna->kgem.nbatch, sna->render_state.gen7.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, mocs | BASE_ADDRESS_MODIFY)); OUT_BATCH(0); /* indirect */ OUT_BATCH(kgem_add_reloc(&sna->kgem, /* instruction */ sna->kgem.nbatch, sna->render_state.gen7.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, mocs | BASE_ADDRESS_MODIFY)); /* upper bounds, disable */ OUT_BATCH(0); OUT_BATCH(BASE_ADDRESS_MODIFY); OUT_BATCH(0); OUT_BATCH(BASE_ADDRESS_MODIFY); } static void gen7_disable_vs(struct sna *sna) { /* For future reference: * A PIPE_CONTROL with post-sync op set to 1 and a depth stall needs * to be emitted just prior to change VS state, i.e. 3DSTATE_VS, * 3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS, * 3DSTATE_BINDING_TABLE_POINTER_VS, 3DSTATE_SAMPLER_STATE_POINTER_VS. * * Here we saved by the full-flush incurred when emitting * the batchbuffer. */ OUT_BATCH(GEN7_3DSTATE_VS | (6 - 2)); OUT_BATCH(0); /* no VS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ #if 0 OUT_BATCH(GEN7_3DSTATE_CONSTANT_VS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS | (2 - 2)); OUT_BATCH(0); #endif } static void gen7_disable_hs(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_HS | (7 - 2)); OUT_BATCH(0); /* no HS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ #if 0 OUT_BATCH(GEN7_3DSTATE_CONSTANT_HS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS | (2 - 2)); OUT_BATCH(0); #endif } static void gen7_disable_te(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_TE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen7_disable_ds(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_DS | (6 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #if 0 OUT_BATCH(GEN7_3DSTATE_CONSTANT_DS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS | (2 - 2)); OUT_BATCH(0); #endif } static void gen7_disable_gs(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_GS | (7 - 2)); OUT_BATCH(0); /* no GS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ #if 0 OUT_BATCH(GEN7_3DSTATE_CONSTANT_GS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS | (2 - 2)); OUT_BATCH(0); #endif } static void gen7_disable_streamout(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_STREAMOUT | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); } static void gen7_emit_sf_invariant(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_SF | (7 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SF_CULL_NONE); OUT_BATCH(2 << GEN7_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen7_emit_cc_invariant(struct sna *sna) { #if 0 /* unused, no change */ OUT_BATCH(GEN7_3DSTATE_CC_STATE_POINTERS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS | (2 - 2)); OUT_BATCH(0); #endif /* XXX clear to be safe */ OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC | (2 - 2)); OUT_BATCH(0); } static void gen7_disable_clip(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_CLIP | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL | (2 - 2)); OUT_BATCH(0); } static void gen7_emit_wm_invariant(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_WM | (3 - 2)); OUT_BATCH(GEN7_WM_DISPATCH_ENABLE | GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(0); #if 0 /* XXX length bias of 7 in old spec? */ OUT_BATCH(GEN7_3DSTATE_CONSTANT_PS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #endif } static void gen7_emit_null_depth_buffer(struct sna *sna) { OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER | (7 - 2)); OUT_BATCH(GEN7_SURFACE_NULL << GEN7_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT | GEN7_DEPTHFORMAT_D32_FLOAT << GEN7_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT); OUT_BATCH(0); /* disable depth, stencil and hiz */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #if 0 OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); #endif } static void gen7_emit_invariant(struct sna *sna) { OUT_BATCH(GEN7_PIPELINE_SELECT | PIPELINE_SELECT_3D); OUT_BATCH(GEN7_3DSTATE_MULTISAMPLE | (4 - 2)); OUT_BATCH(GEN7_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER | GEN7_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_SAMPLE_MASK | (2 - 2)); OUT_BATCH(1); gen7_emit_urb(sna); gen7_emit_state_base_address(sna); gen7_disable_vs(sna); gen7_disable_hs(sna); gen7_disable_te(sna); gen7_disable_ds(sna); gen7_disable_gs(sna); gen7_disable_clip(sna); gen7_emit_sf_invariant(sna); gen7_emit_wm_invariant(sna); gen7_emit_cc_invariant(sna); gen7_disable_streamout(sna); gen7_emit_null_depth_buffer(sna); sna->render_state.gen7.needs_invariant = false; } static void gen7_emit_cc(struct sna *sna, uint32_t blend_offset) { struct gen7_render_state *render = &sna->render_state.gen7; if (render->blend == blend_offset) return; DBG(("%s: blend = %x\n", __FUNCTION__, blend_offset)); /* XXX can have up to 8 blend states preload, selectable via * Render Target Index. What other side-effects of Render Target Index? */ assert (is_aligned(render->cc_blend + blend_offset, 64)); OUT_BATCH(GEN7_3DSTATE_BLEND_STATE_POINTERS | (2 - 2)); OUT_BATCH((render->cc_blend + blend_offset) | 1); render->blend = blend_offset; } static void gen7_emit_sampler(struct sna *sna, uint32_t state) { if (sna->render_state.gen7.samplers == state) return; sna->render_state.gen7.samplers = state; DBG(("%s: sampler = %x\n", __FUNCTION__, state)); assert (is_aligned(sna->render_state.gen7.wm_state + state, 32)); OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS | (2 - 2)); OUT_BATCH(sna->render_state.gen7.wm_state + state); } static void gen7_emit_sf(struct sna *sna, bool has_mask) { int num_sf_outputs = has_mask ? 2 : 1; if (sna->render_state.gen7.num_sf_outputs == num_sf_outputs) return; DBG(("%s: num_sf_outputs=%d, read_length=%d, read_offset=%d\n", __FUNCTION__, num_sf_outputs, 1, 0)); sna->render_state.gen7.num_sf_outputs = num_sf_outputs; OUT_BATCH(GEN7_3DSTATE_SBE | (14 - 2)); OUT_BATCH(num_sf_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT | 1 << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT | 1 << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT); OUT_BATCH(0); OUT_BATCH(0); /* dw4 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* dw8 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* dw12 */ OUT_BATCH(0); OUT_BATCH(0); } static void gen7_emit_wm(struct sna *sna, int kernel) { const uint32_t *kernels; if (sna->render_state.gen7.kernel == kernel) return; sna->render_state.gen7.kernel = kernel; kernels = sna->render_state.gen7.wm_kernel[kernel]; DBG(("%s: switching to %s, num_surfaces=%d (8-wide? %d, 16-wide? %d, 32-wide? %d)\n", __FUNCTION__, wm_kernels[kernel].name, wm_kernels[kernel].num_surfaces, kernels[0], kernels[1], kernels[2])); OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2)); OUT_BATCH(kernels[0] ?: kernels[1] ?: kernels[2]); OUT_BATCH(1 << GEN7_PS_SAMPLER_COUNT_SHIFT | wm_kernels[kernel].num_surfaces << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT); OUT_BATCH(0); /* scratch address */ OUT_BATCH(sna->render_state.gen7.info->max_wm_threads | (kernels[0] ? GEN7_PS_8_DISPATCH_ENABLE : 0) | (kernels[1] ? GEN7_PS_16_DISPATCH_ENABLE : 0) | (kernels[2] ? GEN7_PS_32_DISPATCH_ENABLE : 0) | GEN7_PS_ATTRIBUTE_ENABLE); OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << GEN7_PS_DISPATCH_START_GRF_SHIFT_0 | 8 << GEN7_PS_DISPATCH_START_GRF_SHIFT_1 | 6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_2); OUT_BATCH(kernels[2]); OUT_BATCH(kernels[1]); } static bool gen7_emit_binding_table(struct sna *sna, uint16_t offset) { if (sna->render_state.gen7.surface_table == offset) return false; /* Binding table pointers */ assert(is_aligned(4*offset, 32)); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS | (2 - 2)); OUT_BATCH(offset*4); sna->render_state.gen7.surface_table = offset; return true; } static bool gen7_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; assert(!too_large(abs(op->dst.x), abs(op->dst.y))); assert(!too_large(op->dst.width, op->dst.height)); if (sna->render_state.gen7.drawrect_limit == limit && sna->render_state.gen7.drawrect_offset == offset) return true; sna->render_state.gen7.drawrect_offset = offset; sna->render_state.gen7.drawrect_limit = limit; OUT_BATCH(GEN7_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(limit); OUT_BATCH(offset); return false; } static void gen7_emit_vertex_elements(struct sna *sna, const struct sna_composite_op *op) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0) * texture coordinate 1 if (has_mask is true): same as above */ struct gen7_render_state *render = &sna->render_state.gen7; uint32_t src_format, dw; int id = GEN7_VERTEX(op->u.gen7.flags); bool has_mask; DBG(("%s: setup id=%d\n", __FUNCTION__, id)); if (render->ve_id == id) return; render->ve_id = id; /* The VUE layout * dword 0-3: pad (0.0, 0.0, 0.0. 0.0) * dword 4-7: position (x, y, 1.0, 1.0), * dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0) * dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0) * * dword 4-15 are fetched from vertex buffer */ has_mask = (id >> 2) != 0; OUT_BATCH(GEN7_3DSTATE_VERTEX_ELEMENTS | ((2 * (3 + has_mask)) + 1 - 2)); OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID | GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT << GEN7_VE0_FORMAT_SHIFT | 0 << GEN7_VE0_OFFSET_SHIFT); OUT_BATCH(GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_0_SHIFT | GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT | GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT | GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_3_SHIFT); /* x,y */ OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID | GEN7_SURFACEFORMAT_R16G16_SSCALED << GEN7_VE0_FORMAT_SHIFT | 0 << GEN7_VE0_OFFSET_SHIFT); OUT_BATCH(GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT | GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT | GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT | GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT); /* u0, v0, w0 */ DBG(("%s: first channel %d floats, offset=4b\n", __FUNCTION__, id & 3)); dw = GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT; switch (id & 3) { default: assert(0); case 0: src_format = GEN7_SURFACEFORMAT_R16G16_SSCALED; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; case 1: src_format = GEN7_SURFACEFORMAT_R32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; case 2: src_format = GEN7_SURFACEFORMAT_R32G32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN7_SURFACEFORMAT_R32G32B32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID | src_format << GEN7_VE0_FORMAT_SHIFT | 4 << GEN7_VE0_OFFSET_SHIFT); OUT_BATCH(dw); /* u1, v1, w1 */ if (has_mask) { unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float); DBG(("%s: second channel %d floats, offset=%db\n", __FUNCTION__, id >> 2, offset)); dw = GEN7_VFCOMPONENT_STORE_1_FLT << GEN7_VE1_VFCOMPONENT_3_SHIFT; switch (id >> 2) { case 1: src_format = GEN7_SURFACEFORMAT_R32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; default: assert(0); case 2: src_format = GEN7_SURFACEFORMAT_R32G32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_0 << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; case 3: src_format = GEN7_SURFACEFORMAT_R32G32B32_FLOAT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_0_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_1_SHIFT; dw |= GEN7_VFCOMPONENT_STORE_SRC << GEN7_VE1_VFCOMPONENT_2_SHIFT; break; } OUT_BATCH(id << GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT | GEN7_VE0_VALID | src_format << GEN7_VE0_FORMAT_SHIFT | offset << GEN7_VE0_OFFSET_SHIFT); OUT_BATCH(dw); } } inline static void gen7_emit_pipe_invalidate(struct sna *sna) { OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN7_PIPE_CONTROL_WC_FLUSH | GEN7_PIPE_CONTROL_TC_FLUSH | GEN7_PIPE_CONTROL_CS_STALL); OUT_BATCH(0); OUT_BATCH(0); sna->render_state.gen7.pipe_controls_since_stall = 0; } inline static void gen7_emit_pipe_flush(struct sna *sna, bool need_stall) { unsigned stall; stall = 0; if (need_stall) { stall = GEN7_PIPE_CONTROL_CS_STALL; sna->render_state.gen7.pipe_controls_since_stall = 0; } else sna->render_state.gen7.pipe_controls_since_stall++; OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN7_PIPE_CONTROL_WC_FLUSH | stall); OUT_BATCH(0); OUT_BATCH(0); } inline static void gen7_emit_pipe_stall(struct sna *sna) { OUT_BATCH(GEN7_PIPE_CONTROL | (4 - 2)); OUT_BATCH(GEN7_PIPE_CONTROL_CS_STALL | GEN7_PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH(0); OUT_BATCH(0); sna->render_state.gen7.pipe_controls_since_stall = 0; } static void gen7_emit_state(struct sna *sna, const struct sna_composite_op *op, uint16_t wm_binding_table) { bool need_invalidate; bool need_flush; bool need_stall; assert(op->dst.bo->exec); need_flush = wm_binding_table & 1 || (sna->render_state.gen7.emit_flush && GEN7_READS_DST(op->u.gen7.flags)); if (ALWAYS_FLUSH) need_flush = true; wm_binding_table &= ~1; need_stall = sna->render_state.gen7.surface_table != wm_binding_table; need_invalidate = kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo); if (ALWAYS_INVALIDATE) need_invalidate = true; need_stall &= gen7_emit_drawing_rectangle(sna, op); if (ALWAYS_STALL) need_stall = true; if (sna->kgem.gen < 075 && sna->render_state.gen7.pipe_controls_since_stall >= 3) need_stall = true; if (need_invalidate) { gen7_emit_pipe_invalidate(sna); kgem_clear_dirty(&sna->kgem); assert(op->dst.bo->exec); kgem_bo_mark_dirty(op->dst.bo); need_flush = false; need_stall = false; } if (need_flush) { gen7_emit_pipe_flush(sna, need_stall); need_stall = false; } if (need_stall) gen7_emit_pipe_stall(sna); gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags)); gen7_emit_sampler(sna, GEN7_SAMPLER(op->u.gen7.flags)); gen7_emit_sf(sna, GEN7_VERTEX(op->u.gen7.flags) >> 2); gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags)); gen7_emit_vertex_elements(sna, op); gen7_emit_binding_table(sna, wm_binding_table); sna->render_state.gen7.emit_flush = GEN7_READS_DST(op->u.gen7.flags); } static bool gen7_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { struct gen7_render_state *state = &sna->render_state.gen7; if (!op->need_magic_ca_pass) return false; DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__, sna->render.vertex_start, sna->render.vertex_index)); gen7_emit_pipe_stall(sna); gen7_emit_cc(sna, GEN7_BLEND(gen7_get_blend(PictOpAdd, true, op->dst.format))); gen7_emit_wm(sna, gen7_choose_composite_kernel(PictOpAdd, true, true, op->is_affine)); OUT_BATCH(GEN7_3DPRIMITIVE | (7- 2)); OUT_BATCH(GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST); OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start); OUT_BATCH(sna->render.vertex_start); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ state->last_primitive = sna->kgem.nbatch; return true; } static void null_create(struct sna_static_stream *stream) { /* A bunch of zeros useful for legacy border color and depth-stencil */ sna_static_stream_map(stream, 64, 64); } static void sampler_state_init(struct gen7_sampler_state *sampler_state, sampler_filter_t filter, sampler_extend_t extend) { sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.default_color_mode = GEN7_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SAMPLER_FILTER_NEAREST: sampler_state->ss0.min_filter = GEN7_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = GEN7_MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: sampler_state->ss0.min_filter = GEN7_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = GEN7_MAPFILTER_LINEAR; break; } switch (extend) { default: case SAMPLER_EXTEND_NONE: sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_WRAP; sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_WRAP; sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_CLAMP; sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_CLAMP; sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: sampler_state->ss3.r_wrap_mode = GEN7_TEXCOORDMODE_MIRROR; sampler_state->ss3.s_wrap_mode = GEN7_TEXCOORDMODE_MIRROR; sampler_state->ss3.t_wrap_mode = GEN7_TEXCOORDMODE_MIRROR; break; } } static void sampler_copy_init(struct gen7_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static void sampler_fill_init(struct gen7_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static uint32_t gen7_tiling_bits(uint32_t tiling) { switch (tiling) { default: assert(0); case I915_TILING_NONE: return 0; case I915_TILING_X: return GEN7_SURFACE_TILED; case I915_TILING_Y: return GEN7_SURFACE_TILED | GEN7_SURFACE_TILED_Y; } } /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static uint32_t gen7_bind_bo(struct sna *sna, struct kgem_bo *bo, uint32_t width, uint32_t height, uint32_t format, bool is_dst) { uint32_t *ss; uint32_t domains; int offset; uint32_t is_scanout = is_dst && bo->scanout; COMPILE_TIME_ASSERT(sizeof(struct gen7_surface_state) == 32); /* After the first bind, we manage the cache domains within the batch */ offset = kgem_bo_get_binding(bo, format | is_dst << 30 | is_scanout << 31); if (offset) { assert(offset >= sna->kgem.surface); if (is_dst) kgem_bo_mark_dirty(bo); return offset * sizeof(uint32_t); } offset = sna->kgem.surface -= sizeof(struct gen7_surface_state) / sizeof(uint32_t); ss = sna->kgem.batch + offset; ss[0] = (GEN7_SURFACE_2D << GEN7_SURFACE_TYPE_SHIFT | gen7_tiling_bits(bo->tiling) | format << GEN7_SURFACE_FORMAT_SHIFT); if (bo->tiling == I915_TILING_Y) ss[0] |= GEN7_SURFACE_VALIGN_4; if (is_dst) { ss[0] |= GEN7_SURFACE_RC_READ_WRITE; domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER; } else domains = I915_GEM_DOMAIN_SAMPLER << 16; ss[1] = kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0); ss[2] = ((width - 1) << GEN7_SURFACE_WIDTH_SHIFT | (height - 1) << GEN7_SURFACE_HEIGHT_SHIFT); ss[3] = (bo->pitch - 1) << GEN7_SURFACE_PITCH_SHIFT; ss[4] = 0; ss[5] = (is_scanout || bo->io) ? 0 : sna->render_state.gen7.info->mocs << 16; ss[6] = 0; ss[7] = 0; if (is_hsw(sna)) ss[7] |= HSW_SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA); kgem_bo_set_binding(bo, format | is_dst << 30 | is_scanout << 31, offset); DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n", offset, bo->handle, ss[1], format, width, height, bo->pitch, bo->tiling, domains & 0xffff ? "render" : "sampler")); return offset * sizeof(uint32_t); } static void gen7_emit_vertex_buffer(struct sna *sna, const struct sna_composite_op *op) { int id = GEN7_VERTEX(op->u.gen7.flags); OUT_BATCH(GEN7_3DSTATE_VERTEX_BUFFERS | (5 - 2)); OUT_BATCH(id << GEN7_VB0_BUFFER_INDEX_SHIFT | GEN7_VB0_VERTEXDATA | GEN7_VB0_ADDRESS_MODIFY_ENABLE | 4*op->floats_per_vertex << GEN7_VB0_BUFFER_PITCH_SHIFT); sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch; OUT_BATCH(0); OUT_BATCH(~0); /* max address: disabled */ OUT_BATCH(0); sna->render.vb_id |= 1 << id; } static void gen7_emit_primitive(struct sna *sna) { if (sna->kgem.nbatch == sna->render_state.gen7.last_primitive) { sna->render.vertex_offset = sna->kgem.nbatch - 5; return; } OUT_BATCH(GEN7_3DPRIMITIVE | (7- 2)); OUT_BATCH(GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST); sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(sna->render.vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ sna->render.vertex_start = sna->render.vertex_index; sna->render_state.gen7.last_primitive = sna->kgem.nbatch; } static bool gen7_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { int id = 1 << GEN7_VERTEX(op->u.gen7.flags); int ndwords; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; ndwords = op->need_magic_ca_pass ? 60 : 6; if ((sna->render.vb_id & id) == 0) ndwords += 5; if (!kgem_check_batch(&sna->kgem, ndwords)) return false; if ((sna->render.vb_id & id) == 0) gen7_emit_vertex_buffer(sna, op); gen7_emit_primitive(sna); return true; } static int gen7_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 6)) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 2)) return 0; if (sna->render.vertex_offset) { gen4_vertex_flush(sna); if (gen7_magic_ca_pass(sna, op)) { gen7_emit_pipe_stall(sna); gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags)); gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags)); } } return gen4_vertex_finish(sna); } inline static int gen7_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want, void (*emit_state)(struct sna *sna, const struct sna_composite_op *op)) { int rem; assert(want); start: rem = vertex_space(sna); if (unlikely(rem < op->floats_per_rect)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen7_get_rectangles__flush(sna, op); if (unlikely(rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen7_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; assert(want > 0); sna->render.vertex_index += 3*want; return want; flush: if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen7_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); emit_state(sna, op); goto start; } inline static uint32_t *gen7_composite_get_binding_table(struct sna *sna, uint16_t *offset) { uint32_t *table; sna->kgem.surface -= sizeof(struct gen7_surface_state) / sizeof(uint32_t); /* Clear all surplus entries to zero in case of prefetch */ table = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(struct gen7_surface_state)); DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface)); *offset = sna->kgem.surface; return table; } static void gen7_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) { DBG(("%s: flushing batch: %d < %d+%d\n", __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch, 150, 4*8)); _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } assert(sna->kgem.mode == KGEM_RENDER); assert(sna->kgem.ring == KGEM_RENDER); if (sna->render_state.gen7.needs_invariant) gen7_emit_invariant(sna); } static void gen7_emit_composite_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen7_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen7_get_dest_format(op->dst.format), true); binding_table[1] = gen7_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (op->mask.bo) { binding_table[2] = gen7_bind_bo(sna, op->mask.bo, op->mask.width, op->mask.height, op->mask.card_format, false); } if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen7.surface_table) == *(uint64_t*)binding_table && (op->mask.bo == NULL || sna->kgem.batch[sna->render_state.gen7.surface_table+2] == binding_table[2])) { sna->kgem.surface += sizeof(struct gen7_surface_state) / sizeof(uint32_t); offset = sna->render_state.gen7.surface_table; } if (sna->kgem.batch[sna->render_state.gen7.surface_table] == binding_table[0]) dirty = 0; gen7_emit_state(sna, op, offset | dirty); } static void gen7_align_vertex(struct sna *sna, const struct sna_composite_op *op) { if (op->floats_per_vertex != sna->render_state.gen7.floats_per_vertex) { DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen7.floats_per_vertex, op->floats_per_vertex)); gen4_vertex_align(sna, op); sna->render_state.gen7.floats_per_vertex = op->floats_per_vertex; } } fastcall static void gen7_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { gen7_get_rectangles(sna, op, 1, gen7_emit_composite_state); op->prim_emit(sna, op, r); } fastcall static void gen7_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; gen7_get_rectangles(sna, op, 1, gen7_emit_composite_state); DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); } static void gen7_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("composite_boxes(%d)\n", nbox)); do { int nbox_this_time; nbox_this_time = gen7_get_rectangles(sna, op, nbox, gen7_emit_composite_state); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen7_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen7_get_rectangles(sna, op, nbox, gen7_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } static void gen7_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen7_get_rectangles(sna, op, nbox, gen7_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif static uint32_t gen7_composite_create_blend_state(struct sna_static_stream *stream) { char *base, *ptr; int src, dst; base = sna_static_stream_map(stream, GEN7_BLENDFACTOR_COUNT * GEN7_BLENDFACTOR_COUNT * GEN7_BLEND_STATE_PADDED_SIZE, 64); ptr = base; for (src = 0; src < GEN7_BLENDFACTOR_COUNT; src++) { for (dst= 0; dst < GEN7_BLENDFACTOR_COUNT; dst++) { struct gen7_blend_state *blend = (struct gen7_blend_state *)ptr; blend->blend0.dest_blend_factor = dst; blend->blend0.source_blend_factor = src; blend->blend0.blend_func = GEN7_BLENDFUNCTION_ADD; blend->blend0.blend_enable = !(dst == GEN7_BLENDFACTOR_ZERO && src == GEN7_BLENDFACTOR_ONE); blend->blend1.post_blend_clamp_enable = 1; blend->blend1.pre_blend_clamp_enable = 1; ptr += GEN7_BLEND_STATE_PADDED_SIZE; } } return sna_static_stream_offsetof(stream, base); } static uint32_t gen7_bind_video_source(struct sna *sna, struct kgem_bo *bo, uint32_t offset, int width, int height, int pitch, uint32_t format) { uint32_t *ss, bind; bind = sna->kgem.surface -= sizeof(struct gen7_surface_state) / sizeof(uint32_t); assert(bo->tiling == I915_TILING_NONE); ss = sna->kgem.batch + bind; ss[0] = (GEN7_SURFACE_2D << GEN7_SURFACE_TYPE_SHIFT | format << GEN7_SURFACE_FORMAT_SHIFT); ss[1] = kgem_add_reloc(&sna->kgem, bind + 1, bo, I915_GEM_DOMAIN_SAMPLER << 16, offset); ss[2] = ((width - 1) << GEN7_SURFACE_WIDTH_SHIFT | (height - 1) << GEN7_SURFACE_HEIGHT_SHIFT); ss[3] = (pitch - 1) << GEN7_SURFACE_PITCH_SHIFT; ss[4] = 0; ss[5] = 0; ss[6] = 0; ss[7] = 0; if (is_hsw(sna)) ss[7] |= HSW_SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA); DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, offset=%d\n", bind, bo->handle, ss[1], format, width, height, pitch, offset)); return bind * sizeof(uint32_t); } static void gen7_emit_video_state(struct sna *sna, const struct sna_composite_op *op) { struct sna_video_frame *frame = op->priv; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; uint32_t *binding_table; uint16_t offset, dirty; int n_src, n; gen7_get_batch(sna, op); src_surf_base[0] = 0; src_surf_base[1] = 0; src_surf_base[2] = frame->VBufOffset; src_surf_base[3] = frame->VBufOffset; src_surf_base[4] = frame->UBufOffset; src_surf_base[5] = frame->UBufOffset; if (is_planar_fourcc(frame->id)) { src_surf_format = GEN7_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = frame->width; src_height[1] = src_height[0] = frame->height; src_pitch[1] = src_pitch[0] = frame->pitch[1]; src_width[4] = src_width[5] = src_width[2] = src_width[3] = frame->width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = frame->height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = frame->pitch[0]; n_src = 6; } else { if (frame->id == FOURCC_UYVY) src_surf_format = GEN7_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = GEN7_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = frame->width; src_height[0] = frame->height; src_pitch[0] = frame->pitch[0]; n_src = 1; } binding_table = gen7_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen7_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen7_get_dest_format(op->dst.format), true); for (n = 0; n < n_src; n++) { binding_table[1+n] = gen7_bind_video_source(sna, frame->bo, src_surf_base[n], src_width[n], src_height[n], src_pitch[n], src_surf_format); } gen7_emit_state(sna, op, offset | dirty); } static bool gen7_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_composite_op tmp; struct sna_pixmap *priv = sna_pixmap(pixmap); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; unsigned filter; const BoxRec *box; int nbox; DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n", __FUNCTION__, src_width, src_height, dst_width, dst_height, region_num_rects(dstRegion), REGION_EXTENTS(NULL, dstRegion)->x1, REGION_EXTENTS(NULL, dstRegion)->y1, REGION_EXTENTS(NULL, dstRegion)->x2, REGION_EXTENTS(NULL, dstRegion)->y2)); assert(priv->gpu_bo); memset(&tmp, 0, sizeof(tmp)); tmp.dst.pixmap = pixmap; tmp.dst.width = pixmap->drawable.width; tmp.dst.height = pixmap->drawable.height; tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; if (src_width == dst_width && src_height == dst_height) filter = SAMPLER_FILTER_NEAREST; else filter = SAMPLER_FILTER_BILINEAR; tmp.u.gen7.flags = GEN7_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, is_planar_fourcc(frame->id) ? GEN7_WM_KERNEL_VIDEO_PLANAR : GEN7_WM_KERNEL_VIDEO_PACKED, 2); tmp.priv = frame; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) return false; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &tmp); gen7_emit_video_state(sna, &tmp); DBG(("%s: src=(%d, %d)x(%d, %d); frame=(%dx%d), dst=(%dx%d)\n", __FUNCTION__, frame->src.x1, frame->src.y1, src_width, src_height, dst_width, dst_height, frame->width, frame->height)); src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; DBG(("%s: scale=(%f, %f), offset=(%f, %f)\n", __FUNCTION__, src_scale_x, src_scale_y, src_offset_x, src_offset_y)); box = region_rects(dstRegion); nbox = region_num_rects(dstRegion); while (nbox--) { DBG(("%s: dst=(%d, %d), (%d, %d); src=(%f, %f), (%f, %f)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, box->x1 * src_scale_x + src_offset_x, box->y1 * src_scale_y + src_offset_y, box->x2 * src_scale_x + src_offset_x, box->y2 * src_scale_y + src_offset_y)); gen7_get_rectangles(sna, &tmp, 1, gen7_emit_video_state); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); box++; } gen4_vertex_flush(sna); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } static int gen7_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->is_solid = false; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen4_channel_init_linear(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen7_check_repeat(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (!gen7_check_filter(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; assert(picture->pDrawable); pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat || (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen4_channel_init_solid(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; channel->pict_format = picture->format; channel->card_format = gen7_get_card_format(picture->format); if (channel->card_format == (unsigned)-1) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); } DBG(("%s: pixmap, repeat=%d, filter=%d, transform?=%d [affine? %d], format=%08x\n", __FUNCTION__, channel->repeat, channel->filter, channel->transform != NULL, channel->is_affine, channel->pict_format)); if (channel->transform) { DBG(("%s: transform=[%f %f %f, %f %f %f, %f %f %f]\n", __FUNCTION__, channel->transform->matrix[0][0] / 65536., channel->transform->matrix[0][1] / 65536., channel->transform->matrix[0][2] / 65536., channel->transform->matrix[1][0] / 65536., channel->transform->matrix[1][1] / 65536., channel->transform->matrix[1][2] / 65536., channel->transform->matrix[2][0] / 65536., channel->transform->matrix[2][1] / 65536., channel->transform->matrix[2][2] / 65536.)); } return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } inline static void gen7_composite_channel_convert(struct sna_composite_channel *channel) { channel->repeat = gen7_repeat(channel->repeat); channel->filter = gen7_filter(channel->filter); if (channel->card_format == (unsigned)-1) channel->card_format = gen7_get_card_format(channel->pict_format); assert(channel->card_format != (unsigned)-1); } static void gen7_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { if (sna->render.vertex_offset) { gen4_vertex_flush(sna); gen7_magic_ca_pass(sna, op); } if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } inline static bool gen7_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned int hint; DBG(("%s: (%d, %d)x(%d, %d), partial?=%d\n", __FUNCTION__, x, y, w, h, partial)); op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.format = dst->format; op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; if (w | h) { assert(w && h); box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (too_large(op->dst.width, op->dst.height) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool try_blt(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) goto execute; if (untiled_tlb_miss(bo)) goto execute; if (bo->rq) { if (RQ_IS_BLT(bo->rq)) goto execute; return false; } if (bo->tiling == I915_TILING_Y) goto upload; if (src->pDrawable == dst->pDrawable && (sna->render_state.gt < 3 || width*height < 1024) && can_switch_to_blt(sna, bo, 0)) goto execute; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) goto upload; if (prefer_blt_bo(sna, s, bo)) goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } upload: flags |= COMPOSITE_UPLOAD; execute: return sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } static bool check_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(PicturePtr p) { return p->pDrawable && unattached(p->pDrawable) && untransformed(p); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL || priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (p->pSourcePict) return check_gradient(p, precise); if (!gen7_check_repeat(p) || !gen7_check_format(p->format)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen7_check_filter(p) || need_upload(p); } static bool gen7_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen7_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (sna_picture_is_solid(mask, &color)) return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen7_check_repeat(mask)) return false; if (!gen7_check_filter(mask)) return false; if (!gen7_check_format(mask->format)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen7_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen7_filter(mask->filter); mc->pict_format = mask->format; mc->card_format = gen7_get_card_format(mask->format); mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen7_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { if (op >= ARRAY_SIZE(gen7_blend_op)) return false; DBG(("%s: %dx%d, current mode=%d/%d\n", __FUNCTION__, width, height, sna->kgem.mode, sna->kgem.ring)); if (mask == NULL && try_blt(sna, op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen7_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, tmp); if (op == PictOpClear && src == sna->clear) op = PictOpSrc; tmp->op = op; if (!gen7_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) goto fallback; switch (gen7_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: /* Did we just switch rings to prepare the source? */ if (mask == NULL && prefer_blt_composite(sna, tmp) && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; gen7_composite_channel_convert(&tmp->src); break; } tmp->is_affine = tmp->src.is_affine; tmp->has_component_alpha = false; tmp->need_magic_ca_pass = false; tmp->mask.bo = NULL; tmp->mask.filter = SAMPLER_FILTER_NEAREST; tmp->mask.repeat = SAMPLER_EXTEND_NONE; if (mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { tmp->has_component_alpha = true; /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (gen7_blend_op[op].src_alpha && (gen7_blend_op[op].src_blend != GEN7_BLENDFACTOR_ZERO)) { if (op != PictOpOver) goto cleanup_src; tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, msk_x, msk_y)) { switch (gen7_composite_picture(sna, mask, &tmp->mask, msk_x, msk_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_src; case 0: if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: gen7_composite_channel_convert(&tmp->mask); break; } } tmp->is_affine &= tmp->mask.is_affine; } tmp->u.gen7.flags = GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter, tmp->src.repeat, tmp->mask.filter, tmp->mask.repeat), gen7_get_blend(tmp->op, tmp->has_component_alpha, tmp->dst.format), gen7_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine), gen4_choose_composite_emitter(sna, tmp)); tmp->blt = gen7_render_composite_blt; tmp->box = gen7_render_composite_box; tmp->boxes = gen7_render_composite_boxes__blt; if (tmp->emit_boxes){ tmp->boxes = gen7_render_composite_boxes; tmp->thread_boxes = gen7_render_composite_boxes__thread; } tmp->done = gen7_render_composite_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, tmp); gen7_emit_composite_state(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } #if !NO_COMPOSITE_SPANS fastcall static void gen7_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen7_get_rectangles(sna, &op->base, 1, gen7_emit_composite_state); op->prim_emit(sna, op, box, opacity); } static void gen7_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen7_get_rectangles(sna, &op->base, nbox, gen7_emit_composite_state); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen7_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen7_get_rectangles(sna, &op->base, nbox, gen7_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen7_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); if (op->base.src.bo) kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen7_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { if (op >= ARRAY_SIZE(gen7_blend_op)) return false; if (gen7_composite_fallback(sna, src, NULL, dst)) return false; if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } return true; } static bool gen7_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s: %dx%d with flags=%x, current mode=%d/%d\n", __FUNCTION__, width, height, flags, sna->kgem.mode, sna->kgem.ring)); assert(gen7_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; if (!gen7_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) return false; switch (gen7_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: gen7_composite_channel_convert(&tmp->base.src); break; } tmp->base.mask.bo = NULL; tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.need_magic_ca_pass = false; tmp->base.u.gen7.flags = GEN7_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_PAD), gen7_get_blend(tmp->base.op, false, tmp->base.dst.format), GEN7_WM_KERNEL_OPACITY | !tmp->base.is_affine, gen4_choose_spans_emitter(sna, tmp)); tmp->box = gen7_render_composite_spans_box; tmp->boxes = gen7_render_composite_spans_boxes; if (tmp->emit_boxes) tmp->thread_boxes = gen7_render_composite_spans_boxes__thread; tmp->done = gen7_render_composite_spans_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &tmp->base); gen7_emit_composite_state(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } #endif static void gen7_emit_copy_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen7_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen7_get_dest_format(op->dst.format), true); binding_table[1] = gen7_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen7.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen7_surface_state) / sizeof(uint32_t); offset = sna->render_state.gen7.surface_table; } if (sna->kgem.batch[sna->render_state.gen7.surface_table] == binding_table[0]) dirty = 0; assert(!GEN7_READS_DST(op->u.gen7.flags)); gen7_emit_state(sna, op, offset | dirty); } static inline bool prefer_blt_copy(struct sna *sna, struct kgem_bo *src_bo, struct kgem_bo *dst_bo, unsigned flags) { if (sna->kgem.mode == KGEM_BLT) return true; assert((flags & COPY_SYNC) == 0); if (untiled_tlb_miss(src_bo) || untiled_tlb_miss(dst_bo)) return true; if (flags & COPY_DRI && !sna->kgem.has_semaphores) return false; if (force_blt_ring(sna, dst_bo)) return true; if ((flags & COPY_SMALL || (sna->render_state.gt < 3 && src_bo == dst_bo)) && can_switch_to_blt(sna, dst_bo, flags)) return true; if (kgem_bo_is_render(dst_bo) || kgem_bo_is_render(src_bo)) return false; if (flags & COPY_LAST && sna->render_state.gt < 3 && can_switch_to_blt(sna, dst_bo, flags)) return true; if (prefer_render_ring(sna, dst_bo)) return false; if (!prefer_blt_ring(sna, dst_bo, flags)) return false; return prefer_blt_bo(sna, src_bo, dst_bo); } static bool gen7_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; BoxRec extents; DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, flags=%x, self-copy=%d, overlaps? %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu, flags, src_bo == dst_bo, overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents))); if (prefer_blt_copy(sna, src_bo, dst_bo, flags) && sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear)) { fallback_blt: DBG(("%s: fallback blt\n", __FUNCTION__)); if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } if (overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents)) { bool big = too_large(extents.x2-extents.x1, extents.y2-extents.y1); if ((big || !prefer_render_ring(sna, dst_bo)) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (big) goto fallback_blt; assert(src_bo == dst_bo); assert(src->depth == dst->depth); assert(src->width == dst->width); assert(src->height == dst->height); return sna_render_copy_boxes__overlap(sna, alu, dst, dst_bo, src_dx, src_dy, dst_dx, dst_dy, box, n, &extents); } if (dst->depth == src->depth) { tmp.dst.format = sna_render_format_for_depth(dst->depth); tmp.src.pict_format = tmp.dst.format; } else { tmp.dst.format = sna_format_for_depth(dst->depth); tmp.src.pict_format = sna_format_for_depth(src->depth); } if (!gen7_check_format(tmp.src.pict_format)) goto fallback_blt; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } tmp.src.card_format = gen7_get_card_format(tmp.src.pict_format); if (too_large(src->width, src->height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, extents.x1 + src_dx, extents.y1 + src_dy, extents.x2 - extents.x1, extents.y2 - extents.y1)) goto fallback_tiled_dst; } else { tmp.src.bo = src_bo; tmp.src.width = src->width; tmp.src.height = src->height; tmp.src.offset[0] = tmp.src.offset[1] = 0; } tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = 0; tmp.u.gen7.flags = COPY_FLAGS(alu); kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); goto fallback_blt; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } src_dx += tmp.src.offset[0]; src_dy += tmp.src.offset[1]; dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; gen7_align_vertex(sna, &tmp); gen7_emit_copy_state(sna, &tmp); do { int16_t *v; int n_this_time; n_this_time = gen7_get_rectangles(sna, &tmp, n, gen7_emit_copy_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); v[0] = box->x2 + dst_dx; v[2] = box->x2 + src_dx; v[1] = v[5] = box->y2 + dst_dy; v[3] = v[7] = box->y2 + src_dy; v[8] = v[4] = box->x1 + dst_dx; v[10] = v[6] = box->x1 + src_dx; v[9] = box->y1 + dst_dy; v[11] = box->y1 + src_dy; v += 12; box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; fallback_tiled_dst: if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); fallback_tiled: DBG(("%s: fallback tiled\n", __FUNCTION__)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen7_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { int16_t *v; gen7_get_rectangles(sna, &op->base, 1, gen7_emit_copy_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dx+w; v[1] = dy+h; v[2] = sx+w; v[3] = sy+h; v[4] = dx; v[5] = dy+h; v[6] = sx; v[7] = sy+h; v[8] = dx; v[9] = dy; v[10] = sx; v[11] = sy; } static void gen7_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); } static bool gen7_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op) { DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n", __FUNCTION__, alu, src->drawable.width, src->drawable.height, dst->drawable.width, dst->drawable.height)); if (prefer_blt_copy(sna, src_bo, dst_bo, 0) && sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height)) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); } if (dst->drawable.depth == src->drawable.depth) { op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth); op->base.src.pict_format = op->base.dst.format; } else { op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.src.pict_format = sna_format_for_depth(src->drawable.depth); } if (!gen7_check_format(op->base.src.pict_format)) goto fallback; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.bo = dst_bo; op->base.src.bo = src_bo; op->base.src.card_format = gen7_get_card_format(op->base.src.pict_format); op->base.src.width = src->drawable.width; op->base.src.height = src->drawable.height; op->base.mask.bo = NULL; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen7.flags = COPY_FLAGS(alu); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &op->base); gen7_emit_copy_state(sna, &op->base); op->blt = gen7_render_copy_blt; op->done = gen7_render_copy_done; return true; } static void gen7_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) { uint16_t dirty; uint32_t *binding_table; uint16_t offset; /* XXX Render Target Fast Clear * Set RTFC Enable in PS and render a rectangle. * Limited to a clearing the full MSC surface only with a * specific kernel. */ gen7_get_batch(sna, op); binding_table = gen7_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen7_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen7_get_dest_format(op->dst.format), true); binding_table[1] = gen7_bind_bo(sna, op->src.bo, 1, 1, GEN7_SURFACEFORMAT_B8G8R8A8_UNORM, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen7.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += sizeof(struct gen7_surface_state)/sizeof(uint32_t); offset = sna->render_state.gen7.surface_table; } if (sna->kgem.batch[sna->render_state.gen7.surface_table] == binding_table[0]) dirty = 0; gen7_emit_state(sna, op, offset | dirty); } static bool gen7_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; DBG(("%s (op=%d, color=(%04x, %04x, %04x, %04x) [%08x])\n", __FUNCTION__, op, color->red, color->green, color->blue, color->alpha, (int)format)); if (op >= ARRAY_SIZE(gen7_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (prefer_blt_fill(sna, dst_bo, FILL_BOXES) || !gen7_check_dst_format(format)) { uint8_t alu = GXinvalid; if (op <= PictOpSrc) { pixel = 0; if (op == PictOpClear) alu = GXclear; else if (sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) alu = GXcopy; } if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n)) return true; if (!gen7_check_dst_format(format)) return false; } if (op == PictOpClear) { pixel = 0; op = PictOpSrc; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s(%08x x %d [(%d, %d), (%d, %d) ...])\n", __FUNCTION__, pixel, n, box[0].x1, box[0].y1, box[0].x2, box[0].y2)); tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(dst->width, dst->height)) { BoxRec extents; boxes_extents(box, n, &extents); if (!sna_render_composite_redirect(sna, &tmp, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen7.flags = FILL_FLAGS(op, format); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &tmp); gen7_emit_fill_state(sna, &tmp); do { int n_this_time; int16_t *v; n_this_time = gen7_get_rectangles(sna, &tmp, n, gen7_emit_fill_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d), (%d, %d)\n", box->x1, box->y1, box->x2, box->y2)); v[0] = box->x2; v[5] = v[1] = box->y2; v[8] = v[4] = box->x1; v[9] = box->y1; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; v += 12; box++; } while (--n_this_time); } while (n); gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); sna_render_composite_redirect_done(sna, &tmp); return true; } static void gen7_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { int16_t *v; DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); gen7_get_rectangles(sna, &op->base, 1, gen7_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x+w; v[4] = v[8] = x; v[1] = v[5] = y+h; v[9] = y; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen7_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { int16_t *v; DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen7_get_rectangles(sna, &op->base, 1, gen7_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen7_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time; int16_t *v; nbox_this_time = gen7_get_rectangles(sna, &op->base, nbox, gen7_emit_fill_state); nbox -= nbox_this_time; v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6 * nbox_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; box++; v += 12; } while (--nbox_this_time); } while (nbox); } static void gen7_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { if (sna->render.vertex_offset) gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, op->base.src.bo); } static bool gen7_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *op) { DBG(("%s: (alu=%d, color=%x)\n", __FUNCTION__, alu, color)); if (prefer_blt_fill(sna, dst_bo, flags) && sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op)) return true; if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op); if (alu == GXclear) color = 0; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.dst.bo = dst_bo; op->base.dst.x = op->base.dst.y = 0; op->base.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); op->base.mask.bo = NULL; op->base.need_magic_ca_pass = false; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen7.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, op->base.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &op->base); gen7_emit_fill_state(sna, &op->base); op->blt = gen7_render_fill_op_blt; op->box = gen7_render_fill_op_box; op->boxes = gen7_render_fill_op_boxes; op->points = NULL; op->done = gen7_render_fill_op_done; return true; } static bool gen7_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen7_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; int16_t *v; /* Prefer to use the BLT if already engaged */ if (prefer_blt_fill(sna, bo, FILL_BOXES) && gen7_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height)) return gen7_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); if (alu == GXclear) color = 0; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen7.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &tmp); gen7_emit_fill_state(sna, &tmp); gen7_get_rectangles(sna, &tmp, 1, gen7_emit_fill_state); DBG((" (%d, %d), (%d, %d)\n", x1, y1, x2, y2)); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x2; v[8] = v[4] = x1; v[5] = v[1] = y2; v[9] = y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static bool gen7_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = dst->drawable.width; box.y2 = dst->drawable.height; return sna_blt_fill_boxes(sna, GXclear, bo, dst->drawable.bitsPerPixel, 0, &box, 1); } static bool gen7_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { struct sna_composite_op tmp; int16_t *v; DBG(("%s: %dx%d\n", __FUNCTION__, dst->drawable.width, dst->drawable.height)); /* Prefer to use the BLT if already engaged */ if (sna->kgem.mode == KGEM_BLT && gen7_render_clear_try_blt(sna, dst, bo)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(dst->drawable.width, dst->drawable.height)) return gen7_render_clear_try_blt(sna, dst, bo); tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, 0); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen7.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen7_align_vertex(sna, &tmp); gen7_emit_fill_state(sna, &tmp); gen7_get_rectangles(sna, &tmp, 1, gen7_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst->drawable.width; v[5] = v[1] = dst->drawable.height; v[8] = v[4] = 0; v[9] = 0; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static void gen7_render_reset(struct sna *sna) { sna->render_state.gen7.pipe_controls_since_stall = 0; sna->render_state.gen7.emit_flush = false; sna->render_state.gen7.needs_invariant = true; sna->render_state.gen7.ve_id = 3 << 2; sna->render_state.gen7.last_primitive = -1; sna->render_state.gen7.num_sf_outputs = 0; sna->render_state.gen7.samplers = -1; sna->render_state.gen7.blend = -1; sna->render_state.gen7.kernel = -1; sna->render_state.gen7.drawrect_offset = -1; sna->render_state.gen7.drawrect_limit = -1; sna->render_state.gen7.surface_table = 0; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); discard_vbo(sna); } sna->render.vertex_offset = 0; sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; } static void gen7_render_fini(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render_state.gen7.general_bo); } static bool is_gt3(struct sna *sna, int devid) { assert(sna->kgem.gen == 075); return devid & 0x20; } static bool is_gt2(struct sna *sna, int devid) { return devid & (is_hsw(sna)? 0x30 : 0x20); } static bool is_mobile(struct sna *sna, int devid) { return (devid & 0xf) == 0x6; } static bool gen7_render_setup(struct sna *sna, int devid) { struct gen7_render_state *state = &sna->render_state.gen7; struct sna_static_stream general; struct gen7_sampler_state *ss; int i, j, k, l, m; if (is_ivb(sna)) { state->info = &ivb_gt_info; if (devid & 0xf) { state->info = &ivb_gt1_info; if (is_gt2(sna, devid)) state->info = &ivb_gt2_info; /* XXX requires GT_MODE WiZ disabled */ } } else if (is_byt(sna)) { state->info = &byt_gt_info; } else if (is_hsw(sna)) { state->info = &hsw_gt_info; if (devid & 0xf) { if (is_gt3(sna, devid)) state->info = &hsw_gt3_info; else if (is_gt2(sna, devid)) state->info = &hsw_gt2_info; else state->info = &hsw_gt1_info; } } else return false; state->gt = state->info->gt; sna_static_stream_init(&general); /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer * dumps, you know it points to zero. */ null_create(&general); for (m = 0; m < GEN7_WM_KERNEL_COUNT; m++) { if (wm_kernels[m].size) { state->wm_kernel[m][1] = sna_static_stream_add(&general, wm_kernels[m].data, wm_kernels[m].size, 64); } else { if (USE_8_PIXEL_DISPATCH) { state->wm_kernel[m][0] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 8); } if (USE_16_PIXEL_DISPATCH) { state->wm_kernel[m][1] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } if (USE_32_PIXEL_DISPATCH) { state->wm_kernel[m][2] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 32); } } assert(state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]); } ss = sna_static_stream_map(&general, 2 * sizeof(*ss) * (2 + FILTER_COUNT * EXTEND_COUNT * FILTER_COUNT * EXTEND_COUNT), 32); state->wm_state = sna_static_stream_offsetof(&general, ss); sampler_copy_init(ss); ss += 2; sampler_fill_init(ss); ss += 2; for (i = 0; i < FILTER_COUNT; i++) { for (j = 0; j < EXTEND_COUNT; j++) { for (k = 0; k < FILTER_COUNT; k++) { for (l = 0; l < EXTEND_COUNT; l++) { sampler_state_init(ss++, i, j); sampler_state_init(ss++, k, l); } } } } state->cc_blend = gen7_composite_create_blend_state(&general); state->general_bo = sna_static_stream_fini(sna, &general); return state->general_bo != NULL; } const char *gen7_render_init(struct sna *sna, const char *backend) { int devid = intel_get_device_id(sna->dev); if (!gen7_render_setup(sna, devid)) return backend; sna->kgem.context_switch = gen6_render_context_switch; sna->kgem.retire = gen6_render_retire; sna->kgem.expire = gen4_render_expire; #if !NO_COMPOSITE sna->render.composite = gen7_render_composite; sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen7_check_composite_spans; sna->render.composite_spans = gen7_render_composite_spans; if (is_mobile(sna, devid) || is_gt2(sna, devid) || is_byt(sna)) sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif sna->render.video = gen7_render_video; #if !NO_COPY_BOXES sna->render.copy_boxes = gen7_render_copy_boxes; #endif #if !NO_COPY sna->render.copy = gen7_render_copy; #endif #if !NO_FILL_BOXES sna->render.fill_boxes = gen7_render_fill_boxes; #endif #if !NO_FILL sna->render.fill = gen7_render_fill; #endif #if !NO_FILL_ONE sna->render.fill_one = gen7_render_fill_one; #endif #if !NO_FILL_CLEAR sna->render.clear = gen7_render_clear; #endif sna->render.flush = gen4_render_flush; sna->render.reset = gen7_render_reset; sna->render.fini = gen7_render_fini; sna->render.max_3d_size = GEN7_MAX_SIZE; sna->render.max_3d_pitch = 1 << 18; return sna->render_state.gen7.info->name; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen7_render.h000066400000000000000000001522401267532330400242170ustar00rootroot00000000000000#ifndef GEN7_RENDER_H #define GEN7_RENDER_H #define INTEL_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low)) #define GEN7_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define GEN7_STATE_BASE_ADDRESS GEN7_3D(0, 1, 1) #define GEN7_STATE_SIP GEN7_3D(0, 1, 2) #define GEN7_PIPELINE_SELECT GEN7_3D(1, 1, 4) #define GEN7_MEDIA_STATE_POINTERS GEN7_3D(2, 0, 0) #define GEN7_MEDIA_OBJECT GEN7_3D(2, 1, 0) #define GEN7_3DSTATE_VERTEX_BUFFERS GEN7_3D(3, 0, 8) #define GEN7_3DSTATE_VERTEX_ELEMENTS GEN7_3D(3, 0, 9) #define GEN7_3DSTATE_INDEX_BUFFER GEN7_3D(3, 0, 0xa) #define GEN7_3DSTATE_VF_STATISTICS GEN7_3D(3, 0, 0xb) #define GEN7_3DSTATE_DRAWING_RECTANGLE GEN7_3D(3, 1, 0) #define GEN7_3DSTATE_CONSTANT_COLOR GEN7_3D(3, 1, 1) #define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD GEN7_3D(3, 1, 2) #define GEN7_3DSTATE_CHROMA_KEY GEN7_3D(3, 1, 4) #define GEN7_3DSTATE_POLY_STIPPLE_OFFSET GEN7_3D(3, 1, 6) #define GEN7_3DSTATE_POLY_STIPPLE_PATTERN GEN7_3D(3, 1, 7) #define GEN7_3DSTATE_LINE_STIPPLE GEN7_3D(3, 1, 8) #define GEN7_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP GEN7_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define GEN7_3DSTATE_AA_LINE_PARAMS GEN7_3D(3, 1, 0xa) #define GEN7_3DSTATE_GS_SVB_INDEX GEN7_3D(3, 1, 0xb) #define GEN7_3DPRIMITIVE GEN7_3D(3, 3, 0) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS GEN7_3D(3, 0, 0x02) # define GEN7_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN7_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN7_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN7_3DSTATE_URB GEN7_3D(3, 0, 0x05) /* DW1 */ # define GEN7_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN7_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN7_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN7_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS GEN7_3D(3, 0, 0x0d) # define GEN7_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN7_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN7_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN7_3DSTATE_CC_STATE_POINTERS GEN7_3D(3, 0, 0x0e) #define GEN7_3DSTATE_VS GEN7_3D(3, 0, 0x10) #define GEN7_3DSTATE_GS GEN7_3D(3, 0, 0x11) /* DW4 */ # define GEN7_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN7_3DSTATE_CLIP GEN7_3D(3, 0, 0x12) #define GEN7_3DSTATE_SF GEN7_3D(3, 0, 0x13) /* DW1 */ # define GEN7_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN7_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN7_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN7_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN7_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN7_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN7_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN7_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN7_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN7_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN7_3DSTATE_WM GEN7_3D(3, 0, 0x14) /* DW1 */ # define GEN7_WM_STATISTICS_ENABLE (1 << 31) # define GEN7_WM_DEPTH_CLEAR (1 << 30) # define GEN7_WM_DISPATCH_ENABLE (1 << 29) # define GEN7_WM_DEPTH_RESOLVE (1 << 28) # define GEN7_WM_HIERARCHICAL_DEPTH_RESOLVE (1 << 27) # define GEN7_WM_KILL_ENABLE (1 << 25) # define GEN7_WM_PSCDEPTH_OFF (0 << 23) # define GEN7_WM_PSCDEPTH_ON (1 << 23) # define GEN7_WM_PSCDEPTH_ON_GE (2 << 23) # define GEN7_WM_PSCDEPTH_ON_LE (3 << 23) # define GEN7_WM_USES_SOURCE_DEPTH (1 << 20) # define GEN7_WM_USES_SOURCE_W (1 << 19) # define GEN7_WM_POSITION_ZW_PIXEL (0 << 17) # define GEN7_WM_POSITION_ZW_CENTROID (2 << 17) # define GEN7_WM_POSITION_ZW_SAMPLE (3 << 17) # define GEN7_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16) # define GEN7_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15) # define GEN7_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14) # define GEN7_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13) # define GEN7_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12) # define GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11) # define GEN7_WM_USES_INPUT_COVERAGE_MASK (1 << 10) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_2_0 (2 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_4_0 (3 << 8) # define GEN7_WM_LINE_AA_WIDTH_0_5 (0 << 6) # define GEN7_WM_LINE_AA_WIDTH_1_0 (1 << 6) # define GEN7_WM_LINE_AA_WIDTH_2_0 (2 << 6) # define GEN7_WM_LINE_AA_WIDTH_4_0 (3 << 6) # define GEN7_WM_POLYGON_STIPPLE_ENABLE (1 << 4) # define GEN7_WM_LINE_STIPPLE_ENABLE (1 << 3) # define GEN7_WM_POINT_RASTRULE_UPPER_RIGHT (1 << 2) # define GEN7_WM_MSRAST_OFF_PIXEL (0 << 0) # define GEN7_WM_MSRAST_OFF_PATTERN (1 << 0) # define GEN7_WM_MSRAST_ON_PIXEL (2 << 0) # define GEN7_WM_MSRAST_ON_PATTERN (3 << 0) /* DW2 */ # define GEN7_WM_MSDISPMODE_PERPIXEL (1 << 31) #define GEN7_3DSTATE_CONSTANT_VS GEN7_3D(3, 0, 0x15) #define GEN7_3DSTATE_CONSTANT_GS GEN7_3D(3, 0, 0x16) #define GEN7_3DSTATE_CONSTANT_PS GEN7_3D(3, 0, 0x17) #define GEN7_3DSTATE_SAMPLE_MASK GEN7_3D(3, 0, 0x18) #define GEN7_3DSTATE_MULTISAMPLE GEN7_3D(3, 1, 0x0d) /* DW1 */ # define GEN7_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN7_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN7_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN7_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN7_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 /* for GEN7_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for GEN7_PIPE_CONTROL */ #define GEN7_PIPE_CONTROL GEN7_3D(3, 2, 0) #define GEN7_PIPE_CONTROL_CS_STALL (1 << 20) #define GEN7_PIPE_CONTROL_NOWRITE (0 << 14) #define GEN7_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define GEN7_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define GEN7_PIPE_CONTROL_WRITE_TIME (3 << 14) #define GEN7_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define GEN7_PIPE_CONTROL_WC_FLUSH (1 << 12) #define GEN7_PIPE_CONTROL_IS_FLUSH (1 << 11) #define GEN7_PIPE_CONTROL_TC_FLUSH (1 << 10) #define GEN7_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define GEN7_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define GEN7_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define GEN7_PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) #define GEN7_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define GEN7_VB0_BUFFER_INDEX_SHIFT 26 #define GEN7_VB0_VERTEXDATA (0 << 20) #define GEN7_VB0_INSTANCEDATA (1 << 20) #define GEN7_VB0_BUFFER_PITCH_SHIFT 0 #define GEN7_VB0_ADDRESS_MODIFY_ENABLE (1 << 14) /* VERTEX_ELEMENT_STATE Structure */ #define GEN7_VE0_VERTEX_BUFFER_INDEX_SHIFT 26 #define GEN7_VE0_VALID (1 << 25) #define GEN7_VE0_FORMAT_SHIFT 16 #define GEN7_VE0_OFFSET_SHIFT 0 #define GEN7_VE1_VFCOMPONENT_0_SHIFT 28 #define GEN7_VE1_VFCOMPONENT_1_SHIFT 24 #define GEN7_VE1_VFCOMPONENT_2_SHIFT 20 #define GEN7_VE1_VFCOMPONENT_3_SHIFT 16 #define GEN7_VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define GEN7_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define GEN7_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) #define GEN7_SVG_CTL 0x7400 #define GEN7_SVG_CTL_GS_BA (0 << 8) #define GEN7_SVG_CTL_SS_BA (1 << 8) #define GEN7_SVG_CTL_IO_BA (2 << 8) #define GEN7_SVG_CTL_GS_AUB (3 << 8) #define GEN7_SVG_CTL_IO_AUB (4 << 8) #define GEN7_SVG_CTL_SIP (5 << 8) #define GEN7_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN7_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define GEN7_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define GEN7_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define GEN7_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define GEN7_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define GEN7_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define GEN7_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define GEN7_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN7_VF_STRG_VAL 0x7504 #define GEN7_VF_STR_VL_OVR 0x7508 #define GEN7_VF_VC_OVR 0x750c #define GEN7_VF_STR_PSKIP 0x7510 #define GEN7_VF_MAX_PRIM 0x7514 #define GEN7_VF_RDATA 0x7518 #define GEN7_VS_CTL 0x7600 #define GEN7_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN7_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define GEN7_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define GEN7_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define GEN7_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define GEN7_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN7_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN7_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN7_VS_STRG_VAL 0x7604 #define GEN7_VS_RDATA 0x7608 #define GEN7_SF_CTL 0x7b00 #define GEN7_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define GEN7_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define GEN7_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define GEN7_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define GEN7_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN7_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN7_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN7_SF_STRG_VAL 0x7b04 #define GEN7_SF_RDATA 0x7b18 #define GEN7_WIZ_CTL 0x7c00 #define GEN7_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN7_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define GEN7_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define GEN7_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define GEN7_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define GEN7_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define GEN7_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define GEN7_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define GEN7_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define GEN7_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define GEN7_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define GEN7_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN7_WIZ_STRG_VAL 0x7c04 #define GEN7_WIZ_RDATA 0x7c18 #define GEN7_TS_CTL 0x7e00 #define GEN7_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define GEN7_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define GEN7_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define GEN7_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define GEN7_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define GEN7_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define GEN7_TS_STRG_VAL 0x7e04 #define GEN7_TS_RDATA 0x7e08 #define GEN7_TD_CTL 0x8000 #define GEN7_TD_CTL_MUX_SHIFT 8 #define GEN7_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define GEN7_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define GEN7_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define GEN7_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define GEN7_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define GEN7_TD_CTL2 0x8004 #define GEN7_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define GEN7_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define GEN7_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define GEN7_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define GEN7_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define GEN7_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define GEN7_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define GEN7_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define GEN7_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define GEN7_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define GEN7_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define GEN7_TD_VF_VS_EMSK 0x8008 #define GEN7_TD_GS_EMSK 0x800c #define GEN7_TD_CLIP_EMSK 0x8010 #define GEN7_TD_SF_EMSK 0x8014 #define GEN7_TD_WIZ_EMSK 0x8018 #define GEN7_TD_0_6_EHTRG_VAL 0x801c #define GEN7_TD_0_7_EHTRG_VAL 0x8020 #define GEN7_TD_0_6_EHTRG_MSK 0x8024 #define GEN7_TD_0_7_EHTRG_MSK 0x8028 #define GEN7_TD_RDATA 0x802c #define GEN7_TD_TS_EMSK 0x8030 #define GEN7_EU_CTL 0x8800 #define GEN7_EU_CTL_SELECT_SHIFT 16 #define GEN7_EU_CTL_DATA_MUX_SHIFT 8 #define GEN7_EU_ATT_0 0x8810 #define GEN7_EU_ATT_1 0x8814 #define GEN7_EU_ATT_DATA_0 0x8820 #define GEN7_EU_ATT_DATA_1 0x8824 #define GEN7_EU_ATT_CLR_0 0x8830 #define GEN7_EU_ATT_CLR_1 0x8834 #define GEN7_EU_RDATA 0x8840 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define GEN7_ANISORATIO_2 0 #define GEN7_ANISORATIO_4 1 #define GEN7_ANISORATIO_6 2 #define GEN7_ANISORATIO_8 3 #define GEN7_ANISORATIO_10 4 #define GEN7_ANISORATIO_12 5 #define GEN7_ANISORATIO_14 6 #define GEN7_ANISORATIO_16 7 #define GEN7_BLENDFACTOR_ONE 0x1 #define GEN7_BLENDFACTOR_SRC_COLOR 0x2 #define GEN7_BLENDFACTOR_SRC_ALPHA 0x3 #define GEN7_BLENDFACTOR_DST_ALPHA 0x4 #define GEN7_BLENDFACTOR_DST_COLOR 0x5 #define GEN7_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define GEN7_BLENDFACTOR_CONST_COLOR 0x7 #define GEN7_BLENDFACTOR_CONST_ALPHA 0x8 #define GEN7_BLENDFACTOR_SRC1_COLOR 0x9 #define GEN7_BLENDFACTOR_SRC1_ALPHA 0x0A #define GEN7_BLENDFACTOR_ZERO 0x11 #define GEN7_BLENDFACTOR_INV_SRC_COLOR 0x12 #define GEN7_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define GEN7_BLENDFACTOR_INV_DST_ALPHA 0x14 #define GEN7_BLENDFACTOR_INV_DST_COLOR 0x15 #define GEN7_BLENDFACTOR_INV_CONST_COLOR 0x17 #define GEN7_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define GEN7_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define GEN7_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define GEN7_BLENDFUNCTION_ADD 0 #define GEN7_BLENDFUNCTION_SUBTRACT 1 #define GEN7_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define GEN7_BLENDFUNCTION_MIN 3 #define GEN7_BLENDFUNCTION_MAX 4 #define GEN7_ALPHATEST_FORMAT_UNORM8 0 #define GEN7_ALPHATEST_FORMAT_FLOAT32 1 #define GEN7_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define GEN7_CHROMAKEY_REPLACE_BLACK 1 #define GEN7_CLIP_API_OGL 0 #define GEN7_CLIP_API_DX 1 #define GEN7_CLIPMODE_NORMAL 0 #define GEN7_CLIPMODE_CLIP_ALL 1 #define GEN7_CLIPMODE_CLIP_NON_REJECTED 2 #define GEN7_CLIPMODE_REJECT_ALL 3 #define GEN7_CLIPMODE_ACCEPT_ALL 4 #define GEN7_CLIP_NDCSPACE 0 #define GEN7_CLIP_SCREENSPACE 1 #define GEN7_COMPAREFUNCTION_ALWAYS 0 #define GEN7_COMPAREFUNCTION_NEVER 1 #define GEN7_COMPAREFUNCTION_LESS 2 #define GEN7_COMPAREFUNCTION_EQUAL 3 #define GEN7_COMPAREFUNCTION_LEQUAL 4 #define GEN7_COMPAREFUNCTION_GREATER 5 #define GEN7_COMPAREFUNCTION_NOTEQUAL 6 #define GEN7_COMPAREFUNCTION_GEQUAL 7 #define GEN7_COVERAGE_PIXELS_HALF 0 #define GEN7_COVERAGE_PIXELS_1 1 #define GEN7_COVERAGE_PIXELS_2 2 #define GEN7_COVERAGE_PIXELS_4 3 #define GEN7_CULLMODE_BOTH 0 #define GEN7_CULLMODE_NONE 1 #define GEN7_CULLMODE_FRONT 2 #define GEN7_CULLMODE_BACK 3 #define GEN7_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define GEN7_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define GEN7_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define GEN7_DEPTHFORMAT_D32_FLOAT 1 #define GEN7_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define GEN7_DEPTHFORMAT_D16_UNORM 5 #define GEN7_FLOATING_POINT_IEEE_754 0 #define GEN7_FLOATING_POINT_NON_IEEE_754 1 #define GEN7_FRONTWINDING_CW 0 #define GEN7_FRONTWINDING_CCW 1 #define GEN7_INDEX_BYTE 0 #define GEN7_INDEX_WORD 1 #define GEN7_INDEX_DWORD 2 #define GEN7_LOGICOPFUNCTION_CLEAR 0 #define GEN7_LOGICOPFUNCTION_NOR 1 #define GEN7_LOGICOPFUNCTION_AND_INVERTED 2 #define GEN7_LOGICOPFUNCTION_COPY_INVERTED 3 #define GEN7_LOGICOPFUNCTION_AND_REVERSE 4 #define GEN7_LOGICOPFUNCTION_INVERT 5 #define GEN7_LOGICOPFUNCTION_XOR 6 #define GEN7_LOGICOPFUNCTION_NAND 7 #define GEN7_LOGICOPFUNCTION_AND 8 #define GEN7_LOGICOPFUNCTION_EQUIV 9 #define GEN7_LOGICOPFUNCTION_NOOP 10 #define GEN7_LOGICOPFUNCTION_OR_INVERTED 11 #define GEN7_LOGICOPFUNCTION_COPY 12 #define GEN7_LOGICOPFUNCTION_OR_REVERSE 13 #define GEN7_LOGICOPFUNCTION_OR 14 #define GEN7_LOGICOPFUNCTION_SET 15 #define GEN7_MAPFILTER_NEAREST 0x0 #define GEN7_MAPFILTER_LINEAR 0x1 #define GEN7_MAPFILTER_ANISOTROPIC 0x2 #define GEN7_MIPFILTER_NONE 0 #define GEN7_MIPFILTER_NEAREST 1 #define GEN7_MIPFILTER_LINEAR 3 #define GEN7_POLYGON_FRONT_FACING 0 #define GEN7_POLYGON_BACK_FACING 1 #define GEN7_PREFILTER_ALWAYS 0x0 #define GEN7_PREFILTER_NEVER 0x1 #define GEN7_PREFILTER_LESS 0x2 #define GEN7_PREFILTER_EQUAL 0x3 #define GEN7_PREFILTER_LEQUAL 0x4 #define GEN7_PREFILTER_GREATER 0x5 #define GEN7_PREFILTER_NOTEQUAL 0x6 #define GEN7_PREFILTER_GEQUAL 0x7 #define GEN7_PROVOKING_VERTEX_0 0 #define GEN7_PROVOKING_VERTEX_1 1 #define GEN7_PROVOKING_VERTEX_2 2 #define GEN7_RASTRULE_UPPER_LEFT 0 #define GEN7_RASTRULE_UPPER_RIGHT 1 #define GEN7_RENDERTARGET_CLAMPRANGE_UNORM 0 #define GEN7_RENDERTARGET_CLAMPRANGE_SNORM 1 #define GEN7_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define GEN7_STENCILOP_KEEP 0 #define GEN7_STENCILOP_ZERO 1 #define GEN7_STENCILOP_REPLACE 2 #define GEN7_STENCILOP_INCRSAT 3 #define GEN7_STENCILOP_DECRSAT 4 #define GEN7_STENCILOP_INCR 5 #define GEN7_STENCILOP_DECR 6 #define GEN7_STENCILOP_INVERT 7 #define GEN7_SURFACE_MIPMAPLAYOUT_BELOW 0 #define GEN7_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define GEN7_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define GEN7_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define GEN7_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define GEN7_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define GEN7_SURFACEFORMAT_R64G64_FLOAT 0x005 #define GEN7_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define GEN7_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define GEN7_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define GEN7_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define GEN7_SURFACEFORMAT_R32G32B32_SINT 0x041 #define GEN7_SURFACEFORMAT_R32G32B32_UINT 0x042 #define GEN7_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define GEN7_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define GEN7_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define GEN7_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define GEN7_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define GEN7_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define GEN7_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define GEN7_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define GEN7_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define GEN7_SURFACEFORMAT_R32G32_FLOAT 0x085 #define GEN7_SURFACEFORMAT_R32G32_SINT 0x086 #define GEN7_SURFACEFORMAT_R32G32_UINT 0x087 #define GEN7_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define GEN7_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define GEN7_SURFACEFORMAT_L32A32_FLOAT 0x08A #define GEN7_SURFACEFORMAT_R32G32_UNORM 0x08B #define GEN7_SURFACEFORMAT_R32G32_SNORM 0x08C #define GEN7_SURFACEFORMAT_R64_FLOAT 0x08D #define GEN7_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define GEN7_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define GEN7_SURFACEFORMAT_A32X32_FLOAT 0x090 #define GEN7_SURFACEFORMAT_L32X32_FLOAT 0x091 #define GEN7_SURFACEFORMAT_I32X32_FLOAT 0x092 #define GEN7_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define GEN7_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define GEN7_SURFACEFORMAT_R32G32_SSCALED 0x095 #define GEN7_SURFACEFORMAT_R32G32_USCALED 0x096 #define GEN7_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define GEN7_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define GEN7_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define GEN7_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define GEN7_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define GEN7_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define GEN7_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define GEN7_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define GEN7_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define GEN7_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define GEN7_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define GEN7_SURFACEFORMAT_R16G16_UNORM 0x0CC #define GEN7_SURFACEFORMAT_R16G16_SNORM 0x0CD #define GEN7_SURFACEFORMAT_R16G16_SINT 0x0CE #define GEN7_SURFACEFORMAT_R16G16_UINT 0x0CF #define GEN7_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define GEN7_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define GEN7_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define GEN7_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define GEN7_SURFACEFORMAT_R32_SINT 0x0D6 #define GEN7_SURFACEFORMAT_R32_UINT 0x0D7 #define GEN7_SURFACEFORMAT_R32_FLOAT 0x0D8 #define GEN7_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define GEN7_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define GEN7_SURFACEFORMAT_L16A16_UNORM 0x0DF #define GEN7_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define GEN7_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define GEN7_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define GEN7_SURFACEFORMAT_I32_FLOAT 0x0E3 #define GEN7_SURFACEFORMAT_L32_FLOAT 0x0E4 #define GEN7_SURFACEFORMAT_A32_FLOAT 0x0E5 #define GEN7_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define GEN7_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define GEN7_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define GEN7_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define GEN7_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define GEN7_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define GEN7_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define GEN7_SURFACEFORMAT_R32_UNORM 0x0F1 #define GEN7_SURFACEFORMAT_R32_SNORM 0x0F2 #define GEN7_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define GEN7_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define GEN7_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define GEN7_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define GEN7_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define GEN7_SURFACEFORMAT_R32_SSCALED 0x0F8 #define GEN7_SURFACEFORMAT_R32_USCALED 0x0F9 #define GEN7_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define GEN7_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define GEN7_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define GEN7_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define GEN7_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define GEN7_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define GEN7_SURFACEFORMAT_R8G8_UNORM 0x106 #define GEN7_SURFACEFORMAT_R8G8_SNORM 0x107 #define GEN7_SURFACEFORMAT_R8G8_SINT 0x108 #define GEN7_SURFACEFORMAT_R8G8_UINT 0x109 #define GEN7_SURFACEFORMAT_R16_UNORM 0x10A #define GEN7_SURFACEFORMAT_R16_SNORM 0x10B #define GEN7_SURFACEFORMAT_R16_SINT 0x10C #define GEN7_SURFACEFORMAT_R16_UINT 0x10D #define GEN7_SURFACEFORMAT_R16_FLOAT 0x10E #define GEN7_SURFACEFORMAT_I16_UNORM 0x111 #define GEN7_SURFACEFORMAT_L16_UNORM 0x112 #define GEN7_SURFACEFORMAT_A16_UNORM 0x113 #define GEN7_SURFACEFORMAT_L8A8_UNORM 0x114 #define GEN7_SURFACEFORMAT_I16_FLOAT 0x115 #define GEN7_SURFACEFORMAT_L16_FLOAT 0x116 #define GEN7_SURFACEFORMAT_A16_FLOAT 0x117 #define GEN7_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define GEN7_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define GEN7_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define GEN7_SURFACEFORMAT_R8G8_SSCALED 0x11C #define GEN7_SURFACEFORMAT_R8G8_USCALED 0x11D #define GEN7_SURFACEFORMAT_R16_SSCALED 0x11E #define GEN7_SURFACEFORMAT_R16_USCALED 0x11F #define GEN7_SURFACEFORMAT_R8_UNORM 0x140 #define GEN7_SURFACEFORMAT_R8_SNORM 0x141 #define GEN7_SURFACEFORMAT_R8_SINT 0x142 #define GEN7_SURFACEFORMAT_R8_UINT 0x143 #define GEN7_SURFACEFORMAT_A8_UNORM 0x144 #define GEN7_SURFACEFORMAT_I8_UNORM 0x145 #define GEN7_SURFACEFORMAT_L8_UNORM 0x146 #define GEN7_SURFACEFORMAT_P4A4_UNORM 0x147 #define GEN7_SURFACEFORMAT_A4P4_UNORM 0x148 #define GEN7_SURFACEFORMAT_R8_SSCALED 0x149 #define GEN7_SURFACEFORMAT_R8_USCALED 0x14A #define GEN7_SURFACEFORMAT_R1_UINT 0x181 #define GEN7_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define GEN7_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define GEN7_SURFACEFORMAT_BC1_UNORM 0x186 #define GEN7_SURFACEFORMAT_BC2_UNORM 0x187 #define GEN7_SURFACEFORMAT_BC3_UNORM 0x188 #define GEN7_SURFACEFORMAT_BC4_UNORM 0x189 #define GEN7_SURFACEFORMAT_BC5_UNORM 0x18A #define GEN7_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define GEN7_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define GEN7_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define GEN7_SURFACEFORMAT_MONO8 0x18E #define GEN7_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define GEN7_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define GEN7_SURFACEFORMAT_DXT1_RGB 0x191 #define GEN7_SURFACEFORMAT_FXT1 0x192 #define GEN7_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define GEN7_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define GEN7_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define GEN7_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define GEN7_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define GEN7_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define GEN7_SURFACEFORMAT_BC4_SNORM 0x199 #define GEN7_SURFACEFORMAT_BC5_SNORM 0x19A #define GEN7_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define GEN7_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define GEN7_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define GEN7_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define GEN7_SURFACERETURNFORMAT_FLOAT32 0 #define GEN7_SURFACERETURNFORMAT_S1 1 #define GEN7_SURFACE_1D 0 #define GEN7_SURFACE_2D 1 #define GEN7_SURFACE_3D 2 #define GEN7_SURFACE_CUBE 3 #define GEN7_SURFACE_BUFFER 4 #define GEN7_SURFACE_NULL 7 #define GEN7_BORDER_COLOR_MODE_DEFAULT 0 #define GEN7_BORDER_COLOR_MODE_LEGACY 1 #define GEN7_TEXCOORDMODE_WRAP 0 #define GEN7_TEXCOORDMODE_MIRROR 1 #define GEN7_TEXCOORDMODE_CLAMP 2 #define GEN7_TEXCOORDMODE_CUBE 3 #define GEN7_TEXCOORDMODE_CLAMP_BORDER 4 #define GEN7_TEXCOORDMODE_MIRROR_ONCE 5 #define GEN7_THREAD_PRIORITY_NORMAL 0 #define GEN7_THREAD_PRIORITY_HIGH 1 #define GEN7_TILEWALK_XMAJOR 0 #define GEN7_TILEWALK_YMAJOR 1 #define GEN7_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define GEN7_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define GEN7_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define GEN7_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define GEN7_VFCOMPONENT_NOSTORE 0 #define GEN7_VFCOMPONENT_STORE_SRC 1 #define GEN7_VFCOMPONENT_STORE_0 2 #define GEN7_VFCOMPONENT_STORE_1_FLT 3 #define GEN7_VFCOMPONENT_STORE_1_INT 4 #define GEN7_VFCOMPONENT_STORE_VID 5 #define GEN7_VFCOMPONENT_STORE_IID 6 #define GEN7_VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define GEN7_ALIGN_1 0 #define GEN7_ALIGN_16 1 #define GEN7_ADDRESS_DIRECT 0 #define GEN7_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define GEN7_CHANNEL_X 0 #define GEN7_CHANNEL_Y 1 #define GEN7_CHANNEL_Z 2 #define GEN7_CHANNEL_W 3 #define GEN7_COMPRESSION_NONE 0 #define GEN7_COMPRESSION_2NDHALF 1 #define GEN7_COMPRESSION_COMPRESSED 2 #define GEN7_CONDITIONAL_NONE 0 #define GEN7_CONDITIONAL_Z 1 #define GEN7_CONDITIONAL_NZ 2 #define GEN7_CONDITIONAL_EQ 1 /* Z */ #define GEN7_CONDITIONAL_NEQ 2 /* NZ */ #define GEN7_CONDITIONAL_G 3 #define GEN7_CONDITIONAL_GE 4 #define GEN7_CONDITIONAL_L 5 #define GEN7_CONDITIONAL_LE 6 #define GEN7_CONDITIONAL_C 7 #define GEN7_CONDITIONAL_O 8 #define GEN7_DEBUG_NONE 0 #define GEN7_DEBUG_BREAKPOINT 1 #define GEN7_DEPENDENCY_NORMAL 0 #define GEN7_DEPENDENCY_NOTCLEARED 1 #define GEN7_DEPENDENCY_NOTCHECKED 2 #define GEN7_DEPENDENCY_DISABLE 3 #define GEN7_EXECUTE_1 0 #define GEN7_EXECUTE_2 1 #define GEN7_EXECUTE_4 2 #define GEN7_EXECUTE_8 3 #define GEN7_EXECUTE_16 4 #define GEN7_EXECUTE_32 5 #define GEN7_HORIZONTAL_STRIDE_0 0 #define GEN7_HORIZONTAL_STRIDE_1 1 #define GEN7_HORIZONTAL_STRIDE_2 2 #define GEN7_HORIZONTAL_STRIDE_4 3 #define GEN7_INSTRUCTION_NORMAL 0 #define GEN7_INSTRUCTION_SATURATE 1 #define INTEL_MASK_ENABLE 0 #define INTEL_MASK_DISABLE 1 #define GEN7_OPCODE_MOV 1 #define GEN7_OPCODE_SEL 2 #define GEN7_OPCODE_NOT 4 #define GEN7_OPCODE_AND 5 #define GEN7_OPCODE_OR 6 #define GEN7_OPCODE_XOR 7 #define GEN7_OPCODE_SHR 8 #define GEN7_OPCODE_SHL 9 #define GEN7_OPCODE_RSR 10 #define GEN7_OPCODE_RSL 11 #define GEN7_OPCODE_ASR 12 #define GEN7_OPCODE_CMP 16 #define GEN7_OPCODE_JMPI 32 #define GEN7_OPCODE_IF 34 #define GEN7_OPCODE_IFF 35 #define GEN7_OPCODE_ELSE 36 #define GEN7_OPCODE_ENDIF 37 #define GEN7_OPCODE_DO 38 #define GEN7_OPCODE_WHILE 39 #define GEN7_OPCODE_BREAK 40 #define GEN7_OPCODE_CONTINUE 41 #define GEN7_OPCODE_HALT 42 #define GEN7_OPCODE_MSAVE 44 #define GEN7_OPCODE_MRESTORE 45 #define GEN7_OPCODE_PUSH 46 #define GEN7_OPCODE_POP 47 #define GEN7_OPCODE_WAIT 48 #define GEN7_OPCODE_SEND 49 #define GEN7_OPCODE_ADD 64 #define GEN7_OPCODE_MUL 65 #define GEN7_OPCODE_AVG 66 #define GEN7_OPCODE_FRC 67 #define GEN7_OPCODE_RNDU 68 #define GEN7_OPCODE_RNDD 69 #define GEN7_OPCODE_RNDE 70 #define GEN7_OPCODE_RNDZ 71 #define GEN7_OPCODE_MAC 72 #define GEN7_OPCODE_MACH 73 #define GEN7_OPCODE_LZD 74 #define GEN7_OPCODE_SAD2 80 #define GEN7_OPCODE_SADA2 81 #define GEN7_OPCODE_DP4 84 #define GEN7_OPCODE_DPH 85 #define GEN7_OPCODE_DP3 86 #define GEN7_OPCODE_DP2 87 #define GEN7_OPCODE_DPA2 88 #define GEN7_OPCODE_LINE 89 #define GEN7_OPCODE_NOP 126 #define GEN7_PREDICATE_NONE 0 #define GEN7_PREDICATE_NORMAL 1 #define GEN7_PREDICATE_ALIGN1_ANYV 2 #define GEN7_PREDICATE_ALIGN1_ALLV 3 #define GEN7_PREDICATE_ALIGN1_ANY2H 4 #define GEN7_PREDICATE_ALIGN1_ALL2H 5 #define GEN7_PREDICATE_ALIGN1_ANY4H 6 #define GEN7_PREDICATE_ALIGN1_ALL4H 7 #define GEN7_PREDICATE_ALIGN1_ANY8H 8 #define GEN7_PREDICATE_ALIGN1_ALL8H 9 #define GEN7_PREDICATE_ALIGN1_ANY16H 10 #define GEN7_PREDICATE_ALIGN1_ALL16H 11 #define GEN7_PREDICATE_ALIGN16_REPLICATE_X 2 #define GEN7_PREDICATE_ALIGN16_REPLICATE_Y 3 #define GEN7_PREDICATE_ALIGN16_REPLICATE_Z 4 #define GEN7_PREDICATE_ALIGN16_REPLICATE_W 5 #define GEN7_PREDICATE_ALIGN16_ANY4H 6 #define GEN7_PREDICATE_ALIGN16_ALL4H 7 #define GEN7_ARCHITECTURE_REGISTER_FILE 0 #define GEN7_GENERAL_REGISTER_FILE 1 #define GEN7_MESSAGE_REGISTER_FILE 2 #define GEN7_IMMEDIATE_VALUE 3 #define GEN7_REGISTER_TYPE_UD 0 #define GEN7_REGISTER_TYPE_D 1 #define GEN7_REGISTER_TYPE_UW 2 #define GEN7_REGISTER_TYPE_W 3 #define GEN7_REGISTER_TYPE_UB 4 #define GEN7_REGISTER_TYPE_B 5 #define GEN7_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define GEN7_REGISTER_TYPE_HF 6 #define GEN7_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define GEN7_REGISTER_TYPE_F 7 #define GEN7_ARF_NULL 0x00 #define GEN7_ARF_ADDRESS 0x10 #define GEN7_ARF_ACCUMULATOR 0x20 #define GEN7_ARF_FLAG 0x30 #define GEN7_ARF_MASK 0x40 #define GEN7_ARF_MASK_STACK 0x50 #define GEN7_ARF_MASK_STACK_DEPTH 0x60 #define GEN7_ARF_STATE 0x70 #define GEN7_ARF_CONTROL 0x80 #define GEN7_ARF_NOTIFICATION_COUNT 0x90 #define GEN7_ARF_IP 0xA0 #define GEN7_AMASK 0 #define GEN7_IMASK 1 #define GEN7_LMASK 2 #define GEN7_CMASK 3 #define GEN7_THREAD_NORMAL 0 #define GEN7_THREAD_ATOMIC 1 #define GEN7_THREAD_SWITCH 2 #define GEN7_VERTICAL_STRIDE_0 0 #define GEN7_VERTICAL_STRIDE_1 1 #define GEN7_VERTICAL_STRIDE_2 2 #define GEN7_VERTICAL_STRIDE_4 3 #define GEN7_VERTICAL_STRIDE_8 4 #define GEN7_VERTICAL_STRIDE_16 5 #define GEN7_VERTICAL_STRIDE_32 6 #define GEN7_VERTICAL_STRIDE_64 7 #define GEN7_VERTICAL_STRIDE_128 8 #define GEN7_VERTICAL_STRIDE_256 9 #define GEN7_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define GEN7_WIDTH_1 0 #define GEN7_WIDTH_2 1 #define GEN7_WIDTH_4 2 #define GEN7_WIDTH_8 3 #define GEN7_WIDTH_16 4 #define GEN7_STATELESS_BUFFER_BOUNDARY_1K 0 #define GEN7_STATELESS_BUFFER_BOUNDARY_2K 1 #define GEN7_STATELESS_BUFFER_BOUNDARY_4K 2 #define GEN7_STATELESS_BUFFER_BOUNDARY_8K 3 #define GEN7_STATELESS_BUFFER_BOUNDARY_16K 4 #define GEN7_STATELESS_BUFFER_BOUNDARY_32K 5 #define GEN7_STATELESS_BUFFER_BOUNDARY_64K 6 #define GEN7_STATELESS_BUFFER_BOUNDARY_128K 7 #define GEN7_STATELESS_BUFFER_BOUNDARY_256K 8 #define GEN7_STATELESS_BUFFER_BOUNDARY_512K 9 #define GEN7_STATELESS_BUFFER_BOUNDARY_1M 10 #define GEN7_STATELESS_BUFFER_BOUNDARY_2M 11 #define GEN7_POLYGON_FACING_FRONT 0 #define GEN7_POLYGON_FACING_BACK 1 #define GEN7_MESSAGE_TARGET_NULL 0 #define GEN7_MESSAGE_TARGET_MATH 1 #define GEN7_MESSAGE_TARGET_SAMPLER 2 #define GEN7_MESSAGE_TARGET_GATEWAY 3 #define GEN7_MESSAGE_TARGET_DATAPORT_READ 4 #define GEN7_MESSAGE_TARGET_DATAPORT_WRITE 5 #define GEN7_MESSAGE_TARGET_URB 6 #define GEN7_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN7_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define GEN7_SAMPLER_RETURN_FORMAT_UINT32 2 #define GEN7_SAMPLER_RETURN_FORMAT_SINT32 3 #define GEN7_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define GEN7_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define GEN7_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define GEN7_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define GEN7_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define GEN7_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define GEN7_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define GEN7_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define GEN7_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define GEN7_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define GEN7_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define GEN7_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define GEN7_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define GEN7_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define GEN7_SAMPLER_MESSAGE_SIMD8_LD 3 #define GEN7_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN7_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define GEN7_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define GEN7_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define GEN7_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define GEN7_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define GEN7_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define GEN7_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define GEN7_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define GEN7_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define GEN7_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define GEN7_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define GEN7_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define GEN7_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define GEN7_DATAPORT_READ_TARGET_DATA_CACHE 0 #define GEN7_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define GEN7_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define GEN7_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define GEN7_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define GEN7_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define GEN7_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define GEN7_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define GEN7_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define GEN7_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define GEN7_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define GEN7_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define GEN7_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define GEN7_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define GEN7_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define GEN7_MATH_FUNCTION_INV 1 #define GEN7_MATH_FUNCTION_LOG 2 #define GEN7_MATH_FUNCTION_EXP 3 #define GEN7_MATH_FUNCTION_SQRT 4 #define GEN7_MATH_FUNCTION_RSQ 5 #define GEN7_MATH_FUNCTION_SIN 6 /* was 7 */ #define GEN7_MATH_FUNCTION_COS 7 /* was 8 */ #define GEN7_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define GEN7_MATH_FUNCTION_TAN 9 #define GEN7_MATH_FUNCTION_POW 10 #define GEN7_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define GEN7_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define GEN7_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define GEN7_MATH_INTEGER_UNSIGNED 0 #define GEN7_MATH_INTEGER_SIGNED 1 #define GEN7_MATH_PRECISION_FULL 0 #define GEN7_MATH_PRECISION_PARTIAL 1 #define GEN7_MATH_SATURATE_NONE 0 #define GEN7_MATH_SATURATE_SATURATE 1 #define GEN7_MATH_DATA_VECTOR 0 #define GEN7_MATH_DATA_SCALAR 1 #define GEN7_URB_OPCODE_WRITE 0 #define GEN7_URB_SWIZZLE_NONE 0 #define GEN7_URB_SWIZZLE_INTERLEAVE 1 #define GEN7_URB_SWIZZLE_TRANSPOSE 2 #define GEN7_SCRATCH_SPACE_SIZE_1K 0 #define GEN7_SCRATCH_SPACE_SIZE_2K 1 #define GEN7_SCRATCH_SPACE_SIZE_4K 2 #define GEN7_SCRATCH_SPACE_SIZE_8K 3 #define GEN7_SCRATCH_SPACE_SIZE_16K 4 #define GEN7_SCRATCH_SPACE_SIZE_32K 5 #define GEN7_SCRATCH_SPACE_SIZE_64K 6 #define GEN7_SCRATCH_SPACE_SIZE_128K 7 #define GEN7_SCRATCH_SPACE_SIZE_256K 8 #define GEN7_SCRATCH_SPACE_SIZE_512K 9 #define GEN7_SCRATCH_SPACE_SIZE_1M 10 #define GEN7_SCRATCH_SPACE_SIZE_2M 11 /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct gen7_sampler_default_border_color { float color[4]; }; struct gen7_sampler_legacy_border_color { uint8_t color[4]; }; struct gen7_blend_state { struct { uint32_t dest_blend_factor:5; uint32_t source_blend_factor:5; uint32_t pad3:1; uint32_t blend_func:3; uint32_t pad2:1; uint32_t ia_dest_blend_factor:5; uint32_t ia_source_blend_factor:5; uint32_t pad1:1; uint32_t ia_blend_func:3; uint32_t pad0:1; uint32_t ia_blend_enable:1; uint32_t blend_enable:1; } blend0; struct { uint32_t post_blend_clamp_enable:1; uint32_t pre_blend_clamp_enable:1; uint32_t clamp_range:2; uint32_t pad0:4; uint32_t x_dither_offset:2; uint32_t y_dither_offset:2; uint32_t dither_enable:1; uint32_t alpha_test_func:3; uint32_t alpha_test_enable:1; uint32_t pad1:1; uint32_t logic_op_func:4; uint32_t logic_op_enable:1; uint32_t pad2:1; uint32_t write_disable_b:1; uint32_t write_disable_g:1; uint32_t write_disable_r:1; uint32_t write_disable_a:1; uint32_t pad3:1; uint32_t alpha_to_coverage_dither:1; uint32_t alpha_to_one:1; uint32_t alpha_to_coverage:1; } blend1; }; struct gen7_color_calc_state { struct { uint32_t alpha_test_format:1; uint32_t pad0:14; uint32_t round_disable:1; uint32_t bf_stencil_ref:8; uint32_t stencil_ref:8; } cc0; union { float alpha_ref_f; struct { uint32_t ui:8; uint32_t pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen7_depth_stencil_state { struct { uint32_t pad0:3; uint32_t bf_stencil_pass_depth_pass_op:3; uint32_t bf_stencil_pass_depth_fail_op:3; uint32_t bf_stencil_fail_op:3; uint32_t bf_stencil_func:3; uint32_t bf_stencil_enable:1; uint32_t pad1:2; uint32_t stencil_write_enable:1; uint32_t stencil_pass_depth_pass_op:3; uint32_t stencil_pass_depth_fail_op:3; uint32_t stencil_fail_op:3; uint32_t stencil_func:3; uint32_t stencil_enable:1; } ds0; struct { uint32_t bf_stencil_write_mask:8; uint32_t bf_stencil_test_mask:8; uint32_t stencil_write_mask:8; uint32_t stencil_test_mask:8; } ds1; struct { uint32_t pad0:26; uint32_t depth_write_enable:1; uint32_t depth_test_func:3; uint32_t pad1:1; uint32_t depth_test_enable:1; } ds2; }; struct gen7_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad2:2; unsigned int render_cache_read_write:1; unsigned int pad1:1; unsigned int surface_array_spacing:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int horizontal_alignment:1; unsigned int vertical_alignment:2; unsigned int surface_format:9; /**< BRW_SURFACEFORMAT_x */ unsigned int pad0:1; unsigned int is_array:1; unsigned int surface_type:3; /**< BRW_SURFACE_1D/2D/3D/CUBE */ } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int width:14; unsigned int pad1:2; unsigned int height:14; unsigned int pad0:2; } ss2; struct { unsigned int pitch:18; unsigned int pad:3; unsigned int depth:11; } ss3; struct { unsigned int multisample_position_palette_index:3; unsigned int num_multisamples:3; unsigned int multisampled_surface_storage_format:1; unsigned int render_target_view_extent:11; unsigned int min_array_elt:11; unsigned int rotation:2; unsigned int pad0:1; } ss4; struct { unsigned int mip_count:4; unsigned int min_lod:4; unsigned int pad1:12; unsigned int y_offset:4; unsigned int pad0:1; unsigned int x_offset:7; } ss5; struct { unsigned int pad; /* Multisample Control Surface stuff */ } ss6; struct { unsigned int resource_min_lod:12; unsigned int pad0:16; unsigned int alpha_clear_color:1; unsigned int blue_clear_color:1; unsigned int green_clear_color:1; unsigned int red_clear_color:1; } ss7; }; struct gen7_sampler_state { struct { unsigned int aniso_algorithm:1; unsigned int lod_bias:13; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad1:1; unsigned int lod_preclamp:1; unsigned int default_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int cube_control_mode:1; unsigned int shadow_function:3; unsigned int pad:4; unsigned int max_lod:12; unsigned int min_lod:12; } ss1; struct { unsigned int pad:5; unsigned int default_color_pointer:27; } ss2; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:1; unsigned int non_normalized_coord:1; unsigned int trilinear_quality:2; unsigned int address_round:6; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int pad0:6; } ss3; }; /* Surface state DW0 */ #define GEN7_SURFACE_RC_READ_WRITE (1 << 8) #define GEN7_SURFACE_VALIGN_4 (1 << 16) #define GEN7_SURFACE_HALIGN_8 (1 << 15) #define GEN7_SURFACE_TILED (1 << 14) #define GEN7_SURFACE_TILED_Y (1 << 13) #define GEN7_SURFACE_FORMAT_SHIFT 18 #define GEN7_SURFACE_TYPE_SHIFT 29 /* Surface state DW2 */ #define GEN7_SURFACE_HEIGHT_SHIFT 16 #define GEN7_SURFACE_WIDTH_SHIFT 0 /* Surface state DW3 */ #define GEN7_SURFACE_DEPTH_SHIFT 21 #define GEN7_SURFACE_PITCH_SHIFT 0 #define HSW_SWIZZLE_ZERO 0 #define HSW_SWIZZLE_ONE 1 #define HSW_SWIZZLE_RED 4 #define HSW_SWIZZLE_GREEN 5 #define HSW_SWIZZLE_BLUE 6 #define HSW_SWIZZLE_ALPHA 7 #define __HSW_SURFACE_SWIZZLE(r,g,b,a) \ ((a) << 16 | (b) << 19 | (g) << 22 | (r) << 25) #define HSW_SURFACE_SWIZZLE(r,g,b,a) \ __HSW_SURFACE_SWIZZLE(HSW_SWIZZLE_##r, HSW_SWIZZLE_##g, HSW_SWIZZLE_##b, HSW_SWIZZLE_##a) /* _3DSTATE_VERTEX_BUFFERS on GEN7*/ /* DW1 */ #define GEN7_VB0_ADDRESS_MODIFYENABLE (1 << 14) /* _3DPRIMITIVE on GEN7 */ /* DW1 */ # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8) # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM (1 << 8) #define GEN7_3DSTATE_CLEAR_PARAMS GEN7_3D(3, 0, 0x04) #define GEN7_3DSTATE_DEPTH_BUFFER GEN7_3D(3, 0, 0x05) # define GEN7_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define GEN7_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 /* DW1 */ # define GEN7_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) #define GEN7_3DSTATE_CONSTANT_HS GEN7_3D(3, 0, 0x19) #define GEN7_3DSTATE_CONSTANT_DS GEN7_3D(3, 0, 0x1a) #define GEN7_3DSTATE_HS GEN7_3D(3, 0, 0x1b) #define GEN7_3DSTATE_TE GEN7_3D(3, 0, 0x1c) #define GEN7_3DSTATE_DS GEN7_3D(3, 0, 0x1d) #define GEN7_3DSTATE_STREAMOUT GEN7_3D(3, 0, 0x1e) #define GEN7_3DSTATE_SBE GEN7_3D(3, 0, 0x1f) /* DW1 */ # define GEN7_SBE_SWIZZLE_CONTROL_MODE (1 << 28) # define GEN7_SBE_NUM_OUTPUTS_SHIFT 22 # define GEN7_SBE_SWIZZLE_ENABLE (1 << 21) # define GEN7_SBE_POINT_SPRITE_LOWERLEFT (1 << 20) # define GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT 4 #define GEN7_3DSTATE_PS GEN7_3D(3, 0, 0x20) /* DW1: kernel pointer */ /* DW2 */ # define GEN7_PS_SPF_MODE (1 << 31) # define GEN7_PS_VECTOR_MASK_ENABLE (1 << 30) # define GEN7_PS_SAMPLER_COUNT_SHIFT 27 # define GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 # define GEN7_PS_FLOATING_POINT_MODE_IEEE_754 (0 << 16) # define GEN7_PS_FLOATING_POINT_MODE_ALT (1 << 16) /* DW3: scratch space */ /* DW4 */ # define IVB_PS_MAX_THREADS_SHIFT 24 # define HSW_PS_MAX_THREADS_SHIFT 23 # define HSW_PS_SAMPLE_MASK_SHIFT 12 # define GEN7_PS_PUSH_CONSTANT_ENABLE (1 << 11) # define GEN7_PS_ATTRIBUTE_ENABLE (1 << 10) # define GEN7_PS_OMASK_TO_RENDER_TARGET (1 << 9) # define GEN7_PS_DUAL_SOURCE_BLEND_ENABLE (1 << 7) # define GEN7_PS_POSOFFSET_NONE (0 << 3) # define GEN7_PS_POSOFFSET_CENTROID (2 << 3) # define GEN7_PS_POSOFFSET_SAMPLE (3 << 3) # define GEN7_PS_32_DISPATCH_ENABLE (1 << 2) # define GEN7_PS_16_DISPATCH_ENABLE (1 << 1) # define GEN7_PS_8_DISPATCH_ENABLE (1 << 0) /* DW5 */ # define GEN7_PS_DISPATCH_START_GRF_SHIFT_0 16 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_1 8 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_2 0 /* DW6: kernel 1 pointer */ /* DW7: kernel 2 pointer */ #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL GEN7_3D(3, 0, 0x21) #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC GEN7_3D(3, 0, 0x23) #define GEN7_3DSTATE_BLEND_STATE_POINTERS GEN7_3D(3, 0, 0x24) #define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS GEN7_3D(3, 0, 0x25) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS GEN7_3D(3, 0, 0x26) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS GEN7_3D(3, 0, 0x27) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS GEN7_3D(3, 0, 0x28) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS GEN7_3D(3, 0, 0x29) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS GEN7_3D(3, 0, 0x2a) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS GEN7_3D(3, 0, 0x2b) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS GEN7_3D(3, 0, 0x2e) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS GEN7_3D(3, 0, 0x2f) #define GEN7_3DSTATE_URB_VS GEN7_3D(3, 0, 0x30) #define GEN7_3DSTATE_URB_HS GEN7_3D(3, 0, 0x31) #define GEN7_3DSTATE_URB_DS GEN7_3D(3, 0, 0x32) #define GEN7_3DSTATE_URB_GS GEN7_3D(3, 0, 0x33) /* DW1 */ # define GEN7_URB_ENTRY_NUMBER_SHIFT 0 # define GEN7_URB_ENTRY_SIZE_SHIFT 16 # define GEN7_URB_STARTING_ADDRESS_SHIFT 25 #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS GEN7_3D(3, 1, 0x12) #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS GEN7_3D(3, 1, 0x16) /* DW1 */ # define GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT 16 struct gen7_cc_viewport { float min_depth; float max_depth; }; typedef enum { SAMPLER_FILTER_NEAREST = 0, SAMPLER_FILTER_BILINEAR, FILTER_COUNT } sampler_filter_t; typedef enum { SAMPLER_EXTEND_NONE = 0, SAMPLER_EXTEND_REPEAT, SAMPLER_EXTEND_PAD, SAMPLER_EXTEND_REFLECT, EXTEND_COUNT } sampler_extend_t; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_eu.c000066400000000000000000001036711267532330400233510ustar00rootroot00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "compiler.h" #include "brw/brw.h" #include "gen8_eu.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) #endif /* EU ISA */ #define MRF_HACK_START 111 struct gen8_instruction { uint32_t data[4]; }; static inline unsigned __gen8_mask(unsigned high, unsigned low) { assert(high >= low); return (1 << (high - low + 1)) - 1; } /** * Fetch a set of contiguous bits from the instruction. * * Bits indexes range from 0..127; fields may not cross 32-bit boundaries. */ static inline unsigned __gen8_bits(struct gen8_instruction *insn, unsigned high, unsigned low) { /* We assume the field doesn't cross 32-bit boundaries. */ const unsigned word = high / 32; assert(word == low / 32); high %= 32; low %= 32; return (insn->data[word] >> low) & __gen8_mask(high, low); } /** * Set bits in the instruction, with proper shifting and masking. * * Bits indexes range from 0..127; fields may not cross 32-bit boundaries. */ static inline void __gen8_set_bits(struct gen8_instruction *insn, unsigned high, unsigned low, unsigned value) { const unsigned word = high / 32; unsigned mask; assert(word == low / 32); high %= 32; low %= 32; assert(value < __gen8_mask(high, low) + 1); mask = __gen8_mask(high, low) << low; insn->data[word] &= ~mask; insn->data[word] |= (value << low) & mask; assert(__gen8_bits(insn, 32*word+high, 32*word+low) == value); } #define F(name, high, low) \ static inline void __gen8_set_##name(struct gen8_instruction *insn, unsigned v) \ { \ __gen8_set_bits(insn, high, low, v); \ } \ static inline unsigned __gen8_##name(struct gen8_instruction *insn) \ { \ return __gen8_bits(insn, high, low); \ } /** * Direct addressing only: * @{ */ F(src1_da_reg_nr, 108, 101); F(src0_da_reg_nr, 76, 69); F(dst_da1_hstride, 62, 61); F(dst_da_reg_nr, 60, 53); F(dst_da16_subreg_nr, 52, 52); F(dst_da1_subreg_nr, 52, 48); F(da16_writemask, 51, 48); /* Dst.ChanEn */ /** @} */ F(src1_vert_stride, 120, 117) F(src1_da1_width, 116, 114) F(src1_da16_swiz_w, 115, 114) F(src1_da16_swiz_z, 113, 112) F(src1_da1_hstride, 113, 112) F(src1_address_mode, 111, 111) /** Src1.SrcMod @{ */ F(src1_negate, 110, 110) F(src1_abs, 109, 109) /** @} */ F(src1_da16_subreg_nr, 100, 100) F(src1_da1_subreg_nr, 100, 96) F(src1_da16_swiz_y, 99, 98) F(src1_da16_swiz_x, 97, 96) F(src1_reg_type, 94, 91) F(src1_reg_file, 90, 89) F(src0_vert_stride, 88, 85) F(src0_da1_width, 84, 82) F(src0_da16_swiz_w, 83, 82) F(src0_da16_swiz_z, 81, 80) F(src0_da1_hstride, 81, 80) F(src0_address_mode, 79, 79) /** Src0.SrcMod @{ */ F(src0_negate, 78, 78) F(src0_abs, 77, 77) /** @} */ F(src0_da16_subreg_nr, 68, 68) F(src0_da1_subreg_nr, 68, 64) F(src0_da16_swiz_y, 67, 66) F(src0_da16_swiz_x, 65, 64) F(dst_address_mode, 63, 63) F(src0_reg_type, 46, 43) F(src0_reg_file, 42, 41) F(dst_reg_type, 40, 37) F(dst_reg_file, 36, 35) F(mask_control, 34, 34) F(flag_reg_nr, 33, 33) F(flag_subreg_nr, 32, 32) F(saturate, 31, 31) F(branch_control, 30, 30) F(debug_control, 30, 30) F(cmpt_control, 29, 29) F(acc_wr_control, 28, 28) F(cond_modifier, 27, 24) F(exec_size, 23, 21) F(pred_inv, 20, 20) F(pred_control, 19, 16) F(thread_control, 15, 14) F(qtr_control, 13, 12) F(nib_control, 11, 11) F(dep_control, 10, 9) F(access_mode, 8, 8) /* Bit 7 is Reserved (for future Opcode expansion) */ F(opcode, 6, 0) /** * Three-source instructions: * @{ */ F(src2_3src_reg_nr, 125, 118) F(src2_3src_subreg_nr, 117, 115) F(src2_3src_swizzle, 114, 107) F(src2_3src_rep_ctrl, 106, 106) F(src1_3src_reg_nr, 104, 97) F(src1_3src_subreg_hi, 96, 96) F(src1_3src_subreg_lo, 95, 94) F(src1_3src_swizzle, 93, 86) F(src1_3src_rep_ctrl, 85, 85) F(src0_3src_reg_nr, 83, 76) F(src0_3src_subreg_nr, 75, 73) F(src0_3src_swizzle, 72, 65) F(src0_3src_rep_ctrl, 64, 64) F(dst_3src_reg_nr, 63, 56) F(dst_3src_subreg_nr, 55, 53) F(dst_3src_writemask, 52, 49) F(dst_3src_type, 48, 46) F(src_3src_type, 45, 43) F(src2_3src_negate, 42, 42) F(src2_3src_abs, 41, 41) F(src1_3src_negate, 40, 40) F(src1_3src_abs, 39, 39) F(src0_3src_negate, 38, 38) F(src0_3src_abs, 37, 37) /** @} */ /** * Fields for SEND messages: * @{ */ F(eot, 127, 127) F(mlen, 124, 121) F(rlen, 120, 116) F(header_present, 115, 115) F(function_control, 114, 96) F(sfid, 27, 24) F(math_function, 27, 24) /** @} */ /** * URB message function control bits: * @{ */ F(urb_per_slot_offset, 113, 113) F(urb_interleave, 111, 111) F(urb_global_offset, 110, 100) F(urb_opcode, 99, 96) /** @} */ /** * Sampler message function control bits: * @{ */ F(sampler_simd_mode, 114, 113) F(sampler_msg_type, 112, 108) F(sampler, 107, 104) F(binding_table_index, 103, 96) /** @} */ /** * Data port message function control bits: * @ { */ F(dp_category, 114, 114) F(dp_message_type, 113, 110) F(dp_message_control, 109, 104) F(dp_binding_table_index, 103, 96) /** @} */ /** * Thread Spawn message function control bits: * @ { */ F(ts_resource_select, 100, 100) F(ts_request_type, 97, 97) F(ts_opcode, 96, 96) /** @} */ /** * Video Motion Estimation message function control bits: * @ { */ F(vme_message_type, 110, 109) F(vme_binding_table_index, 103, 96) /** @} */ /** * Check & Refinement Engine message function control bits: * @ { */ F(cre_message_type, 110, 109) F(cre_binding_table_index, 103, 96) /** @} */ #undef F /** * Flow control instruction bits: * @{ */ static inline unsigned __gen8_uip(struct gen8_instruction *insn) { return insn->data[2]; } static inline void __gen8_set_uip(struct gen8_instruction *insn, unsigned uip) { insn->data[2] = uip; } static inline unsigned __gen8_jip(struct gen8_instruction *insn) { return insn->data[3]; } static inline void __gen8_set_jip(struct gen8_instruction *insn, unsigned jip) { insn->data[3] = jip; } /** @} */ static inline int __gen8_src1_imm_d(struct gen8_instruction *insn) { return insn->data[3]; } static inline unsigned __gen8_src1_imm_ud(struct gen8_instruction *insn) { return insn->data[3]; } static inline float __gen8_src1_imm_f(struct gen8_instruction *insn) { union { uint32_t u; float f; } ft = { insn->data[3] }; return ft.f; } static void __gen8_set_dst(struct brw_compile *p, struct gen8_instruction *inst, struct brw_reg reg) { /* MRFs haven't existed since Gen7, so we better not be using them. */ if (reg.file == BRW_MESSAGE_REGISTER_FILE) { reg.file = BRW_GENERAL_REGISTER_FILE; reg.nr += MRF_HACK_START; } assert(reg.file != BRW_MESSAGE_REGISTER_FILE); if (reg.file == BRW_GENERAL_REGISTER_FILE) assert(reg.nr < BRW_MAX_GRF); __gen8_set_dst_reg_file(inst, reg.file); __gen8_set_dst_reg_type(inst, reg.type); assert(reg.address_mode == BRW_ADDRESS_DIRECT); __gen8_set_dst_da_reg_nr(inst, reg.nr); if (__gen8_access_mode(inst) == BRW_ALIGN_1) { /* Set Dst.SubRegNum[4:0] */ __gen8_set_dst_da1_subreg_nr(inst, reg.subnr); /* Set Dst.HorzStride */ if (reg.hstride == BRW_HORIZONTAL_STRIDE_0) reg.hstride = BRW_HORIZONTAL_STRIDE_1; __gen8_set_dst_da1_hstride(inst, reg.hstride); } else { /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ assert(reg.subnr == 0 || reg.subnr == 16); __gen8_set_dst_da16_subreg_nr(inst, reg.subnr >> 4); __gen8_set_da16_writemask(inst, reg.dw1.bits.writemask); } #if 1 if (reg.width == BRW_WIDTH_8 && p->compressed) __gen8_set_exec_size(inst, BRW_EXECUTE_16); else __gen8_set_exec_size(inst, reg.width); #else if (reg.width < BRW_EXECUTE_8) __gen8_set_exec_size(inst, reg.width); #endif } static void __gen8_validate_reg(struct gen8_instruction *inst, struct brw_reg reg) { int hstride_for_reg[] = {0, 1, 2, 4}; int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256}; int width_for_reg[] = {1, 2, 4, 8, 16}; int execsize_for_reg[] = {1, 2, 4, 8, 16}; int width, hstride, vstride, execsize; if (reg.file == BRW_IMMEDIATE_VALUE) { /* TODO: check immediate vectors */ return; } if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE) return; assert(reg.hstride >= 0 && reg.hstride < ARRAY_SIZE(hstride_for_reg)); hstride = hstride_for_reg[reg.hstride]; if (reg.vstride == 0xf) { vstride = -1; } else { assert(reg.vstride >= 0 && reg.vstride < ARRAY_SIZE(vstride_for_reg)); vstride = vstride_for_reg[reg.vstride]; } assert(reg.width >= 0 && reg.width < ARRAY_SIZE(width_for_reg)); width = width_for_reg[reg.width]; assert(__gen8_exec_size(inst) >= 0 && __gen8_exec_size(inst) < ARRAY_SIZE(execsize_for_reg)); execsize = execsize_for_reg[__gen8_exec_size(inst)]; /* Restrictions from 3.3.10: Register Region Restrictions. */ /* 3. */ assert(execsize >= width); /* 4. */ if (execsize == width && hstride != 0) { assert(vstride == -1 || vstride == width * hstride); } /* 5. */ if (execsize == width && hstride == 0) { /* no restriction on vstride. */ } /* 6. */ if (width == 1) { assert(hstride == 0); } /* 7. */ if (execsize == 1 && width == 1) { assert(hstride == 0); assert(vstride == 0); } /* 8. */ if (vstride == 0 && hstride == 0) { assert(width == 1); } /* 10. Check destination issues. */ } static void __gen8_set_src0(struct gen8_instruction *inst, struct brw_reg reg) { /* MRFs haven't existed since Gen7, so we better not be using them. */ if (reg.file == BRW_MESSAGE_REGISTER_FILE) { reg.file = BRW_GENERAL_REGISTER_FILE; reg.nr += MRF_HACK_START; } if (reg.file == BRW_GENERAL_REGISTER_FILE) assert(reg.nr < BRW_MAX_GRF); __gen8_validate_reg(inst, reg); __gen8_set_src0_reg_file(inst, reg.file); __gen8_set_src0_reg_type(inst, reg.type); __gen8_set_src0_abs(inst, reg.abs); __gen8_set_src0_negate(inst, reg.negate); assert(reg.address_mode == BRW_ADDRESS_DIRECT); if (reg.file == BRW_IMMEDIATE_VALUE) { inst->data[3] = reg.dw1.ud; /* Required to set some fields in src1 as well: */ __gen8_set_src1_reg_file(inst, 0); /* arf */ __gen8_set_src1_reg_type(inst, reg.type); } else { __gen8_set_src0_da_reg_nr(inst, reg.nr); if (__gen8_access_mode(inst) == BRW_ALIGN_1) { /* Set Src0.SubRegNum[4:0] */ __gen8_set_src0_da1_subreg_nr(inst, reg.subnr); if (reg.width == BRW_WIDTH_1 && __gen8_exec_size(inst) == BRW_EXECUTE_1) { __gen8_set_src0_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0); __gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_0); } else { __gen8_set_src0_da1_hstride(inst, reg.hstride); __gen8_set_src0_vert_stride(inst, reg.vstride); } __gen8_set_src0_da1_width(inst, reg.width); } else { /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ assert(reg.subnr == 0 || reg.subnr == 16); __gen8_set_src0_da16_subreg_nr(inst, reg.subnr >> 4); __gen8_set_src0_da16_swiz_x(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X)); __gen8_set_src0_da16_swiz_y(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y)); __gen8_set_src0_da16_swiz_z(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z)); __gen8_set_src0_da16_swiz_w(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W)); /* This is an oddity of the fact that we're using the same * descriptions for registers in both Align16 and Align1 modes. */ if (reg.vstride == BRW_VERTICAL_STRIDE_8) __gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_4); else __gen8_set_src0_vert_stride(inst, reg.vstride); } } } static void __gen8_set_src1(struct gen8_instruction *inst, struct brw_reg reg) { /* MRFs haven't existed since Gen7, so we better not be using them. */ if (reg.file == BRW_MESSAGE_REGISTER_FILE) { reg.file = BRW_GENERAL_REGISTER_FILE; reg.nr += MRF_HACK_START; } if (reg.file == BRW_GENERAL_REGISTER_FILE) assert(reg.nr < BRW_MAX_GRF); __gen8_validate_reg(inst, reg); __gen8_set_src1_reg_file(inst, reg.file); __gen8_set_src1_reg_type(inst, reg.type); __gen8_set_src1_abs(inst, reg.abs); __gen8_set_src1_negate(inst, reg.negate); /* Only src1 can be an immediate in two-argument instructions. */ assert(__gen8_src0_reg_file(inst) != BRW_IMMEDIATE_VALUE); assert(reg.address_mode == BRW_ADDRESS_DIRECT); if (reg.file == BRW_IMMEDIATE_VALUE) { inst->data[3] = reg.dw1.ud; } else { __gen8_set_src1_da_reg_nr(inst, reg.nr); if (__gen8_access_mode(inst) == BRW_ALIGN_1) { /* Set Src0.SubRegNum[4:0] */ __gen8_set_src1_da1_subreg_nr(inst, reg.subnr); if (reg.width == BRW_WIDTH_1 && __gen8_exec_size(inst) == BRW_EXECUTE_1) { __gen8_set_src1_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0); __gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_0); } else { __gen8_set_src1_da1_hstride(inst, reg.hstride); __gen8_set_src1_vert_stride(inst, reg.vstride); } __gen8_set_src1_da1_width(inst, reg.width); } else { /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */ assert(reg.subnr == 0 || reg.subnr == 16); __gen8_set_src1_da16_subreg_nr(inst, reg.subnr >> 4); __gen8_set_src1_da16_swiz_x(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X)); __gen8_set_src1_da16_swiz_y(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y)); __gen8_set_src1_da16_swiz_z(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z)); __gen8_set_src1_da16_swiz_w(inst, BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W)); /* This is an oddity of the fact that we're using the same * descriptions for registers in both Align16 and Align1 modes. */ if (reg.vstride == BRW_VERTICAL_STRIDE_8) __gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_4); else __gen8_set_src1_vert_stride(inst, reg.vstride); } } } /** * Set the Message Descriptor and Extended Message Descriptor fields * for SEND messages. * * \note This zeroes out the Function Control bits, so it must be called * \b before filling out any message-specific data. Callers can * choose not to fill in irrelevant bits; they will be zero. */ static void __gen8_set_message_descriptor(struct gen8_instruction *inst, enum brw_message_target sfid, unsigned msg_length, unsigned response_length, bool header_present, bool end_of_thread) { __gen8_set_src1(inst, brw_imm_d(0)); __gen8_set_sfid(inst, sfid); __gen8_set_mlen(inst, msg_length); __gen8_set_rlen(inst, response_length); __gen8_set_header_present(inst, header_present); __gen8_set_eot(inst, end_of_thread); } #if 0 static void __gen8_set_urb_message(struct gen8_instruction *inst, unsigned opcode, unsigned msg_length, unsigned response_length, bool end_of_thread, unsigned offset, bool interleave) { __gen8_set_message_descriptor(inst, BRW_SFID_URB, msg_length, response_length, true, end_of_thread); __gen8_set_src0(inst, brw_vec8_grf(MRF_HACK_START + 1, 0)); __gen8_set_urb_opcode(inst, 0); /* URB_WRITE_HWORD */ __gen8_set_urb_global_offset(inst, offset); __gen8_set_urb_interleave(inst, interleave); /* per_slot_offset = 0 makes it ignore offsets in message header */ __gen8_set_urb_per_slot_offset(inst, 0); } #endif static void __gen8_set_sampler_message(struct gen8_instruction *inst, unsigned binding_table_index, unsigned sampler, unsigned msg_type, unsigned response_length, unsigned msg_length, bool header_present, unsigned simd_mode) { __gen8_set_message_descriptor(inst, BRW_SFID_SAMPLER, msg_length, response_length, header_present, false); __gen8_set_binding_table_index(inst, binding_table_index); __gen8_set_sampler(inst, sampler); __gen8_set_sampler_msg_type(inst, msg_type); __gen8_set_sampler_simd_mode(inst, simd_mode); } static void __gen8_set_dp_message(struct gen8_instruction *inst, enum brw_message_target sfid, unsigned binding_table_index, unsigned msg_type, unsigned msg_control, unsigned mlen, unsigned rlen, bool header_present, bool end_of_thread) { /* Binding table index is from 0..255 */ assert((binding_table_index & 0xff) == binding_table_index); /* Message Type is only 5 bits */ assert((msg_type & 0x1f) == msg_type); /* Message Control is only 6 bits */ assert((msg_control & 0x3f) == msg_control); __gen8_set_message_descriptor(inst, sfid, mlen, rlen, header_present, end_of_thread); __gen8_set_function_control(inst, binding_table_index | msg_type << 14 | msg_control << 8); } static inline struct gen8_instruction * gen8_next_insn(struct brw_compile *p, int opcode) { struct gen8_instruction *insn; assert(p->nr_insn + 1 < BRW_EU_MAX_INSN); insn = memcpy(&p->store[p->nr_insn++], p->current, sizeof(*insn)); __gen8_set_opcode(insn, opcode); return insn; } static void gen8_math(struct brw_compile *p, struct brw_reg dst, unsigned function, unsigned saturate, unsigned msg_reg_nr, struct brw_reg src, unsigned data_type, unsigned precision) { struct gen8_instruction *insn = gen8_next_insn(p, BRW_OPCODE_MATH); assert(dst.file == BRW_GENERAL_REGISTER_FILE); assert(src.file == BRW_GENERAL_REGISTER_FILE); assert(dst.hstride == BRW_HORIZONTAL_STRIDE_1); assert(src.hstride == BRW_HORIZONTAL_STRIDE_1); /* Source modifiers are ignored for extended math instructions. */ assert(!src.negate); assert(!src.abs); if (function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT && function != BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER) { assert(src.type == BRW_REGISTER_TYPE_F); } /* Math is the same ISA format as other opcodes, except that CondModifier * becomes FC[3:0] and ThreadCtrl becomes FC[5:4]. */ __gen8_set_cond_modifier(insn, function); __gen8_set_saturate(insn, saturate); __gen8_set_dst(p, insn, dst); __gen8_set_src0(insn, src); __gen8_set_src1(insn, brw_null_reg()); } static inline void gen8_math_invert(struct brw_compile *p, struct brw_reg dst, struct brw_reg src) { gen8_math(p, dst, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 0, src, BRW_MATH_PRECISION_FULL, BRW_MATH_DATA_VECTOR); } /* Helpers for regular instructions: */ static inline struct gen8_instruction *gen8_alu1(struct brw_compile *p, unsigned opcode, struct brw_reg dst, struct brw_reg src) { struct gen8_instruction *insn = gen8_next_insn(p, opcode); __gen8_set_dst(p, insn, dst); __gen8_set_src0(insn, src); return insn; } static inline struct gen8_instruction *gen8_alu2(struct brw_compile *p, unsigned opcode, struct brw_reg dst, struct brw_reg src0, struct brw_reg src1) { struct gen8_instruction *insn = gen8_next_insn(p, opcode); __gen8_set_dst(p, insn, dst); __gen8_set_src0(insn, src0); __gen8_set_src1(insn, src1); return insn; } #define ALU1(OP) \ static inline struct gen8_instruction *gen8_##OP(struct brw_compile *p, \ struct brw_reg dst, \ struct brw_reg src0) \ { \ return gen8_alu1(p, BRW_OPCODE_##OP, dst, src0); \ } #define ALU2(OP) \ static inline struct gen8_instruction *gen8_##OP(struct brw_compile *p, \ struct brw_reg dst, \ struct brw_reg src0, \ struct brw_reg src1) \ { \ return gen8_alu2(p, BRW_OPCODE_##OP, dst, src0, src1); \ } static inline struct gen8_instruction *gen8_ADD(struct brw_compile *p, struct brw_reg dst, struct brw_reg src0, struct brw_reg src1) { /* 6.2.2: add */ if (src0.type == BRW_REGISTER_TYPE_F || (src0.file == BRW_IMMEDIATE_VALUE && src0.type == BRW_REGISTER_TYPE_VF)) { assert(src1.type != BRW_REGISTER_TYPE_UD); assert(src1.type != BRW_REGISTER_TYPE_D); } if (src1.type == BRW_REGISTER_TYPE_F || (src1.file == BRW_IMMEDIATE_VALUE && src1.type == BRW_REGISTER_TYPE_VF)) { assert(src0.type != BRW_REGISTER_TYPE_UD); assert(src0.type != BRW_REGISTER_TYPE_D); } return gen8_alu2(p, BRW_OPCODE_ADD, dst, src0, src1); } static inline struct gen8_instruction *gen8_MUL(struct brw_compile *p, struct brw_reg dst, struct brw_reg src0, struct brw_reg src1) { /* 6.32.38: mul */ if (src0.type == BRW_REGISTER_TYPE_D || src0.type == BRW_REGISTER_TYPE_UD || src1.type == BRW_REGISTER_TYPE_D || src1.type == BRW_REGISTER_TYPE_UD) { assert(dst.type != BRW_REGISTER_TYPE_F); } if (src0.type == BRW_REGISTER_TYPE_F || (src0.file == BRW_IMMEDIATE_VALUE && src0.type == BRW_REGISTER_TYPE_VF)) { assert(src1.type != BRW_REGISTER_TYPE_UD); assert(src1.type != BRW_REGISTER_TYPE_D); } if (src1.type == BRW_REGISTER_TYPE_F || (src1.file == BRW_IMMEDIATE_VALUE && src1.type == BRW_REGISTER_TYPE_VF)) { assert(src0.type != BRW_REGISTER_TYPE_UD); assert(src0.type != BRW_REGISTER_TYPE_D); } assert(src0.file != BRW_ARCHITECTURE_REGISTER_FILE || src0.nr != BRW_ARF_ACCUMULATOR); assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE || src1.nr != BRW_ARF_ACCUMULATOR); return gen8_alu2(p, BRW_OPCODE_MUL, dst, src0, src1); } ALU1(MOV); ALU2(SEL); ALU1(NOT); ALU2(AND); ALU2(OR); ALU2(XOR); ALU2(SHR); ALU2(SHL); ALU2(RSR); ALU2(RSL); ALU2(ASR); ALU1(FRC); ALU1(RNDD); ALU2(MAC); ALU2(MACH); ALU1(LZD); ALU2(DP4); ALU2(DPH); ALU2(DP3); ALU2(DP2); ALU2(LINE); ALU2(PLN); ALU1(RNDZ); ALU1(RNDE); #undef ALU1 #undef ALU2 static void gen8_set_compression_control(struct brw_compile *p, enum brw_compression compression_control) { unsigned v; p->compressed = compression_control == BRW_COMPRESSION_COMPRESSED; switch (compression_control) { default: assert(0); case BRW_COMPRESSION_NONE: v = GEN6_COMPRESSION_1Q; break; case BRW_COMPRESSION_2NDHALF: v = GEN6_COMPRESSION_2Q; break; case BRW_COMPRESSION_COMPRESSED: v = GEN6_COMPRESSION_1H; break; } __gen8_set_cmpt_control((struct gen8_instruction *)p->current, v); } static inline void gen8_set_mask_control(struct brw_compile *p, unsigned value) { __gen8_set_mask_control((struct gen8_instruction *)p->current, value); } static inline void gen8_set_saturate(struct brw_compile *p, unsigned value) { __gen8_set_saturate((struct gen8_instruction *)p->current, value); } static inline void gen8_set_acc_write_control(struct brw_compile *p, unsigned value) { __gen8_set_acc_wr_control((struct gen8_instruction *)p->current, value); } static void gen8_SAMPLE(struct brw_compile *p, struct brw_reg dst, unsigned msg_reg_nr, unsigned binding_table_index, unsigned sampler, unsigned writemask, unsigned msg_type, unsigned response_length, unsigned msg_length, bool header_present, unsigned simd_mode) { struct brw_reg src0 = brw_message_reg(msg_reg_nr); assert(writemask); if (writemask != WRITEMASK_XYZW) { writemask = ~writemask & WRITEMASK_XYZW; brw_push_insn_state(p); gen8_set_compression_control(p, BRW_COMPRESSION_NONE); gen8_set_mask_control(p, BRW_MASK_DISABLE); gen8_MOV(p, __retype_ud(src0), __retype_ud(brw_vec8_grf(0,0))); gen8_MOV(p, get_element_ud(src0, 2), brw_imm_ud(writemask << 12)); brw_pop_insn_state(p); } { struct gen8_instruction *insn; insn = gen8_next_insn(p, BRW_OPCODE_SEND); __gen8_set_pred_control(insn, 0); /* XXX */ __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); __gen8_set_dst(p, insn, dst); __gen8_set_src0(insn, src0); __gen8_set_sampler_message(insn, binding_table_index, sampler, msg_type, response_length, msg_length, header_present, simd_mode); } } /* shader logic */ static void wm_affine_st(struct brw_compile *p, int dw, int channel, int msg) { int uv; if (dw == 16) { gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); uv = 6; } else { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); uv = 4; } uv += 2*channel; msg++; gen8_PLN(p, brw_message_reg(msg), brw_vec1_grf(uv, 0), brw_vec8_grf(2, 0)); msg += dw/8; gen8_PLN(p, brw_message_reg(msg), brw_vec1_grf(uv, 4), brw_vec8_grf(2, 0)); } static inline unsigned simd(int dw) { return dw == 16 ? BRW_SAMPLER_SIMD_MODE_SIMD16 : BRW_SAMPLER_SIMD_MODE_SIMD8; } static inline struct brw_reg sample_result(int dw, int result) { return brw_reg(BRW_GENERAL_REGISTER_FILE, result, 0, BRW_REGISTER_TYPE_UW, dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } static int wm_sample(struct brw_compile *p, int dw, int channel, int msg, int result) { int len = dw == 16 ? 4 : 2; gen8_SAMPLE(p, sample_result(dw, result), ++msg, channel+1, channel, WRITEMASK_XYZW, 0, 2*len, len, false, simd(dw)); return result; } static int wm_sample__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { int mlen, rlen; if (dw == 8) { mlen = 3; rlen = 1; } else { mlen = 5; rlen = 2; } gen8_SAMPLE(p, sample_result(dw, result), msg, channel+1, channel, WRITEMASK_W, 0, rlen, mlen, true, simd(dw)); return result; } static int wm_affine(struct brw_compile *p, int dw, int channel, int msg, int result) { wm_affine_st(p, dw, channel, msg); return wm_sample(p, dw, channel, msg, result); } static int wm_affine__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { wm_affine_st(p, dw, channel, msg); return wm_sample__alpha(p, dw, channel, msg, result); } static inline struct brw_reg null_result(int dw) { return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, BRW_ARF_NULL, 0, BRW_REGISTER_TYPE_UW, dw == 16 ? BRW_VERTICAL_STRIDE_16 : BRW_VERTICAL_STRIDE_8, dw == 16 ? BRW_WIDTH_16 : BRW_WIDTH_8, BRW_HORIZONTAL_STRIDE_1, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW); } static void fb_write(struct brw_compile *p, int dw) { struct gen8_instruction *insn; unsigned msg_control, msg_len; struct brw_reg src0; if (dw == 16) { msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; msg_len = 8; } else { msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; msg_len = 4; } msg_control |= 1 << 4; /* Last Render Target */ /* The execution mask is ignored for render target writes. */ insn = gen8_next_insn(p, BRW_OPCODE_SEND); __gen8_set_pred_control(insn, 0); __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); src0 = brw_message_reg(2); __gen8_set_dst(p, insn, null_result(dw)); __gen8_set_src0(insn, src0); __gen8_set_dp_message(insn, GEN6_SFID_DATAPORT_RENDER_CACHE, 0, GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, msg_control, msg_len, 0, false, true); } static void wm_write__mask(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8) { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + n, 0), brw_vec8_grf(mask, 0)); } else { gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask, 0)); } fb_write(p, dw); } static void wm_write__opacity(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8) { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + n, 0), brw_vec1_grf(mask, 3)); } else { gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec1_grf(mask, 3)); } fb_write(p, dw); } static void wm_write__mask_ca(struct brw_compile *p, int dw, int src, int mask) { int n; if (dw == 8) { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + n), brw_vec8_grf(src + n, 0), brw_vec8_grf(mask + n, 0)); } else { gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); for (n = 0; n < 4; n++) gen8_MUL(p, brw_message_reg(2 + 2*n), brw_vec8_grf(src + 2*n, 0), brw_vec8_grf(mask + 2*n, 0)); } fb_write(p, dw); } static void gen8_compile_init(struct brw_compile *p) { struct gen8_instruction *insn = memset(p->current, 0, sizeof(*insn)); COMPILE_TIME_ASSERT(sizeof(*insn) == sizeof(*p->current)); __gen8_set_mask_control(insn, BRW_MASK_ENABLE); __gen8_set_saturate(insn, 0); __gen8_set_cmpt_control(insn, GEN6_COMPRESSION_1Q); //__gen8_set_pred_control(insn, 0xf); } bool gen8_wm_kernel__affine(struct brw_compile *p, int dispatch) { gen8_compile_init(p); wm_affine(p, dispatch, 0, 10, MRF_HACK_START+2); fb_write(p, dispatch); return true; } bool gen8_wm_kernel__affine_mask(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_affine(p, dispatch, 0, 1, 12); mask = wm_affine__alpha(p, dispatch, 1, 6, 20); wm_write__mask(p, dispatch, src, mask); return true; } bool gen8_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_affine(p, dispatch, 0, 1, 12); mask = wm_affine(p, dispatch, 1, 6, 20); wm_write__mask_ca(p, dispatch, src, mask); return true; } bool gen8_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_affine__alpha(p, dispatch, 0, 1, 12); mask = wm_affine(p, dispatch, 1, 6, 16); wm_write__mask(p, dispatch, mask, src); return true; } /* Projective variants */ static void wm_projective_st(struct brw_compile *p, int dw, int channel, int msg) { int uv; gen8_compile_init(p); if (dw == 16) { gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); uv = 6; } else { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); uv = 4; } uv += 2*channel; msg++; /* First compute 1/z */ gen8_PLN(p, brw_vec8_grf(30, 0), brw_vec1_grf(uv+1, 0), brw_vec8_grf(2, 0)); if (dw == 16) { gen8_set_compression_control(p, BRW_COMPRESSION_NONE); gen8_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); gen8_math_invert(p, brw_vec8_grf(31, 0), brw_vec8_grf(31, 0)); gen8_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); } else gen8_math_invert(p, brw_vec8_grf(30, 0), brw_vec8_grf(30, 0)); gen8_PLN(p, brw_vec8_grf(26, 0), brw_vec1_grf(uv, 0), brw_vec8_grf(2, 0)); gen8_PLN(p, brw_vec8_grf(28, 0), brw_vec1_grf(uv, 4), brw_vec8_grf(2, 0)); gen8_MUL(p, brw_message_reg(msg), brw_vec8_grf(26, 0), brw_vec8_grf(30, 0)); gen8_MUL(p, brw_message_reg(msg + dw/8), brw_vec8_grf(28, 0), brw_vec8_grf(30, 0)); } static int wm_projective(struct brw_compile *p, int dw, int channel, int msg, int result) { gen8_compile_init(p); wm_projective_st(p, dw, channel, msg); return wm_sample(p, dw, channel, msg, result); } static int wm_projective__alpha(struct brw_compile *p, int dw, int channel, int msg, int result) { gen8_compile_init(p); wm_projective_st(p, dw, channel, msg); return wm_sample__alpha(p, dw, channel, msg, result); } bool gen8_wm_kernel__projective(struct brw_compile *p, int dispatch) { gen8_compile_init(p); wm_projective(p, dispatch, 0, 10, MRF_HACK_START+2); fb_write(p, dispatch); return true; } bool gen8_wm_kernel__projective_mask(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_projective(p, dispatch, 0, 1, 12); mask = wm_projective__alpha(p, dispatch, 1, 6, 20); wm_write__mask(p, dispatch, src, mask); return true; } bool gen8_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_projective(p, dispatch, 0, 1, 12); mask = wm_projective(p, dispatch, 1, 6, 20); wm_write__mask_ca(p, dispatch, src, mask); return true; } bool gen8_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_projective__alpha(p, dispatch, 0, 1, 12); mask = wm_projective(p, dispatch, 1, 6, 16); wm_write__mask(p, dispatch, mask, src); return true; } bool gen8_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); src = wm_affine(p, dispatch, 0, 1, 12); mask = dispatch == 16 ? 8 : 6; wm_write__opacity(p, dispatch, src, mask); return true; } bool gen8_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch) { int src, mask; gen8_compile_init(p); mask = dispatch == 16 ? 8 : 6; src = wm_projective(p, dispatch, 0, 1, 12); wm_write__opacity(p, dispatch, src, mask); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_eu.h000066400000000000000000000015661267532330400233560ustar00rootroot00000000000000#ifndef GEN8_EU_H #define GEN8_EU_H #include "brw/brw_eu.h" bool gen8_wm_kernel__affine(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__affine_mask(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__projective(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__projective_mask(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch_width); bool gen8_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch_width); #endif /* GEN8_EU_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_render.c000066400000000000000000003201671267532330400242200ustar00rootroot00000000000000/* * Copyright © 2012,2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_video.h" #include "gen8_render.h" #include "gen8_eu.h" #include "gen4_common.h" #include "gen4_source.h" #include "gen4_vertex.h" #include "gen6_common.h" #include "gen8_vertex.h" #define SIM 1 #define ALWAYS_INVALIDATE 0 #define ALWAYS_FLUSH 0 #define ALWAYS_STALL 0 #define NO_COMPOSITE 0 #define NO_COMPOSITE_SPANS 0 #define NO_COPY 0 #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_BOXES 0 #define NO_FILL_ONE 0 #define NO_FILL_CLEAR 0 #define NO_VIDEO 0 #define USE_8_PIXEL_DISPATCH 1 #define USE_16_PIXEL_DISPATCH 1 #define USE_32_PIXEL_DISPATCH 0 #if !USE_8_PIXEL_DISPATCH && !USE_16_PIXEL_DISPATCH && !USE_32_PIXEL_DISPATCH #error "Must select at least 8, 16 or 32 pixel dispatch" #endif #define GEN8_MAX_SIZE 16384 /* XXX Todo * * STR (software tiled rendering) mode. No, really. * 64x32 pixel blocks align with the rendering cache. Worth considering. */ #define is_aligned(x, y) (((x) & ((y) - 1)) == 0) /* Pipeline stages: * 1. Command Streamer (CS) * 2. Vertex Fetch (VF) * 3. Vertex Shader (VS) * 4. Hull Shader (HS) * 5. Tesselation Engine (TE) * 6. Domain Shader (DS) * 7. Geometry Shader (GS) * 8. Stream Output Logic (SOL) * 9. Clipper (CLIP) * 10. Strip/Fan (SF) * 11. Windower/Masker (WM) * 12. Color Calculator (CC) */ #if !NO_VIDEO static const uint32_t ps_kernel_packed[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_argb.g8b" #include "exa_wm_yuv_rgb.g8b" #include "exa_wm_write.g8b" }; static const uint32_t ps_kernel_planar[][4] = { #include "exa_wm_src_affine.g8b" #include "exa_wm_src_sample_planar.g8b" #include "exa_wm_yuv_rgb.g8b" #include "exa_wm_write.g8b" }; #endif #define SURFACE_DW (64 / sizeof(uint32_t)); #define KERNEL(kernel_enum, kernel, num_surfaces) \ [GEN8_WM_KERNEL_##kernel_enum] = {#kernel_enum, kernel, sizeof(kernel), num_surfaces} #define NOKERNEL(kernel_enum, func, num_surfaces) \ [GEN8_WM_KERNEL_##kernel_enum] = {#kernel_enum, (void *)func, 0, num_surfaces} static const struct wm_kernel_info { const char *name; const void *data; unsigned int size; int num_surfaces; } wm_kernels[] = { NOKERNEL(NOMASK, gen8_wm_kernel__affine, 2), NOKERNEL(NOMASK_P, gen8_wm_kernel__projective, 2), NOKERNEL(MASK, gen8_wm_kernel__affine_mask, 3), NOKERNEL(MASK_P, gen8_wm_kernel__projective_mask, 3), NOKERNEL(MASKCA, gen8_wm_kernel__affine_mask_ca, 3), NOKERNEL(MASKCA_P, gen8_wm_kernel__projective_mask_ca, 3), NOKERNEL(MASKSA, gen8_wm_kernel__affine_mask_sa, 3), NOKERNEL(MASKSA_P, gen8_wm_kernel__projective_mask_sa, 3), NOKERNEL(OPACITY, gen8_wm_kernel__affine_opacity, 2), NOKERNEL(OPACITY_P, gen8_wm_kernel__projective_opacity, 2), #if !NO_VIDEO KERNEL(VIDEO_PLANAR, ps_kernel_planar, 7), KERNEL(VIDEO_PACKED, ps_kernel_packed, 2), #endif }; #undef KERNEL static const struct blendinfo { uint8_t src_alpha; uint8_t src_blend; uint8_t dst_blend; } gen8_blend_op[] = { /* Clear */ {0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO}, /* Src */ {0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO}, /* Dst */ {0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE}, /* Over */ {1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE}, /* In */ {0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO}, /* InReverse */ {1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA}, /* Out */ {0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO}, /* OutReverse */ {1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, BLENDFACTOR_ONE, BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in gen8_blend_op. * * This leaves out GEN8_BLENDFACTOR_INV_DST_COLOR, * GEN8_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * GEN8_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define GEN8_BLENDFACTOR_COUNT (BLENDFACTOR_INV_DST_ALPHA + 1) #define GEN8_BLEND_STATE_PADDED_SIZE ALIGN(sizeof(struct gen8_blend_state), 64) #define BLEND_OFFSET(s, d) \ ((d != BLENDFACTOR_ZERO) << 15 | ((s) * GEN8_BLENDFACTOR_COUNT + (d)) << 4) #define NO_BLEND BLEND_OFFSET(BLENDFACTOR_ONE, BLENDFACTOR_ZERO) #define CLEAR BLEND_OFFSET(BLENDFACTOR_ZERO, BLENDFACTOR_ZERO) #define SAMPLER_OFFSET(sf, se, mf, me) \ (((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) + 2) #define VERTEX_2s2s 0 #define COPY_SAMPLER 0 #define COPY_VERTEX VERTEX_2s2s #define COPY_FLAGS(a) GEN8_SET_FLAGS(COPY_SAMPLER, (a) == GXcopy ? NO_BLEND : CLEAR, GEN8_WM_KERNEL_NOMASK, COPY_VERTEX) #define FILL_SAMPLER 1 #define FILL_VERTEX VERTEX_2s2s #define FILL_FLAGS(op, format) GEN8_SET_FLAGS(FILL_SAMPLER, gen8_get_blend((op), false, (format)), GEN8_WM_KERNEL_NOMASK, FILL_VERTEX) #define FILL_FLAGS_NOBLEND GEN8_SET_FLAGS(FILL_SAMPLER, NO_BLEND, GEN8_WM_KERNEL_NOMASK, FILL_VERTEX) #define GEN8_SAMPLER(f) (((f) >> 20) & 0xfff) #define GEN8_BLEND(f) (((f) >> 4) & 0x7ff) #define GEN8_READS_DST(f) (((f) >> 15) & 1) #define GEN8_KERNEL(f) (((f) >> 16) & 0xf) #define GEN8_VERTEX(f) (((f) >> 0) & 0xf) #define GEN8_SET_FLAGS(S, B, K, V) ((S) << 20 | (K) << 16 | (B) | (V)) #define OUT_BATCH(v) batch_emit(sna, v) #define OUT_BATCH64(v) batch_emit64(sna, v) #define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y) #define OUT_VERTEX_F(v) vertex_emit(sna, v) struct gt_info { const char *name; struct { int max_vs_entries; } urb; }; static const struct gt_info bdw_gt_info = { .name = "Broadwell (gen8)", .urb = { .max_vs_entries = 960 }, }; static bool is_bdw(struct sna *sna) { return sna->kgem.gen == 0100; } static const struct gt_info chv_gt_info = { .name = "Cherryview (gen8)", .urb = { .max_vs_entries = 640 }, }; static bool is_chv(struct sna *sna) { return sna->kgem.gen == 0101; } static inline bool too_large(int width, int height) { return width > GEN8_MAX_SIZE || height > GEN8_MAX_SIZE; } static inline bool unaligned(struct kgem_bo *bo, int bpp) { /* XXX What exactly do we need to meet H_ALIGN and V_ALIGN? */ #if 0 int x, y; if (bo->proxy == NULL) return false; /* Assume that all tiled proxies are constructed correctly. */ if (bo->tiling) return false; DBG(("%s: checking alignment of a linear proxy, offset=%d, pitch=%d, bpp=%d: => (%d, %d)\n", __FUNCTION__, bo->delta, bo->pitch, bpp, 8 * (bo->delta % bo->pitch) / bpp, bo->delta / bo->pitch)); /* This may be a random userptr map, check that it meets the * render alignment of SURFACE_VALIGN_4 | SURFACE_HALIGN_4. */ y = bo->delta / bo->pitch; if (y & 3) return true; x = 8 * (bo->delta - y * bo->pitch); if (x & (4*bpp - 1)) return true; return false; #else return false; #endif } static uint32_t gen8_get_blend(int op, bool has_component_alpha, uint32_t dst_format) { uint32_t src, dst; COMPILE_TIME_ASSERT(BLENDFACTOR_INV_DST_ALPHA*GEN8_BLENDFACTOR_COUNT + BLENDFACTOR_INV_DST_ALPHA <= 0x7ff); src = gen8_blend_op[op].src_blend; dst = gen8_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that * we'll treat it always as 1. */ if (PICT_FORMAT_A(dst_format) == 0) { if (src == BLENDFACTOR_DST_ALPHA) src = BLENDFACTOR_ONE; else if (src == BLENDFACTOR_INV_DST_ALPHA) src = BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a * case where the source blend factor is 0, and the source blend * value is the mask channels multiplied by the source picture's alpha. */ if (has_component_alpha && gen8_blend_op[op].src_alpha) { if (dst == BLENDFACTOR_SRC_ALPHA) dst = BLENDFACTOR_SRC_COLOR; else if (dst == BLENDFACTOR_INV_SRC_ALPHA) dst = BLENDFACTOR_INV_SRC_COLOR; } DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n", op, dst_format, PICT_FORMAT_A(dst_format), src, dst, (int)(BLEND_OFFSET(src, dst)>>4))); assert(BLEND_OFFSET(src, dst) >> 4 <= 0xfff); return BLEND_OFFSET(src, dst); } static uint32_t gen8_get_card_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: return SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_x8r8g8b8: return SURFACEFORMAT_B8G8R8X8_UNORM; case PICT_a8b8g8r8: return SURFACEFORMAT_R8G8B8A8_UNORM; case PICT_x8b8g8r8: return SURFACEFORMAT_R8G8B8X8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: return SURFACEFORMAT_B10G10R10A2_UNORM; case PICT_x2r10g10b10: return SURFACEFORMAT_B10G10R10X2_UNORM; #endif case PICT_r8g8b8: return SURFACEFORMAT_R8G8B8_UNORM; case PICT_r5g6b5: return SURFACEFORMAT_B5G6R5_UNORM; case PICT_a1r5g5b5: return SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: return SURFACEFORMAT_B4G4R4A4_UNORM; } } static uint32_t gen8_get_dest_format(PictFormat format) { switch (format) { default: return -1; case PICT_a8r8g8b8: case PICT_x8r8g8b8: return SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return SURFACEFORMAT_R8G8B8A8_UNORM; #ifdef PICT_a2r10g10b10 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return SURFACEFORMAT_B4G4R4A4_UNORM; } } static bool gen8_check_dst_format(PictFormat format) { if (gen8_get_dest_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static bool gen8_check_format(uint32_t format) { if (gen8_get_card_format(format) != -1) return true; DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format)); return false; } static uint32_t gen8_filter(uint32_t filter) { switch (filter) { default: assert(0); case PictFilterNearest: return SAMPLER_FILTER_NEAREST; case PictFilterBilinear: return SAMPLER_FILTER_BILINEAR; } } static uint32_t gen8_check_filter(PicturePtr picture) { switch (picture->filter) { case PictFilterNearest: case PictFilterBilinear: return true; default: return false; } } static uint32_t gen8_repeat(uint32_t repeat) { switch (repeat) { default: assert(0); case RepeatNone: return SAMPLER_EXTEND_NONE; case RepeatNormal: return SAMPLER_EXTEND_REPEAT; case RepeatPad: return SAMPLER_EXTEND_PAD; case RepeatReflect: return SAMPLER_EXTEND_REFLECT; } } static bool gen8_check_repeat(PicturePtr picture) { if (!picture->repeat) return true; switch (picture->repeatType) { case RepeatNone: case RepeatNormal: case RepeatPad: case RepeatReflect: return true; default: return false; } } static int gen8_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine) { int base; if (has_mask) { if (is_ca) { if (gen8_blend_op[op].src_alpha) base = GEN8_WM_KERNEL_MASKSA; else base = GEN8_WM_KERNEL_MASKCA; } else base = GEN8_WM_KERNEL_MASK; } else base = GEN8_WM_KERNEL_NOMASK; return base + !is_affine; } static void gen8_emit_push_constants(struct sna *sna) { #if SIM OUT_BATCH(GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2)); OUT_BATCH(0); #endif } static void gen8_emit_urb(struct sna *sna) { /* num of VS entries must be divisible by 8 if size < 9 */ OUT_BATCH(GEN8_3DSTATE_URB_VS | (2 - 2)); OUT_BATCH(sna->render_state.gen8.info->urb.max_vs_entries << URB_ENTRY_NUMBER_SHIFT | (2 - 1) << URB_ENTRY_SIZE_SHIFT | 4 << URB_STARTING_ADDRESS_SHIFT); OUT_BATCH(GEN8_3DSTATE_URB_HS | (2 - 2)); OUT_BATCH(0 << URB_ENTRY_SIZE_SHIFT | 4 << URB_STARTING_ADDRESS_SHIFT); OUT_BATCH(GEN8_3DSTATE_URB_DS | (2 - 2)); OUT_BATCH(0 << URB_ENTRY_SIZE_SHIFT | 4 << URB_STARTING_ADDRESS_SHIFT); OUT_BATCH(GEN8_3DSTATE_URB_GS | (2 - 2)); OUT_BATCH(0 << URB_ENTRY_SIZE_SHIFT | 4 << URB_STARTING_ADDRESS_SHIFT); } static void gen8_emit_state_base_address(struct sna *sna) { uint32_t num_pages; assert(sna->kgem.surface - sna->kgem.nbatch <= 16384); OUT_BATCH(GEN8_STATE_BASE_ADDRESS | (16 - 2)); OUT_BATCH64(0); /* general */ OUT_BATCH(0); /* stateless dataport */ OUT_BATCH64(kgem_add_reloc64(&sna->kgem, /* surface */ sna->kgem.nbatch, NULL, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH64(kgem_add_reloc64(&sna->kgem, /* dynamic */ sna->kgem.nbatch, sna->render_state.gen8.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); OUT_BATCH64(0); /* indirect */ OUT_BATCH64(kgem_add_reloc64(&sna->kgem, /* instruction */ sna->kgem.nbatch, sna->render_state.gen8.general_bo, I915_GEM_DOMAIN_INSTRUCTION << 16, BASE_ADDRESS_MODIFY)); /* upper bounds */ num_pages = sna->render_state.gen8.general_bo->size.pages.count; OUT_BATCH(0); /* general */ OUT_BATCH(num_pages << 12 | 1); /* dynamic */ OUT_BATCH(0); /* indirect */ OUT_BATCH(num_pages << 12 | 1); /* instruction */ } static void gen8_emit_vs_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_VS | (9 - 2)); OUT_BATCH64(0); /* no VS kernel */ OUT_BATCH(0); OUT_BATCH64(0); /* scratch */ OUT_BATCH(0); OUT_BATCH(1 << 1); /* pass-through */ OUT_BATCH(1 << 16 | 1 << 21); /* urb write to SBE */ #if SIM OUT_BATCH(GEN8_3DSTATE_CONSTANT_VS | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH(GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS | (2 - 2)); OUT_BATCH(0); #endif } static void gen8_emit_hs_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_HS | (9 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); /* no HS kernel */ OUT_BATCH64(0); /* scratch */ OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ #if SIM OUT_BATCH(GEN8_3DSTATE_CONSTANT_HS | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); #if 1 OUT_BATCH(GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS | (2 - 2)); OUT_BATCH(0); #endif #endif } static void gen8_emit_te_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_TE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen8_emit_ds_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_DS | (9 - 2)); OUT_BATCH64(0); /* no kernel */ OUT_BATCH(0); OUT_BATCH64(0); /* scratch */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #if SIM OUT_BATCH(GEN8_3DSTATE_CONSTANT_DS | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); #if 1 OUT_BATCH(GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS | (2 - 2)); OUT_BATCH(0); #endif #endif } static void gen8_emit_gs_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_GS | (10 - 2)); OUT_BATCH64(0); /* no GS kernel */ OUT_BATCH(0); OUT_BATCH64(0); /* scratch */ OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(0); OUT_BATCH(0); #if SIM OUT_BATCH(GEN8_3DSTATE_CONSTANT_GS | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); #if 1 OUT_BATCH(GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS | (2 - 2)); OUT_BATCH(0); #endif #endif } static void gen8_emit_sol_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_STREAMOUT | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen8_emit_sf_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_SF | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } static void gen8_emit_clip_invariant(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_CLIP | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC | (2 - 2)); OUT_BATCH(0); } static void gen8_emit_null_depth_buffer(struct sna *sna) { OUT_BATCH(GEN8_3DSTATE_DEPTH_BUFFER | (8 - 2)); #if 0 OUT_BATCH(SURFACE_NULL << DEPTH_BUFFER_TYPE_SHIFT | DEPTHFORMAT_D32_FLOAT << DEPTH_BUFFER_FORMAT_SHIFT); #else OUT_BATCH(SURFACE_2D << DEPTH_BUFFER_TYPE_SHIFT | DEPTHFORMAT_D16_UNORM << DEPTH_BUFFER_FORMAT_SHIFT); #endif OUT_BATCH64(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #if SIM OUT_BATCH(GEN8_3DSTATE_HIER_DEPTH_BUFFER | (5 - 2)); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH(0); #endif #if SIM OUT_BATCH(GEN8_3DSTATE_STENCIL_BUFFER | (5 - 2)); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH(0); #endif #if SIM OUT_BATCH(GEN8_3DSTATE_WM_DEPTH_STENCIL | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); #endif #if SIM OUT_BATCH(GEN8_3DSTATE_CLEAR_PARAMS | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); #endif } static void gen8_emit_wm_invariant(struct sna *sna) { gen8_emit_null_depth_buffer(sna); #if SIM OUT_BATCH(GEN8_3DSTATE_SCISSOR_STATE_POINTERS | (2 - 2)); OUT_BATCH(0); #endif OUT_BATCH(GEN8_3DSTATE_WM | (2 - 2)); //OUT_BATCH(WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC); /* XXX */ OUT_BATCH(WM_PERSPECTIVE_PIXEL_BARYCENTRIC); #if SIM OUT_BATCH(GEN8_3DSTATE_WM_CHROMAKEY | (2 - 2)); OUT_BATCH(0); #endif #if 0 OUT_BATCH(GEN8_3DSTATE_WM_HZ_OP | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #endif OUT_BATCH(GEN8_3DSTATE_PS_EXTRA | (2 - 2)); OUT_BATCH(PSX_PIXEL_SHADER_VALID | PSX_ATTRIBUTE_ENABLE); OUT_BATCH(GEN8_3DSTATE_RASTER | (5 - 2)); OUT_BATCH(RASTER_FRONT_WINDING_CCW | RASTER_CULL_NONE); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_SBE_SWIZ | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); #if SIM OUT_BATCH(GEN8_3DSTATE_CONSTANT_PS | (11 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); OUT_BATCH64(0); #endif } static void gen8_emit_cc_invariant(struct sna *sna) { } static void gen8_emit_vf_invariant(struct sna *sna) { int n; #if 1 OUT_BATCH(GEN8_3DSTATE_VF | (2 - 2)); OUT_BATCH(0); #endif OUT_BATCH(GEN8_3DSTATE_VF_SGVS | (2 - 2)); OUT_BATCH(0); OUT_BATCH(GEN8_3DSTATE_VF_TOPOLOGY | (2 - 2)); OUT_BATCH(RECTLIST); OUT_BATCH(GEN8_3DSTATE_VF_STATISTICS | 0); for (n = 1; n <= 3; n++) { OUT_BATCH(GEN8_3DSTATE_VF_INSTANCING | (3 - 2)); OUT_BATCH(n); OUT_BATCH(0); } } static void gen8_emit_invariant(struct sna *sna) { OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_3D); #if SIM OUT_BATCH(GEN8_STATE_SIP | (3 - 2)); OUT_BATCH64(0); #endif OUT_BATCH(GEN8_3DSTATE_MULTISAMPLE | (2 - 2)); OUT_BATCH(MULTISAMPLE_PIXEL_LOCATION_CENTER | MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */ OUT_BATCH(GEN8_3DSTATE_SAMPLE_MASK | (2 - 2)); OUT_BATCH(1); #if SIM OUT_BATCH(GEN8_3DSTATE_SAMPLE_PATTERN | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); //OUT_BATCH(8<<20 | 8<<16); OUT_BATCH(0); #endif gen8_emit_push_constants(sna); gen8_emit_urb(sna); gen8_emit_state_base_address(sna); gen8_emit_vf_invariant(sna); gen8_emit_vs_invariant(sna); gen8_emit_hs_invariant(sna); gen8_emit_te_invariant(sna); gen8_emit_ds_invariant(sna); gen8_emit_gs_invariant(sna); gen8_emit_sol_invariant(sna); gen8_emit_clip_invariant(sna); gen8_emit_sf_invariant(sna); gen8_emit_wm_invariant(sna); gen8_emit_cc_invariant(sna); sna->render_state.gen8.needs_invariant = false; } static void gen8_emit_cc(struct sna *sna, uint32_t blend) { struct gen8_render_state *render = &sna->render_state.gen8; if (render->blend == blend) return; DBG(("%s: blend=%x (current=%x), src=%d, dst=%d\n", __FUNCTION__, blend, render->blend, blend / GEN8_BLENDFACTOR_COUNT, blend % GEN8_BLENDFACTOR_COUNT)); assert(blend < GEN8_BLENDFACTOR_COUNT * GEN8_BLENDFACTOR_COUNT); assert(blend / GEN8_BLENDFACTOR_COUNT > 0); assert(blend % GEN8_BLENDFACTOR_COUNT > 0); /* XXX can have up to 8 blend states preload, selectable via * Render Target Index. What other side-effects of Render Target Index? */ OUT_BATCH(GEN8_3DSTATE_PS_BLEND | (2 - 2)); if (blend != GEN8_BLEND(NO_BLEND)) { uint32_t src = blend / GEN8_BLENDFACTOR_COUNT; uint32_t dst = blend % GEN8_BLENDFACTOR_COUNT; OUT_BATCH(PS_BLEND_HAS_WRITEABLE_RT | PS_BLEND_COLOR_BLEND_ENABLE | src << PS_BLEND_SRC_ALPHA_SHIFT | dst << PS_BLEND_DST_ALPHA_SHIFT | src << PS_BLEND_SRC_SHIFT | dst << PS_BLEND_DST_SHIFT); } else OUT_BATCH(PS_BLEND_HAS_WRITEABLE_RT); assert(is_aligned(render->cc_blend + blend * GEN8_BLEND_STATE_PADDED_SIZE, 64)); OUT_BATCH(GEN8_3DSTATE_BLEND_STATE_POINTERS | (2 - 2)); OUT_BATCH((render->cc_blend + blend * GEN8_BLEND_STATE_PADDED_SIZE) | 1); /* Force a CC_STATE pointer change to improve blend performance */ OUT_BATCH(GEN8_3DSTATE_CC_STATE_POINTERS | (2 - 2)); OUT_BATCH(0); render->blend = blend; } static void gen8_emit_sampler(struct sna *sna, uint32_t state) { if (sna->render_state.gen8.samplers == state) return; sna->render_state.gen8.samplers = state; DBG(("%s: sampler = %x\n", __FUNCTION__, state)); assert(2 * sizeof(struct gen8_sampler_state) == 32); OUT_BATCH(GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS | (2 - 2)); OUT_BATCH(sna->render_state.gen8.wm_state + state * 2 * sizeof(struct gen8_sampler_state)); } static void gen8_emit_sf(struct sna *sna, bool has_mask) { int num_sf_outputs = has_mask ? 2 : 1; if (sna->render_state.gen8.num_sf_outputs == num_sf_outputs) return; DBG(("%s: num_sf_outputs=%d\n", __FUNCTION__, num_sf_outputs)); sna->render_state.gen8.num_sf_outputs = num_sf_outputs; OUT_BATCH(GEN8_3DSTATE_SBE | (4 - 2)); OUT_BATCH(num_sf_outputs << SBE_NUM_OUTPUTS_SHIFT | SBE_FORCE_VERTEX_URB_READ_LENGTH | /* forced is faster */ SBE_FORCE_VERTEX_URB_READ_OFFSET | 1 << SBE_URB_ENTRY_READ_LENGTH_SHIFT | 1 << SBE_URB_ENTRY_READ_OFFSET_SHIFT); OUT_BATCH(0); OUT_BATCH(0); } static void gen8_emit_wm(struct sna *sna, int kernel) { const uint32_t *kernels; assert(kernel < ARRAY_SIZE(wm_kernels)); if (sna->render_state.gen8.kernel == kernel) return; sna->render_state.gen8.kernel = kernel; kernels = sna->render_state.gen8.wm_kernel[kernel]; DBG(("%s: switching to %s, num_surfaces=%d (8-wide? %d, 16-wide? %d, 32-wide? %d)\n", __FUNCTION__, wm_kernels[kernel].name, wm_kernels[kernel].num_surfaces, kernels[0], kernels[1], kernels[2])); assert(is_aligned(kernels[0], 64)); assert(is_aligned(kernels[1], 64)); assert(is_aligned(kernels[2], 64)); OUT_BATCH(GEN8_3DSTATE_PS | (12 - 2)); OUT_BATCH64(kernels[0] ?: kernels[1] ?: kernels[2]); OUT_BATCH(1 << PS_SAMPLER_COUNT_SHIFT | PS_VECTOR_MASK_ENABLE | wm_kernels[kernel].num_surfaces << PS_BINDING_TABLE_ENTRY_COUNT_SHIFT); OUT_BATCH64(0); /* scratch address */ OUT_BATCH(PS_MAX_THREADS | (kernels[0] ? PS_8_DISPATCH_ENABLE : 0) | (kernels[1] ? PS_16_DISPATCH_ENABLE : 0) | (kernels[2] ? PS_32_DISPATCH_ENABLE : 0)); OUT_BATCH((kernels[0] ? 4 : kernels[1] ? 6 : 8) << PS_DISPATCH_START_GRF_SHIFT_0 | 8 << PS_DISPATCH_START_GRF_SHIFT_1 | 6 << PS_DISPATCH_START_GRF_SHIFT_2); OUT_BATCH64(kernels[2]); OUT_BATCH64(kernels[1]); } static bool gen8_emit_binding_table(struct sna *sna, uint16_t offset) { if (sna->render_state.gen8.surface_table == offset) return false; /* Binding table pointers */ assert(is_aligned(4*offset, 32)); OUT_BATCH(GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS | (2 - 2)); OUT_BATCH(offset*4); sna->render_state.gen8.surface_table = offset; return true; } static bool gen8_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op) { uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1); uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x; assert(!too_large(abs(op->dst.x), abs(op->dst.y))); assert(!too_large(op->dst.width, op->dst.height)); if (sna->render_state.gen8.drawrect_limit == limit && sna->render_state.gen8.drawrect_offset == offset) return true; sna->render_state.gen8.drawrect_offset = offset; sna->render_state.gen8.drawrect_limit = limit; OUT_BATCH(GEN8_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(limit); OUT_BATCH(offset); return false; } static void gen8_emit_vertex_elements(struct sna *sna, const struct sna_composite_op *op) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0) * texture coordinate 1 if (has_mask is true): same as above */ struct gen8_render_state *render = &sna->render_state.gen8; uint32_t src_format, dw; int id = GEN8_VERTEX(op->u.gen8.flags); bool has_mask; DBG(("%s: setup id=%d\n", __FUNCTION__, id)); if (render->ve_id == id) return; render->ve_id = id; /* The VUE layout * dword 0-3: pad (0.0, 0.0, 0.0. 0.0) * dword 4-7: position (x, y, 1.0, 1.0), * dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0) * dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0) * * dword 4-15 are fetched from vertex buffer */ has_mask = (id >> 2) != 0; OUT_BATCH(GEN8_3DSTATE_VERTEX_ELEMENTS | ((2 * (3 + has_mask)) + 1 - 2)); OUT_BATCH(id << VE_INDEX_SHIFT | VE_VALID | SURFACEFORMAT_R32G32B32A32_FLOAT << VE_FORMAT_SHIFT | 0 << VE_OFFSET_SHIFT); OUT_BATCH(COMPONENT_STORE_0 << VE_COMPONENT_0_SHIFT | COMPONENT_STORE_0 << VE_COMPONENT_1_SHIFT | COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT | COMPONENT_STORE_0 << VE_COMPONENT_3_SHIFT); /* x,y */ OUT_BATCH(id << VE_INDEX_SHIFT | VE_VALID | SURFACEFORMAT_R16G16_SSCALED << VE_FORMAT_SHIFT | 0 << VE_OFFSET_SHIFT); OUT_BATCH(COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT | COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT | COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT | COMPONENT_STORE_1_FLT << VE_COMPONENT_3_SHIFT); /* u0, v0, w0 */ DBG(("%s: first channel %d floats, offset=4\n", __FUNCTION__, id & 3)); dw = COMPONENT_STORE_1_FLT << VE_COMPONENT_3_SHIFT; switch (id & 3) { default: assert(0); case 0: src_format = SURFACEFORMAT_R16G16_SSCALED; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT; break; case 1: src_format = SURFACEFORMAT_R32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT; break; case 2: src_format = SURFACEFORMAT_R32G32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT; break; case 3: src_format = SURFACEFORMAT_R32G32B32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE_INDEX_SHIFT | VE_VALID | src_format << VE_FORMAT_SHIFT | 4 << VE_OFFSET_SHIFT); OUT_BATCH(dw); /* u1, v1, w1 */ if (has_mask) { unsigned offset = 4 + ((id & 3) ?: 1) * sizeof(float); DBG(("%s: second channel %d floats, offset=%d\n", __FUNCTION__, (id >> 2) & 3, offset)); dw = COMPONENT_STORE_1_FLT << VE_COMPONENT_3_SHIFT; switch (id >> 2) { case 1: src_format = SURFACEFORMAT_R32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT; break; default: assert(0); case 2: src_format = SURFACEFORMAT_R32G32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_0 << VE_COMPONENT_2_SHIFT; break; case 3: src_format = SURFACEFORMAT_R32G32B32_FLOAT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_0_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_1_SHIFT; dw |= COMPONENT_STORE_SRC << VE_COMPONENT_2_SHIFT; break; } OUT_BATCH(id << VE_INDEX_SHIFT | VE_VALID | src_format << VE_FORMAT_SHIFT | offset << VE_OFFSET_SHIFT); OUT_BATCH(dw); } } inline static void gen8_emit_pipe_invalidate(struct sna *sna) { OUT_BATCH(GEN8_PIPE_CONTROL | (6 - 2)); OUT_BATCH(PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | PIPE_CONTROL_CS_STALL); OUT_BATCH64(0); OUT_BATCH64(0); } inline static void gen8_emit_pipe_flush(struct sna *sna, bool need_stall) { unsigned stall; stall = 0; if (need_stall) stall = (PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH(GEN8_PIPE_CONTROL | (6 - 2)); OUT_BATCH(PIPE_CONTROL_WC_FLUSH | stall); OUT_BATCH64(0); OUT_BATCH64(0); } inline static void gen8_emit_pipe_stall(struct sna *sna) { OUT_BATCH(GEN8_PIPE_CONTROL | (6 - 2)); OUT_BATCH(PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH64(0); OUT_BATCH64(0); } static void gen8_emit_state(struct sna *sna, const struct sna_composite_op *op, uint16_t wm_binding_table) { bool need_invalidate; bool need_flush; bool need_stall; assert(op->dst.bo->exec); need_flush = wm_binding_table & 1 || (sna->render_state.gen8.emit_flush && GEN8_READS_DST(op->u.gen8.flags)); if (ALWAYS_FLUSH) need_flush = true; wm_binding_table &= ~1; need_stall = sna->render_state.gen8.surface_table != wm_binding_table; need_invalidate = kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo); if (ALWAYS_INVALIDATE) need_invalidate = true; need_stall &= gen8_emit_drawing_rectangle(sna, op); if (ALWAYS_STALL) need_stall = true; if (need_invalidate) { gen8_emit_pipe_invalidate(sna); kgem_clear_dirty(&sna->kgem); assert(op->dst.bo->exec); kgem_bo_mark_dirty(op->dst.bo); need_flush = false; need_stall = false; } if (need_flush) { gen8_emit_pipe_flush(sna, need_stall); need_stall = false; } if (need_stall) gen8_emit_pipe_stall(sna); gen8_emit_cc(sna, GEN8_BLEND(op->u.gen8.flags)); gen8_emit_sampler(sna, GEN8_SAMPLER(op->u.gen8.flags)); gen8_emit_sf(sna, GEN8_VERTEX(op->u.gen8.flags) >> 2); gen8_emit_wm(sna, GEN8_KERNEL(op->u.gen8.flags)); gen8_emit_vertex_elements(sna, op); gen8_emit_binding_table(sna, wm_binding_table); sna->render_state.gen8.emit_flush = GEN8_READS_DST(op->u.gen8.flags); } static bool gen8_magic_ca_pass(struct sna *sna, const struct sna_composite_op *op) { struct gen8_render_state *state = &sna->render_state.gen8; if (!op->need_magic_ca_pass) return false; DBG(("%s: CA fixup (%d -> %d)\n", __FUNCTION__, sna->render.vertex_start, sna->render.vertex_index)); gen8_emit_pipe_stall(sna); gen8_emit_cc(sna, GEN8_BLEND(gen8_get_blend(PictOpAdd, true, op->dst.format))); gen8_emit_wm(sna, gen8_choose_composite_kernel(PictOpAdd, true, true, op->is_affine)); OUT_BATCH(GEN8_3DPRIMITIVE | (7 - 2)); OUT_BATCH(0); /* ignored, see VF_TOPOLOGY */ OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start); OUT_BATCH(sna->render.vertex_start); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ state->last_primitive = sna->kgem.nbatch; return true; } static void null_create(struct sna_static_stream *stream) { /* A bunch of zeros useful for legacy border color and depth-stencil */ sna_static_stream_map(stream, 64, 64); } static void sampler_state_init(struct gen8_sampler_state *sampler_state, sampler_filter_t filter, sampler_extend_t extend) { COMPILE_TIME_ASSERT(sizeof(*sampler_state) == 4*sizeof(uint32_t)); sampler_state->ss0.lod_preclamp = 2; /* GL mode */ sampler_state->ss0.default_color_mode = 1; switch (filter) { default: case SAMPLER_FILTER_NEAREST: sampler_state->ss0.min_filter = MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = MAPFILTER_NEAREST; break; case SAMPLER_FILTER_BILINEAR: sampler_state->ss0.min_filter = MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = MAPFILTER_LINEAR; break; } /* XXX bicubic filter using MAPFILTER_FLEXIBLE */ switch (extend) { default: case SAMPLER_EXTEND_NONE: sampler_state->ss3.r_wrap_mode = TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.s_wrap_mode = TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.t_wrap_mode = TEXCOORDMODE_CLAMP_BORDER; break; case SAMPLER_EXTEND_REPEAT: sampler_state->ss3.r_wrap_mode = TEXCOORDMODE_WRAP; sampler_state->ss3.s_wrap_mode = TEXCOORDMODE_WRAP; sampler_state->ss3.t_wrap_mode = TEXCOORDMODE_WRAP; break; case SAMPLER_EXTEND_PAD: sampler_state->ss3.r_wrap_mode = TEXCOORDMODE_CLAMP; sampler_state->ss3.s_wrap_mode = TEXCOORDMODE_CLAMP; sampler_state->ss3.t_wrap_mode = TEXCOORDMODE_CLAMP; break; case SAMPLER_EXTEND_REFLECT: sampler_state->ss3.r_wrap_mode = TEXCOORDMODE_MIRROR; sampler_state->ss3.s_wrap_mode = TEXCOORDMODE_MIRROR; sampler_state->ss3.t_wrap_mode = TEXCOORDMODE_MIRROR; break; } } static void sampler_copy_init(struct gen8_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static void sampler_fill_init(struct gen8_sampler_state *ss) { sampler_state_init(ss, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_REPEAT); ss->ss3.non_normalized_coord = 1; sampler_state_init(ss+1, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE); } static uint32_t gen8_tiling_bits(uint32_t tiling) { switch (tiling) { default: assert(0); case I915_TILING_NONE: return 0; case I915_TILING_X: return SURFACE_TILED; case I915_TILING_Y: return SURFACE_TILED | SURFACE_TILED_Y; } } #define MOCS_WT (2 << 5) #define MOCS_WB (3 << 5) #define MOCS_eLLC_ONLY (0 << 3) #define MOCS_LLC_ONLY (1 << 3) #define MOCS_eLLC_LLC (2 << 3) #define MOCS_ALL_CACHES (3 << 3) /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static uint32_t gen8_bind_bo(struct sna *sna, struct kgem_bo *bo, uint32_t width, uint32_t height, uint32_t format, bool is_dst) { uint32_t *ss; uint32_t domains; int offset; uint32_t is_scanout = is_dst && bo->scanout; /* After the first bind, we manage the cache domains within the batch */ offset = kgem_bo_get_binding(bo, format | is_dst << 30 | is_scanout << 31); if (offset) { if (is_dst) kgem_bo_mark_dirty(bo); assert(offset >= sna->kgem.surface); return offset * sizeof(uint32_t); } offset = sna->kgem.surface -= SURFACE_DW; ss = sna->kgem.batch + offset; ss[0] = (SURFACE_2D << SURFACE_TYPE_SHIFT | gen8_tiling_bits(bo->tiling) | format << SURFACE_FORMAT_SHIFT | SURFACE_VALIGN_4 | SURFACE_HALIGN_4); if (is_dst) { ss[0] |= SURFACE_RC_READ_WRITE; domains = I915_GEM_DOMAIN_RENDER << 16 |I915_GEM_DOMAIN_RENDER; } else domains = I915_GEM_DOMAIN_SAMPLER << 16; ss[1] = (is_dst && is_uncached(sna, bo)) ? 0 : is_scanout ? (MOCS_WT | MOCS_ALL_CACHES) << 24 : (MOCS_WB | MOCS_ALL_CACHES) << 24; ss[2] = ((width - 1) << SURFACE_WIDTH_SHIFT | (height - 1) << SURFACE_HEIGHT_SHIFT); ss[3] = (bo->pitch - 1) << SURFACE_PITCH_SHIFT; ss[4] = 0; ss[5] = 0; ss[6] = 0; ss[7] = SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA); *(uint64_t *)(ss+8) = kgem_add_reloc64(&sna->kgem, offset + 8, bo, domains, 0); ss[10] = 0; ss[11] = 0; ss[12] = 0; ss[13] = 0; ss[14] = 0; ss[15] = 0; kgem_bo_set_binding(bo, format | is_dst << 30 | is_scanout << 31, offset); DBG(("[%x] bind bo(handle=%d, addr=%lx), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n", offset, bo->handle, *(uint64_t *)(ss+8), format, width, height, bo->pitch, bo->tiling, domains & 0xffff ? "render" : "sampler")); return offset * sizeof(uint32_t); } static void gen8_emit_vertex_buffer(struct sna *sna, const struct sna_composite_op *op) { int id = GEN8_VERTEX(op->u.gen8.flags); OUT_BATCH(GEN8_3DSTATE_VERTEX_BUFFERS | (5 - 2)); OUT_BATCH(id << VB_INDEX_SHIFT | VB_MODIFY_ENABLE | 4*op->floats_per_vertex); sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch; OUT_BATCH64(0); OUT_BATCH(~0); /* buffer size: disabled */ sna->render.vb_id |= 1 << id; } static void gen8_emit_primitive(struct sna *sna) { if (sna->kgem.nbatch == sna->render_state.gen8.last_primitive) { sna->render.vertex_offset = sna->kgem.nbatch - 5; return; } OUT_BATCH(GEN8_3DPRIMITIVE | (7 - 2)); OUT_BATCH(0); /* ignored, see VF_TOPOLOGY */ sna->render.vertex_offset = sna->kgem.nbatch; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(sna->render.vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ sna->render.vertex_start = sna->render.vertex_index; sna->render_state.gen8.last_primitive = sna->kgem.nbatch; } static bool gen8_rectangle_begin(struct sna *sna, const struct sna_composite_op *op) { int id = 1 << GEN8_VERTEX(op->u.gen8.flags); int ndwords; if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) return true; ndwords = op->need_magic_ca_pass ? 60 : 6; if ((sna->render.vb_id & id) == 0) ndwords += 5; if (!kgem_check_batch(&sna->kgem, ndwords)) return false; if ((sna->render.vb_id & id) == 0) gen8_emit_vertex_buffer(sna, op); gen8_emit_primitive(sna); return true; } static int gen8_get_rectangles__flush(struct sna *sna, const struct sna_composite_op *op) { /* Preventing discarding new vbo after lock contention */ if (sna_vertex_wait__locked(&sna->render)) { int rem = vertex_space(sna); if (rem > op->floats_per_rect) return rem; } if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 6)) return 0; if (!kgem_check_reloc_and_exec(&sna->kgem, 2)) return 0; if (sna->render.vertex_offset) { gen8_vertex_flush(sna); if (gen8_magic_ca_pass(sna, op)) { gen8_emit_pipe_invalidate(sna); gen8_emit_cc(sna, GEN8_BLEND(op->u.gen8.flags)); gen8_emit_wm(sna, GEN8_KERNEL(op->u.gen8.flags)); } } return gen8_vertex_finish(sna); } inline static int gen8_get_rectangles(struct sna *sna, const struct sna_composite_op *op, int want, void (*emit_state)(struct sna *sna, const struct sna_composite_op *op)) { int rem; assert(want); start: rem = vertex_space(sna); if (unlikely(rem < op->floats_per_rect)) { DBG(("flushing vbo for %s: %d < %d\n", __FUNCTION__, rem, op->floats_per_rect)); rem = gen8_get_rectangles__flush(sna, op); if (unlikely(rem == 0)) goto flush; } if (unlikely(sna->render.vertex_offset == 0)) { if (!gen8_rectangle_begin(sna, op)) goto flush; else goto start; } assert(rem <= vertex_space(sna)); assert(op->floats_per_rect <= rem); if (want > 1 && want * op->floats_per_rect > rem) want = rem / op->floats_per_rect; assert(want > 0); sna->render.vertex_index += 3*want; return want; flush: if (sna->render.vertex_offset) { gen8_vertex_flush(sna); gen8_magic_ca_pass(sna, op); } sna_vertex_wait__locked(&sna->render); _kgem_submit(&sna->kgem); emit_state(sna, op); goto start; } inline static uint32_t *gen8_composite_get_binding_table(struct sna *sna, uint16_t *offset) { uint32_t *table; assert(sna->kgem.surface <= 16384); sna->kgem.surface -= SURFACE_DW; /* Clear all surplus entries to zero in case of prefetch */ table = memset(sna->kgem.batch + sna->kgem.surface, 0, 64); DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface)); *offset = sna->kgem.surface; return table; } static void gen8_get_batch(struct sna *sna, const struct sna_composite_op *op) { kgem_set_mode(&sna->kgem, KGEM_RENDER, op->dst.bo); if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 2*(1+3))) { DBG(("%s: flushing batch: %d < %d+%d\n", __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch, 150, 4*8*2)); _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } assert(sna->kgem.mode == KGEM_RENDER); assert(sna->kgem.ring == KGEM_RENDER); if (sna->render_state.gen8.needs_invariant) gen8_emit_invariant(sna); } static void gen8_emit_composite_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen8_get_batch(sna, op); binding_table = gen8_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen8_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen8_get_dest_format(op->dst.format), true); binding_table[1] = gen8_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (op->mask.bo) { binding_table[2] = gen8_bind_bo(sna, op->mask.bo, op->mask.width, op->mask.height, op->mask.card_format, false); } if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen8.surface_table) == *(uint64_t*)binding_table && (op->mask.bo == NULL || sna->kgem.batch[sna->render_state.gen8.surface_table+2] == binding_table[2])) { sna->kgem.surface += SURFACE_DW; offset = sna->render_state.gen8.surface_table; } if (sna->kgem.batch[sna->render_state.gen8.surface_table] == binding_table[0]) dirty = 0; gen8_emit_state(sna, op, offset | dirty); } static void gen8_align_vertex(struct sna *sna, const struct sna_composite_op *op) { if (op->floats_per_vertex != sna->render_state.gen8.floats_per_vertex) { DBG(("aligning vertex: was %d, now %d floats per vertex\n", sna->render_state.gen8.floats_per_vertex, op->floats_per_vertex)); gen8_vertex_align(sna, op); sna->render_state.gen8.floats_per_vertex = op->floats_per_vertex; } } fastcall static void gen8_render_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { gen8_get_rectangles(sna, op, 1, gen8_emit_composite_state); op->prim_emit(sna, op, r); } fastcall static void gen8_render_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; gen8_get_rectangles(sna, op, 1, gen8_emit_composite_state); DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); } static void gen8_render_composite_boxes__blt(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("composite_boxes(%d)\n", nbox)); do { int nbox_this_time; nbox_this_time = gen8_get_rectangles(sna, op, nbox, gen8_emit_composite_state); nbox -= nbox_this_time; do { struct sna_composite_rectangles r; DBG((" %s: (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); r.dst.x = box->x1; r.dst.y = box->y1; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; r.src = r.mask = r.dst; op->prim_emit(sna, op, &r); box++; } while (--nbox_this_time); } while (nbox); } static void gen8_render_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { int nbox_this_time; float *v; nbox_this_time = gen8_get_rectangles(sna, op, nbox, gen8_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; } while (nbox); } static void gen8_render_composite_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen8_get_rectangles(sna, op, nbox, gen8_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } static uint32_t gen8_create_blend_state(struct sna_static_stream *stream) { char *base, *ptr; int src, dst; COMPILE_TIME_ASSERT(((GEN8_BLENDFACTOR_COUNT * GEN8_BLENDFACTOR_COUNT << 4) & (1 << 15)) == 0); base = sna_static_stream_map(stream, GEN8_BLENDFACTOR_COUNT * GEN8_BLENDFACTOR_COUNT * GEN8_BLEND_STATE_PADDED_SIZE, 64); ptr = base; for (src = 0; src < GEN8_BLENDFACTOR_COUNT; src++) { for (dst = 0; dst < GEN8_BLENDFACTOR_COUNT; dst++) { struct gen8_blend_state *blend = (struct gen8_blend_state *)ptr; assert(((ptr - base) & 63) == 0); COMPILE_TIME_ASSERT(sizeof(blend->common) == 4); COMPILE_TIME_ASSERT(sizeof(blend->rt) == 8); COMPILE_TIME_ASSERT((char *)&blend->rt - (char *)blend == 4); blend->rt.post_blend_clamp = 1; blend->rt.pre_blend_clamp = 1; blend->rt.color_blend = !(dst == BLENDFACTOR_ZERO && src == BLENDFACTOR_ONE); blend->rt.dest_blend_factor = dst; blend->rt.source_blend_factor = src; blend->rt.color_blend_function = BLENDFUNCTION_ADD; blend->rt.dest_alpha_blend_factor = dst; blend->rt.source_alpha_blend_factor = src; blend->rt.alpha_blend_function = BLENDFUNCTION_ADD; ptr += GEN8_BLEND_STATE_PADDED_SIZE; } } return sna_static_stream_offsetof(stream, base); } static int gen8_composite_picture(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int x, int y, int w, int h, int dst_x, int dst_y, bool precise) { PixmapPtr pixmap; uint32_t color; int16_t dx, dy; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); channel->is_solid = false; channel->card_format = -1; if (sna_picture_is_solid(picture, &color)) return gen4_channel_init_solid(sna, channel, color); if (picture->pDrawable == NULL) { int ret; if (picture->pSourcePict->type == SourcePictTypeLinear) return gen4_channel_init_linear(sna, picture, channel, x, y, w, h, dst_x, dst_y); DBG(("%s -- fixup, gradient\n", __FUNCTION__)); ret = -1; if (!precise) ret = sna_render_picture_approximate_gradient(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (ret == -1) ret = sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); return ret; } if (picture->alphaMap) { DBG(("%s -- fallback, alphamap\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } if (!gen8_check_repeat(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); if (!gen8_check_filter(picture)) return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); channel->repeat = picture->repeat ? picture->repeatType : RepeatNone; channel->filter = picture->filter; pixmap = get_drawable_pixmap(picture->pDrawable); get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy); x += dx + picture->pDrawable->x; y += dy + picture->pDrawable->y; channel->is_affine = sna_transform_is_affine(picture->transform); if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) { DBG(("%s: integer translation (%d, %d), removing\n", __FUNCTION__, dx, dy)); x += dx; y += dy; channel->transform = NULL; channel->filter = PictFilterNearest; if (channel->repeat || (x >= 0 && y >= 0 && x + w <= pixmap->drawable.width && y + h <= pixmap->drawable.height)) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear) { DBG(("%s: converting large pixmap source into solid [%08x]\n", __FUNCTION__, priv->clear_color)); return gen4_channel_init_solid(sna, channel, solid_color(picture->format, priv->clear_color)); } } } else channel->transform = picture->transform; channel->pict_format = picture->format; channel->card_format = gen8_get_card_format(picture->format); if (channel->card_format == (unsigned)-1) return sna_render_picture_convert(sna, picture, channel, pixmap, x, y, w, h, dst_x, dst_y, false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); return sna_render_picture_extract(sna, picture, channel, x, y, w, h, dst_x, dst_y); } return sna_render_pixmap_bo(sna, channel, pixmap, x, y, w, h, dst_x, dst_y); } inline static bool gen8_composite_channel_convert(struct sna_composite_channel *channel) { if (unaligned(channel->bo, PICT_FORMAT_BPP(channel->pict_format))) return false; channel->repeat = gen8_repeat(channel->repeat); channel->filter = gen8_filter(channel->filter); if (channel->card_format == (unsigned)-1) channel->card_format = gen8_get_card_format(channel->pict_format); assert(channel->card_format != (unsigned)-1); return true; } static void gen8_render_composite_done(struct sna *sna, const struct sna_composite_op *op) { if (sna->render.vertex_offset) { gen8_vertex_flush(sna); gen8_magic_ca_pass(sna, op); } if (op->mask.bo) kgem_bo_destroy(&sna->kgem, op->mask.bo); if (op->src.bo) kgem_bo_destroy(&sna->kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } inline static bool gen8_composite_set_target(struct sna *sna, struct sna_composite_op *op, PicturePtr dst, int x, int y, int w, int h, bool partial) { BoxRec box; unsigned int hint; DBG(("%s: (%d, %d)x(%d, %d), partial?=%d\n", __FUNCTION__, x, y, w, h, partial)); op->dst.pixmap = get_drawable_pixmap(dst->pDrawable); op->dst.format = dst->format; op->dst.width = op->dst.pixmap->drawable.width; op->dst.height = op->dst.pixmap->drawable.height; if (w | h) { assert(w && h); box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; } else sna_render_picture_extents(dst, &box); hint = PREFER_GPU | FORCE_GPU | RENDER_GPU; if (!partial) { hint |= IGNORE_DAMAGE; if (w == op->dst.width && h == op->dst.height) hint |= REPLACES; } op->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &box, &op->damage); if (op->dst.bo == NULL) return false; if (unaligned(op->dst.bo, dst->pDrawable->bitsPerPixel)) return false; if (hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } get_drawable_deltas(dst->pDrawable, op->dst.pixmap, &op->dst.x, &op->dst.y); DBG(("%s: pixmap=%ld, format=%08x, size=%dx%d, pitch=%d, delta=(%d,%d),damage=%p\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, (int)op->dst.format, op->dst.width, op->dst.height, op->dst.bo->pitch, op->dst.x, op->dst.y, op->damage ? *op->damage : (void *)-1)); assert(op->dst.bo->proxy == NULL); if (too_large(op->dst.width, op->dst.height) && !sna_render_composite_redirect(sna, op, x, y, w, h, partial)) return false; return true; } static bool try_blt(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { struct kgem_bo *bo; if (sna->kgem.mode == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } if (too_large(width, height)) { DBG(("%s: operation too large for 3D pipe (%d, %d)\n", __FUNCTION__, width, height)); goto execute; } bo = __sna_drawable_peek_bo(dst->pDrawable); if (bo == NULL) goto execute; if (untiled_tlb_miss(bo)) goto execute; if (bo->rq) { if (RQ_IS_BLT(bo->rq)) goto execute; return false; } if (bo->tiling == I915_TILING_Y) goto upload; if (sna_picture_is_solid(src, NULL) && can_switch_to_blt(sna, bo, 0)) goto execute; if (src->pDrawable == dst->pDrawable && (sna->render_state.gt < 3 || width*height < 1024) && can_switch_to_blt(sna, bo, 0)) goto execute; if (src->pDrawable) { struct kgem_bo *s = __sna_drawable_peek_bo(src->pDrawable); if (s == NULL) goto upload; if (prefer_blt_bo(sna, s, bo)) goto execute; } if (sna->kgem.ring == KGEM_BLT) { DBG(("%s: already performing BLT\n", __FUNCTION__)); goto execute; } upload: flags |= COMPOSITE_UPLOAD; execute: return sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } static bool check_gradient(PicturePtr picture, bool precise) { if (picture->pDrawable) return false; switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return precise; } } static bool has_alphamap(PicturePtr p) { return p->alphaMap != NULL; } static bool need_upload(PicturePtr p) { return p->pDrawable && unattached(p->pDrawable) && untransformed(p); } static bool source_is_busy(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL || priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; return priv->gpu_damage && !priv->cpu_damage; } static bool source_fallback(PicturePtr p, PixmapPtr pixmap, bool precise) { if (sna_picture_is_solid(p, NULL)) return false; if (p->pSourcePict) return check_gradient(p, precise); if (!gen8_check_repeat(p) || !gen8_check_format(p->format)) return true; if (pixmap && source_is_busy(pixmap)) return false; return has_alphamap(p) || !gen8_check_filter(p) || need_upload(p); } static bool gen8_composite_fallback(struct sna *sna, PicturePtr src, PicturePtr mask, PicturePtr dst) { PixmapPtr src_pixmap; PixmapPtr mask_pixmap; PixmapPtr dst_pixmap; bool src_fallback, mask_fallback; if (!gen8_check_dst_format(dst->format)) { DBG(("%s: unknown destination format: %d\n", __FUNCTION__, dst->format)); return true; } dst_pixmap = get_drawable_pixmap(dst->pDrawable); src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL; src_fallback = source_fallback(src, src_pixmap, dst->polyMode == PolyModePrecise); if (mask) { mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL; mask_fallback = source_fallback(mask, mask_pixmap, dst->polyMode == PolyModePrecise); } else { mask_pixmap = NULL; mask_fallback = false; } /* If we are using the destination as a source and need to * readback in order to upload the source, do it all * on the cpu. */ if (src_pixmap == dst_pixmap && src_fallback) { DBG(("%s: src is dst and will fallback\n",__FUNCTION__)); return true; } if (mask_pixmap == dst_pixmap && mask_fallback) { DBG(("%s: mask is dst and will fallback\n",__FUNCTION__)); return true; } /* If anything is on the GPU, push everything out to the GPU */ if (dst_use_gpu(dst_pixmap)) { DBG(("%s: dst is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (src_pixmap && !src_fallback) { DBG(("%s: src is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } if (mask_pixmap && !mask_fallback) { DBG(("%s: mask is already on the GPU, try to use GPU\n", __FUNCTION__)); return false; } /* However if the dst is not on the GPU and we need to * render one of the sources using the CPU, we may * as well do the entire operation in place onthe CPU. */ if (src_fallback) { DBG(("%s: dst is on the CPU and src will fallback\n", __FUNCTION__)); return true; } if (mask && mask_fallback) { DBG(("%s: dst is on the CPU and mask will fallback\n", __FUNCTION__)); return true; } if (too_large(dst_pixmap->drawable.width, dst_pixmap->drawable.height) && dst_is_cpu(dst_pixmap)) { DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__)); return true; } DBG(("%s: dst is not on the GPU and the operation should not fallback\n", __FUNCTION__)); return dst_use_cpu(dst_pixmap); } static int reuse_source(struct sna *sna, PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y, PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y) { uint32_t color; if (src_x != msk_x || src_y != msk_y) return false; if (src == mask) { DBG(("%s: mask is source\n", __FUNCTION__)); *mc = *sc; mc->bo = kgem_bo_reference(mc->bo); return true; } if (sna_picture_is_solid(mask, &color)) return gen4_channel_init_solid(sna, mc, color); if (sc->is_solid) return false; if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable) return false; DBG(("%s: mask reuses source drawable\n", __FUNCTION__)); if (!sna_transform_equal(src->transform, mask->transform)) return false; if (!sna_picture_alphamap_equal(src, mask)) return false; if (!gen8_check_repeat(mask)) return false; if (!gen8_check_filter(mask)) return false; if (!gen8_check_format(mask->format)) return false; DBG(("%s: reusing source channel for mask with a twist\n", __FUNCTION__)); *mc = *sc; mc->repeat = gen8_repeat(mask->repeat ? mask->repeatType : RepeatNone); mc->filter = gen8_filter(mask->filter); mc->pict_format = mask->format; mc->card_format = gen8_get_card_format(mask->format); mc->bo = kgem_bo_reference(mc->bo); return true; } static bool gen8_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { if (op >= ARRAY_SIZE(gen8_blend_op)) return false; DBG(("%s: %dx%d, current mode=%d/%d\n", __FUNCTION__, width, height, sna->kgem.mode, sna->kgem.ring)); if (mask == NULL && try_blt(sna, op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, flags, tmp)) return true; if (gen8_composite_fallback(sna, src, mask, dst)) goto fallback; if (need_tiling(sna, width, height)) return sna_tiling_composite(op, src, mask, dst, src_x, src_y, msk_x, msk_y, dst_x, dst_y, width, height, tmp); if (op == PictOpClear && src == sna->clear) op = PictOpSrc; tmp->op = op; if (!gen8_composite_set_target(sna, tmp, dst, dst_x, dst_y, width, height, flags & COMPOSITE_PARTIAL || op > PictOpSrc)) goto fallback; switch (gen8_composite_picture(sna, src, &tmp->src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: /* Did we just switch rings to prepare the source? */ if (mask == NULL && (prefer_blt_composite(sna, tmp) || unaligned(tmp->src.bo, PICT_FORMAT_BPP(tmp->src.pict_format))) && sna_blt_composite__convert(sna, dst_x, dst_y, width, height, tmp)) return true; if (!gen8_composite_channel_convert(&tmp->src)) goto cleanup_src; break; } tmp->is_affine = tmp->src.is_affine; tmp->has_component_alpha = false; tmp->need_magic_ca_pass = false; tmp->mask.bo = NULL; tmp->mask.filter = SAMPLER_FILTER_NEAREST; tmp->mask.repeat = SAMPLER_EXTEND_NONE; if (mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) { tmp->has_component_alpha = true; /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (gen8_blend_op[op].src_alpha && (gen8_blend_op[op].src_blend != BLENDFACTOR_ZERO)) { if (op != PictOpOver) goto cleanup_src; tmp->need_magic_ca_pass = true; tmp->op = PictOpOutReverse; } } if (!reuse_source(sna, src, &tmp->src, src_x, src_y, mask, &tmp->mask, msk_x, msk_y)) { switch (gen8_composite_picture(sna, mask, &tmp->mask, msk_x, msk_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_src; case 0: if (!gen4_channel_init_solid(sna, &tmp->mask, 0)) goto cleanup_src; /* fall through to fixup */ case 1: if (!gen8_composite_channel_convert(&tmp->mask)) goto cleanup_mask; break; } } tmp->is_affine &= tmp->mask.is_affine; } tmp->u.gen8.flags = GEN8_SET_FLAGS(SAMPLER_OFFSET(tmp->src.filter, tmp->src.repeat, tmp->mask.filter, tmp->mask.repeat), gen8_get_blend(tmp->op, tmp->has_component_alpha, tmp->dst.format), gen8_choose_composite_kernel(tmp->op, tmp->mask.bo != NULL, tmp->has_component_alpha, tmp->is_affine), gen4_choose_composite_emitter(sna, tmp)); tmp->blt = gen8_render_composite_blt; tmp->box = gen8_render_composite_box; tmp->boxes = gen8_render_composite_boxes__blt; if (tmp->emit_boxes){ tmp->boxes = gen8_render_composite_boxes; tmp->thread_boxes = gen8_render_composite_boxes__thread; } tmp->done = gen8_render_composite_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->dst.bo, tmp->src.bo, tmp->mask.bo, NULL)) goto cleanup_mask; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, tmp); gen8_emit_composite_state(sna, tmp); return true; cleanup_mask: if (tmp->mask.bo) { kgem_bo_destroy(&sna->kgem, tmp->mask.bo); tmp->mask.bo = NULL; } cleanup_src: if (tmp->src.bo) { kgem_bo_destroy(&sna->kgem, tmp->src.bo); tmp->src.bo = NULL; } cleanup_dst: if (tmp->redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp->dst.bo); tmp->redirect.real_bo = NULL; } fallback: return (mask == NULL && sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp)); } #if !NO_COMPOSITE_SPANS fastcall static void gen8_render_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n", __FUNCTION__, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); gen8_get_rectangles(sna, &op->base, 1, gen8_emit_composite_state); op->prim_emit(sna, op, box, opacity); } static void gen8_render_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], opacity, op->base.dst.x, op->base.dst.y)); do { int nbox_this_time; nbox_this_time = gen8_get_rectangles(sna, &op->base, nbox, gen8_emit_composite_state); nbox -= nbox_this_time; do { DBG((" %s: (%d, %d) x (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); op->prim_emit(sna, op, box++, opacity); } while (--nbox_this_time); } while (nbox); } fastcall static void gen8_render_composite_spans_boxes__thread(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox) { DBG(("%s: nbox=%d, src=+(%d, %d), dst=+(%d, %d)\n", __FUNCTION__, nbox, op->base.src.offset[0], op->base.src.offset[1], op->base.dst.x, op->base.dst.y)); sna_vertex_lock(&sna->render); do { int nbox_this_time; float *v; nbox_this_time = gen8_get_rectangles(sna, &op->base, nbox, gen8_emit_composite_state); assert(nbox_this_time); nbox -= nbox_this_time; v = sna->render.vertices + sna->render.vertex_used; sna->render.vertex_used += nbox_this_time * op->base.floats_per_rect; sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); op->emit_boxes(op, box, nbox_this_time, v); box += nbox_this_time; sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); } while (nbox); sna_vertex_unlock(&sna->render); } fastcall static void gen8_render_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { if (sna->render.vertex_offset) gen8_vertex_flush(sna); DBG(("%s()\n", __FUNCTION__)); if (op->base.src.bo) kgem_bo_destroy(&sna->kgem, op->base.src.bo); sna_render_composite_redirect_done(sna, &op->base); } static bool gen8_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { if (op >= ARRAY_SIZE(gen8_blend_op)) return false; if (gen8_composite_fallback(sna, src, NULL, dst)) return false; if (need_tiling(sna, width, height) && !is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback, tiled operation not on GPU\n", __FUNCTION__)); return false; } return true; } static bool gen8_render_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__, width, height, flags, sna->kgem.ring)); assert(gen8_check_composite_spans(sna, op, src, dst, width, height, flags)); if (need_tiling(sna, width, height)) { DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n", __FUNCTION__, width, height)); return sna_tiling_composite_spans(op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags, tmp); } tmp->base.op = op; if (!gen8_composite_set_target(sna, &tmp->base, dst, dst_x, dst_y, width, height, true)) return false; switch (gen8_composite_picture(sna, src, &tmp->base.src, src_x, src_y, width, height, dst_x, dst_y, dst->polyMode == PolyModePrecise)) { case -1: goto cleanup_dst; case 0: if (!gen4_channel_init_solid(sna, &tmp->base.src, 0)) goto cleanup_dst; /* fall through to fixup */ case 1: if (!gen8_composite_channel_convert(&tmp->base.src)) goto cleanup_src; break; } tmp->base.mask.bo = NULL; tmp->base.is_affine = tmp->base.src.is_affine; tmp->base.need_magic_ca_pass = false; tmp->base.u.gen8.flags = GEN8_SET_FLAGS(SAMPLER_OFFSET(tmp->base.src.filter, tmp->base.src.repeat, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_PAD), gen8_get_blend(tmp->base.op, false, tmp->base.dst.format), GEN8_WM_KERNEL_OPACITY | !tmp->base.is_affine, gen4_choose_spans_emitter(sna, tmp)); tmp->box = gen8_render_composite_spans_box; tmp->boxes = gen8_render_composite_spans_boxes; if (tmp->emit_boxes) tmp->thread_boxes = gen8_render_composite_spans_boxes__thread; tmp->done = gen8_render_composite_spans_done; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->base.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp->base.dst.bo, tmp->base.src.bo, NULL)) goto cleanup_src; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &tmp->base); gen8_emit_composite_state(sna, &tmp->base); return true; cleanup_src: if (tmp->base.src.bo) kgem_bo_destroy(&sna->kgem, tmp->base.src.bo); cleanup_dst: if (tmp->base.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo); return false; } #endif static void gen8_emit_copy_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; gen8_get_batch(sna, op); binding_table = gen8_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen8_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen8_get_dest_format(op->dst.format), true); binding_table[1] = gen8_bind_bo(sna, op->src.bo, op->src.width, op->src.height, op->src.card_format, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen8.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += SURFACE_DW; offset = sna->render_state.gen8.surface_table; } if (sna->kgem.batch[sna->render_state.gen8.surface_table] == binding_table[0]) dirty = 0; assert(!GEN8_READS_DST(op->u.gen8.flags)); gen8_emit_state(sna, op, offset | dirty); } static inline bool prefer_blt_copy(struct sna *sna, struct kgem_bo *src_bo, struct kgem_bo *dst_bo, unsigned flags) { if (sna->kgem.mode == KGEM_BLT) return true; assert((flags & COPY_SYNC) == 0); if (untiled_tlb_miss(src_bo) || untiled_tlb_miss(dst_bo)) return true; if (flags & COPY_DRI && !sna->kgem.has_semaphores) return false; if (force_blt_ring(sna, dst_bo)) return true; if ((flags & COPY_SMALL || (sna->render_state.gt < 3 && src_bo == dst_bo)) && can_switch_to_blt(sna, dst_bo, flags)) return true; if (kgem_bo_is_render(dst_bo) || kgem_bo_is_render(src_bo)) return false; if (flags & COPY_LAST && sna->render_state.gt < 3 && can_switch_to_blt(sna, dst_bo, flags)) return true; if (prefer_render_ring(sna, dst_bo)) return false; if (!prefer_blt_ring(sna, dst_bo, flags)) return false; return prefer_blt_bo(sna, src_bo, dst_bo); } static bool gen8_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { struct sna_composite_op tmp; BoxRec extents; DBG(("%s (%d, %d)->(%d, %d) x %d, alu=%x, flags=%x, self-copy=%d, overlaps? %d\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n, alu, flags, src_bo == dst_bo, overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents))); if (prefer_blt_copy(sna, src_bo, dst_bo, flags) && sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (!(alu == GXcopy || alu == GXclear) || unaligned(src_bo, src->bitsPerPixel) || unaligned(dst_bo, dst->bitsPerPixel)) { fallback_blt: DBG(("%s: fallback blt\n", __FUNCTION__)); if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes_fallback(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } if (overlaps(sna, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, n, flags, &extents)) { bool big = too_large(extents.x2-extents.x1, extents.y2-extents.y1); if ((big || !prefer_render_ring(sna, dst_bo)) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; if (big) goto fallback_blt; assert(src_bo == dst_bo); assert(src->depth == dst->depth); assert(src->width == dst->width); assert(src->height == dst->height); return sna_render_copy_boxes__overlap(sna, alu, dst, dst_bo, src_dx, src_dy, dst_dx, dst_dy, box, n, &extents); } if (dst->depth == src->depth) { tmp.dst.format = sna_render_format_for_depth(dst->depth); tmp.src.pict_format = tmp.dst.format; } else { tmp.dst.format = sna_format_for_depth(dst->depth); tmp.src.pict_format = sna_format_for_depth(src->depth); } if (!gen8_check_format(tmp.src.pict_format)) goto fallback_blt; tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(tmp.dst.width, tmp.dst.height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_composite_redirect(sna, &tmp, extents.x1 + dst_dx, extents.y1 + dst_dy, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) goto fallback_tiled; } tmp.src.card_format = gen8_get_card_format(tmp.src.pict_format); if (too_large(src->width, src->height)) { int i; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src, extents.x1 + src_dx, extents.y1 + src_dy, extents.x2 - extents.x1, extents.y2 - extents.y1)) goto fallback_tiled_dst; } else { tmp.src.bo = src_bo; tmp.src.width = src->width; tmp.src.height = src->height; tmp.src.offset[0] = tmp.src.offset[1] = 0; } tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = 0; tmp.u.gen8.flags = COPY_FLAGS(alu); kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, tmp.src.bo, NULL)) { if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); goto fallback_blt; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } src_dx += tmp.src.offset[0]; src_dy += tmp.src.offset[1]; dst_dx += tmp.dst.x; dst_dy += tmp.dst.y; tmp.dst.x = tmp.dst.y = 0; gen8_align_vertex(sna, &tmp); gen8_emit_copy_state(sna, &tmp); do { int16_t *v; int n_this_time; n_this_time = gen8_get_rectangles(sna, &tmp, n, gen8_emit_copy_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d) -> (%d, %d) + (%d, %d)\n", box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1)); v[0] = box->x2 + dst_dx; v[2] = box->x2 + src_dx; v[1] = v[5] = box->y2 + dst_dy; v[3] = v[7] = box->y2 + src_dy; v[8] = v[4] = box->x1 + dst_dx; v[10] = v[6] = box->x1 + src_dx; v[9] = box->y1 + dst_dy; v[11] = box->y1 + src_dy; v += 12; box++; } while (--n_this_time); } while (n); gen8_vertex_flush(sna); sna_render_composite_redirect_done(sna, &tmp); if (tmp.src.bo != src_bo) kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; fallback_tiled_dst: if (tmp.redirect.real_bo) kgem_bo_destroy(&sna->kgem, tmp.dst.bo); fallback_tiled: DBG(("%s: fallback tiled\n", __FUNCTION__)); if (sna_blt_compare_depth(src, dst) && sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n)) return true; return sna_tiling_copy_boxes(sna, alu, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, box, n); } static void gen8_render_copy_blt(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy) { int16_t *v; gen8_get_rectangles(sna, &op->base, 1, gen8_emit_copy_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dx+w; v[1] = dy+h; v[2] = sx+w; v[3] = sy+h; v[4] = dx; v[5] = dy+h; v[6] = sx; v[7] = sy+h; v[8] = dx; v[9] = dy; v[10] = sx; v[11] = sy; } static void gen8_render_copy_done(struct sna *sna, const struct sna_copy_op *op) { if (sna->render.vertex_offset) gen8_vertex_flush(sna); } static bool gen8_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op) { DBG(("%s (alu=%d, src=(%dx%d), dst=(%dx%d))\n", __FUNCTION__, alu, src->drawable.width, src->drawable.height, dst->drawable.width, dst->drawable.height)); if (prefer_blt_copy(sna, src_bo, dst_bo, 0) && sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op)) return true; if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo || too_large(src->drawable.width, src->drawable.height) || too_large(dst->drawable.width, dst->drawable.height) || unaligned(src_bo, src->drawable.bitsPerPixel) || unaligned(dst_bo, dst->drawable.bitsPerPixel)) { fallback: if (!sna_blt_compare_depth(&src->drawable, &dst->drawable)) return false; return sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, op); } if (dst->drawable.depth == src->drawable.depth) { op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth); op->base.src.pict_format = op->base.dst.format; } else { op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.src.pict_format = sna_format_for_depth(src->drawable.depth); } if (!gen8_check_format(op->base.src.pict_format)) goto fallback; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.bo = dst_bo; op->base.src.bo = src_bo; op->base.src.card_format = gen8_get_card_format(op->base.src.pict_format); op->base.src.width = src->drawable.width; op->base.src.height = src->drawable.height; op->base.mask.bo = NULL; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen8.flags = COPY_FLAGS(alu); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) goto fallback; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &op->base); gen8_emit_copy_state(sna, &op->base); op->blt = gen8_render_copy_blt; op->done = gen8_render_copy_done; return true; } static void gen8_emit_fill_state(struct sna *sna, const struct sna_composite_op *op) { uint32_t *binding_table; uint16_t offset, dirty; /* XXX Render Target Fast Clear * Set RTFC Enable in PS and render a rectangle. * Limited to a clearing the full MSC surface only with a * specific kernel. */ gen8_get_batch(sna, op); binding_table = gen8_composite_get_binding_table(sna, &offset); dirty = kgem_bo_is_dirty(op->dst.bo); binding_table[0] = gen8_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen8_get_dest_format(op->dst.format), true); binding_table[1] = gen8_bind_bo(sna, op->src.bo, 1, 1, SURFACEFORMAT_B8G8R8A8_UNORM, false); if (sna->kgem.surface == offset && *(uint64_t *)(sna->kgem.batch + sna->render_state.gen8.surface_table) == *(uint64_t*)binding_table) { sna->kgem.surface += SURFACE_DW; offset = sna->render_state.gen8.surface_table; } if (sna->kgem.batch[sna->render_state.gen8.surface_table] == binding_table[0]) dirty = 0; gen8_emit_state(sna, op, offset | dirty); } static bool gen8_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { struct sna_composite_op tmp; uint32_t pixel; DBG(("%s (op=%d, color=(%04x, %04x, %04x, %04x) [%08x])\n", __FUNCTION__, op, color->red, color->green, color->blue, color->alpha, (int)format)); if (op >= ARRAY_SIZE(gen8_blend_op)) { DBG(("%s: fallback due to unhandled blend op: %d\n", __FUNCTION__, op)); return false; } if (prefer_blt_fill(sna, dst_bo, FILL_BOXES) || !gen8_check_dst_format(format) || unaligned(dst_bo, PICT_FORMAT_BPP(format))) { uint8_t alu = GXinvalid; if (op <= PictOpSrc) { pixel = 0; if (op == PictOpClear) alu = GXclear; else if (sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) alu = GXcopy; } if (alu != GXinvalid && sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n)) return true; if (!gen8_check_dst_format(format)) return false; } if (op == PictOpClear) { pixel = 0; op = PictOpSrc; } else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, PICT_a8r8g8b8)) return false; DBG(("%s(%08x x %d [(%d, %d), (%d, %d) ...])\n", __FUNCTION__, pixel, n, box[0].x1, box[0].y1, box[0].x2, box[0].y2)); tmp.dst.pixmap = (PixmapPtr)dst; tmp.dst.width = dst->width; tmp.dst.height = dst->height; tmp.dst.format = format; tmp.dst.bo = dst_bo; tmp.dst.x = tmp.dst.y = 0; tmp.damage = NULL; sna_render_composite_redirect_init(&tmp); if (too_large(dst->width, dst->height)) { BoxRec extents; boxes_extents(box, n, &extents); if (!sna_render_composite_redirect(sna, &tmp, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, n > 1)) return sna_tiling_fill_boxes(sna, op, format, color, dst, dst_bo, box, n); } tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen8.flags = FILL_FLAGS(op, format); kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); tmp.src.bo = NULL; if (tmp.redirect.real_bo) { kgem_bo_destroy(&sna->kgem, tmp.dst.bo); tmp.redirect.real_bo = NULL; } return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &tmp); gen8_emit_fill_state(sna, &tmp); do { int n_this_time; int16_t *v; n_this_time = gen8_get_rectangles(sna, &tmp, n, gen8_emit_fill_state); n -= n_this_time; v = (int16_t *)(sna->render.vertices + sna->render.vertex_used); sna->render.vertex_used += 6 * n_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { DBG((" (%d, %d), (%d, %d)\n", box->x1, box->y1, box->x2, box->y2)); v[0] = box->x2; v[5] = v[1] = box->y2; v[8] = v[4] = box->x1; v[9] = box->y1; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; v += 12; box++; } while (--n_this_time); } while (n); gen8_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); sna_render_composite_redirect_done(sna, &tmp); return true; } static void gen8_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h) { int16_t *v; DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); gen8_get_rectangles(sna, &op->base, 1, gen8_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x+w; v[4] = v[8] = x; v[1] = v[5] = y+h; v[9] = y; v[2] = v[3] = v[7] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen8_render_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { int16_t *v; DBG(("%s: (%d, %d),(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); gen8_get_rectangles(sna, &op->base, 1, gen8_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; } fastcall static void gen8_render_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { DBG(("%s: (%d, %d),(%d, %d)... x %d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, nbox)); do { int nbox_this_time; int16_t *v; nbox_this_time = gen8_get_rectangles(sna, &op->base, nbox, gen8_emit_fill_state); nbox -= nbox_this_time; v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6 * nbox_this_time; assert(sna->render.vertex_used <= sna->render.vertex_size); do { v[0] = box->x2; v[8] = v[4] = box->x1; v[5] = v[1] = box->y2; v[9] = box->y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; box++; v += 12; } while (--nbox_this_time); } while (nbox); } static void gen8_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op) { if (sna->render.vertex_offset) gen8_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, op->base.src.bo); } static bool gen8_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *op) { DBG(("%s: (alu=%d, color=%x)\n", __FUNCTION__, alu, color)); if (prefer_blt_fill(sna, dst_bo, flags) && sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op)) return true; if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height) || unaligned(dst_bo, dst->drawable.bitsPerPixel)) return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, op); if (alu == GXclear) color = 0; op->base.dst.pixmap = dst; op->base.dst.width = dst->drawable.width; op->base.dst.height = dst->drawable.height; op->base.dst.format = sna_format_for_depth(dst->drawable.depth); op->base.dst.bo = dst_bo; op->base.dst.x = op->base.dst.y = 0; op->base.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); op->base.mask.bo = NULL; op->base.need_magic_ca_pass = false; op->base.floats_per_vertex = 2; op->base.floats_per_rect = 6; op->base.u.gen8.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_bo_destroy(&sna->kgem, op->base.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &op->base); gen8_emit_fill_state(sna, &op->base); op->blt = gen8_render_fill_op_blt; op->box = gen8_render_fill_op_box; op->boxes = gen8_render_fill_op_boxes; op->points = NULL; op->done = gen8_render_fill_op_done; return true; } static bool gen8_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool gen8_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { struct sna_composite_op tmp; int16_t *v; /* Prefer to use the BLT if already engaged */ if (prefer_blt_fill(sna, bo, FILL_BOXES) && gen8_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu)) return true; /* Must use the BLT if we can't RENDER... */ if (!(alu == GXcopy || alu == GXclear) || too_large(dst->drawable.width, dst->drawable.height) || unaligned(bo, dst->drawable.bitsPerPixel)) return gen8_render_fill_one_try_blt(sna, dst, bo, color, x1, y1, x2, y2, alu); if (alu == GXclear) color = 0; tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, sna_rgba_for_color(color, dst->drawable.depth)); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen8.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &tmp); gen8_emit_fill_state(sna, &tmp); gen8_get_rectangles(sna, &tmp, 1, gen8_emit_fill_state); DBG((" (%d, %d), (%d, %d)\n", x1, y1, x2, y2)); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = x2; v[8] = v[4] = x1; v[5] = v[1] = y2; v[9] = y1; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen8_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } static bool gen8_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = dst->drawable.width; box.y2 = dst->drawable.height; return sna_blt_fill_boxes(sna, GXclear, bo, dst->drawable.bitsPerPixel, 0, &box, 1); } static bool gen8_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { struct sna_composite_op tmp; int16_t *v; DBG(("%s: %dx%d\n", __FUNCTION__, dst->drawable.width, dst->drawable.height)); /* Prefer to use the BLT if already engaged */ if (sna->kgem.mode == KGEM_BLT && gen8_render_clear_try_blt(sna, dst, bo)) return true; /* Must use the BLT if we can't RENDER... */ if (too_large(dst->drawable.width, dst->drawable.height) || unaligned(bo, dst->drawable.bitsPerPixel)) return gen8_render_clear_try_blt(sna, dst, bo); tmp.dst.pixmap = dst; tmp.dst.width = dst->drawable.width; tmp.dst.height = dst->drawable.height; tmp.dst.format = sna_format_for_depth(dst->drawable.depth); tmp.dst.bo = bo; tmp.dst.x = tmp.dst.y = 0; tmp.src.bo = sna_render_get_solid(sna, 0); tmp.mask.bo = NULL; tmp.floats_per_vertex = 2; tmp.floats_per_rect = 6; tmp.need_magic_ca_pass = false; tmp.u.gen8.flags = FILL_FLAGS_NOBLEND; kgem_set_mode(&sna->kgem, KGEM_RENDER, bo); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, bo, NULL)) { kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; } _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &tmp); gen8_emit_fill_state(sna, &tmp); gen8_get_rectangles(sna, &tmp, 1, gen8_emit_fill_state); v = (int16_t *)&sna->render.vertices[sna->render.vertex_used]; sna->render.vertex_used += 6; assert(sna->render.vertex_used <= sna->render.vertex_size); v[0] = dst->drawable.width; v[5] = v[1] = dst->drawable.height; v[8] = v[4] = 0; v[9] = 0; v[7] = v[2] = v[3] = 1; v[6] = v[10] = v[11] = 0; gen8_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); return true; } #if !NO_VIDEO static uint32_t gen8_bind_video_source(struct sna *sna, struct kgem_bo *bo, uint32_t delta, int width, int height, int pitch, uint32_t format) { uint32_t *ss; int offset; offset = sna->kgem.surface -= SURFACE_DW; ss = sna->kgem.batch + offset; ss[0] = (SURFACE_2D << SURFACE_TYPE_SHIFT | gen8_tiling_bits(bo->tiling) | format << SURFACE_FORMAT_SHIFT | SURFACE_VALIGN_4 | SURFACE_HALIGN_4); ss[1] = 0; ss[2] = ((width - 1) << SURFACE_WIDTH_SHIFT | (height - 1) << SURFACE_HEIGHT_SHIFT); ss[3] = (pitch - 1) << SURFACE_PITCH_SHIFT; ss[4] = 0; ss[5] = 0; ss[6] = 0; ss[7] = SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA); *(uint64_t *)(ss+8) = kgem_add_reloc64(&sna->kgem, offset + 8, bo, I915_GEM_DOMAIN_SAMPLER << 16, delta); ss[10] = 0; ss[11] = 0; ss[12] = 0; ss[13] = 0; ss[14] = 0; ss[15] = 0; DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> sampler\n", offset, bo->handle, ss[1], format, width, height, bo->pitch, bo->tiling)); return offset * sizeof(uint32_t); } static void gen8_emit_video_state(struct sna *sna, const struct sna_composite_op *op) { struct sna_video_frame *frame = op->priv; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; uint32_t *binding_table; uint16_t offset; int n_src, n; /* XXX VeBox, bicubic */ gen8_get_batch(sna, op); src_surf_base[0] = 0; src_surf_base[1] = 0; src_surf_base[2] = frame->VBufOffset; src_surf_base[3] = frame->VBufOffset; src_surf_base[4] = frame->UBufOffset; src_surf_base[5] = frame->UBufOffset; if (is_planar_fourcc(frame->id)) { src_surf_format = SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = frame->width; src_height[1] = src_height[0] = frame->height; src_pitch[1] = src_pitch[0] = frame->pitch[1]; src_width[4] = src_width[5] = src_width[2] = src_width[3] = frame->width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = frame->height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = frame->pitch[0]; n_src = 6; } else { if (frame->id == FOURCC_UYVY) src_surf_format = SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = frame->width; src_height[0] = frame->height; src_pitch[0] = frame->pitch[0]; n_src = 1; } binding_table = gen8_composite_get_binding_table(sna, &offset); binding_table[0] = gen8_bind_bo(sna, op->dst.bo, op->dst.width, op->dst.height, gen8_get_dest_format(op->dst.format), true); for (n = 0; n < n_src; n++) { binding_table[1+n] = gen8_bind_video_source(sna, frame->bo, src_surf_base[n], src_width[n], src_height[n], src_pitch[n], src_surf_format); } gen8_emit_state(sna, op, offset); } static bool gen8_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap) { struct sna_composite_op tmp; struct sna_pixmap *priv = sna_pixmap(pixmap); int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; int src_width = frame->src.x2 - frame->src.x1; int src_height = frame->src.y2 - frame->src.y1; float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; unsigned filter; const BoxRec *box; int nbox; DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n", __FUNCTION__, src_width, src_height, dst_width, dst_height, region_num_rects(dstRegion), REGION_EXTENTS(NULL, dstRegion)->x1, REGION_EXTENTS(NULL, dstRegion)->y1, REGION_EXTENTS(NULL, dstRegion)->x2, REGION_EXTENTS(NULL, dstRegion)->y2)); assert(priv->gpu_bo); assert(!too_large(pixmap->drawable.width, pixmap->drawable.height)); assert(!unaligned(priv->gpu_bo, pixmap->drawable.bitsPerPixel)); memset(&tmp, 0, sizeof(tmp)); tmp.dst.pixmap = pixmap; tmp.dst.width = pixmap->drawable.width; tmp.dst.height = pixmap->drawable.height; tmp.dst.format = sna_render_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; tmp.src.bo = frame->bo; tmp.mask.bo = NULL; tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; if (src_width == dst_width && src_height == dst_height) filter = SAMPLER_FILTER_NEAREST; else filter = SAMPLER_FILTER_BILINEAR; tmp.u.gen8.flags = GEN8_SET_FLAGS(SAMPLER_OFFSET(filter, SAMPLER_EXTEND_PAD, SAMPLER_FILTER_NEAREST, SAMPLER_EXTEND_NONE), NO_BLEND, is_planar_fourcc(frame->id) ? GEN8_WM_KERNEL_VIDEO_PLANAR : GEN8_WM_KERNEL_VIDEO_PACKED, 2); tmp.priv = frame; kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) return false; _kgem_set_mode(&sna->kgem, KGEM_RENDER); } gen8_align_vertex(sna, &tmp); gen8_emit_video_state(sna, &tmp); DBG(("%s: src=(%d, %d)x(%d, %d); frame=(%dx%d), dst=(%dx%d)\n", __FUNCTION__, frame->src.x1, frame->src.y1, src_width, src_height, dst_width, dst_height, frame->width, frame->height)); src_scale_x = (float)src_width / dst_width / frame->width; src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; src_scale_y = (float)src_height / dst_height / frame->height; src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; DBG(("%s: scale=(%f, %f), offset=(%f, %f)\n", __FUNCTION__, src_scale_x, src_scale_y, src_offset_x, src_offset_y)); box = region_rects(dstRegion); nbox = region_num_rects(dstRegion); while (nbox--) { DBG(("%s: dst=(%d, %d), (%d, %d) + (%d, %d); src=(%f, %f), (%f, %f)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, box->x1 * src_scale_x + src_offset_x, box->y1 * src_scale_y + src_offset_y, box->x2 * src_scale_x + src_offset_x, box->y2 * src_scale_y + src_offset_y)); gen8_get_rectangles(sna, &tmp, 1, gen8_emit_video_state); OUT_VERTEX(box->x2, box->y2); OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y2); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(box->x1, box->y1); OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); box++; } gen8_vertex_flush(sna); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add(&priv->gpu_damage, dstRegion); return true; } #endif static void gen8_render_flush(struct sna *sna) { gen8_vertex_close(sna); assert(sna->render.vb_id == 0); assert(sna->render.vertex_offset == 0); } static void gen8_render_reset(struct sna *sna) { sna->render_state.gen8.emit_flush = false; sna->render_state.gen8.needs_invariant = true; sna->render_state.gen8.ve_id = 3 << 2; sna->render_state.gen8.last_primitive = -1; sna->render_state.gen8.num_sf_outputs = 0; sna->render_state.gen8.samplers = -1; sna->render_state.gen8.blend = -1; sna->render_state.gen8.kernel = -1; sna->render_state.gen8.drawrect_offset = -1; sna->render_state.gen8.drawrect_limit = -1; sna->render_state.gen8.surface_table = 0; if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); discard_vbo(sna); } sna->render.vertex_offset = 0; sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; } static void gen8_render_fini(struct sna *sna) { kgem_bo_destroy(&sna->kgem, sna->render_state.gen8.general_bo); } static bool gen8_render_setup(struct sna *sna) { struct gen8_render_state *state = &sna->render_state.gen8; struct sna_static_stream general; struct gen8_sampler_state *ss; int i, j, k, l, m; uint32_t devid; devid = intel_get_device_id(sna->dev); if (devid & 0xf) state->gt = ((devid >> 4) & 0xf) + 1; DBG(("%s: gt=%d\n", __FUNCTION__, state->gt)); if (is_bdw(sna)) state->info = &bdw_gt_info; else if (is_chv(sna)) state->info = &chv_gt_info; else return false; sna_static_stream_init(&general); /* Zero pad the start. If you see an offset of 0x0 in the batchbuffer * dumps, you know it points to zero. */ null_create(&general); for (m = 0; m < ARRAY_SIZE(wm_kernels); m++) { if (wm_kernels[m].size) { state->wm_kernel[m][1] = sna_static_stream_add(&general, wm_kernels[m].data, wm_kernels[m].size, 64); } else { if (USE_8_PIXEL_DISPATCH) { state->wm_kernel[m][0] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 8); } if (USE_16_PIXEL_DISPATCH) { state->wm_kernel[m][1] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 16); } if (USE_32_PIXEL_DISPATCH) { state->wm_kernel[m][2] = sna_static_stream_compile_wm(sna, &general, wm_kernels[m].data, 32); } } assert(state->wm_kernel[m][0]|state->wm_kernel[m][1]|state->wm_kernel[m][2]); } COMPILE_TIME_ASSERT(SAMPLER_OFFSET(FILTER_COUNT, EXTEND_COUNT, FILTER_COUNT, EXTEND_COUNT) <= 0x7ff); ss = sna_static_stream_map(&general, 2 * sizeof(*ss) * (2 + FILTER_COUNT * EXTEND_COUNT * FILTER_COUNT * EXTEND_COUNT), 32); state->wm_state = sna_static_stream_offsetof(&general, ss); sampler_copy_init(ss); ss += 2; sampler_fill_init(ss); ss += 2; for (i = 0; i < FILTER_COUNT; i++) { for (j = 0; j < EXTEND_COUNT; j++) { for (k = 0; k < FILTER_COUNT; k++) { for (l = 0; l < EXTEND_COUNT; l++) { sampler_state_init(ss++, i, j); sampler_state_init(ss++, k, l); } } } } state->cc_blend = gen8_create_blend_state(&general); state->general_bo = sna_static_stream_fini(sna, &general); return state->general_bo != NULL; } const char *gen8_render_init(struct sna *sna, const char *backend) { if (!gen8_render_setup(sna)) return backend; sna->kgem.context_switch = gen6_render_context_switch; sna->kgem.retire = gen6_render_retire; sna->kgem.expire = gen4_render_expire; #if !NO_COMPOSITE sna->render.composite = gen8_render_composite; sna->render.prefer_gpu |= PREFER_GPU_RENDER; #endif #if !NO_COMPOSITE_SPANS sna->render.check_composite_spans = gen8_check_composite_spans; sna->render.composite_spans = gen8_render_composite_spans; sna->render.prefer_gpu |= PREFER_GPU_SPANS; #endif #if !NO_VIDEO sna->render.video = gen8_render_video; #endif #if !NO_COPY_BOXES sna->render.copy_boxes = gen8_render_copy_boxes; #endif #if !NO_COPY sna->render.copy = gen8_render_copy; #endif #if !NO_FILL_BOXES sna->render.fill_boxes = gen8_render_fill_boxes; #endif #if !NO_FILL sna->render.fill = gen8_render_fill; #endif #if !NO_FILL_ONE sna->render.fill_one = gen8_render_fill_one; #endif #if !NO_FILL_CLEAR sna->render.clear = gen8_render_clear; #endif sna->render.flush = gen8_render_flush; sna->render.reset = gen8_render_reset; sna->render.fini = gen8_render_fini; sna->render.max_3d_size = GEN8_MAX_SIZE; sna->render.max_3d_pitch = 1 << 18; return sna->render_state.gen8.info->name; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_render.h000066400000000000000000001322371267532330400242240ustar00rootroot00000000000000#ifndef GEN8_RENDER_H #define GEN8_RENDER_H #define INTEL_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low)) #define GEN8_3D(pipeline,op,sub) \ ((3 << 29) | ((pipeline) << 27) | ((op) << 24) | ((sub) << 16)) #define GEN8_STATE_BASE_ADDRESS GEN8_3D(0, 1, 1) # define BASE_ADDRESS_MODIFY (1 << 0) #define GEN8_STATE_SIP GEN8_3D(0, 1, 2) #define GEN8_3DSTATE_VF_STATISTICS GEN8_3D(1, 0, 0xb) #define GEN8_PIPELINE_SELECT GEN8_3D(1, 1, 4) # define PIPELINE_SELECT_3D 0 # define PIPELINE_SELECT_MEDIA 1 #define GEN8_MEDIA_STATE_POINTERS GEN8_3D(2, 0, 0) #define GEN8_MEDIA_OBJECT GEN8_3D(2, 1, 0) #define GEN8_3DSTATE_CLEAR_PARAMS GEN8_3D(3, 0, 0x04) #define GEN8_3DSTATE_DEPTH_BUFFER GEN8_3D(3, 0, 0x05) # define DEPTH_BUFFER_TYPE_SHIFT 29 # define DEPTH_BUFFER_FORMAT_SHIFT 18 #define GEN8_3DSTATE_STENCIL_BUFFER GEN8_3D(3, 0, 0x06) #define GEN8_3DSTATE_HIER_DEPTH_BUFFER GEN8_3D(3, 0, 0x07) #define GEN8_3DSTATE_VERTEX_BUFFERS GEN8_3D(3, 0, 0x08) # define VB_INDEX_SHIFT 26 # define VB_MODIFY_ENABLE (1 << 14) #define GEN8_3DSTATE_VERTEX_ELEMENTS GEN8_3D(3, 0, 0x09) # define VE_INDEX_SHIFT 26 # define VE_VALID (1 << 25) # define VE_FORMAT_SHIFT 16 # define VE_OFFSET_SHIFT 0 # define VE_COMPONENT_0_SHIFT 28 # define VE_COMPONENT_1_SHIFT 24 # define VE_COMPONENT_2_SHIFT 20 # define VE_COMPONENT_3_SHIFT 16 #define GEN8_3DSTATE_INDEX_BUFFER GEN8_3D(3, 0, 0x0a) #define GEN8_3DSTATE_VF GEN8_3D(3, 0, 0x0c) #define GEN8_3DSTATE_MULTISAMPLE GEN8_3D(3, 0, 0x0d) /* DW1 */ # define MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define MULTISAMPLE_NUMSAMPLES_8 (3 << 1) #define GEN8_3DSTATE_CC_STATE_POINTERS GEN8_3D(3, 0, 0x0e) #define GEN8_3DSTATE_SCISSOR_STATE_POINTERS GEN8_3D(3, 0, 0x0f) #define GEN8_3DSTATE_VS GEN8_3D(3, 0, 0x10) #define GEN8_3DSTATE_GS GEN8_3D(3, 0, 0x11) #define GEN8_3DSTATE_CLIP GEN8_3D(3, 0, 0x12) #define GEN8_3DSTATE_SF GEN8_3D(3, 0, 0x13) # define SF_TRI_PROVOKE_SHIFT 29 # define SF_LINE_PROVOKE_SHIFT 27 # define SF_FAN_PROVOKE_SHIFT 25 #define GEN8_3DSTATE_WM GEN8_3D(3, 0, 0x14) /* DW1 */ # define WM_STATISTICS_ENABLE (1 << 31) # define WM_DEPTH_CLEAR (1 << 30) # define WM_DEPTH_RESOLVE (1 << 28) # define WM_HIERARCHICAL_DEPTH_RESOLVE (1 << 27) # define WM_KILL_ENABLE (1 << 25) # define WM_POSITION_ZW_PIXEL (0 << 17) # define WM_POSITION_ZW_CENTROID (2 << 17) # define WM_POSITION_ZW_SAMPLE (3 << 17) # define WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16) # define WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15) # define WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14) # define WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13) # define WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12) # define WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11) # define WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8) # define WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8) # define WM_LINE_END_CAP_AA_WIDTH_2_0 (2 << 8) # define WM_LINE_END_CAP_AA_WIDTH_4_0 (3 << 8) # define WM_LINE_AA_WIDTH_0_5 (0 << 6) # define WM_LINE_AA_WIDTH_1_0 (1 << 6) # define WM_LINE_AA_WIDTH_2_0 (2 << 6) # define WM_LINE_AA_WIDTH_4_0 (3 << 6) # define WM_POLYGON_STIPPLE_ENABLE (1 << 4) # define WM_LINE_STIPPLE_ENABLE (1 << 3) # define WM_POINT_RASTRULE_UPPER_RIGHT (1 << 2) # define WM_MSRAST_OFF_PIXEL (0 << 0) # define WM_MSRAST_OFF_PATTERN (1 << 0) # define WM_MSRAST_ON_PIXEL (2 << 0) # define WM_MSRAST_ON_PATTERN (3 << 0) #define GEN8_3DSTATE_CONSTANT_VS GEN8_3D(3, 0, 0x15) #define GEN8_3DSTATE_CONSTANT_GS GEN8_3D(3, 0, 0x16) #define GEN8_3DSTATE_CONSTANT_PS GEN8_3D(3, 0, 0x17) #define GEN8_3DSTATE_SAMPLE_MASK GEN8_3D(3, 0, 0x18) #define GEN8_3DSTATE_CONSTANT_HS GEN8_3D(3, 0, 0x19) #define GEN8_3DSTATE_CONSTANT_DS GEN8_3D(3, 0, 0x1a) #define GEN8_3DSTATE_HS GEN8_3D(3, 0, 0x1b) #define GEN8_3DSTATE_TE GEN8_3D(3, 0, 0x1c) #define GEN8_3DSTATE_DS GEN8_3D(3, 0, 0x1d) #define GEN8_3DSTATE_STREAMOUT GEN8_3D(3, 0, 0x1e) #define GEN8_3DSTATE_SBE GEN8_3D(3, 0, 0x1f) /* DW1 */ # define SBE_FORCE_VERTEX_URB_READ_LENGTH (1<<29) # define SBE_FORCE_VERTEX_URB_READ_OFFSET (1<<28) # define SBE_NUM_OUTPUTS_SHIFT 22 # define SBE_SWIZZLE_ENABLE (1 << 21) # define SBE_POINT_SPRITE_LOWERLEFT (1 << 20) # define SBE_URB_ENTRY_READ_LENGTH_SHIFT 11 # define SBE_URB_ENTRY_READ_OFFSET_SHIFT 5 #define GEN8_3DSTATE_PS GEN8_3D(3, 0, 0x20) /* DW1:DW2 kernel pointer */ /* DW3 */ # define PS_SPF_MODE (1 << 31) # define PS_VECTOR_MASK_ENABLE (1 << 30) # define PS_SAMPLER_COUNT_SHIFT 27 # define PS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 # define PS_FLOATING_POINT_MODE_IEEE_754 (0 << 16) # define PS_FLOATING_POINT_MODE_ALT (1 << 16) /* DW4:DW5: scratch space */ /* DW6 */ # define PS_MAX_THREADS_SHIFT 23 # define PS_MAX_THREADS (62 << PS_MAX_THREADS_SHIFT) # define PS_PUSH_CONSTANT_ENABLE (1 << 11) # define PS_RENDER_TARGET_CLEAR (1 << 8) # define PS_RENDER_TARGET_RESOLVE (1 << 6) # define PS_POSOFFSET_NONE (0 << 3) # define PS_POSOFFSET_CENTROID (2 << 3) # define PS_POSOFFSET_SAMPLE (3 << 3) # define PS_32_DISPATCH_ENABLE (1 << 2) # define PS_16_DISPATCH_ENABLE (1 << 1) # define PS_8_DISPATCH_ENABLE (1 << 0) /* DW7 */ # define PS_DISPATCH_START_GRF_SHIFT_0 16 # define PS_DISPATCH_START_GRF_SHIFT_1 8 # define PS_DISPATCH_START_GRF_SHIFT_2 0 /* DW8:D9: kernel 1 pointer */ /* DW10:D11: kernel 2 pointer */ #define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP GEN8_3D(3, 0, 0x21) #define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC GEN8_3D(3, 0, 0x23) #define GEN8_3DSTATE_BLEND_STATE_POINTERS GEN8_3D(3, 0, 0x24) #define GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS GEN8_3D(3, 0, 0x26) #define GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS GEN8_3D(3, 0, 0x27) #define GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS GEN8_3D(3, 0, 0x28) #define GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS GEN8_3D(3, 0, 0x29) #define GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS GEN8_3D(3, 0, 0x2a) #define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS GEN8_3D(3, 0, 0x2b) #define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS GEN8_3D(3, 0, 0x2c) #define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS GEN8_3D(3, 0, 0x2d) #define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS GEN8_3D(3, 0, 0x2e) #define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS GEN8_3D(3, 0, 0x2f) #define GEN8_3DSTATE_URB_VS GEN8_3D(3, 0, 0x30) #define GEN8_3DSTATE_URB_HS GEN8_3D(3, 0, 0x31) #define GEN8_3DSTATE_URB_DS GEN8_3D(3, 0, 0x32) #define GEN8_3DSTATE_URB_GS GEN8_3D(3, 0, 0x33) /* DW1 */ # define URB_ENTRY_NUMBER_SHIFT 0 # define URB_ENTRY_SIZE_SHIFT 16 # define URB_STARTING_ADDRESS_SHIFT 25 #define GEN8_3DSTATE_GATHER_CONSTANT_VS GEN8_3D(3, 0, 0x34) #define GEN8_3DSTATE_GATHER_CONSTANT_GS GEN8_3D(3, 0, 0x35) #define GEN8_3DSTATE_GATHER_CONSTANT_HS GEN8_3D(3, 0, 0x36) #define GEN8_3DSTATE_GATHER_CONSTANT_DS GEN8_3D(3, 0, 0x37) #define GEN8_3DSTATE_GATHER_CONSTANT_PS GEN8_3D(3, 0, 0x38) #define GEN8_3DSTATE_DX9_CONSTANTF_VS GEN8_3D(3, 0, 0x39) #define GEN8_3DSTATE_DX9_CONSTANTF_PS GEN8_3D(3, 0, 0x3a) #define GEN8_3DSTATE_DX9_CONSTANTI_VS GEN8_3D(3, 0, 0x3b) #define GEN8_3DSTATE_DX9_CONSTANTI_PS GEN8_3D(3, 0, 0x3c) #define GEN8_3DSTATE_DX9_CONSTANTB_VS GEN8_3D(3, 0, 0x3d) #define GEN8_3DSTATE_DX9_CONSTANTB_PS GEN8_3D(3, 0, 0x3e) #define GEN8_3DSTATE_DX9_LOCAL_VALID_VS GEN8_3D(3, 0, 0x3f) #define GEN8_3DSTATE_DX9_LOCAL_VALID_PS GEN8_3D(3, 0, 0x40) #define GEN8_3DSTATE_DX9_GENERATE_ACTIVE_VS GEN8_3D(3, 0, 0x41) #define GEN8_3DSTATE_DX9_GENERATE_ACTIVE_PS GEN8_3D(3, 0, 0x42) #define GEN8_3DSTATE_BINDING_TABLE_EDIT_VS GEN8_3D(3, 0, 0x43) #define GEN8_3DSTATE_BINDING_TABLE_EDIT_GS GEN8_3D(3, 0, 0x44) #define GEN8_3DSTATE_BINDING_TABLE_EDIT_HS GEN8_3D(3, 0, 0x45) #define GEN8_3DSTATE_BINDING_TABLE_EDIT_DS GEN8_3D(3, 0, 0x46) #define GEN8_3DSTATE_BINDING_TABLE_EDIT_PS GEN8_3D(3, 0, 0x47) #define GEN8_3DSTATE_VF_INSTANCING GEN8_3D(3, 0, 0x49) #define GEN8_3DSTATE_VF_SGVS GEN8_3D(3, 0, 0x4a) # define SGVS_ENABLE_INSTANCE_ID (1 << 31) # define SGVS_INSTANCE_ID_COMPONENT_SHIFT 29 # define SGVS_INSTANCE_ID_ELEMENT_OFFSET_SHIFT 16 # define SGVS_ENABLE_VERTEX_ID (1 << 15) # define SGVS_VERTEX_ID_COMPONENT_SHIFT 13 # define SGVS_VERTEX_ID_ELEMENT_OFFSET_SHIFT 0 #define GEN8_3DSTATE_VF_TOPOLOGY GEN8_3D(3, 0, 0x4b) # define POINTLIST 0x01 # define LINELIST 0x02 # define LINESTRIP 0x03 # define TRILIST 0x04 # define TRISTRIP 0x05 # define TRIFAN 0x06 # define QUADLIST 0x07 # define QUADSTRIP 0x08 # define LINELIST_ADJ 0x09 # define LINESTRIP_ADJ 0x0A # define TRILIST_ADJ 0x0B # define TRISTRIP_ADJ 0x0C # define TRISTRIP_REVERSE 0x0D # define POLYGON 0x0E # define RECTLIST 0x0F # define LINELOOP 0x10 # define POINTLIST_BF 0x11 # define LINESTRIP_CONT 0x12 # define LINESTRIP_BF 0x13 # define LINESTRIP_CONT_BF 0x14 # define TRIFAN_NOSTIPPLE 0x15 #define GEN8_3DSTATE_WM_CHROMAKEY GEN8_3D(3, 0, 0x4c) #define GEN8_3DSTATE_PS_BLEND GEN8_3D(3, 0, 0x4d) # define PS_BLEND_ALPHA_TO_COVERAGE_ENABLE (1 << 31) # define PS_BLEND_HAS_WRITEABLE_RT (1 << 30) # define PS_BLEND_COLOR_BLEND_ENABLE (1 << 29) # define PS_BLEND_SRC_ALPHA_SHIFT 24 # define PS_BLEND_DST_ALPHA_SHIFT 19 # define PS_BLEND_SRC_SHIFT 14 # define PS_BLEND_DST_SHIFT 9 # define PS_BLEND_ALPHA_TEST_ENABLE (1 << 8) # define PS_BLEND_INDEPENDENT_ALPHA_BLEND_ENABLE (1 << 7) #define GEN8_3DSTATE_WM_DEPTH_STENCIL GEN8_3D(3, 0, 0x4e) /* DW1 */ # define WM_DS_STENCIL_TEST_MASK_MASK INTEL_MASK(31, 24) # define WM_DS_STENCIL_TEST_MASK_SHIFT 24 # define WM_DS_STENCIL_WRITE_MASK_MASK INTEL_MASK(23, 16) # define WM_DS_STENCIL_WRITE_MASK_SHIFT 16 # define WM_DS_BF_STENCIL_TEST_MASK_MASK INTEL_MASK(15, 8) # define WM_DS_BF_STENCIL_TEST_MASK_SHIFT 8 # define WM_DS_BF_STENCIL_WRITE_MASK_MASK INTEL_MASK(7, 0) # define WM_DS_DEPTH_FUNC_SHIFT 5 # define WM_DS_DOUBLE_SIDED_STENCIL_ENABLE (1 << 4) # define WM_DS_STENCIL_TEST_ENABLE (1 << 3) # define WM_DS_STENCIL_BUFFER_WRITE_ENABLE (1 << 2) # define WM_DS_DEPTH_TEST_ENABLE (1 << 1) # define WM_DS_DEPTH_BUFFER_WRITE_ENABLE (1 << 0) /* DW2 */ # define WM_DS_STENCIL_TEST_MASK_MASK INTEL_MASK(31, 24) # define WM_DS_STENCIL_TEST_MASK_SHIFT 24 # define WM_DS_STENCIL_WRITE_MASK_MASK INTEL_MASK(23, 16) # define WM_DS_STENCIL_WRITE_MASK_SHIFT 16 # define WM_DS_BF_STENCIL_TEST_MASK_MASK INTEL_MASK(15, 8) # define WM_DS_BF_STENCIL_TEST_MASK_SHIFT 8 # define WM_DS_BF_STENCIL_WRITE_MASK_MASK INTEL_MASK(7, 0) # define WM_DS_BF_STENCIL_WRITE_MASK_SHIFT 0 #define GEN8_3DSTATE_PS_EXTRA GEN8_3D(3, 0, 0x4f) # define PSX_PIXEL_SHADER_VALID (1 << 31) # define PSX_PIXEL_SHADER_NO_RT_WRITE (1 << 30) # define PSX_OMASK_TO_RENDER_TARGET (1 << 29) # define PSX_KILL_ENABLE (1 << 28) # define PSX_PSCDEPTH_OFF (0 << 26) # define PSX_PSCDEPTH_ON (1 << 26) # define PSX_PSCDEPTH_ON_GE (2 << 26) # define PSX_PSCDEPTH_ON_LE (3 << 26) # define PSX_FORCE_COMPUTED_DEPTH (1 << 25) # define PSX_USES_SOURCE_DEPTH (1 << 24) # define PSX_USES_SOURCE_W (1 << 23) # define PSX_ATTRIBUTE_ENABLE (1 << 8) # define PSX_SHADER_DISABLES_ALPHA_TO_COVERAGE (1 << 7) # define PSX_SHADER_IS_PER_SAMPLE (1 << 6) # define PSX_SHADER_HAS_UAV (1 << 2) # define PSX_SHADER_USES_INPUT_COVERAGE_MASK (1 << 1) #define GEN8_3DSTATE_RASTER GEN8_3D(3, 0, 0x50) /* DW1 */ # define RASTER_FRONT_WINDING_CCW (1 << 21) # define RASTER_CULL_BOTH (0 << 16) # define RASTER_CULL_NONE (1 << 16) # define RASTER_CULL_FRONT (2 << 16) # define RASTER_CULL_BACK (3 << 16) # define RASTER_SMOOTH_POINT_ENABLE (1 << 13) # define RASTER_LINE_AA_ENABLE (1 << 2) # define RASTER_VIEWPORT_Z_CLIP_TEST_ENABLE (1 << 0) #define GEN8_3DSTATE_SBE_SWIZ GEN8_3D(3, 0, 0x51) #define GEN8_3DSTATE_WM_HZ_OP GEN8_3D(3, 0, 0x52) #define GEN8_3DSTATE_DRAWING_RECTANGLE GEN8_3D(3, 1, 0x00) #define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD GEN8_3D(3, 1, 0x02) #define GEN8_3DSTATE_CHROMA_KEY GEN8_3D(3, 1, 0x04) #define GEN8_3DSTATE_POLY_STIPPLE_OFFSET GEN8_3D(3, 1, 0x06) #define GEN8_3DSTATE_POLY_STIPPLE_PATTERN GEN8_3D(3, 1, 0x07) #define GEN8_3DSTATE_LINE_STIPPLE GEN8_3D(3, 1, 0x08) #define GEN8_3DSTATE_AA_LINE_PARAMS GEN8_3D(3, 1, 0x0a) #define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1 GEN8_3D(3, 1, 0x0c) #define GEN8_3DSTATE_MONOFILTER_SIZE GEN8_3D(3, 1, 0x11) #define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS GEN8_3D(3, 1, 0x12) #define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS GEN8_3D(3, 1, 0x13) #define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS GEN8_3D(3, 1, 0x14) #define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS GEN8_3D(3, 1, 0x15) #define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS GEN8_3D(3, 1, 0x16) /* DW1 */ # define PUSH_CONSTANT_BUFFER_OFFSET_SHIFT 16 # define PUSH_CONSTANT_BUFFER_SIZE_SHIFT 0 #define GEN8_3DSTATE_SO_DECL_LIST GEN8_3D(3, 1, 0x17) #define GEN8_3DSTATE_SO_BUFFER GEN8_3D(3, 1, 0x18) #define GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC GEN8_3D(3, 1, 0x19) #define GEN8_3DSTATE_GATHER_BUFFER_POOL_ALLOC GEN8_3D(3, 1, 0x1a) #define GEN8_3DSTATE_DX9_CONSTANT_BUFFER_POOL_ALLOC GEN8_3D(3, 1, 0x1b) #define GEN8_3DSTATE_SAMPLE_PATTERN GEN8_3D(3, 1, 0x1c) /* for GEN8_PIPE_CONTROL */ #define GEN8_PIPE_CONTROL GEN8_3D(3, 2, 0) #define PIPE_CONTROL_CS_STALL (1 << 20) #define PIPE_CONTROL_NOWRITE (0 << 14) #define PIPE_CONTROL_WRITE_QWORD (1 << 14) #define PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define PIPE_CONTROL_WRITE_TIME (3 << 14) #define PIPE_CONTROL_DEPTH_STALL (1 << 13) #define PIPE_CONTROL_WC_FLUSH (1 << 12) #define PIPE_CONTROL_IS_FLUSH (1 << 11) #define PIPE_CONTROL_TC_FLUSH (1 << 10) #define PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) #define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) #define GEN8_3DPRIMITIVE GEN8_3D(3, 3, 0) /* 3DPRIMITIVE bits */ #define VERTEX_SEQUENTIAL (0 << 15) #define VERTEX_RANDOM (1 << 15) #define ANISORATIO_2 0 #define ANISORATIO_4 1 #define ANISORATIO_6 2 #define ANISORATIO_8 3 #define ANISORATIO_10 4 #define ANISORATIO_12 5 #define ANISORATIO_14 6 #define ANISORATIO_16 7 #define BLENDFACTOR_ONE 0x1 #define BLENDFACTOR_SRC_COLOR 0x2 #define BLENDFACTOR_SRC_ALPHA 0x3 #define BLENDFACTOR_DST_ALPHA 0x4 #define BLENDFACTOR_DST_COLOR 0x5 #define BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define BLENDFACTOR_CONST_COLOR 0x7 #define BLENDFACTOR_CONST_ALPHA 0x8 #define BLENDFACTOR_SRC1_COLOR 0x9 #define BLENDFACTOR_SRC1_ALPHA 0x0A #define BLENDFACTOR_ZERO 0x11 #define BLENDFACTOR_INV_SRC_COLOR 0x12 #define BLENDFACTOR_INV_SRC_ALPHA 0x13 #define BLENDFACTOR_INV_DST_ALPHA 0x14 #define BLENDFACTOR_INV_DST_COLOR 0x15 #define BLENDFACTOR_INV_CONST_COLOR 0x17 #define BLENDFACTOR_INV_CONST_ALPHA 0x18 #define BLENDFACTOR_INV_SRC1_COLOR 0x19 #define BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define BLENDFUNCTION_ADD 0 #define BLENDFUNCTION_SUBTRACT 1 #define BLENDFUNCTION_REVERSE_SUBTRACT 2 #define GEN8_BLENDFUNCTION_MIN 3 #define BLENDFUNCTION_MAX 4 #define ALPHATEST_FORMAT_UNORM8 0 #define ALPHATEST_FORMAT_FLOAT32 1 #define CHROMAKEY_KILL_ON_ANY_MATCH 0 #define CHROMAKEY_REPLACE_BLACK 1 #define CLIP_API_OGL 0 #define CLIP_API_DX 1 #define CLIPMODE_NORMAL 0 #define CLIPMODE_CLIP_ALL 1 #define CLIPMODE_CLIP_NON_REJECTED 2 #define CLIPMODE_REJECT_ALL 3 #define CLIPMODE_ACCEPT_ALL 4 #define CLIP_NDCSPACE 0 #define CLIP_SCREENSPACE 1 #define COMPAREFUNCTION_ALWAYS 0 #define COMPAREFUNCTION_NEVER 1 #define COMPAREFUNCTION_LESS 2 #define COMPAREFUNCTION_EQUAL 3 #define COMPAREFUNCTION_LEQUAL 4 #define COMPAREFUNCTION_GREATER 5 #define COMPAREFUNCTION_NOTEQUAL 6 #define COMPAREFUNCTION_GEQUAL 7 #define COVERAGE_PIXELS_HALF 0 #define COVERAGE_PIXELS_1 1 #define COVERAGE_PIXELS_2 2 #define COVERAGE_PIXELS_4 3 #define DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define DEPTHFORMAT_D32_FLOAT 1 #define DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define DEPTHFORMAT_D16_UNORM 5 #define FLOATING_POINT_IEEE_754 0 #define FLOATING_POINT_NON_IEEE_754 1 #define INDEX_BYTE 0 #define INDEX_WORD 1 #define INDEX_DWORD 2 #define LOGICOPFUNCTION_CLEAR 0 #define LOGICOPFUNCTION_NOR 1 #define LOGICOPFUNCTION_AND_INVERTED 2 #define LOGICOPFUNCTION_COPY_INVERTED 3 #define LOGICOPFUNCTION_AND_REVERSE 4 #define LOGICOPFUNCTION_INVERT 5 #define LOGICOPFUNCTION_XOR 6 #define LOGICOPFUNCTION_NAND 7 #define LOGICOPFUNCTION_AND 8 #define LOGICOPFUNCTION_EQUIV 9 #define LOGICOPFUNCTION_NOOP 10 #define LOGICOPFUNCTION_OR_INVERTED 11 #define LOGICOPFUNCTION_COPY 12 #define LOGICOPFUNCTION_OR_REVERSE 13 #define LOGICOPFUNCTION_OR 14 #define LOGICOPFUNCTION_SET 15 #define MAPFILTER_NEAREST 0x0 #define MAPFILTER_LINEAR 0x1 #define MAPFILTER_ANISOTROPIC 0x2 #define MAPFILTER_FLEXIBLE 0x3 #define MAPFILTER_MONO 0x6 #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define POLYGON_FRONT_FACING 0 #define POLYGON_BACK_FACING 1 #define PREFILTER_ALWAYS 0x0 #define PREFILTER_NEVER 0x1 #define PREFILTER_LESS 0x2 #define PREFILTER_EQUAL 0x3 #define PREFILTER_LEQUAL 0x4 #define PREFILTER_GREATER 0x5 #define PREFILTER_NOTEQUAL 0x6 #define PREFILTER_GEQUAL 0x7 #define RASTRULE_UPPER_LEFT 0 #define RASTRULE_UPPER_RIGHT 1 #define STENCILOP_KEEP 0 #define STENCILOP_ZERO 1 #define STENCILOP_REPLACE 2 #define STENCILOP_INCRSAT 3 #define STENCILOP_DECRSAT 4 #define STENCILOP_INCR 5 #define STENCILOP_DECR 6 #define STENCILOP_INVERT 7 #define SURFACE_MIPMAPLAYOUT_BELOW 0 #define SURFACE_MIPMAPLAYOUT_RIGHT 1 #define SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define SURFACEFORMAT_R64G64_FLOAT 0x005 #define SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define SURFACEFORMAT_R32G32B32_SINT 0x041 #define SURFACEFORMAT_R32G32B32_UINT 0x042 #define SURFACEFORMAT_R32G32B32_UNORM 0x043 #define SURFACEFORMAT_R32G32B32_SNORM 0x044 #define SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define SURFACEFORMAT_R32G32B32_USCALED 0x046 #define SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define SURFACEFORMAT_R32G32_FLOAT 0x085 #define SURFACEFORMAT_R32G32_SINT 0x086 #define SURFACEFORMAT_R32G32_UINT 0x087 #define SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define SURFACEFORMAT_L32A32_FLOAT 0x08A #define SURFACEFORMAT_R32G32_UNORM 0x08B #define SURFACEFORMAT_R32G32_SNORM 0x08C #define SURFACEFORMAT_R64_FLOAT 0x08D #define SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define SURFACEFORMAT_A32X32_FLOAT 0x090 #define SURFACEFORMAT_L32X32_FLOAT 0x091 #define SURFACEFORMAT_I32X32_FLOAT 0x092 #define SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define SURFACEFORMAT_R32G32_SSCALED 0x095 #define SURFACEFORMAT_R32G32_USCALED 0x096 #define SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define SURFACEFORMAT_R16G16_UNORM 0x0CC #define SURFACEFORMAT_R16G16_SNORM 0x0CD #define SURFACEFORMAT_R16G16_SINT 0x0CE #define SURFACEFORMAT_R16G16_UINT 0x0CF #define SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define SURFACEFORMAT_R32_SINT 0x0D6 #define SURFACEFORMAT_R32_UINT 0x0D7 #define SURFACEFORMAT_R32_FLOAT 0x0D8 #define SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define SURFACEFORMAT_L16A16_UNORM 0x0DF #define SURFACEFORMAT_I24X8_UNORM 0x0E0 #define SURFACEFORMAT_L24X8_UNORM 0x0E1 #define SURFACEFORMAT_A24X8_UNORM 0x0E2 #define SURFACEFORMAT_I32_FLOAT 0x0E3 #define SURFACEFORMAT_L32_FLOAT 0x0E4 #define SURFACEFORMAT_A32_FLOAT 0x0E5 #define SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define SURFACEFORMAT_R32_UNORM 0x0F1 #define SURFACEFORMAT_R32_SNORM 0x0F2 #define SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define SURFACEFORMAT_R16G16_USCALED 0x0F7 #define SURFACEFORMAT_R32_SSCALED 0x0F8 #define SURFACEFORMAT_R32_USCALED 0x0F9 #define SURFACEFORMAT_B5G6R5_UNORM 0x100 #define SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define SURFACEFORMAT_R8G8_UNORM 0x106 #define SURFACEFORMAT_R8G8_SNORM 0x107 #define SURFACEFORMAT_R8G8_SINT 0x108 #define SURFACEFORMAT_R8G8_UINT 0x109 #define SURFACEFORMAT_R16_UNORM 0x10A #define SURFACEFORMAT_R16_SNORM 0x10B #define SURFACEFORMAT_R16_SINT 0x10C #define SURFACEFORMAT_R16_UINT 0x10D #define SURFACEFORMAT_R16_FLOAT 0x10E #define SURFACEFORMAT_I16_UNORM 0x111 #define SURFACEFORMAT_L16_UNORM 0x112 #define SURFACEFORMAT_A16_UNORM 0x113 #define SURFACEFORMAT_L8A8_UNORM 0x114 #define SURFACEFORMAT_I16_FLOAT 0x115 #define SURFACEFORMAT_L16_FLOAT 0x116 #define SURFACEFORMAT_A16_FLOAT 0x117 #define SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define SURFACEFORMAT_R8G8_SSCALED 0x11C #define SURFACEFORMAT_R8G8_USCALED 0x11D #define SURFACEFORMAT_R16_SSCALED 0x11E #define SURFACEFORMAT_R16_USCALED 0x11F #define SURFACEFORMAT_R8_UNORM 0x140 #define SURFACEFORMAT_R8_SNORM 0x141 #define SURFACEFORMAT_R8_SINT 0x142 #define SURFACEFORMAT_R8_UINT 0x143 #define SURFACEFORMAT_A8_UNORM 0x144 #define SURFACEFORMAT_I8_UNORM 0x145 #define SURFACEFORMAT_L8_UNORM 0x146 #define SURFACEFORMAT_P4A4_UNORM 0x147 #define SURFACEFORMAT_A4P4_UNORM 0x148 #define SURFACEFORMAT_R8_SSCALED 0x149 #define SURFACEFORMAT_R8_USCALED 0x14A #define SURFACEFORMAT_R1_UINT 0x181 #define SURFACEFORMAT_YCRCB_NORMAL 0x182 #define SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define SURFACEFORMAT_BC1_UNORM 0x186 #define SURFACEFORMAT_BC2_UNORM 0x187 #define SURFACEFORMAT_BC3_UNORM 0x188 #define SURFACEFORMAT_BC4_UNORM 0x189 #define SURFACEFORMAT_BC5_UNORM 0x18A #define SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define SURFACEFORMAT_MONO8 0x18E #define SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define SURFACEFORMAT_YCRCB_SWAPY 0x190 #define SURFACEFORMAT_DXT1_RGB 0x191 #define SURFACEFORMAT_FXT1 0x192 #define SURFACEFORMAT_R8G8B8_UNORM 0x193 #define SURFACEFORMAT_R8G8B8_SNORM 0x194 #define SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define SURFACEFORMAT_R8G8B8_USCALED 0x196 #define SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define SURFACEFORMAT_BC4_SNORM 0x199 #define SURFACEFORMAT_BC5_SNORM 0x19A #define SURFACEFORMAT_R16G16B16_UNORM 0x19C #define SURFACEFORMAT_R16G16B16_SNORM 0x19D #define SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define SURFACEFORMAT_R16G16B16_USCALED 0x19F #define SURFACE_1D 0 #define SURFACE_2D 1 #define SURFACE_3D 2 #define SURFACE_CUBE 3 #define SURFACE_BUFFER 4 #define SURFACE_NULL 7 #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP 2 #define TEXCOORDMODE_CUBE 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORDMODE_MIRROR_ONCE 5 #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_HIGH 1 #define VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define COMPONENT_NOSTORE 0 #define COMPONENT_STORE_SRC 1 #define COMPONENT_STORE_0 2 #define COMPONENT_STORE_1_FLT 3 #define COMPONENT_STORE_1_INT 4 #define COMPONENT_STORE_VID 5 #define COMPONENT_STORE_IID 6 #define COMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define GEN8_ALIGN_1 0 #define GEN8_ALIGN_16 1 #define GEN8_ADDRESS_DIRECT 0 #define GEN8_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define GEN8_CHANNEL_X 0 #define GEN8_CHANNEL_Y 1 #define GEN8_CHANNEL_Z 2 #define GEN8_CHANNEL_W 3 #define GEN8_COMPRESSION_NONE 0 #define GEN8_COMPRESSION_2NDHALF 1 #define GEN8_COMPRESSION_COMPRESSED 2 #define GEN8_CONDITIONAL_NONE 0 #define GEN8_CONDITIONAL_Z 1 #define GEN8_CONDITIONAL_NZ 2 #define GEN8_CONDITIONAL_EQ 1 /* Z */ #define GEN8_CONDITIONAL_NEQ 2 /* NZ */ #define GEN8_CONDITIONAL_G 3 #define GEN8_CONDITIONAL_GE 4 #define GEN8_CONDITIONAL_L 5 #define GEN8_CONDITIONAL_LE 6 #define GEN8_CONDITIONAL_C 7 #define GEN8_CONDITIONAL_O 8 #define GEN8_DEBUG_NONE 0 #define GEN8_DEBUG_BREAKPOINT 1 #define GEN8_DEPENDENCY_NORMAL 0 #define GEN8_DEPENDENCY_NOTCLEARED 1 #define GEN8_DEPENDENCY_NOTCHECKED 2 #define GEN8_DEPENDENCY_DISABLE 3 #define GEN8_EXECUTE_1 0 #define GEN8_EXECUTE_2 1 #define GEN8_EXECUTE_4 2 #define GEN8_EXECUTE_8 3 #define GEN8_EXECUTE_16 4 #define GEN8_EXECUTE_32 5 #define GEN8_HORIZONTAL_STRIDE_0 0 #define GEN8_HORIZONTAL_STRIDE_1 1 #define GEN8_HORIZONTAL_STRIDE_2 2 #define GEN8_HORIZONTAL_STRIDE_4 3 #define GEN8_INSTRUCTION_NORMAL 0 #define GEN8_INSTRUCTION_SATURATE 1 #define GEN8_OPCODE_MOV 1 #define GEN8_OPCODE_SEL 2 #define GEN8_OPCODE_NOT 4 #define GEN8_OPCODE_AND 5 #define GEN8_OPCODE_OR 6 #define GEN8_OPCODE_XOR 7 #define GEN8_OPCODE_SHR 8 #define GEN8_OPCODE_SHL 9 #define GEN8_OPCODE_RSR 10 #define GEN8_OPCODE_RSL 11 #define GEN8_OPCODE_ASR 12 #define GEN8_OPCODE_CMP 16 #define GEN8_OPCODE_JMPI 32 #define GEN8_OPCODE_IF 34 #define GEN8_OPCODE_IFF 35 #define GEN8_OPCODE_ELSE 36 #define GEN8_OPCODE_ENDIF 37 #define GEN8_OPCODE_DO 38 #define GEN8_OPCODE_WHILE 39 #define GEN8_OPCODE_BREAK 40 #define GEN8_OPCODE_CONTINUE 41 #define GEN8_OPCODE_HALT 42 #define GEN8_OPCODE_MSAVE 44 #define GEN8_OPCODE_MRESTORE 45 #define GEN8_OPCODE_PUSH 46 #define GEN8_OPCODE_POP 47 #define GEN8_OPCODE_WAIT 48 #define GEN8_OPCODE_SEND 49 #define GEN8_OPCODE_ADD 64 #define GEN8_OPCODE_MUL 65 #define GEN8_OPCODE_AVG 66 #define GEN8_OPCODE_FRC 67 #define GEN8_OPCODE_RNDU 68 #define GEN8_OPCODE_RNDD 69 #define GEN8_OPCODE_RNDE 70 #define GEN8_OPCODE_RNDZ 71 #define GEN8_OPCODE_MAC 72 #define GEN8_OPCODE_MACH 73 #define GEN8_OPCODE_LZD 74 #define GEN8_OPCODE_SAD2 80 #define GEN8_OPCODE_SADA2 81 #define GEN8_OPCODE_DP4 84 #define GEN8_OPCODE_DPH 85 #define GEN8_OPCODE_DP3 86 #define GEN8_OPCODE_DP2 87 #define GEN8_OPCODE_DPA2 88 #define GEN8_OPCODE_LINE 89 #define GEN8_OPCODE_NOP 126 #define GEN8_PREDICATE_NONE 0 #define GEN8_PREDICATE_NORMAL 1 #define GEN8_PREDICATE_ALIGN1_ANYV 2 #define GEN8_PREDICATE_ALIGN1_ALLV 3 #define GEN8_PREDICATE_ALIGN1_ANY2H 4 #define GEN8_PREDICATE_ALIGN1_ALL2H 5 #define GEN8_PREDICATE_ALIGN1_ANY4H 6 #define GEN8_PREDICATE_ALIGN1_ALL4H 7 #define GEN8_PREDICATE_ALIGN1_ANY8H 8 #define GEN8_PREDICATE_ALIGN1_ALL8H 9 #define GEN8_PREDICATE_ALIGN1_ANY16H 10 #define GEN8_PREDICATE_ALIGN1_ALL16H 11 #define GEN8_PREDICATE_ALIGN16_REPLICATE_X 2 #define GEN8_PREDICATE_ALIGN16_REPLICATE_Y 3 #define GEN8_PREDICATE_ALIGN16_REPLICATE_Z 4 #define GEN8_PREDICATE_ALIGN16_REPLICATE_W 5 #define GEN8_PREDICATE_ALIGN16_ANY4H 6 #define GEN8_PREDICATE_ALIGN16_ALL4H 7 #define GEN8_ARCHITECTURE_REGISTER_FILE 0 #define GEN8_GENERAL_REGISTER_FILE 1 #define GEN8_MESSAGE_REGISTER_FILE 2 #define GEN8_IMMEDIATE_VALUE 3 #define GEN8_REGISTER_TYPE_UD 0 #define GEN8_REGISTER_TYPE_D 1 #define GEN8_REGISTER_TYPE_UW 2 #define GEN8_REGISTER_TYPE_W 3 #define GEN8_REGISTER_TYPE_UB 4 #define GEN8_REGISTER_TYPE_B 5 #define GEN8_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define GEN8_REGISTER_TYPE_HF 6 #define GEN8_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define GEN8_REGISTER_TYPE_F 7 #define GEN8_ARF_NULL 0x00 #define GEN8_ARF_ADDRESS 0x10 #define GEN8_ARF_ACCUMULATOR 0x20 #define GEN8_ARF_FLAG 0x30 #define GEN8_ARF_MASK 0x40 #define GEN8_ARF_MASK_STACK 0x50 #define GEN8_ARF_MASK_STACK_DEPTH 0x60 #define GEN8_ARF_STATE 0x70 #define GEN8_ARF_CONTROL 0x80 #define GEN8_ARF_NOTIFICATION_COUNT 0x90 #define GEN8_ARF_IP 0xA0 #define GEN8_AMASK 0 #define GEN8_IMASK 1 #define GEN8_LMASK 2 #define GEN8_CMASK 3 #define GEN8_THREAD_NORMAL 0 #define GEN8_THREAD_ATOMIC 1 #define GEN8_THREAD_SWITCH 2 #define GEN8_VERTICAL_STRIDE_0 0 #define GEN8_VERTICAL_STRIDE_1 1 #define GEN8_VERTICAL_STRIDE_2 2 #define GEN8_VERTICAL_STRIDE_4 3 #define GEN8_VERTICAL_STRIDE_8 4 #define GEN8_VERTICAL_STRIDE_16 5 #define GEN8_VERTICAL_STRIDE_32 6 #define GEN8_VERTICAL_STRIDE_64 7 #define GEN8_VERTICAL_STRIDE_128 8 #define GEN8_VERTICAL_STRIDE_256 9 #define GEN8_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define GEN8_WIDTH_1 0 #define GEN8_WIDTH_2 1 #define GEN8_WIDTH_4 2 #define GEN8_WIDTH_8 3 #define GEN8_WIDTH_16 4 #define GEN8_STATELESS_BUFFER_BOUNDARY_1K 0 #define GEN8_STATELESS_BUFFER_BOUNDARY_2K 1 #define GEN8_STATELESS_BUFFER_BOUNDARY_4K 2 #define GEN8_STATELESS_BUFFER_BOUNDARY_8K 3 #define GEN8_STATELESS_BUFFER_BOUNDARY_16K 4 #define GEN8_STATELESS_BUFFER_BOUNDARY_32K 5 #define GEN8_STATELESS_BUFFER_BOUNDARY_64K 6 #define GEN8_STATELESS_BUFFER_BOUNDARY_128K 7 #define GEN8_STATELESS_BUFFER_BOUNDARY_256K 8 #define GEN8_STATELESS_BUFFER_BOUNDARY_512K 9 #define GEN8_STATELESS_BUFFER_BOUNDARY_1M 10 #define GEN8_STATELESS_BUFFER_BOUNDARY_2M 11 #define GEN8_POLYGON_FACING_FRONT 0 #define GEN8_POLYGON_FACING_BACK 1 #define GEN8_MESSAGE_TARGET_NULL 0 #define GEN8_MESSAGE_TARGET_MATH 1 #define GEN8_MESSAGE_TARGET_SAMPLER 2 #define GEN8_MESSAGE_TARGET_GATEWAY 3 #define GEN8_MESSAGE_TARGET_DATAPORT_READ 4 #define GEN8_MESSAGE_TARGET_DATAPORT_WRITE 5 #define GEN8_MESSAGE_TARGET_URB 6 #define GEN8_MESSAGE_TARGET_THREAD_SPAWNER 7 #define GEN8_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define GEN8_SAMPLER_RETURN_FORMAT_UINT32 2 #define GEN8_SAMPLER_RETURN_FORMAT_SINT32 3 #define GEN8_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define GEN8_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define GEN8_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define GEN8_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define GEN8_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define GEN8_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define GEN8_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define GEN8_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define GEN8_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define GEN8_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define GEN8_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define GEN8_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define GEN8_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define GEN8_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define GEN8_SAMPLER_MESSAGE_SIMD8_LD 3 #define GEN8_SAMPLER_MESSAGE_SIMD16_LD 3 #define GEN8_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define GEN8_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define GEN8_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define GEN8_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define GEN8_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define GEN8_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define GEN8_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define GEN8_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define GEN8_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define GEN8_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define GEN8_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define GEN8_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define GEN8_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define GEN8_DATAPORT_READ_TARGET_DATA_CACHE 0 #define GEN8_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define GEN8_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define GEN8_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define GEN8_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define GEN8_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define GEN8_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define GEN8_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define GEN8_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define GEN8_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define GEN8_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define GEN8_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define GEN8_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define GEN8_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define GEN8_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define GEN8_MATH_FUNCTION_INV 1 #define GEN8_MATH_FUNCTION_LOG 2 #define GEN8_MATH_FUNCTION_EXP 3 #define GEN8_MATH_FUNCTION_SQRT 4 #define GEN8_MATH_FUNCTION_RSQ 5 #define GEN8_MATH_FUNCTION_SIN 6 /* was 7 */ #define GEN8_MATH_FUNCTION_COS 7 /* was 8 */ #define GEN8_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define GEN8_MATH_FUNCTION_TAN 9 #define GEN8_MATH_FUNCTION_POW 10 #define GEN8_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define GEN8_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define GEN8_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define GEN8_MATH_INTEGER_UNSIGNED 0 #define GEN8_MATH_INTEGER_SIGNED 1 #define GEN8_MATH_PRECISION_FULL 0 #define GEN8_MATH_PRECISION_PARTIAL 1 #define GEN8_MATH_SATURATE_NONE 0 #define GEN8_MATH_SATURATE_SATURATE 1 #define GEN8_MATH_DATA_VECTOR 0 #define GEN8_MATH_DATA_SCALAR 1 #define GEN8_URB_OPCODE_WRITE 0 #define GEN8_URB_SWIZZLE_NONE 0 #define GEN8_URB_SWIZZLE_INTERLEAVE 1 #define GEN8_URB_SWIZZLE_TRANSPOSE 2 #define GEN8_SCRATCH_SPACE_SIZE_1K 0 #define GEN8_SCRATCH_SPACE_SIZE_2K 1 #define GEN8_SCRATCH_SPACE_SIZE_4K 2 #define GEN8_SCRATCH_SPACE_SIZE_8K 3 #define GEN8_SCRATCH_SPACE_SIZE_16K 4 #define GEN8_SCRATCH_SPACE_SIZE_32K 5 #define GEN8_SCRATCH_SPACE_SIZE_64K 6 #define GEN8_SCRATCH_SPACE_SIZE_128K 7 #define GEN8_SCRATCH_SPACE_SIZE_256K 8 #define GEN8_SCRATCH_SPACE_SIZE_512K 9 #define GEN8_SCRATCH_SPACE_SIZE_1M 10 #define GEN8_SCRATCH_SPACE_SIZE_2M 11 struct gen8_blend_state { struct { /* 00 */ uint32_t pad:19; /* 19 */ uint32_t y_dither_offset:2; /* 21 */ uint32_t x_dither_offset:2; /* 23 */ uint32_t color_dither_enable:1; /* 24 */ uint32_t alpha_test_function:3; /* 27 */ uint32_t alpha_test:1; /* 28 */ uint32_t alpha_to_coverage_dither:1; /* 29 */ uint32_t alpha_to_one:1; /* 30 */ uint32_t ia_blend:1; /* 31 */ uint32_t alpha_to_coverage:1; } common; struct { /* 00 */ uint32_t write_disable_blue:1; /* 01 */ uint32_t write_disable_green:1; /* 02 */ uint32_t write_disable_red:1; /* 03 */ uint32_t write_disable_alpha:1; /* 04 */ uint32_t pad0:1; /* 05 */ uint32_t alpha_blend_function:3; /* 08 */ uint32_t dest_alpha_blend_factor:5; /* 13 */ uint32_t source_alpha_blend_factor:5; /* 18 */ uint32_t color_blend_function:3; /* 21 */ uint32_t dest_blend_factor:5; /* 26 */ uint32_t source_blend_factor:5; /* 31 */ uint32_t color_blend:1; /* 32 */ uint32_t post_blend_clamp:1; /* 33 */ uint32_t pre_blend_clamp:1; /* 34 */ uint32_t color_clamp_range:2; /* 36 */ uint32_t pre_blend_source_only_clamp:1; /* 37 */ uint32_t pad1:22; /* 59 */ uint32_t logic_op_function:4; /* 63 */ uint32_t logic_op:1; } rt; }; struct gen8_color_calc_state { struct { /* 00 */ uint32_t alpha_test_format:1; /* 01 */ uint32_t pad0:14; /* 15 */ uint32_t round_disable:1; /* 16 */ uint32_t bf_stencil_ref:8; /* 24 */ uint32_t stencil_ref:8; } cc0; union { float alpha_ref_f; struct { uint32_t ui:8; uint32_t pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen8_sampler_state { struct { /* 00 */ unsigned int aniso_algorithm:1; /* 01 */ unsigned int lod_bias:13; /* 14 */ unsigned int min_filter:3; /* 17 */ unsigned int mag_filter:3; /* 20 */ unsigned int mip_filter:2; /* 22 */ unsigned int base_level:5; /* 27 */ unsigned int lod_preclamp:2; /* 29 */ unsigned int default_color_mode:1; /* 30 */ unsigned int flexible_filter_clamp:1; /* 31 */ unsigned int disable:1; } ss0; struct { /* 00 */ unsigned int cube_control_mode:1; /* 01 */ unsigned int shadow_function:3; /* 04 */ unsigned int chroma_key_mode:1; /* 05 */ unsigned int chroma_key_index:2; /* 07 */ unsigned int chroma_key_enable:1; /* 08 */ unsigned int max_lod:12; /* 20 */ unsigned int min_lod:12; } ss1; struct { unsigned int pad:6; unsigned int default_color_pointer:26; } ss2; struct { /* 00 */ unsigned int r_wrap_mode:3; /* 03 */ unsigned int t_wrap_mode:3; /* 06 */ unsigned int s_wrap_mode:3; /* 09 */ unsigned int pad:1; /* 10 */ unsigned int non_normalized_coord:1; /* 11 */ unsigned int trilinear_quality:2; /* 13 */ unsigned int address_round:6; /* 19 */ unsigned int max_aniso:3; /* 22 */ unsigned int pad0:2; /* 24 */ unsigned int non_separable_filter:8; } ss3; }; /* Surface state DW0 */ #define SURFACE_RC_READ_WRITE (1 << 8) #define SURFACE_TILED (1 << 13) #define SURFACE_TILED_Y (1 << 12) #define SURFACE_FORMAT_SHIFT 18 #define SURFACE_VALIGN_1 (0 << 16) /* reserved! */ #define SURFACE_VALIGN_4 (1 << 16) #define SURFACE_VALIGN_8 (2 << 16) #define SURFACE_VALIGN_16 (3 << 16) #define SURFACE_HALIGN_1 (0 << 14) /* reserved! */ #define SURFACE_HALIGN_4 (1 << 14) #define SURFACE_HALIGN_8 (2 << 14) #define SURFACE_HALIGN_16 (3 << 14) #define SURFACE_TYPE_SHIFT 29 /* Surface state DW2 */ #define SURFACE_HEIGHT_SHIFT 16 #define SURFACE_WIDTH_SHIFT 0 /* Surface state DW3 */ #define SURFACE_DEPTH_SHIFT 21 #define SURFACE_PITCH_SHIFT 0 #define SWIZZLE_ZERO 0 #define SWIZZLE_ONE 1 #define SWIZZLE_RED 4 #define SWIZZLE_GREEN 5 #define SWIZZLE_BLUE 6 #define SWIZZLE_ALPHA 7 #define __SURFACE_SWIZZLE(r,g,b,a) \ ((a) << 16 | (b) << 19 | (g) << 22 | (r) << 25) #define SURFACE_SWIZZLE(r,g,b,a) \ __SURFACE_SWIZZLE(SWIZZLE_##r, SWIZZLE_##g, SWIZZLE_##b, SWIZZLE_##a) typedef enum { SAMPLER_FILTER_NEAREST = 0, SAMPLER_FILTER_BILINEAR, FILTER_COUNT } sampler_filter_t; typedef enum { SAMPLER_EXTEND_NONE = 0, SAMPLER_EXTEND_REPEAT, SAMPLER_EXTEND_PAD, SAMPLER_EXTEND_REFLECT, EXTEND_COUNT } sampler_extend_t; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_vertex.c000066400000000000000000000223611267532330400242510ustar00rootroot00000000000000/* * Copyright © 2012 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "gen8_vertex.h" void gen8_vertex_align(struct sna *sna, const struct sna_composite_op *op) { int vertex_index; assert(op->floats_per_rect == 3*op->floats_per_vertex); vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; if ((int)sna->render.vertex_size - vertex_index * op->floats_per_vertex < 2*op->floats_per_rect) { DBG(("%s: flushing vertex buffer: new index=%d, max=%d\n", __FUNCTION__, vertex_index, sna->render.vertex_size / op->floats_per_vertex)); if (gen8_vertex_finish(sna) < 2*op->floats_per_rect) { kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_RENDER); } vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; assert(vertex_index * op->floats_per_vertex <= sna->render.vertex_size); } sna->render.vertex_index = vertex_index; sna->render.vertex_used = vertex_index * op->floats_per_vertex; } void gen8_vertex_flush(struct sna *sna) { DBG(("%s[%x] = %d\n", __FUNCTION__, 4*sna->render.vertex_offset, sna->render.vertex_index - sna->render.vertex_start)); assert(sna->render.vertex_offset); assert(sna->render.vertex_offset <= sna->kgem.nbatch); assert(sna->render.vertex_index > sna->render.vertex_start); assert(sna->render.vertex_used <= sna->render.vertex_size); sna->kgem.batch[sna->render.vertex_offset] = sna->render.vertex_index - sna->render.vertex_start; sna->render.vertex_offset = 0; } int gen8_vertex_finish(struct sna *sna) { struct kgem_bo *bo; unsigned int i; unsigned hint, size; DBG(("%s: used=%d / %d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vertex_size)); assert(sna->render.vertex_offset == 0); assert(sna->render.vertex_used); assert(sna->render.vertex_used <= sna->render.vertex_size); sna_vertex_wait__locked(&sna->render); /* Note: we only need dword alignment (currently) */ hint = CREATE_GTT_MAP; bo = sna->render.vbo; if (bo) { for (i = 0; i < sna->render.nvertex_reloc; i++) { DBG(("%s: reloc[%d] = %d\n", __FUNCTION__, i, sna->render.vertex_reloc[i])); *(uint64_t *)(sna->kgem.batch+sna->render.vertex_reloc[i]) = kgem_add_reloc64(&sna->kgem, sna->render.vertex_reloc[i], bo, I915_GEM_DOMAIN_VERTEX << 16, 0); } assert(!sna->render.active); sna->render.nvertex_reloc = 0; sna->render.vertex_used = 0; sna->render.vertex_index = 0; sna->render.vbo = NULL; sna->render.vb_id = 0; kgem_bo_destroy(&sna->kgem, bo); hint |= CREATE_CACHED | CREATE_NO_THROTTLE; } else { if (kgem_is_idle(&sna->kgem)) { sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); return 0; } } size = 256*1024; assert(!sna->render.active); sna->render.vertices = NULL; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); while (sna->render.vbo == NULL && size > 16*1024) { size /= 2; sna->render.vbo = kgem_create_linear(&sna->kgem, size, hint); } if (sna->render.vbo == NULL) sna->render.vbo = kgem_create_linear(&sna->kgem, 256*1024, CREATE_GTT_MAP); if (sna->render.vbo) sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo); if (sna->render.vertices == NULL) { if (sna->render.vbo) { kgem_bo_destroy(&sna->kgem, sna->render.vbo); sna->render.vbo = NULL; } sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); return 0; } if (sna->render.vertex_used) { DBG(("%s: copying initial buffer x %d to handle=%d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vbo->handle)); assert(sizeof(float)*sna->render.vertex_used <= __kgem_bo_size(sna->render.vbo)); memcpy(sna->render.vertices, sna->render.vertex_data, sizeof(float)*sna->render.vertex_used); } size = __kgem_bo_size(sna->render.vbo)/4; if (size >= UINT16_MAX) size = UINT16_MAX - 1; DBG(("%s: create vbo handle=%d, size=%d\n", __FUNCTION__, sna->render.vbo->handle, size)); sna->render.vertex_size = size; return sna->render.vertex_size - sna->render.vertex_used; } void gen8_vertex_close(struct sna *sna) { struct kgem_bo *bo, *free_bo = NULL; unsigned int i, delta = 0; assert(sna->render.vertex_offset == 0); if (!sna->render.vb_id) return; DBG(("%s: used=%d, vbo active? %d, vb=%x, nreloc=%d\n", __FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0, sna->render.vb_id, sna->render.nvertex_reloc)); assert(!sna->render.active); bo = sna->render.vbo; if (bo) { if (sna->render.vertex_size - sna->render.vertex_used < 64) { DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle)); sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } else if (!sna->kgem.has_llc && sna->render.vertices == MAP(bo->map__cpu)) { DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); sna->render.vertices = kgem_bo_map__gtt(&sna->kgem, sna->render.vbo); if (sna->render.vertices == NULL) { sna->render.vbo = NULL; sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } } } else { int size; size = sna->kgem.nbatch; size += sna->kgem.batch_size - sna->kgem.surface; size += sna->render.vertex_used; if (size <= 1024) { DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__, sna->render.vertex_used, sna->kgem.nbatch)); assert(sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface); memcpy(sna->kgem.batch + sna->kgem.nbatch, sna->render.vertex_data, sna->render.vertex_used * 4); delta = sna->kgem.nbatch * 4; bo = NULL; sna->kgem.nbatch += sna->render.vertex_used; } else { size = 256 * 1024; do { bo = kgem_create_linear(&sna->kgem, size, CREATE_GTT_MAP | CREATE_NO_RETIRE | CREATE_NO_THROTTLE | CREATE_CACHED); } while (bo == NULL && (size>>=1) > sizeof(float)*sna->render.vertex_used); sna->render.vertices = NULL; if (bo) sna->render.vertices = kgem_bo_map(&sna->kgem, bo); if (sna->render.vertices != NULL) { DBG(("%s: new vbo: %d / %d\n", __FUNCTION__, sna->render.vertex_used, __kgem_bo_size(bo)/4)); assert(sizeof(float)*sna->render.vertex_used <= __kgem_bo_size(bo)); memcpy(sna->render.vertices, sna->render.vertex_data, sizeof(float)*sna->render.vertex_used); size = __kgem_bo_size(bo)/4; if (size >= UINT16_MAX) size = UINT16_MAX - 1; sna->render.vbo = bo; sna->render.vertex_size = size; } else { DBG(("%s: tmp vbo: %d\n", __FUNCTION__, sna->render.vertex_used)); if (bo) kgem_bo_destroy(&sna->kgem, bo); bo = kgem_create_linear(&sna->kgem, 4*sna->render.vertex_used, CREATE_NO_THROTTLE); if (bo && !kgem_bo_write(&sna->kgem, bo, sna->render.vertex_data, 4*sna->render.vertex_used)) { kgem_bo_destroy(&sna->kgem, bo); bo = NULL; } assert(sna->render.vbo == NULL); sna->render.vertices = sna->render.vertex_data; sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); free_bo = bo; } } } assert(sna->render.nvertex_reloc); for (i = 0; i < sna->render.nvertex_reloc; i++) { DBG(("%s: reloc[%d] = %d\n", __FUNCTION__, i, sna->render.vertex_reloc[i])); *(uint64_t *)(sna->kgem.batch+sna->render.vertex_reloc[i]) = kgem_add_reloc64(&sna->kgem, sna->render.vertex_reloc[i], bo, I915_GEM_DOMAIN_VERTEX << 16, delta); } sna->render.nvertex_reloc = 0; sna->render.vb_id = 0; if (sna->render.vbo == NULL) { assert(!sna->render.active); sna->render.vertex_used = 0; sna->render.vertex_index = 0; assert(sna->render.vertices == sna->render.vertex_data); assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data)); } if (free_bo) kgem_bo_destroy(&sna->kgem, free_bo); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/gen8_vertex.h000066400000000000000000000005211267532330400242500ustar00rootroot00000000000000#ifndef GEN8_VERTEX_H #define GEN8_VERTEX_H #include "compiler.h" #include "sna.h" #include "sna_render.h" void gen8_vertex_align(struct sna *sna, const struct sna_composite_op *op); void gen8_vertex_flush(struct sna *sna); int gen8_vertex_finish(struct sna *sna); void gen8_vertex_close(struct sna *sna); #endif /* GEN8_VERTEX_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem.c000066400000000000000000006244141267532330400227450ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_VALGRIND #include #include #endif #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM #include #endif #include "sna_cpuid.h" static struct kgem_bo * search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags); static struct kgem_bo * search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags); #define DBG_NO_HW 0 #define DBG_NO_EXEC 0 #define DBG_NO_TILING 0 #define DBG_NO_CACHE 0 #define DBG_NO_SNOOP_CACHE 0 #define DBG_NO_CACHE_LEVEL 0 #define DBG_NO_CPU 0 #define DBG_NO_CREATE2 0 #define DBG_NO_USERPTR 0 #define DBG_NO_UNSYNCHRONIZED_USERPTR 0 #define DBG_NO_LLC 0 #define DBG_NO_SEMAPHORES 0 #define DBG_NO_MADV 0 #define DBG_NO_UPLOAD_CACHE 0 #define DBG_NO_UPLOAD_ACTIVE 0 #define DBG_NO_MAP_UPLOAD 0 #define DBG_NO_RELAXED_FENCING 0 #define DBG_NO_SECURE_BATCHES 0 #define DBG_NO_PINNED_BATCHES 0 #define DBG_NO_SHRINK_BATCHES 0 #define DBG_NO_FAST_RELOC 0 #define DBG_NO_HANDLE_LUT 0 #define DBG_NO_WT 0 #define DBG_NO_WC_MMAP 0 #define DBG_NO_BLT_Y 0 #define DBG_NO_SCANOUT_Y 0 #define DBG_NO_DIRTYFB 0 #define DBG_NO_DETILING 0 #define DBG_DUMP 0 #define DBG_NO_MALLOC_CACHE 0 #define FORCE_MMAP_SYNC 0 /* ((1 << DOMAIN_CPU) | (1 << DOMAIN_GTT)) */ #ifndef DEBUG_SYNC #define DEBUG_SYNC 0 #endif #define SHOW_BATCH_BEFORE 0 #define SHOW_BATCH_AFTER 0 #if 0 #define ASSERT_IDLE(kgem__, handle__) assert(!__kgem_busy(kgem__, handle__)) #define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__) assert(!(expect__) || !__kgem_busy(kgem__, handle__)) #else #define ASSERT_IDLE(kgem__, handle__) #define ASSERT_MAYBE_IDLE(kgem__, handle__, expect__) #endif /* Worst case seems to be 965gm where we cannot write within a cacheline that * is being simultaneously being read by the GPU, or within the sampler * prefetch. In general, the chipsets seem to have a requirement that sampler * offsets be aligned to a cacheline (64 bytes). * * Actually, it turns out the BLT color pattern (BR15) has the most severe * alignment restrictions, 64 bytes for 8-bpp, 128 bytes for 16-bpp and 256 * bytes for 32-bpp. */ #define UPLOAD_ALIGNMENT 256 #define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE) #define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE) #define MAX_GTT_VMA_CACHE 512 #define MAX_CPU_VMA_CACHE INT16_MAX #define MAP_PRESERVE_TIME 10 #define MAKE_USER_MAP(ptr) ((void*)((uintptr_t)(ptr) | 1)) #define IS_USER_MAP(ptr) ((uintptr_t)(ptr) & 1) #define LOCAL_I915_PARAM_HAS_BLT 11 #define LOCAL_I915_PARAM_HAS_RELAXED_FENCING 12 #define LOCAL_I915_PARAM_HAS_RELAXED_DELTA 15 #define LOCAL_I915_PARAM_HAS_LLC 17 #define LOCAL_I915_PARAM_HAS_SEMAPHORES 20 #define LOCAL_I915_PARAM_HAS_SECURE_BATCHES 23 #define LOCAL_I915_PARAM_HAS_PINNED_BATCHES 24 #define LOCAL_I915_PARAM_HAS_NO_RELOC 25 #define LOCAL_I915_PARAM_HAS_HANDLE_LUT 26 #define LOCAL_I915_PARAM_HAS_WT 27 #define LOCAL_I915_PARAM_MMAP_VERSION 30 #define LOCAL_I915_EXEC_IS_PINNED (1<<10) #define LOCAL_I915_EXEC_NO_RELOC (1<<11) #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) #define LOCAL_I915_GEM_CREATE2 0x34 #define LOCAL_IOCTL_I915_GEM_CREATE2 DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CREATE2, struct local_i915_gem_create2) struct local_i915_gem_create2 { uint64_t size; uint32_t placement; #define LOCAL_I915_CREATE_PLACEMENT_SYSTEM 0 #define LOCAL_I915_CREATE_PLACEMENT_STOLEN 1 /* Cannot use CPU mmaps or pread/pwrite */ uint32_t domain; uint32_t caching; uint32_t tiling_mode; uint32_t stride; uint32_t flags; uint32_t pad; uint32_t handle; }; #define LOCAL_I915_GEM_USERPTR 0x33 #define LOCAL_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_USERPTR, struct local_i915_gem_userptr) struct local_i915_gem_userptr { uint64_t user_ptr; uint64_t user_size; uint32_t flags; #define I915_USERPTR_READ_ONLY 0x1 #define I915_USERPTR_UNSYNCHRONIZED 0x80000000 uint32_t handle; }; #define UNCACHED 0 #define SNOOPED 1 #define DISPLAY 2 struct local_i915_gem_caching { uint32_t handle; uint32_t caching; }; #define LOCAL_I915_GEM_SET_CACHING 0x2f #define LOCAL_I915_GEM_GET_CACHING 0x30 #define LOCAL_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + LOCAL_I915_GEM_SET_CACHING, struct local_i915_gem_caching) #define LOCAL_IOCTL_I915_GEM_GET_CACHING DRM_IOW(DRM_COMMAND_BASE + LOCAL_I915_GEM_GET_CACHING, struct local_i915_gem_caching) struct local_i915_gem_mmap { uint32_t handle; uint32_t pad; uint64_t offset; uint64_t size; uint64_t addr_ptr; }; #define LOCAL_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap) struct local_i915_gem_mmap2 { uint32_t handle; uint32_t pad; uint64_t offset; uint64_t size; uint64_t addr_ptr; uint64_t flags; #define I915_MMAP_WC 0x1 }; #define LOCAL_IOCTL_I915_GEM_MMAP_v2 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct local_i915_gem_mmap2) struct kgem_buffer { struct kgem_bo base; void *mem; uint32_t used; uint32_t need_io : 1; uint32_t write : 2; uint32_t mmapped : 2; }; enum { MMAPPED_NONE, MMAPPED_GTT, MMAPPED_CPU }; static struct kgem_bo *__kgem_freed_bo; static struct kgem_request *__kgem_freed_request; static struct drm_i915_gem_exec_object2 _kgem_dummy_exec; static inline struct sna *__to_sna(struct kgem *kgem) { /* minor layering violations */ return container_of(kgem, struct sna, kgem); } static inline int bytes(struct kgem_bo *bo) { return __kgem_bo_size(bo); } #define bucket(B) (B)->size.pages.bucket #define num_pages(B) (B)->size.pages.count static int __do_ioctl(int fd, unsigned long req, void *arg) { do { int err; switch ((err = errno)) { case EAGAIN: sched_yield(); case EINTR: break; default: return -err; } if (likely(ioctl(fd, req, arg) == 0)) return 0; } while (1); } inline static int do_ioctl(int fd, unsigned long req, void *arg) { if (likely(ioctl(fd, req, arg) == 0)) return 0; return __do_ioctl(fd, req, arg); } #ifdef DEBUG_MEMORY static void debug_alloc(struct kgem *kgem, size_t size) { kgem->debug_memory.bo_allocs++; kgem->debug_memory.bo_bytes += size; } static void debug_alloc__bo(struct kgem *kgem, struct kgem_bo *bo) { debug_alloc(kgem, bytes(bo)); } #else #define debug_alloc__bo(k, b) #endif #ifndef NDEBUG static void assert_tiling(struct kgem *kgem, struct kgem_bo *bo) { struct drm_i915_gem_get_tiling tiling; assert(bo); if (!kgem->can_fence && kgem->gen >= 040 && bo->tiling) return; /* lies */ VG_CLEAR(tiling); tiling.handle = bo->handle; tiling.tiling_mode = bo->tiling; (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling); assert(tiling.tiling_mode == bo->tiling); } static void assert_caching(struct kgem *kgem, struct kgem_bo *bo) { struct local_i915_gem_caching arg; int expect = kgem->has_llc ? SNOOPED : UNCACHED; VG_CLEAR(arg); arg.handle = bo->handle; arg.caching = expect; (void)do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &arg); assert(arg.caching == expect); } static void assert_bo_retired(struct kgem_bo *bo) { DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); assert(bo->refcnt); assert(bo->rq == NULL); assert(bo->exec == NULL); assert(!bo->needs_flush); assert(list_is_empty(&bo->request)); } #else #define assert_tiling(kgem, bo) #define assert_caching(kgem, bo) #define assert_bo_retired(bo) #endif static int __find_debugfs(struct kgem *kgem) { int i; for (i = 0; i < DRM_MAX_MINOR; i++) { char path[80]; sprintf(path, "/sys/kernel/debug/dri/%d/i915_wedged", i); if (access(path, R_OK) == 0) return i; sprintf(path, "/debug/dri/%d/i915_wedged", i); if (access(path, R_OK) == 0) return i; } return -1; } static int kgem_get_minor(struct kgem *kgem) { struct stat st; if (fstat(kgem->fd, &st)) return __find_debugfs(kgem); if (!S_ISCHR(st.st_mode)) return __find_debugfs(kgem); return st.st_rdev & 0x63; } static bool find_hang_state(struct kgem *kgem, char *path, int maxlen) { int minor = kgem_get_minor(kgem); /* Search for our hang state in a few canonical locations. * In the unlikely event of having multiple devices, we * will need to check which minor actually corresponds to ours. */ snprintf(path, maxlen, "/sys/class/drm/card%d/error", minor); if (access(path, R_OK) == 0) return true; snprintf(path, maxlen, "/sys/kernel/debug/dri/%d/i915_error_state", minor); if (access(path, R_OK) == 0) return true; snprintf(path, maxlen, "/debug/dri/%d/i915_error_state", minor); if (access(path, R_OK) == 0) return true; path[0] = '\0'; return false; } static bool has_error_state(struct kgem *kgem, char *path) { bool ret = false; char no; int fd; fd = open(path, O_RDONLY); if (fd >= 0) { ret = read(fd, &no, 1) == 1 && no != 'N'; close(fd); } return ret; } static int kgem_get_screen_index(struct kgem *kgem) { return __to_sna(kgem)->scrn->scrnIndex; } static void __kgem_set_wedged(struct kgem *kgem) { static int once; char path[256]; if (kgem->wedged) return; if (!once && find_hang_state(kgem, path, sizeof(path)) && has_error_state(kgem, path)) { xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR, "When reporting this, please include %s and the full dmesg.\n", path); once = 1; } kgem->wedged = true; sna_render_mark_wedged(__to_sna(kgem)); } static void kgem_sna_reset(struct kgem *kgem) { struct sna *sna = __to_sna(kgem); sna->render.reset(sna); sna->blt_state.fill_bo = 0; } static void kgem_sna_flush(struct kgem *kgem) { struct sna *sna = __to_sna(kgem); sna->render.flush(sna); if (sna->render.solid_cache.dirty) sna_render_flush_solid(sna); } static bool kgem_set_tiling(struct kgem *kgem, struct kgem_bo *bo, int tiling, int stride) { struct drm_i915_gem_set_tiling set_tiling; int err; if (tiling == bo->tiling) { if (tiling == I915_TILING_NONE) { bo->pitch = stride; return true; } if (stride == bo->pitch) return true; } if (DBG_NO_TILING) return false; VG_CLEAR(set_tiling); restart: set_tiling.handle = bo->handle; set_tiling.tiling_mode = tiling; set_tiling.stride = tiling ? stride : 0; if (ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling) == 0) { bo->tiling = set_tiling.tiling_mode; bo->pitch = set_tiling.tiling_mode ? set_tiling.stride : stride; DBG(("%s: handle=%d, tiling=%d [%d], pitch=%d [%d]: %d\n", __FUNCTION__, bo->handle, bo->tiling, tiling, bo->pitch, stride, set_tiling.tiling_mode == tiling)); return set_tiling.tiling_mode == tiling; } err = errno; if (err == EINTR) goto restart; if (err == EAGAIN) { sched_yield(); goto restart; } ERR(("%s: failed to set-tiling(tiling=%d, pitch=%d) for handle=%d: %d\n", __FUNCTION__, tiling, stride, bo->handle, err)); return false; } static bool gem_set_caching(int fd, uint32_t handle, int caching) { struct local_i915_gem_caching arg; VG_CLEAR(arg); arg.handle = handle; arg.caching = caching; return do_ioctl(fd, LOCAL_IOCTL_I915_GEM_SET_CACHING, &arg) == 0; } static uint32_t gem_userptr(int fd, void *ptr, int size, int read_only) { struct local_i915_gem_userptr arg; VG_CLEAR(arg); arg.user_ptr = (uintptr_t)ptr; arg.user_size = size; arg.flags = I915_USERPTR_UNSYNCHRONIZED; if (read_only) arg.flags |= I915_USERPTR_READ_ONLY; if (DBG_NO_UNSYNCHRONIZED_USERPTR || do_ioctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg)) { arg.flags &= ~I915_USERPTR_UNSYNCHRONIZED; if (do_ioctl(fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg)) { DBG(("%s: failed to map %p + %d bytes: %d\n", __FUNCTION__, ptr, size, errno)); return 0; } } return arg.handle; } static bool __kgem_throttle(struct kgem *kgem, bool harder) { /* Let this be woken up by sigtimer so that we don't block here * too much and completely starve X. We will sleep again shortly, * and so catch up or detect the hang. */ do { if (ioctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE) == 0) { kgem->need_throttle = 0; return false; } if (errno == EIO) return true; } while (harder); return false; } static bool __kgem_throttle_retire(struct kgem *kgem, unsigned flags) { if (flags & CREATE_NO_RETIRE || !kgem->need_retire) { DBG(("%s: not retiring\n", __FUNCTION__)); return false; } if (kgem_retire(kgem)) return true; if (flags & CREATE_NO_THROTTLE || !kgem->need_throttle) { DBG(("%s: not throttling\n", __FUNCTION__)); return false; } __kgem_throttle(kgem, false); return kgem_retire(kgem); } static void *__kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo) { struct drm_i915_gem_mmap_gtt gtt; void *ptr; int err; DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__, bo->handle, bytes(bo))); if (bo->tiling && !kgem->can_fence) return NULL; VG_CLEAR(gtt); retry_gtt: gtt.handle = bo->handle; if ((err = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MMAP_GTT, >t))) { DBG(("%s: failed %d, throttling/cleaning caches\n", __FUNCTION__, err)); assert(err != EINVAL); (void)__kgem_throttle_retire(kgem, 0); if (kgem_expire_cache(kgem)) goto retry_gtt; if (kgem_cleanup_cache(kgem)) goto retry_gtt; ERR(("%s: failed to retrieve GTT offset for handle=%d: %d\n", __FUNCTION__, bo->handle, -err)); return NULL; } retry_mmap: ptr = mmap(0, bytes(bo), PROT_READ | PROT_WRITE, MAP_SHARED, kgem->fd, gtt.offset); if (ptr == MAP_FAILED) { err = errno; DBG(("%s: failed %d, throttling/cleaning caches\n", __FUNCTION__, err)); assert(err != EINVAL); if (__kgem_throttle_retire(kgem, 0)) goto retry_mmap; if (kgem_cleanup_cache(kgem)) goto retry_mmap; ERR(("%s: failed to mmap handle=%d, %d bytes, into GTT domain: %d\n", __FUNCTION__, bo->handle, bytes(bo), err)); ptr = NULL; } /* Cache this mapping to avoid the overhead of an * excruciatingly slow GTT pagefault. This is more an * issue with compositing managers which need to * frequently flush CPU damage to their GPU bo. */ return bo->map__gtt = ptr; } static void *__kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo) { struct local_i915_gem_mmap2 wc; int err; DBG(("%s(handle=%d, size=%d)\n", __FUNCTION__, bo->handle, bytes(bo))); assert(kgem->has_wc_mmap); VG_CLEAR(wc); retry_wc: wc.handle = bo->handle; wc.offset = 0; wc.size = bytes(bo); wc.flags = I915_MMAP_WC; if ((err = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc))) { DBG(("%s: failed %d, throttling/cleaning caches\n", __FUNCTION__, err)); assert(err != EINVAL); if (__kgem_throttle_retire(kgem, 0)) goto retry_wc; if (kgem_cleanup_cache(kgem)) goto retry_wc; ERR(("%s: failed to mmap handle=%d, %d bytes, into CPU(wc) domain: %d\n", __FUNCTION__, bo->handle, bytes(bo), -err)); return NULL; } VG(VALGRIND_MAKE_MEM_DEFINED(wc.addr_ptr, bytes(bo))); DBG(("%s: caching CPU(wc) vma for %d\n", __FUNCTION__, bo->handle)); return bo->map__wc = (void *)(uintptr_t)wc.addr_ptr; } static void *__kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo) { struct local_i915_gem_mmap arg; int err; VG_CLEAR(arg); arg.offset = 0; retry: arg.handle = bo->handle; arg.size = bytes(bo); if ((err = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP, &arg))) { DBG(("%s: failed %d, throttling/cleaning caches\n", __FUNCTION__, err)); assert(err != -EINVAL || bo->prime); if (__kgem_throttle_retire(kgem, 0)) goto retry; if (kgem_cleanup_cache(kgem)) goto retry; ERR(("%s: failed to mmap handle=%d (prime? %d), %d bytes, into CPU domain: %d\n", __FUNCTION__, bo->handle, bo->prime, bytes(bo), -err)); bo->purged = 1; return NULL; } VG(VALGRIND_MAKE_MEM_DEFINED(arg.addr_ptr, bytes(bo))); DBG(("%s: caching CPU vma for %d\n", __FUNCTION__, bo->handle)); return bo->map__cpu = (void *)(uintptr_t)arg.addr_ptr; } static int gem_write(int fd, uint32_t handle, int offset, int length, const void *src) { struct drm_i915_gem_pwrite pwrite; DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__, handle, offset, length)); VG_CLEAR(pwrite); pwrite.handle = handle; pwrite.offset = offset; pwrite.size = length; pwrite.data_ptr = (uintptr_t)src; return do_ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite); } static int gem_write__cachealigned(int fd, uint32_t handle, int offset, int length, const void *src) { struct drm_i915_gem_pwrite pwrite; DBG(("%s(handle=%d, offset=%d, len=%d)\n", __FUNCTION__, handle, offset, length)); VG_CLEAR(pwrite); pwrite.handle = handle; /* align the transfer to cachelines; fortuitously this is safe! */ if ((offset | length) & 63) { pwrite.offset = offset & ~63; pwrite.size = ALIGN(offset+length, 64) - pwrite.offset; pwrite.data_ptr = (uintptr_t)src + pwrite.offset - offset; } else { pwrite.offset = offset; pwrite.size = length; pwrite.data_ptr = (uintptr_t)src; } return do_ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite); } static int gem_read(int fd, uint32_t handle, const void *dst, int offset, int length) { struct drm_i915_gem_pread pread; int ret; DBG(("%s(handle=%d, len=%d)\n", __FUNCTION__, handle, length)); VG_CLEAR(pread); pread.handle = handle; pread.offset = offset; pread.size = length; pread.data_ptr = (uintptr_t)dst; ret = do_ioctl(fd, DRM_IOCTL_I915_GEM_PREAD, &pread); if (ret) { DBG(("%s: failed, errno=%d\n", __FUNCTION__, -ret)); return ret; } VG(VALGRIND_MAKE_MEM_DEFINED(dst, length)); return 0; } bool __kgem_busy(struct kgem *kgem, int handle) { struct drm_i915_gem_busy busy; VG_CLEAR(busy); busy.handle = handle; busy.busy = !kgem->wedged; (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy); DBG(("%s: handle=%d, busy=%d, wedged=%d\n", __FUNCTION__, handle, busy.busy, kgem->wedged)); return busy.busy; } static void kgem_bo_retire(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d [busy?=%d]\n", __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL, __kgem_busy(kgem, bo->handle))); assert(bo->exec == NULL); assert(list_is_empty(&bo->vma)); if (bo->rq) __kgem_retire_requests_upto(kgem, bo); ASSERT_IDLE(kgem, bo->handle); assert_bo_retired(bo); } static void kgem_bo_maybe_retire(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: retiring bo handle=%d (needed flush? %d), rq? %d [busy?=%d]\n", __FUNCTION__, bo->handle, bo->needs_flush, bo->rq != NULL, __kgem_busy(kgem, bo->handle))); assert(bo->exec == NULL); assert(list_is_empty(&bo->vma)); if (bo->rq) { if (!__kgem_busy(kgem, bo->handle)) __kgem_retire_requests_upto(kgem, bo); } else { assert(!bo->needs_flush); ASSERT_IDLE(kgem, bo->handle); } } bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo, const void *data, int length) { void *ptr; int err; assert(bo->refcnt); assert(bo->proxy == NULL); ASSERT_IDLE(kgem, bo->handle); assert(length <= bytes(bo)); retry: ptr = NULL; if (bo->domain == DOMAIN_CPU || (kgem->has_llc && !bo->scanout)) { ptr = bo->map__cpu; if (ptr == NULL) ptr = __kgem_bo_map__cpu(kgem, bo); } else if (kgem->has_wc_mmap) { ptr = bo->map__wc; if (ptr == NULL) ptr = __kgem_bo_map__wc(kgem, bo); } if (ptr) { /* XXX unsynchronized? */ memcpy(ptr, data, length); return true; } if ((err = gem_write(kgem->fd, bo->handle, 0, length, data))) { DBG(("%s: failed %d, throttling/cleaning caches\n", __FUNCTION__, err)); assert(err != EINVAL); (void)__kgem_throttle_retire(kgem, 0); if (kgem_expire_cache(kgem)) goto retry; if (kgem_cleanup_cache(kgem)) goto retry; ERR(("%s: failed to write %d bytes into BO handle=%d: %d\n", __FUNCTION__, length, bo->handle, -err)); return false; } DBG(("%s: flush=%d, domain=%d\n", __FUNCTION__, bo->flush, bo->domain)); if (bo->exec == NULL) kgem_bo_maybe_retire(kgem, bo); bo->domain = DOMAIN_NONE; bo->gtt_dirty = true; return true; } static uint32_t gem_create(int fd, int num_pages) { struct drm_i915_gem_create create; VG_CLEAR(create); create.handle = 0; create.size = PAGE_SIZE * num_pages; (void)do_ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); return create.handle; } static void kgem_bo_set_purgeable(struct kgem *kgem, struct kgem_bo *bo) { #if !DBG_NO_MADV struct drm_i915_gem_madvise madv; assert(bo->exec == NULL); VG_CLEAR(madv); madv.handle = bo->handle; madv.madv = I915_MADV_DONTNEED; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) { bo->purged = true; kgem->need_purge |= !madv.retained && bo->domain != DOMAIN_CPU; } #endif } static bool kgem_bo_is_retained(struct kgem *kgem, struct kgem_bo *bo) { #if DBG_NO_MADV return true; #else struct drm_i915_gem_madvise madv; if (!bo->purged) return true; VG_CLEAR(madv); madv.handle = bo->handle; madv.madv = I915_MADV_DONTNEED; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) return madv.retained; return false; #endif } static bool kgem_bo_clear_purgeable(struct kgem *kgem, struct kgem_bo *bo) { #if DBG_NO_MADV return true; #else struct drm_i915_gem_madvise madv; assert(bo->purged); VG_CLEAR(madv); madv.handle = bo->handle; madv.madv = I915_MADV_WILLNEED; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_MADVISE, &madv) == 0) { bo->purged = !madv.retained; kgem->need_purge |= !madv.retained && bo->domain != DOMAIN_CPU; return madv.retained; } return false; #endif } static void gem_close(int fd, uint32_t handle) { struct drm_gem_close close; VG_CLEAR(close); close.handle = handle; (void)do_ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close); } constant inline static unsigned long __fls(unsigned long word) { #if defined(__GNUC__) && (defined(__i386__) || defined(__x86__) || defined(__x86_64__)) asm("bsr %1,%0" : "=r" (word) : "rm" (word)); return word; #else unsigned int v = 0; while (word >>= 1) v++; return v; #endif } constant inline static int cache_bucket(int num_pages) { return __fls(num_pages); } static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo, int handle, int num_pages) { DBG(("%s(handle=%d, num_pages=%d)\n", __FUNCTION__, handle, num_pages)); assert(num_pages); memset(bo, 0, sizeof(*bo)); bo->refcnt = 1; bo->handle = handle; bo->target_handle = -1; num_pages(bo) = num_pages; bucket(bo) = cache_bucket(num_pages); bo->reusable = true; bo->domain = DOMAIN_CPU; list_init(&bo->request); list_init(&bo->list); list_init(&bo->vma); return bo; } static struct kgem_bo *__kgem_bo_alloc(int handle, int num_pages) { struct kgem_bo *bo; if (__kgem_freed_bo) { bo = __kgem_freed_bo; __kgem_freed_bo = *(struct kgem_bo **)bo; } else { bo = malloc(sizeof(*bo)); if (bo == NULL) return NULL; } return __kgem_bo_init(bo, handle, num_pages); } static struct kgem_request *__kgem_request_alloc(struct kgem *kgem) { struct kgem_request *rq; if (unlikely(kgem->wedged)) { rq = &kgem->static_request; } else { rq = __kgem_freed_request; if (rq) { __kgem_freed_request = *(struct kgem_request **)rq; } else { rq = malloc(sizeof(*rq)); if (rq == NULL) rq = &kgem->static_request; } } list_init(&rq->buffers); rq->bo = NULL; rq->ring = 0; return rq; } static void __kgem_request_free(struct kgem_request *rq) { _list_del(&rq->list); if (DBG_NO_MALLOC_CACHE) { free(rq); } else { *(struct kgem_request **)rq = __kgem_freed_request; __kgem_freed_request = rq; } } static struct list *inactive(struct kgem *kgem, int num_pages) { assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE); assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS); return &kgem->inactive[cache_bucket(num_pages)]; } static struct list *active(struct kgem *kgem, int num_pages, int tiling) { assert(num_pages < MAX_CACHE_SIZE / PAGE_SIZE); assert(cache_bucket(num_pages) < NUM_CACHE_BUCKETS); return &kgem->active[cache_bucket(num_pages)][tiling]; } static size_t agp_aperture_size(struct pci_device *dev, unsigned gen) { /* XXX assume that only future chipsets are unknown and follow * the post gen2 PCI layout. */ return dev->regions[gen < 030 ? 0 : 2].size; } static size_t total_ram_size(void) { #ifdef HAVE_STRUCT_SYSINFO_TOTALRAM struct sysinfo info; if (sysinfo(&info) == 0) return (size_t)info.totalram * info.mem_unit; #endif #ifdef _SC_PHYS_PAGES return (size_t)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGE_SIZE); #endif return 0; } static unsigned cpu_cache_size__cpuid4(void) { /* Deterministic Cache Parameters (Function 04h)": * When EAX is initialized to a value of 4, the CPUID instruction * returns deterministic cache information in the EAX, EBX, ECX * and EDX registers. This function requires ECX be initialized * with an index which indicates which cache to return information * about. The OS is expected to call this function (CPUID.4) with * ECX = 0, 1, 2, until EAX[4:0] == 0, indicating no more caches. * The order in which the caches are returned is not specified * and may change at Intel's discretion. * * Calculating the Cache Size in bytes: * = (Ways +1) * (Partitions +1) * (Line Size +1) * (Sets +1) */ unsigned int eax, ebx, ecx, edx; unsigned int llc_size = 0; int cnt; if (__get_cpuid_max(BASIC_CPUID, NULL) < 4) return 0; cnt = 0; do { unsigned associativity, line_partitions, line_size, sets; __cpuid_count(4, cnt++, eax, ebx, ecx, edx); if ((eax & 0x1f) == 0) break; associativity = ((ebx >> 22) & 0x3ff) + 1; line_partitions = ((ebx >> 12) & 0x3ff) + 1; line_size = (ebx & 0xfff) + 1; sets = ecx + 1; llc_size = associativity * line_partitions * line_size * sets; } while (1); return llc_size; } static unsigned cpu_cache_size(void) { unsigned size; FILE *file; size = cpu_cache_size__cpuid4(); if (size) return size; file = fopen("/proc/cpuinfo", "r"); if (file) { size_t len = 0; char *line = NULL; while (getline(&line, &len, file) != -1) { int kb; if (sscanf(line, "cache size : %d KB", &kb) == 1) { /* Paranoid check against gargantuan caches */ if (kb <= 1<<20) size = kb * 1024; break; } } free(line); fclose(file); } if (size == 0) size = 64 * 1024; return size; } static int gem_param(struct kgem *kgem, int name) { drm_i915_getparam_t gp; int v = -1; /* No param uses the sign bit, reserve it for errors */ VG_CLEAR(gp); gp.param = name; gp.value = &v; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GETPARAM, &gp)) return -1; VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v))); return v; } static bool test_has_execbuffer2(struct kgem *kgem) { struct drm_i915_gem_execbuffer2 execbuf; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffer_count = 1; return do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf) == -EFAULT; } static bool test_has_no_reloc(struct kgem *kgem) { if (DBG_NO_FAST_RELOC) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_NO_RELOC) > 0; } static bool test_has_handle_lut(struct kgem *kgem) { if (DBG_NO_HANDLE_LUT) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_HANDLE_LUT) > 0; } static bool test_has_wt(struct kgem *kgem) { if (DBG_NO_WT) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_WT) > 0; } static bool test_has_semaphores_enabled(struct kgem *kgem) { FILE *file; bool detected = false; int ret; if (DBG_NO_SEMAPHORES) return false; ret = gem_param(kgem, LOCAL_I915_PARAM_HAS_SEMAPHORES); if (ret != -1) return ret > 0; file = fopen("/sys/module/i915/parameters/semaphores", "r"); if (file) { int value; if (fscanf(file, "%d", &value) == 1) detected = value != 0; fclose(file); } return detected; } static bool is_hw_supported(struct kgem *kgem, struct pci_device *dev) { if (DBG_NO_HW) return false; if (!test_has_execbuffer2(kgem)) return false; if (kgem->gen == (unsigned)-1) /* unknown chipset, assume future gen */ return kgem->has_blt; /* Although pre-855gm the GMCH is fubar, it works mostly. So * let the user decide through "NoAccel" whether or not to risk * hw acceleration. */ if (kgem->gen == 060 && dev && dev->revision < 8) { /* pre-production SNB with dysfunctional BLT */ return false; } if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */ return kgem->has_blt; return true; } static bool test_has_relaxed_fencing(struct kgem *kgem) { if (kgem->gen < 040) { if (DBG_NO_RELAXED_FENCING) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_FENCING) > 0; } else return true; } static bool test_has_llc(struct kgem *kgem) { int has_llc = -1; if (DBG_NO_LLC) return false; has_llc = gem_param(kgem, LOCAL_I915_PARAM_HAS_LLC); if (has_llc == -1) { DBG(("%s: no kernel/drm support for HAS_LLC, assuming support for LLC based on GPU generation\n", __FUNCTION__)); has_llc = kgem->gen >= 060; } return has_llc; } static bool test_has_wc_mmap(struct kgem *kgem) { struct local_i915_gem_mmap2 wc; bool ret; if (DBG_NO_WC_MMAP) return false; /* XXX See https://bugs.freedesktop.org/show_bug.cgi?id=90841 */ if (kgem->gen < 033) return false; if (gem_param(kgem, LOCAL_I915_PARAM_MMAP_VERSION) < 1) return false; VG_CLEAR(wc); wc.handle = gem_create(kgem->fd, 1); wc.offset = 0; wc.size = 4096; wc.flags = I915_MMAP_WC; ret = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_MMAP_v2, &wc) == 0; gem_close(kgem->fd, wc.handle); return ret; } static bool test_has_caching(struct kgem *kgem) { uint32_t handle; bool ret; if (DBG_NO_CACHE_LEVEL) return false; /* Incoherent blt and sampler hangs the GPU */ if (kgem->gen == 040) return false; handle = gem_create(kgem->fd, 1); if (handle == 0) return false; ret = gem_set_caching(kgem->fd, handle, UNCACHED); gem_close(kgem->fd, handle); return ret; } static bool test_has_userptr(struct kgem *kgem) { struct local_i915_gem_userptr arg; void *ptr; if (DBG_NO_USERPTR) return false; /* Incoherent blt and sampler hangs the GPU */ if (kgem->gen == 040) return false; if (posix_memalign(&ptr, PAGE_SIZE, PAGE_SIZE)) return false; VG_CLEAR(arg); arg.user_ptr = (uintptr_t)ptr; arg.user_size = PAGE_SIZE; arg.flags = I915_USERPTR_UNSYNCHRONIZED; if (DBG_NO_UNSYNCHRONIZED_USERPTR || do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg)) { arg.flags &= ~I915_USERPTR_UNSYNCHRONIZED; if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_USERPTR, &arg)) arg.handle = 0; /* Leak the userptr bo to keep the mmu_notifier alive */ } else { gem_close(kgem->fd, arg.handle); free(ptr); } return arg.handle != 0; } static bool test_has_create2(struct kgem *kgem) { #if defined(USE_CREATE2) struct local_i915_gem_create2 args; if (DBG_NO_CREATE2) return false; memset(&args, 0, sizeof(args)); args.size = PAGE_SIZE; args.caching = DISPLAY; if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args) == 0) gem_close(kgem->fd, args.handle); return args.handle != 0; #else return false; #endif } static bool test_can_blt_y(struct kgem *kgem) { struct drm_i915_gem_exec_object2 object; uint32_t batch[] = { #define MI_LOAD_REGISTER_IMM (0x22<<23 | (3-2)) #define BCS_SWCTRL 0x22200 #define BCS_SRC_Y (1 << 0) #define BCS_DST_Y (1 << 1) MI_LOAD_REGISTER_IMM, BCS_SWCTRL, (BCS_SRC_Y | BCS_DST_Y) << 16 | (BCS_SRC_Y | BCS_DST_Y), MI_LOAD_REGISTER_IMM, BCS_SWCTRL, (BCS_SRC_Y | BCS_DST_Y) << 16, MI_BATCH_BUFFER_END, 0, }; int ret; if (DBG_NO_BLT_Y) return false; if (kgem->gen < 060) return false; memset(&object, 0, sizeof(object)); object.handle = gem_create(kgem->fd, 1); ret = gem_write(kgem->fd, object.handle, 0, sizeof(batch), batch); if (ret == 0) { struct drm_i915_gem_execbuffer2 execbuf; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)&object; execbuf.buffer_count = 1; execbuf.flags = KGEM_BLT; ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); } gem_close(kgem->fd, object.handle); return ret == 0; } static bool gem_set_tiling(int fd, uint32_t handle, int tiling, int stride) { struct drm_i915_gem_set_tiling set_tiling; if (DBG_NO_TILING) return false; VG_CLEAR(set_tiling); set_tiling.handle = handle; set_tiling.tiling_mode = tiling; set_tiling.stride = stride; if (ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling) == 0) return set_tiling.tiling_mode == tiling; return false; } static bool test_can_scanout_y(struct kgem *kgem) { struct drm_mode_fb_cmd arg; bool ret = false; if (DBG_NO_SCANOUT_Y) return false; VG_CLEAR(arg); arg.width = 32; arg.height = 32; arg.pitch = 4*32; arg.bpp = 32; arg.depth = 24; arg.handle = gem_create(kgem->fd, 1); if (gem_set_tiling(kgem->fd, arg.handle, I915_TILING_Y, arg.pitch)) ret = do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0; if (!ret) { struct local_mode_fb_cmd2 { uint32_t fb_id; uint32_t width, height; uint32_t pixel_format; uint32_t flags; uint32_t handles[4]; uint32_t pitches[4]; uint32_t offsets[4]; uint64_t modifiers[4]; } f; #define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2) memset(&f, 0, sizeof(f)); f.width = arg.width; f.height = arg.height; f.handles[0] = arg.handle; f.pitches[0] = arg.pitch; f.modifiers[0] = (uint64_t)1 << 56 | 2; /* MOD_Y_TILED */ f.pixel_format = 'X' | 'R' << 8 | '2' << 16 | '4' << 24; /* XRGB8888 */ f.flags = 1 << 1; /* + modifier */ if (drmIoctl(kgem->fd, LOCAL_IOCTL_MODE_ADDFB2, &f) == 0) { ret = true; arg.fb_id = f.fb_id; } } do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &arg.fb_id); gem_close(kgem->fd, arg.handle); return ret; } static bool test_has_dirtyfb(struct kgem *kgem) { struct drm_mode_fb_cmd create; bool ret = false; if (DBG_NO_DIRTYFB) return false; VG_CLEAR(create); create.width = 32; create.height = 32; create.pitch = 4*32; create.bpp = 32; create.depth = 32; create.handle = gem_create(kgem->fd, 1); if (create.handle == 0) return false; if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &create) == 0) { struct drm_mode_fb_dirty_cmd dirty; memset(&dirty, 0, sizeof(dirty)); dirty.fb_id = create.fb_id; ret = drmIoctl(kgem->fd, DRM_IOCTL_MODE_DIRTYFB, &dirty) == 0; /* XXX There may be multiple levels of DIRTYFB, depending on * whether the kernel thinks tracking dirty regions is * beneficial vs flagging the whole fb as dirty. */ drmIoctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &create.fb_id); } gem_close(kgem->fd, create.handle); return ret; } static bool test_has_secure_batches(struct kgem *kgem) { if (DBG_NO_SECURE_BATCHES) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_SECURE_BATCHES) > 0; } static bool test_has_pinned_batches(struct kgem *kgem) { if (DBG_NO_PINNED_BATCHES) return false; return gem_param(kgem, LOCAL_I915_PARAM_HAS_PINNED_BATCHES) > 0; } static bool kgem_init_pinned_batches(struct kgem *kgem) { int count[2] = { 16, 4 }; int size[2] = { 1, 4 }; int ret = 0; int n, i; if (unlikely(kgem->wedged)) return true; for (n = 0; n < ARRAY_SIZE(count); n++) { for (i = 0; i < count[n]; i++) { struct drm_i915_gem_pin pin; struct kgem_bo *bo; VG_CLEAR(pin); pin.handle = gem_create(kgem->fd, size[n]); if (pin.handle == 0) goto err; DBG(("%s: new handle=%d, num_pages=%d\n", __FUNCTION__, pin.handle, size[n])); bo = __kgem_bo_alloc(pin.handle, size[n]); if (bo == NULL) { gem_close(kgem->fd, pin.handle); goto err; } pin.alignment = 0; ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin); if (ret) { gem_close(kgem->fd, pin.handle); free(bo); goto err; } bo->presumed_offset = pin.offset; debug_alloc__bo(kgem, bo); list_add(&bo->list, &kgem->pinned_batches[n]); } } return true; err: for (n = 0; n < ARRAY_SIZE(kgem->pinned_batches); n++) { while (!list_is_empty(&kgem->pinned_batches[n])) { kgem_bo_destroy(kgem, list_first_entry(&kgem->pinned_batches[n], struct kgem_bo, list)); } } /* If we fail to pin some memory for 830gm/845g, we need to disable * acceleration as otherwise the machine will eventually fail. However, * the kernel started arbitrarily rejecting PIN, so hope for the best * if the ioctl no longer works. */ if (ret != -ENODEV && kgem->gen == 020) return false; kgem->has_pinned_batches = false; /* For simplicity populate the lists with a single unpinned bo */ for (n = 0; n < ARRAY_SIZE(count); n++) { struct kgem_bo *bo; uint32_t handle; handle = gem_create(kgem->fd, size[n]); if (handle == 0) return false; bo = __kgem_bo_alloc(handle, size[n]); if (bo == NULL) { gem_close(kgem->fd, handle); return false; } debug_alloc__bo(kgem, bo); list_add(&bo->list, &kgem->pinned_batches[n]); } return true; } static void kgem_init_swizzling(struct kgem *kgem) { struct local_i915_gem_get_tiling_v2 { uint32_t handle; uint32_t tiling_mode; uint32_t swizzle_mode; uint32_t phys_swizzle_mode; } tiling; #define LOCAL_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct local_i915_gem_get_tiling_v2) memset(&tiling, 0, sizeof(tiling)); tiling.handle = gem_create(kgem->fd, 1); if (!tiling.handle) return; if (!gem_set_tiling(kgem->fd, tiling.handle, I915_TILING_X, 512)) goto out; if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_TILING, &tiling)) goto out; DBG(("%s: swizzle_mode=%d, phys_swizzle_mode=%d\n", __FUNCTION__, tiling.swizzle_mode, tiling.phys_swizzle_mode)); kgem->can_fence = !DBG_NO_TILING && tiling.swizzle_mode != I915_BIT_6_SWIZZLE_UNKNOWN; if (kgem->gen < 050 && tiling.phys_swizzle_mode != tiling.swizzle_mode) goto out; if (!DBG_NO_DETILING) choose_memcpy_tiled_x(kgem, tiling.swizzle_mode); out: gem_close(kgem->fd, tiling.handle); DBG(("%s: can fence?=%d\n", __FUNCTION__, kgem->can_fence)); } static void kgem_fixup_relocs(struct kgem *kgem, struct kgem_bo *bo, int shrink) { int n; bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle; assert(kgem->nreloc__self <= 256); if (kgem->nreloc__self == 0) return; DBG(("%s: fixing up %d%s self-relocations to handle=%p, presumed-offset=%llx\n", __FUNCTION__, kgem->nreloc__self, kgem->nreloc__self == 256 ? "+" : "", bo->handle, (long long)bo->presumed_offset)); for (n = 0; n < kgem->nreloc__self; n++) { int i = kgem->reloc__self[n]; uint64_t addr; assert(kgem->reloc[i].target_handle == ~0U); kgem->reloc[i].target_handle = bo->target_handle; kgem->reloc[i].presumed_offset = bo->presumed_offset; if (kgem->reloc[i].read_domains == I915_GEM_DOMAIN_INSTRUCTION) { DBG(("%s: moving base of self-reloc[%d:%d] %d -> %d\n", __FUNCTION__, n, i, kgem->reloc[i].delta, kgem->reloc[i].delta - shrink)); kgem->reloc[i].delta -= shrink; } addr = (int)kgem->reloc[i].delta + bo->presumed_offset; kgem->batch[kgem->reloc[i].offset/sizeof(uint32_t)] = addr; if (kgem->gen >= 0100) kgem->batch[kgem->reloc[i].offset/sizeof(uint32_t) + 1] = addr >> 32; } if (n == 256) { for (n = kgem->reloc__self[255]; n < kgem->nreloc; n++) { if (kgem->reloc[n].target_handle == ~0U) { uint64_t addr; kgem->reloc[n].target_handle = bo->target_handle; kgem->reloc[n].presumed_offset = bo->presumed_offset; if (kgem->reloc[n].read_domains == I915_GEM_DOMAIN_INSTRUCTION) { DBG(("%s: moving base of reloc[%d] %d -> %d\n", __FUNCTION__, n, kgem->reloc[n].delta, kgem->reloc[n].delta - shrink)); kgem->reloc[n].delta -= shrink; } addr = (int)kgem->reloc[n].delta + bo->presumed_offset; kgem->batch[kgem->reloc[n].offset/sizeof(uint32_t)] = addr; if (kgem->gen >= 0100) kgem->batch[kgem->reloc[n].offset/sizeof(uint32_t) + 1] = addr >> 32; } } } if (shrink) { DBG(("%s: shrinking by %d\n", __FUNCTION__, shrink)); for (n = 0; n < kgem->nreloc; n++) { if (kgem->reloc[n].offset >= sizeof(uint32_t)*kgem->nbatch) kgem->reloc[n].offset -= shrink; } } } static int kgem_bo_wait(struct kgem *kgem, struct kgem_bo *bo) { struct local_i915_gem_wait { uint32_t handle; uint32_t flags; int64_t timeout; } wait; #define LOCAL_I915_GEM_WAIT 0x2c #define LOCAL_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + LOCAL_I915_GEM_WAIT, struct local_i915_gem_wait) int ret; DBG(("%s: waiting for handle=%d\n", __FUNCTION__, bo->handle)); if (bo->rq == NULL) return 0; VG_CLEAR(wait); wait.handle = bo->handle; wait.flags = 0; wait.timeout = -1; ret = do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_WAIT, &wait); if (ret) { struct drm_i915_gem_set_domain set_domain; VG_CLEAR(set_domain); set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); } if (ret == 0) __kgem_retire_requests_upto(kgem, bo); return ret; } static struct kgem_bo *kgem_new_batch(struct kgem *kgem) { struct kgem_bo *last; unsigned flags; last = kgem->batch_bo; if (last) { kgem_fixup_relocs(kgem, last, 0); kgem->batch = NULL; } if (kgem->batch) { assert(last == NULL); return NULL; } flags = CREATE_CPU_MAP | CREATE_NO_THROTTLE; if (!kgem->has_llc) flags |= CREATE_UNCACHED; restart: kgem->batch_bo = kgem_create_linear(kgem, sizeof(uint32_t)*kgem->batch_size, flags); if (kgem->batch_bo) kgem->batch = kgem_bo_map__cpu(kgem, kgem->batch_bo); if (kgem->batch == NULL) { int ring = kgem->ring == KGEM_BLT; assert(ring < ARRAY_SIZE(kgem->requests)); if (kgem->batch_bo) { kgem_bo_destroy(kgem, kgem->batch_bo); kgem->batch_bo = NULL; } if (!list_is_empty(&kgem->requests[ring])) { struct kgem_request *rq; rq = list_first_entry(&kgem->requests[ring], struct kgem_request, list); assert(rq->ring == ring); assert(rq->bo); assert(RQ(rq->bo->rq) == rq); if (kgem_bo_wait(kgem, rq->bo) == 0) goto restart; } if (flags & CREATE_NO_THROTTLE) { flags &= ~CREATE_NO_THROTTLE; if (kgem_cleanup_cache(kgem)) goto restart; } DBG(("%s: unable to map batch bo, mallocing(size=%d)\n", __FUNCTION__, sizeof(uint32_t)*kgem->batch_size)); if (posix_memalign((void **)&kgem->batch, PAGE_SIZE, ALIGN(sizeof(uint32_t) * kgem->batch_size, PAGE_SIZE))) { ERR(("%s: batch allocation failed, disabling acceleration\n", __FUNCTION__)); __kgem_set_wedged(kgem); } } else { DBG(("%s: allocated and mapped batch handle=%d [size=%d]\n", __FUNCTION__, kgem->batch_bo->handle, sizeof(uint32_t)*kgem->batch_size)); kgem_bo_sync__cpu(kgem, kgem->batch_bo); } DBG(("%s: using last batch handle=%d\n", __FUNCTION__, last ? last->handle : 0)); return last; } static void no_retire(struct kgem *kgem) { (void)kgem; } static void no_expire(struct kgem *kgem) { (void)kgem; } static void no_context_switch(struct kgem *kgem, int new_mode) { (void)kgem; (void)new_mode; } static uint64_t get_gtt_size(int fd) { struct drm_i915_gem_get_aperture aperture; struct local_i915_gem_context_param { uint32_t context; uint32_t size; uint64_t param; #define LOCAL_CONTEXT_PARAM_BAN_PERIOD 0x1 #define LOCAL_CONTEXT_PARAM_NO_ZEROMAP 0x2 #define LOCAL_CONTEXT_PARAM_GTT_SIZE 0x3 uint64_t value; } p; #define LOCAL_I915_GEM_CONTEXT_GETPARAM 0x34 #define LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_GETPARAM, struct local_i915_gem_context_param) memset(&aperture, 0, sizeof(aperture)); memset(&p, 0, sizeof(p)); p.param = LOCAL_CONTEXT_PARAM_GTT_SIZE; if (drmIoctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, &p) == 0) aperture.aper_size = p.value; if (aperture.aper_size == 0) (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture); if (aperture.aper_size == 0) aperture.aper_size = 64*1024*1024; DBG(("%s: aperture size %lld, available now %lld\n", __FUNCTION__, (long long)aperture.aper_size, (long long)aperture.aper_available_size)); /* clamp aperture to uint32_t for simplicity */ if (aperture.aper_size > 0xc0000000) aperture.aper_size = 0xc0000000; return aperture.aper_size; } void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen) { size_t totalram; unsigned half_gpu_max; unsigned int i, j; uint64_t gtt_size; DBG(("%s: fd=%d, gen=%d\n", __FUNCTION__, fd, gen)); kgem->fd = fd; kgem->gen = gen; kgem->retire = no_retire; kgem->expire = no_expire; kgem->context_switch = no_context_switch; list_init(&kgem->requests[0]); list_init(&kgem->requests[1]); list_init(&kgem->batch_buffers); list_init(&kgem->active_buffers); list_init(&kgem->flushing); list_init(&kgem->large); list_init(&kgem->large_inactive); list_init(&kgem->snoop); list_init(&kgem->scanout); for (i = 0; i < ARRAY_SIZE(kgem->pinned_batches); i++) list_init(&kgem->pinned_batches[i]); for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) list_init(&kgem->inactive[i]); for (i = 0; i < ARRAY_SIZE(kgem->active); i++) { for (j = 0; j < ARRAY_SIZE(kgem->active[i]); j++) list_init(&kgem->active[i][j]); } for (i = 0; i < ARRAY_SIZE(kgem->vma); i++) { for (j = 0; j < ARRAY_SIZE(kgem->vma[i].inactive); j++) list_init(&kgem->vma[i].inactive[j]); } kgem->vma[MAP_GTT].count = -MAX_GTT_VMA_CACHE; kgem->vma[MAP_CPU].count = -MAX_CPU_VMA_CACHE; kgem->has_blt = gem_param(kgem, LOCAL_I915_PARAM_HAS_BLT) > 0; DBG(("%s: has BLT ring? %d\n", __FUNCTION__, kgem->has_blt)); kgem->has_relaxed_delta = gem_param(kgem, LOCAL_I915_PARAM_HAS_RELAXED_DELTA) > 0; DBG(("%s: has relaxed delta? %d\n", __FUNCTION__, kgem->has_relaxed_delta)); kgem->has_relaxed_fencing = test_has_relaxed_fencing(kgem); DBG(("%s: has relaxed fencing? %d\n", __FUNCTION__, kgem->has_relaxed_fencing)); kgem->has_llc = test_has_llc(kgem); DBG(("%s: has shared last-level-cache? %d\n", __FUNCTION__, kgem->has_llc)); kgem->has_wt = test_has_wt(kgem); DBG(("%s: has write-through caching for scanouts? %d\n", __FUNCTION__, kgem->has_wt)); kgem->has_wc_mmap = test_has_wc_mmap(kgem); DBG(("%s: has wc-mmapping? %d\n", __FUNCTION__, kgem->has_wc_mmap)); kgem->has_caching = test_has_caching(kgem); DBG(("%s: has set-cache-level? %d\n", __FUNCTION__, kgem->has_caching)); kgem->has_userptr = test_has_userptr(kgem); DBG(("%s: has userptr? %d\n", __FUNCTION__, kgem->has_userptr)); kgem->has_create2 = test_has_create2(kgem); DBG(("%s: has create2? %d\n", __FUNCTION__, kgem->has_create2)); kgem->has_no_reloc = test_has_no_reloc(kgem); DBG(("%s: has no-reloc? %d\n", __FUNCTION__, kgem->has_no_reloc)); kgem->has_handle_lut = test_has_handle_lut(kgem); DBG(("%s: has handle-lut? %d\n", __FUNCTION__, kgem->has_handle_lut)); kgem->has_semaphores = false; if (kgem->has_blt && test_has_semaphores_enabled(kgem)) kgem->has_semaphores = true; DBG(("%s: semaphores enabled? %d\n", __FUNCTION__, kgem->has_semaphores)); kgem->can_blt_cpu = gen >= 030; DBG(("%s: can blt to cpu? %d\n", __FUNCTION__, kgem->can_blt_cpu)); kgem->can_blt_y = test_can_blt_y(kgem); DBG(("%s: can blit to Y-tiled surfaces? %d\n", __FUNCTION__, kgem->can_blt_y)); kgem->can_render_y = gen != 021 && (gen >> 3) != 4; DBG(("%s: can render to Y-tiled surfaces? %d\n", __FUNCTION__, kgem->can_render_y)); kgem->can_scanout_y = test_can_scanout_y(kgem); DBG(("%s: can scanout Y-tiled surfaces? %d\n", __FUNCTION__, kgem->can_scanout_y)); kgem->has_dirtyfb = test_has_dirtyfb(kgem); DBG(("%s: has dirty fb? %d\n", __FUNCTION__, kgem->has_dirtyfb)); kgem->has_secure_batches = test_has_secure_batches(kgem); DBG(("%s: can use privileged batchbuffers? %d\n", __FUNCTION__, kgem->has_secure_batches)); kgem->has_pinned_batches = test_has_pinned_batches(kgem); DBG(("%s: can use pinned batchbuffers (to avoid CS w/a)? %d\n", __FUNCTION__, kgem->has_pinned_batches)); if (!is_hw_supported(kgem, dev)) { xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING, "Detected unsupported/dysfunctional hardware, disabling acceleration.\n"); __kgem_set_wedged(kgem); } else if (__kgem_throttle(kgem, false)) { xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING, "Detected a hung GPU, disabling acceleration.\n"); __kgem_set_wedged(kgem); } kgem->batch_size = UINT16_MAX & ~7; if (gen == 020 && !kgem->has_pinned_batches) /* Limited to what we can pin */ kgem->batch_size = 4*1024; if (gen == 022) /* 865g cannot handle a batch spanning multiple pages */ kgem->batch_size = PAGE_SIZE / sizeof(uint32_t); if (gen >= 070) kgem->batch_size = 16*1024; if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024) kgem->batch_size = 4*1024; if (!kgem_init_pinned_batches(kgem)) { xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING, "Unable to reserve memory for GPU, disabling acceleration.\n"); __kgem_set_wedged(kgem); } DBG(("%s: maximum batch size? %d\n", __FUNCTION__, kgem->batch_size)); kgem_new_batch(kgem); kgem->half_cpu_cache_pages = cpu_cache_size() >> 13; DBG(("%s: last-level cache size: %d bytes, threshold in pages: %d\n", __FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages)); kgem->next_request = __kgem_request_alloc(kgem); DBG(("%s: cpu bo enabled %d: llc? %d, set-cache-level? %d, userptr? %d\n", __FUNCTION__, !DBG_NO_CPU && (kgem->has_llc | kgem->has_userptr | kgem->has_caching), kgem->has_llc, kgem->has_caching, kgem->has_userptr)); gtt_size = get_gtt_size(fd); kgem->aperture_total = gtt_size; kgem->aperture_high = gtt_size * 3/4; kgem->aperture_low = gtt_size * 1/3; if (gen < 033) { /* Severe alignment penalties */ kgem->aperture_high /= 2; kgem->aperture_low /= 2; } DBG(("%s: aperture low=%u [%u], high=%u [%u]\n", __FUNCTION__, kgem->aperture_low, kgem->aperture_low / (1024*1024), kgem->aperture_high, kgem->aperture_high / (1024*1024))); kgem->aperture_mappable = 256 * 1024 * 1024; if (dev != NULL) kgem->aperture_mappable = agp_aperture_size(dev, gen); if (kgem->aperture_mappable == 0 || kgem->aperture_mappable > gtt_size) kgem->aperture_mappable = gtt_size; DBG(("%s: aperture mappable=%d [%d MiB]\n", __FUNCTION__, kgem->aperture_mappable, kgem->aperture_mappable / (1024*1024))); kgem->aperture_fenceable = MIN(256*1024*1024, kgem->aperture_mappable); DBG(("%s: aperture fenceable=%d [%d MiB]\n", __FUNCTION__, kgem->aperture_fenceable, kgem->aperture_fenceable / (1024*1024))); kgem->buffer_size = 64 * 1024; while (kgem->buffer_size < kgem->aperture_mappable >> 10) kgem->buffer_size *= 2; if (kgem->buffer_size >> 12 > kgem->half_cpu_cache_pages) kgem->buffer_size = kgem->half_cpu_cache_pages << 12; kgem->buffer_size = 1 << __fls(kgem->buffer_size); DBG(("%s: buffer size=%d [%d KiB]\n", __FUNCTION__, kgem->buffer_size, kgem->buffer_size / 1024)); assert(kgem->buffer_size); kgem->max_object_size = 3 * (kgem->aperture_high >> 12) << 10; kgem->max_gpu_size = kgem->max_object_size; if (!kgem->has_llc && kgem->max_gpu_size > MAX_CACHE_SIZE) kgem->max_gpu_size = MAX_CACHE_SIZE; totalram = total_ram_size(); if (totalram == 0) { DBG(("%s: total ram size unknown, assuming maximum of total aperture\n", __FUNCTION__)); totalram = kgem->aperture_total; } DBG(("%s: total ram=%lld\n", __FUNCTION__, (long long)totalram)); if (kgem->max_object_size > totalram / 2) kgem->max_object_size = totalram / 2; if (kgem->max_gpu_size > totalram / 4) kgem->max_gpu_size = totalram / 4; if (kgem->aperture_high > totalram / 2) { kgem->aperture_high = totalram / 2; kgem->aperture_low = kgem->aperture_high / 4; DBG(("%s: reduced aperture watermaks to fit into ram; low=%d [%d], high=%d [%d]\n", __FUNCTION__, kgem->aperture_low, kgem->aperture_low / (1024*1024), kgem->aperture_high, kgem->aperture_high / (1024*1024))); } kgem->max_cpu_size = kgem->max_object_size; half_gpu_max = kgem->max_gpu_size / 2; kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2; if (kgem->max_copy_tile_size > half_gpu_max) kgem->max_copy_tile_size = half_gpu_max; if (kgem->has_llc) kgem->max_upload_tile_size = kgem->max_copy_tile_size; else kgem->max_upload_tile_size = kgem->aperture_fenceable / 4; if (kgem->max_upload_tile_size > half_gpu_max) kgem->max_upload_tile_size = half_gpu_max; if (kgem->max_upload_tile_size > kgem->aperture_high/2) kgem->max_upload_tile_size = kgem->aperture_high/2; if (kgem->max_upload_tile_size > kgem->aperture_low) kgem->max_upload_tile_size = kgem->aperture_low; if (kgem->max_upload_tile_size < 16*PAGE_SIZE) kgem->max_upload_tile_size = 16*PAGE_SIZE; kgem->large_object_size = MAX_CACHE_SIZE; if (kgem->large_object_size > half_gpu_max) kgem->large_object_size = half_gpu_max; if (kgem->max_copy_tile_size > kgem->aperture_high/2) kgem->max_copy_tile_size = kgem->aperture_high/2; if (kgem->max_copy_tile_size > kgem->aperture_low) kgem->max_copy_tile_size = kgem->aperture_low; if (kgem->max_copy_tile_size < 16*PAGE_SIZE) kgem->max_copy_tile_size = 16*PAGE_SIZE; if (kgem->has_llc | kgem->has_caching | kgem->has_userptr) { if (kgem->large_object_size > kgem->max_cpu_size) kgem->large_object_size = kgem->max_cpu_size; } else kgem->max_cpu_size = 0; if (DBG_NO_CPU) kgem->max_cpu_size = 0; DBG(("%s: maximum object size=%u\n", __FUNCTION__, kgem->max_object_size)); DBG(("%s: large object thresold=%u\n", __FUNCTION__, kgem->large_object_size)); DBG(("%s: max object sizes (gpu=%u, cpu=%u, tile upload=%u, copy=%u)\n", __FUNCTION__, kgem->max_gpu_size, kgem->max_cpu_size, kgem->max_upload_tile_size, kgem->max_copy_tile_size)); /* Convert the aperture thresholds to pages */ kgem->aperture_mappable /= PAGE_SIZE; kgem->aperture_fenceable /= PAGE_SIZE; kgem->aperture_low /= PAGE_SIZE; kgem->aperture_high /= PAGE_SIZE; kgem->aperture_total /= PAGE_SIZE; kgem->fence_max = gem_param(kgem, I915_PARAM_NUM_FENCES_AVAIL) - 2; if ((int)kgem->fence_max < 0) kgem->fence_max = 5; /* minimum safe value for all hw */ DBG(("%s: max fences=%d\n", __FUNCTION__, kgem->fence_max)); kgem->batch_flags_base = 0; if (kgem->has_no_reloc) kgem->batch_flags_base |= LOCAL_I915_EXEC_NO_RELOC; if (kgem->has_handle_lut) kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT; if (kgem->has_pinned_batches) kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED; kgem_init_swizzling(kgem); } /* XXX hopefully a good approximation */ static uint32_t kgem_get_unique_id(struct kgem *kgem) { uint32_t id; id = ++kgem->unique_id; if (id == 0) id = ++kgem->unique_id; return id; } inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags) { if (flags & CREATE_PRIME) return 256; if (flags & CREATE_SCANOUT) return 64; if (kgem->gen >= 0100) return 32; return 8; } void kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch, int *tile_width, int *tile_height, int *tile_size) { if (kgem->gen <= 030) { if (tiling) { if (kgem->gen < 030) { *tile_width = 128; *tile_height = 16; *tile_size = 2048; } else { *tile_width = 512; *tile_height = 8; *tile_size = 4096; } } else { *tile_width = 1; *tile_height = 1; *tile_size = 1; } } else switch (tiling) { default: case I915_TILING_NONE: *tile_width = 1; *tile_height = 1; *tile_size = 1; break; case I915_TILING_X: *tile_width = 512; *tile_height = 8; *tile_size = 4096; break; case I915_TILING_Y: *tile_width = 128; *tile_height = 32; *tile_size = 4096; break; } /* Force offset alignment to tile-row */ if (tiling && kgem->gen < 033) *tile_width = pitch; } static uint32_t kgem_surface_size(struct kgem *kgem, bool relaxed_fencing, unsigned flags, uint32_t width, uint32_t height, uint32_t bpp, uint32_t tiling, uint32_t *pitch) { uint32_t tile_width, tile_height; uint32_t size; assert(width <= MAXSHORT); assert(height <= MAXSHORT); assert(bpp >= 8); if (kgem->gen <= 030) { if (tiling) { if (kgem->gen < 030) { tile_width = 128; tile_height = 16; } else { tile_width = 512; tile_height = 8; } } else { tile_width = 2 * bpp >> 3; tile_width = ALIGN(tile_width, kgem_pitch_alignment(kgem, flags)); tile_height = 1; } } else switch (tiling) { default: case I915_TILING_NONE: tile_width = 2 * bpp >> 3; tile_width = ALIGN(tile_width, kgem_pitch_alignment(kgem, flags)); tile_height = 1; break; case I915_TILING_X: tile_width = 512; tile_height = 8; break; case I915_TILING_Y: tile_width = 128; tile_height = 32; break; } /* XXX align to an even tile row */ if (!kgem->has_relaxed_fencing) tile_height *= 2; *pitch = ALIGN(width * bpp / 8, tile_width); height = ALIGN(height, tile_height); DBG(("%s: tile_width=%d, tile_height=%d => aligned pitch=%d, height=%d\n", __FUNCTION__, tile_width, tile_height, *pitch, height)); if (kgem->gen >= 040) return PAGE_ALIGN(*pitch * height); /* If it is too wide for the blitter, don't even bother. */ if (tiling != I915_TILING_NONE) { if (*pitch > 8192) { DBG(("%s: too wide for tiled surface (pitch=%d, limit=%d)\n", __FUNCTION__, *pitch, 8192)); return 0; } for (size = tile_width; size < *pitch; size <<= 1) ; *pitch = size; } else { if (*pitch >= 32768) { DBG(("%s: too wide for linear surface (pitch=%d, limit=%d)\n", __FUNCTION__, *pitch, 32767)); return 0; } } size = *pitch * height; if (relaxed_fencing || tiling == I915_TILING_NONE) return PAGE_ALIGN(size); /* We need to allocate a pot fence region for a tiled buffer. */ if (kgem->gen < 030) tile_width = 512 * 1024; else tile_width = 1024 * 1024; while (tile_width < size) tile_width *= 2; return tile_width; } bool kgem_check_surface_size(struct kgem *kgem, uint32_t width, uint32_t height, uint32_t bpp, uint32_t tiling, uint32_t pitch, uint32_t size) { uint32_t min_size, min_pitch; int tile_width, tile_height, tile_size; DBG(("%s(width=%d, height=%d, bpp=%d, tiling=%d, pitch=%d, size=%d)\n", __FUNCTION__, width, height, bpp, tiling, pitch, size)); if (pitch & 3) return false; min_size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, 0, width, height, bpp, tiling, &min_pitch); DBG(("%s: min_pitch=%d, min_size=%d\n", __FUNCTION__, min_pitch, min_size)); if (size < min_size) return false; if (pitch < min_pitch) return false; kgem_get_tile_size(kgem, tiling, min_pitch, &tile_width, &tile_height, &tile_size); DBG(("%s: tile_width=%d, tile_size=%d\n", __FUNCTION__, tile_width, tile_size)); if (pitch & (tile_width - 1)) return false; if (size & (tile_size - 1)) return false; return true; } static uint32_t kgem_aligned_height(struct kgem *kgem, uint32_t height, uint32_t tiling) { uint32_t tile_height; if (kgem->gen <= 030) { tile_height = tiling ? kgem->gen < 030 ? 16 : 8 : 1; } else switch (tiling) { /* XXX align to an even tile row */ default: case I915_TILING_NONE: tile_height = 1; break; case I915_TILING_X: tile_height = 8; break; case I915_TILING_Y: tile_height = 32; break; } /* XXX align to an even tile row */ if (!kgem->has_relaxed_fencing) tile_height *= 2; return ALIGN(height, tile_height); } static struct drm_i915_gem_exec_object2 * kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo) { struct drm_i915_gem_exec_object2 *exec; DBG(("%s: handle=%d, index=%d\n", __FUNCTION__, bo->handle, kgem->nexec)); assert(kgem->nexec < ARRAY_SIZE(kgem->exec)); bo->target_handle = kgem->has_handle_lut ? kgem->nexec : bo->handle; exec = memset(&kgem->exec[kgem->nexec++], 0, sizeof(*exec)); exec->handle = bo->handle; exec->offset = bo->presumed_offset; kgem->aperture += num_pages(bo); return exec; } static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt); assert(bo->proxy == NULL); bo->exec = kgem_add_handle(kgem, bo); bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring); list_move_tail(&bo->request, &kgem->next_request->buffers); if (bo->io && !list_is_empty(&bo->list)) list_move(&bo->list, &kgem->batch_buffers); /* XXX is it worth working around gcc here? */ kgem->flush |= bo->flush; } static void kgem_clear_swctrl(struct kgem *kgem) { uint32_t *b; if (kgem->bcs_state == 0) return; DBG(("%s: clearin SWCTRL LRI from %x\n", __FUNCTION__, kgem->bcs_state)); b = kgem->batch + kgem->nbatch; kgem->nbatch += 7; *b++ = MI_FLUSH_DW; *b++ = 0; *b++ = 0; *b++ = 0; *b++ = MI_LOAD_REGISTER_IMM; *b++ = BCS_SWCTRL; *b++ = (BCS_SRC_Y | BCS_DST_Y) << 16; kgem->bcs_state = 0; } static uint32_t kgem_end_batch(struct kgem *kgem) { kgem_clear_swctrl(kgem); kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END; if (kgem->nbatch & 1) kgem->batch[kgem->nbatch++] = MI_NOOP; return kgem->nbatch; } static void kgem_bo_binding_free(struct kgem *kgem, struct kgem_bo *bo) { struct kgem_bo_binding *b; b = bo->binding.next; while (b) { struct kgem_bo_binding *next = b->next; free(b); b = next; } } static void kgem_bo_rmfb(struct kgem *kgem, struct kgem_bo *bo) { if (bo->scanout && bo->delta) { DBG(("%s: releasing fb=%d for handle=%d\n", __FUNCTION__, bo->delta, bo->handle)); /* XXX will leak if we are not DRM_MASTER. *shrug* */ do_ioctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta); bo->delta = 0; } } static void kgem_bo_free(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo))); assert(bo->refcnt == 0); assert(bo->proxy == NULL); assert(bo->exec == NULL); assert(!bo->snoop || bo->rq == NULL); #ifdef DEBUG_MEMORY kgem->debug_memory.bo_allocs--; kgem->debug_memory.bo_bytes -= bytes(bo); #endif kgem_bo_binding_free(kgem, bo); kgem_bo_rmfb(kgem, bo); if (IS_USER_MAP(bo->map__cpu)) { assert(bo->rq == NULL); assert(!__kgem_busy(kgem, bo->handle)); assert(MAP(bo->map__cpu) != bo || bo->io || bo->flush); if (!(bo->io || bo->flush)) { DBG(("%s: freeing snooped base\n", __FUNCTION__)); assert(bo != MAP(bo->map__cpu)); free(MAP(bo->map__cpu)); } bo->map__cpu = NULL; } DBG(("%s: releasing %p:%p vma for handle=%d, count=%d\n", __FUNCTION__, bo->map__gtt, bo->map__cpu, bo->handle, list_is_empty(&bo->vma) ? 0 : kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count)); if (!list_is_empty(&bo->vma)) { _list_del(&bo->vma); kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--; } if (bo->map__gtt) munmap(bo->map__gtt, bytes(bo)); if (bo->map__wc) { VG(VALGRIND_MAKE_MEM_NOACCESS(bo->map__wc, bytes(bo))); munmap(bo->map__wc, bytes(bo)); } if (bo->map__cpu) { VG(VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map__cpu), bytes(bo))); munmap(MAP(bo->map__cpu), bytes(bo)); } _list_del(&bo->list); _list_del(&bo->request); gem_close(kgem->fd, bo->handle); if (!bo->io && !DBG_NO_MALLOC_CACHE) { *(struct kgem_bo **)bo = __kgem_freed_bo; __kgem_freed_bo = bo; } else free(bo); } inline static void kgem_bo_move_to_inactive(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: moving handle=%d to inactive\n", __FUNCTION__, bo->handle)); assert(bo->refcnt == 0); assert(bo->reusable); assert(bo->rq == NULL); assert(bo->exec == NULL); assert(bo->domain != DOMAIN_GPU); assert(!bo->proxy); assert(!bo->io); assert(!bo->scanout); assert(!bo->snoop); assert(!bo->flush); assert(!bo->needs_flush); assert(!bo->delta); assert(list_is_empty(&bo->vma)); assert_tiling(kgem, bo); assert_caching(kgem, bo); ASSERT_IDLE(kgem, bo->handle); if (bucket(bo) >= NUM_CACHE_BUCKETS) { if (bo->map__gtt) { DBG(("%s: relinquishing large GTT mapping for handle=%d\n", __FUNCTION__, bo->handle)); munmap(bo->map__gtt, bytes(bo)); bo->map__gtt = NULL; } list_move(&bo->list, &kgem->large_inactive); } else { assert(bo->flush == false); assert(list_is_empty(&bo->vma)); list_move(&bo->list, &kgem->inactive[bucket(bo)]); if (bo->map__gtt && !kgem_bo_can_map(kgem, bo)) { DBG(("%s: relinquishing old GTT mapping for handle=%d\n", __FUNCTION__, bo->handle)); munmap(bo->map__gtt, bytes(bo)); bo->map__gtt = NULL; } if (bo->map__gtt || (bo->map__wc && !bo->tiling)) { list_add(&bo->vma, &kgem->vma[0].inactive[bucket(bo)]); kgem->vma[0].count++; } if (bo->map__cpu && list_is_empty(&bo->vma)) { list_add(&bo->vma, &kgem->vma[1].inactive[bucket(bo)]); kgem->vma[1].count++; } } kgem->need_expire = true; } static struct kgem_bo *kgem_bo_replace_io(struct kgem_bo *bo) { struct kgem_bo *base; if (!bo->io) return bo; assert(!bo->snoop); assert(!bo->purged); assert(!bo->scanout); assert(!bo->delta); if (__kgem_freed_bo) { base = __kgem_freed_bo; __kgem_freed_bo = *(struct kgem_bo **)base; } else base = malloc(sizeof(*base)); if (base) { DBG(("%s: transferring io handle=%d to bo\n", __FUNCTION__, bo->handle)); /* transfer the handle to a minimum bo */ memcpy(base, bo, sizeof(*base)); base->io = false; list_init(&base->list); list_replace(&bo->request, &base->request); list_replace(&bo->vma, &base->vma); free(bo); bo = base; } else bo->reusable = false; return bo; } inline static void kgem_bo_remove_from_inactive(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: removing handle=%d from inactive\n", __FUNCTION__, bo->handle)); list_del(&bo->list); assert(bo->rq == NULL); assert(bo->exec == NULL); assert(!bo->purged); if (!list_is_empty(&bo->vma)) { assert(bo->map__gtt || bo->map__wc || bo->map__cpu); list_del(&bo->vma); kgem->vma[bo->map__gtt == NULL && bo->map__wc == NULL].count--; } } inline static void kgem_bo_remove_from_active(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: removing handle=%d from active\n", __FUNCTION__, bo->handle)); list_del(&bo->list); assert(bo->rq != NULL); if (RQ(bo->rq) == (void *)kgem) { assert(bo->exec == NULL); list_del(&bo->request); } assert(list_is_empty(&bo->vma)); } static void _kgem_bo_delete_buffer(struct kgem *kgem, struct kgem_bo *bo) { struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy; DBG(("%s: size=%d, offset=%d, parent used=%d\n", __FUNCTION__, bo->size.bytes, bo->delta, io->used)); if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used) io->used = bo->delta; } static bool check_scanout_size(struct kgem *kgem, struct kgem_bo *bo, int width, int height) { struct drm_mode_fb_cmd info; assert(bo->scanout); VG_CLEAR(info); info.fb_id = bo->delta; if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info)) return false; gem_close(kgem->fd, info.handle); if (width != info.width || height != info.height) { DBG(("%s: not using scanout %d (%dx%d), want (%dx%d)\n", __FUNCTION__, info.fb_id, info.width, info.height, width, height)); return false; } return true; } static void kgem_bo_move_to_scanout(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt == 0); assert(bo->scanout); assert(!bo->flush); assert(!bo->snoop); assert(!bo->io); if (bo->purged) { /* for stolen fb */ if (!bo->exec) { DBG(("%s: discarding purged scanout - stolen?\n", __FUNCTION__)); kgem_bo_free(kgem, bo); } return; } DBG(("%s: moving %d [fb %d] to scanout cache, active? %d\n", __FUNCTION__, bo->handle, bo->delta, bo->rq != NULL)); if (bo->rq) list_move_tail(&bo->list, &kgem->scanout); else list_move(&bo->list, &kgem->scanout); kgem->need_expire = true; } static void kgem_bo_move_to_snoop(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->reusable); assert(!bo->scanout); assert(!bo->flush); assert(!bo->needs_flush); assert(bo->refcnt == 0); assert(bo->exec == NULL); assert(!bo->purged); assert(!bo->delta); if (DBG_NO_SNOOP_CACHE) { kgem_bo_free(kgem, bo); return; } if (num_pages(bo) > kgem->max_cpu_size >> 13) { DBG(("%s handle=%d discarding large CPU buffer (%d >%d pages)\n", __FUNCTION__, bo->handle, num_pages(bo), kgem->max_cpu_size >> 13)); kgem_bo_free(kgem, bo); return; } assert(bo->tiling == I915_TILING_NONE); assert(bo->rq == NULL); DBG(("%s: moving %d to snoop cachee\n", __FUNCTION__, bo->handle)); list_add(&bo->list, &kgem->snoop); kgem->need_expire = true; } static bool kgem_bo_move_to_cache(struct kgem *kgem, struct kgem_bo *bo) { bool retired = false; DBG(("%s: release handle=%d\n", __FUNCTION__, bo->handle)); if (bo->prime) { DBG(("%s: discarding imported prime handle=%d\n", __FUNCTION__, bo->handle)); kgem_bo_free(kgem, bo); } else if (bo->snoop) { kgem_bo_move_to_snoop(kgem, bo); } else if (bo->scanout) { kgem_bo_move_to_scanout(kgem, bo); } else if ((bo = kgem_bo_replace_io(bo))->reusable) { kgem_bo_move_to_inactive(kgem, bo); retired = true; } else kgem_bo_free(kgem, bo); return retired; } static struct kgem_bo * search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags) { struct kgem_bo *bo, *first = NULL; DBG(("%s: num_pages=%d, flags=%x\n", __FUNCTION__, num_pages, flags)); if ((kgem->has_caching | kgem->has_userptr) == 0) return NULL; if (list_is_empty(&kgem->snoop)) { DBG(("%s: inactive and cache empty\n", __FUNCTION__)); if (!__kgem_throttle_retire(kgem, flags)) { DBG(("%s: nothing retired\n", __FUNCTION__)); return NULL; } } list_for_each_entry(bo, &kgem->snoop, list) { assert(bo->refcnt == 0); assert(bo->snoop); assert(!bo->scanout); assert(!bo->purged); assert(bo->proxy == NULL); assert(bo->tiling == I915_TILING_NONE); assert(bo->rq == NULL); assert(bo->exec == NULL); if (num_pages > num_pages(bo)) continue; if (num_pages(bo) > 2*num_pages) { if (first == NULL) first = bo; continue; } list_del(&bo->list); bo->pitch = 0; bo->delta = 0; DBG((" %s: found handle=%d (num_pages=%d) in snoop cache\n", __FUNCTION__, bo->handle, num_pages(bo))); return bo; } if (first) { list_del(&first->list); first->pitch = 0; first->delta = 0; DBG((" %s: found handle=%d (num_pages=%d) in snoop cache\n", __FUNCTION__, first->handle, num_pages(first))); return first; } return NULL; } void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo) { if (kgem->nexec != 1 || bo->exec == NULL) return; assert(bo); DBG(("%s: only handle in batch, discarding last operations for handle=%d\n", __FUNCTION__, bo->handle)); assert(bo->exec == &_kgem_dummy_exec || bo->exec == &kgem->exec[0]); assert(kgem->exec[0].handle == bo->handle); assert(RQ(bo->rq) == kgem->next_request); bo->refcnt++; kgem_reset(kgem); bo->refcnt--; assert(kgem->nreloc == 0); assert(kgem->nexec == 0); assert(bo->exec == NULL); } void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b) { if (kgem->nexec > 2) return; if (kgem->nexec == 1) { if (a) kgem_bo_undo(kgem, a); if (b) kgem_bo_undo(kgem, b); return; } if (a == NULL || b == NULL) return; assert(a != b); if (a->exec == NULL || b->exec == NULL) return; DBG(("%s: only handles in batch, discarding last operations for handle=%d (index=%d) and handle=%d (index=%d)\n", __FUNCTION__, a->handle, a->proxy ? -1 : a->exec - kgem->exec, b->handle, b->proxy ? -1 : b->exec - kgem->exec)); assert(a->exec == &_kgem_dummy_exec || a->exec == &kgem->exec[0] || a->exec == &kgem->exec[1]); assert(a->handle == kgem->exec[0].handle || a->handle == kgem->exec[1].handle); assert(RQ(a->rq) == kgem->next_request); assert(b->exec == &_kgem_dummy_exec || b->exec == &kgem->exec[0] || b->exec == &kgem->exec[1]); assert(b->handle == kgem->exec[0].handle || b->handle == kgem->exec[1].handle); assert(RQ(b->rq) == kgem->next_request); a->refcnt++; b->refcnt++; kgem_reset(kgem); b->refcnt--; a->refcnt--; assert(kgem->nreloc == 0); assert(kgem->nexec == 0); assert(a->exec == NULL); assert(b->exec == NULL); } static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, size=%d\n", __FUNCTION__, bo->handle, bytes(bo))); assert(list_is_empty(&bo->list)); assert(list_is_empty(&bo->vma)); assert(bo->refcnt == 0); assert(bo->proxy == NULL); assert(bo->active_scanout == 0); assert_tiling(kgem, bo); bo->binding.offset = 0; if (DBG_NO_CACHE) goto destroy; if (bo->prime) goto destroy; if (bo->snoop && !bo->flush) { DBG(("%s: handle=%d is snooped\n", __FUNCTION__, bo->handle)); assert(bo->reusable); assert(list_is_empty(&bo->list)); if (bo->exec == NULL && bo->rq && !__kgem_busy(kgem, bo->handle)) __kgem_bo_clear_busy(bo); if (bo->rq == NULL) kgem_bo_move_to_snoop(kgem, bo); return; } if (!IS_USER_MAP(bo->map__cpu)) bo->flush = false; if (bo->scanout) { kgem_bo_move_to_scanout(kgem, bo); return; } if (bo->io) bo = kgem_bo_replace_io(bo); if (!bo->reusable) { DBG(("%s: handle=%d, not reusable\n", __FUNCTION__, bo->handle)); goto destroy; } assert(list_is_empty(&bo->vma)); assert(list_is_empty(&bo->list)); assert(bo->flush == false); assert(bo->snoop == false); assert(bo->io == false); assert(bo->scanout == false); assert_caching(kgem, bo); kgem_bo_undo(kgem, bo); assert(bo->refcnt == 0); if (bo->rq && bo->exec == NULL && !__kgem_busy(kgem, bo->handle)) __kgem_bo_clear_busy(bo); if (bo->rq) { struct list *cache; DBG(("%s: handle=%d -> active\n", __FUNCTION__, bo->handle)); if (bucket(bo) < NUM_CACHE_BUCKETS) cache = &kgem->active[bucket(bo)][bo->tiling]; else cache = &kgem->large; list_add(&bo->list, cache); return; } assert(bo->exec == NULL); assert(list_is_empty(&bo->request)); if (bo->map__cpu == NULL || bucket(bo) >= NUM_CACHE_BUCKETS) { if (!kgem->has_llc && bo->domain == DOMAIN_CPU) goto destroy; DBG(("%s: handle=%d, purged\n", __FUNCTION__, bo->handle)); } kgem_bo_move_to_inactive(kgem, bo); return; destroy: if (!bo->exec) kgem_bo_free(kgem, bo); } static void kgem_bo_unref(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt); if (--bo->refcnt == 0) __kgem_bo_destroy(kgem, bo); } static void kgem_buffer_release(struct kgem *kgem, struct kgem_buffer *bo) { assert(bo->base.io); while (!list_is_empty(&bo->base.vma)) { struct kgem_bo *cached; cached = list_first_entry(&bo->base.vma, struct kgem_bo, vma); assert(cached->proxy == &bo->base); assert(cached != &bo->base); list_del(&cached->vma); assert(*(struct kgem_bo **)cached->map__gtt == cached); *(struct kgem_bo **)cached->map__gtt = NULL; cached->map__gtt = NULL; kgem_bo_destroy(kgem, cached); } } void kgem_retire__buffers(struct kgem *kgem) { while (!list_is_empty(&kgem->active_buffers)) { struct kgem_buffer *bo = list_last_entry(&kgem->active_buffers, struct kgem_buffer, base.list); DBG(("%s: handle=%d, busy? %d [%d]\n", __FUNCTION__, bo->base.handle, bo->base.rq != NULL, bo->base.exec != NULL)); assert(bo->base.exec == NULL || RQ(bo->base.rq) == kgem->next_request); if (bo->base.rq) break; DBG(("%s: releasing upload cache for handle=%d? %d\n", __FUNCTION__, bo->base.handle, !list_is_empty(&bo->base.vma))); list_del(&bo->base.list); kgem_buffer_release(kgem, bo); kgem_bo_unref(kgem, &bo->base); } } static bool kgem_retire__flushing(struct kgem *kgem) { struct kgem_bo *bo, *next; bool retired = false; list_for_each_entry_safe(bo, next, &kgem->flushing, request) { assert(RQ(bo->rq) == (void *)kgem); assert(bo->exec == NULL); if (__kgem_busy(kgem, bo->handle)) break; __kgem_bo_clear_busy(bo); if (bo->refcnt) continue; retired |= kgem_bo_move_to_cache(kgem, bo); } #if HAS_DEBUG_FULL { int count = 0; list_for_each_entry(bo, &kgem->flushing, request) count++; DBG(("%s: %d bo on flushing list, retired? %d\n", __FUNCTION__, count, retired)); } #endif kgem->need_retire |= !list_is_empty(&kgem->flushing); return retired; } static bool __kgem_bo_flush(struct kgem *kgem, struct kgem_bo *bo) { struct drm_i915_gem_busy busy; if (!bo->needs_flush) return false; bo->needs_flush = false; VG_CLEAR(busy); busy.handle = bo->handle; busy.busy = !kgem->wedged; (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUSY, &busy); DBG(("%s: handle=%d, busy=%d, wedged=%d\n", __FUNCTION__, bo->handle, busy.busy, kgem->wedged)); if (busy.busy == 0) return false; DBG(("%s: moving %d to flushing\n", __FUNCTION__, bo->handle)); list_add(&bo->request, &kgem->flushing); bo->rq = MAKE_REQUEST(kgem, !!(busy.busy & ~0x1ffff)); bo->needs_flush = busy.busy & 0xffff; kgem->need_retire = true; return true; } static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq) { bool retired = false; DBG(("%s: request %d complete\n", __FUNCTION__, rq->bo->handle)); assert(RQ(rq->bo->rq) == rq); assert(rq != (struct kgem_request *)kgem); assert(rq != &kgem->static_request); if (rq == kgem->fence[rq->ring]) kgem->fence[rq->ring] = NULL; while (!list_is_empty(&rq->buffers)) { struct kgem_bo *bo; bo = list_first_entry(&rq->buffers, struct kgem_bo, request); assert(RQ(bo->rq) == rq); assert(bo->exec == NULL); assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE); list_del(&bo->request); if (unlikely(__kgem_bo_flush(kgem, bo))) { assert(bo != rq->bo); DBG(("%s: movied %d to flushing\n", __FUNCTION__, bo->handle)); continue; } bo->domain = DOMAIN_NONE; bo->rq = NULL; if (bo->refcnt) continue; retired |= kgem_bo_move_to_cache(kgem, bo); } assert(rq->bo->rq == NULL); assert(rq->bo->exec == NULL); assert(list_is_empty(&rq->bo->request)); assert(rq->bo->refcnt > 0); if (--rq->bo->refcnt == 0) { kgem_bo_move_to_inactive(kgem, rq->bo); retired = true; } __kgem_request_free(rq); return retired; } static bool kgem_retire__requests_ring(struct kgem *kgem, int ring) { bool retired = false; assert(ring < ARRAY_SIZE(kgem->requests)); while (!list_is_empty(&kgem->requests[ring])) { struct kgem_request *rq; DBG(("%s: retiring ring %d\n", __FUNCTION__, ring)); rq = list_first_entry(&kgem->requests[ring], struct kgem_request, list); assert(rq->ring == ring); assert(rq->bo); assert(RQ(rq->bo->rq) == rq); if (__kgem_busy(kgem, rq->bo->handle)) break; retired |= __kgem_retire_rq(kgem, rq); } #if HAS_DEBUG_FULL { struct kgem_bo *bo; int count = 0; list_for_each_entry(bo, &kgem->requests[ring], request) count++; bo = NULL; if (!list_is_empty(&kgem->requests[ring])) bo = list_first_entry(&kgem->requests[ring], struct kgem_request, list)->bo; DBG(("%s: ring=%d, %d outstanding requests, oldest=%d, retired? %d\n", __FUNCTION__, ring, count, bo ? bo->handle : 0, retired)); } #endif return retired; } static bool kgem_retire__requests(struct kgem *kgem) { bool retired = false; int n; for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) { retired |= kgem_retire__requests_ring(kgem, n); kgem->need_retire |= !list_is_empty(&kgem->requests[n]); } return retired; } bool kgem_retire(struct kgem *kgem) { bool retired = false; DBG(("%s, need_retire?=%d\n", __FUNCTION__, kgem->need_retire)); kgem->need_retire = false; retired |= kgem_retire__flushing(kgem); retired |= kgem_retire__requests(kgem); DBG(("%s -- retired=%d, need_retire=%d\n", __FUNCTION__, retired, kgem->need_retire)); kgem->retire(kgem); return retired; } bool __kgem_ring_is_idle(struct kgem *kgem, int ring) { struct kgem_request *rq; assert(ring < ARRAY_SIZE(kgem->requests)); assert(!list_is_empty(&kgem->requests[ring])); rq = kgem->fence[ring]; if (rq) { struct kgem_request *tmp; if (__kgem_busy(kgem, rq->bo->handle)) { DBG(("%s: last fence handle=%d still busy\n", __FUNCTION__, rq->bo->handle)); return false; } do { tmp = list_first_entry(&kgem->requests[ring], struct kgem_request, list); assert(tmp->ring == ring); __kgem_retire_rq(kgem, tmp); } while (tmp != rq); assert(kgem->fence[ring] == NULL); if (list_is_empty(&kgem->requests[ring])) return true; } rq = list_last_entry(&kgem->requests[ring], struct kgem_request, list); assert(rq->ring == ring); assert(rq->bo); assert(RQ(rq->bo->rq) == rq); if (__kgem_busy(kgem, rq->bo->handle)) { DBG(("%s: last requests handle=%d still busy\n", __FUNCTION__, rq->bo->handle)); kgem->fence[ring] = rq; return false; } DBG(("%s: ring=%d idle (handle=%d)\n", __FUNCTION__, ring, rq->bo->handle)); while (!list_is_empty(&kgem->requests[ring])) { rq = list_first_entry(&kgem->requests[ring], struct kgem_request, list); assert(rq->ring == ring); __kgem_retire_rq(kgem, rq); } return true; } bool __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo) { struct kgem_request * const rq = RQ(bo->rq), *tmp; struct list *requests = &kgem->requests[rq->ring]; DBG(("%s(handle=%d, ring=%d)\n", __FUNCTION__, bo->handle, rq->ring)); assert(rq != &kgem->static_request); if (rq == (struct kgem_request *)kgem) { __kgem_bo_clear_busy(bo); return false; } assert(rq->ring < ARRAY_SIZE(kgem->requests)); do { tmp = list_first_entry(requests, struct kgem_request, list); assert(tmp->ring == rq->ring); __kgem_retire_rq(kgem, tmp); } while (tmp != rq); assert(bo->needs_flush || bo->rq == NULL); assert(bo->needs_flush || list_is_empty(&bo->request)); assert(bo->needs_flush || bo->domain == DOMAIN_NONE); return bo->rq; } #if 0 static void kgem_commit__check_reloc(struct kgem *kgem) { struct kgem_request *rq = kgem->next_request; struct kgem_bo *bo; bool has_64bit = kgem->gen >= 0100; int i; for (i = 0; i < kgem->nreloc; i++) { list_for_each_entry(bo, &rq->buffers, request) { if (bo->target_handle == kgem->reloc[i].target_handle) { uint64_t value = 0; gem_read(kgem->fd, rq->bo->handle, &value, kgem->reloc[i].offset, has_64bit ? 8 : 4); assert(bo->exec->offset == -1 || value == bo->exec->offset + (int)kgem->reloc[i].delta); break; } } } } #else #define kgem_commit__check_reloc(kgem) #endif #ifndef NDEBUG static void kgem_commit__check_buffers(struct kgem *kgem) { struct kgem_buffer *bo; list_for_each_entry(bo, &kgem->active_buffers, base.list) assert(bo->base.exec == NULL); } #else #define kgem_commit__check_buffers(kgem) #endif static void kgem_commit(struct kgem *kgem) { struct kgem_request *rq = kgem->next_request; struct kgem_bo *bo, *next; kgem_commit__check_reloc(kgem); list_for_each_entry_safe(bo, next, &rq->buffers, request) { assert(next->request.prev == &bo->request); DBG(("%s: release handle=%d (proxy? %d), dirty? %d flush? %d, snoop? %d -> offset=%x\n", __FUNCTION__, bo->handle, bo->proxy != NULL, bo->gpu_dirty, bo->needs_flush, bo->snoop, (unsigned)bo->exec->offset)); assert(bo->exec); assert(bo->proxy == NULL || bo->exec == &_kgem_dummy_exec); assert(RQ(bo->rq) == rq || (RQ(bo->proxy->rq) == rq)); bo->presumed_offset = bo->exec->offset; bo->exec = NULL; bo->target_handle = -1; if (!bo->refcnt && !bo->reusable) { assert(!bo->snoop); assert(!bo->proxy); kgem_bo_free(kgem, bo); continue; } bo->binding.offset = 0; bo->domain = DOMAIN_GPU; bo->gpu_dirty = false; bo->gtt_dirty = false; if (bo->proxy) { /* proxies are not used for domain tracking */ __kgem_bo_clear_busy(bo); } kgem->scanout_busy |= bo->scanout && bo->needs_flush; } if (rq == &kgem->static_request) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: syncing due to allocation failure\n", __FUNCTION__)); VG_CLEAR(set_domain); set_domain.handle = rq->bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } while (!list_is_empty(&rq->buffers)) { bo = list_first_entry(&rq->buffers, struct kgem_bo, request); assert(RQ(bo->rq) == rq); assert(bo->exec == NULL); assert(bo->domain == DOMAIN_GPU); list_del(&bo->request); bo->domain = DOMAIN_NONE; bo->rq = NULL; if (bo->refcnt == 0) _kgem_bo_destroy(kgem, bo); } kgem_retire(kgem); assert(list_is_empty(&rq->buffers)); assert(rq->bo->map__gtt == NULL); assert(rq->bo->map__wc == NULL); assert(rq->bo->map__cpu == NULL); gem_close(kgem->fd, rq->bo->handle); kgem_cleanup_cache(kgem); } else { assert(rq != (struct kgem_request *)kgem); assert(rq->ring < ARRAY_SIZE(kgem->requests)); assert(rq->bo); list_add_tail(&rq->list, &kgem->requests[rq->ring]); kgem->need_throttle = kgem->need_retire = 1; if (kgem->fence[rq->ring] == NULL && __kgem_busy(kgem, rq->bo->handle)) kgem->fence[rq->ring] = rq; } kgem->next_request = NULL; kgem_commit__check_buffers(kgem); } static void kgem_close_list(struct kgem *kgem, struct list *head) { while (!list_is_empty(head)) kgem_bo_free(kgem, list_first_entry(head, struct kgem_bo, list)); } static void kgem_close_inactive(struct kgem *kgem) { unsigned int i; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) { kgem_close_list(kgem, &kgem->inactive[i]); assert(list_is_empty(&kgem->inactive[i])); } } static void kgem_finish_buffers(struct kgem *kgem) { struct kgem_buffer *bo, *next; list_for_each_entry_safe(bo, next, &kgem->batch_buffers, base.list) { DBG(("%s: buffer handle=%d, used=%d, exec?=%d, write=%d, mmapped=%s, refcnt=%d\n", __FUNCTION__, bo->base.handle, bo->used, bo->base.exec!=NULL, bo->write, bo->mmapped == MMAPPED_CPU ? "cpu" : bo->mmapped == MMAPPED_GTT ? "gtt" : "no", bo->base.refcnt)); assert(next->base.list.prev == &bo->base.list); assert(bo->base.io); assert(bo->base.refcnt >= 1); if (bo->base.refcnt > 1 && !bo->base.exec) { DBG(("%s: skipping unattached handle=%d, used=%d, refcnt=%d\n", __FUNCTION__, bo->base.handle, bo->used, bo->base.refcnt)); continue; } if (!bo->write) { assert(bo->base.exec || bo->base.refcnt > 1); goto decouple; } if (bo->mmapped) { uint32_t used; assert(!bo->need_io); used = ALIGN(bo->used, PAGE_SIZE); if (!DBG_NO_UPLOAD_ACTIVE && used + PAGE_SIZE <= bytes(&bo->base) && (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) { DBG(("%s: retaining upload buffer (%d/%d): used=%d, refcnt=%d\n", __FUNCTION__, bo->used, bytes(&bo->base), used, bo->base.refcnt)); bo->used = used; list_move(&bo->base.list, &kgem->active_buffers); kgem->need_retire = true; continue; } DBG(("%s: discarding mmapped buffer, used=%d, map type=%d\n", __FUNCTION__, bo->used, bo->mmapped)); goto decouple; } if (!bo->used || !bo->base.exec) { /* Unless we replace the handle in the execbuffer, * then this bo will become active. So decouple it * from the buffer list and track it in the normal * manner. */ goto decouple; } assert(bo->need_io); assert(bo->base.rq == MAKE_REQUEST(kgem->next_request, kgem->ring)); assert(bo->base.domain != DOMAIN_GPU); if (bo->base.refcnt == 1 && bo->base.size.pages.count > 1 && bo->used < bytes(&bo->base) / 2) { struct kgem_bo *shrink; unsigned alloc = NUM_PAGES(bo->used); shrink = search_snoop_cache(kgem, alloc, CREATE_INACTIVE | CREATE_NO_RETIRE); if (shrink) { void *map; int n; DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n", __FUNCTION__, bo->used, bytes(&bo->base), bytes(shrink), bo->base.handle, shrink->handle)); assert(bo->used <= bytes(shrink)); map = kgem_bo_map__cpu(kgem, shrink); if (map) { kgem_bo_sync__cpu(kgem, shrink); memcpy(map, bo->mem, bo->used); shrink->target_handle = kgem->has_handle_lut ? bo->base.target_handle : shrink->handle; for (n = 0; n < kgem->nreloc; n++) { if (kgem->reloc[n].target_handle == bo->base.target_handle) { uint64_t addr = (int)kgem->reloc[n].delta + shrink->presumed_offset; kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] = addr; if (kgem->gen >= 0100) kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0]) + 1] = addr >> 32; kgem->reloc[n].target_handle = shrink->target_handle; kgem->reloc[n].presumed_offset = shrink->presumed_offset; } } bo->base.exec->handle = shrink->handle; bo->base.exec->offset = shrink->presumed_offset; shrink->exec = bo->base.exec; shrink->rq = bo->base.rq; list_replace(&bo->base.request, &shrink->request); list_init(&bo->base.request); shrink->needs_flush = bo->base.gpu_dirty; bo->base.exec = NULL; bo->base.rq = NULL; bo->base.gpu_dirty = false; bo->base.needs_flush = false; bo->used = 0; goto decouple; } __kgem_bo_destroy(kgem, shrink); } shrink = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_NO_RETIRE); if (shrink) { int n; DBG(("%s: used=%d, shrinking %d to %d, handle %d to %d\n", __FUNCTION__, bo->used, bytes(&bo->base), bytes(shrink), bo->base.handle, shrink->handle)); assert(bo->used <= bytes(shrink)); if (gem_write__cachealigned(kgem->fd, shrink->handle, 0, bo->used, bo->mem) == 0) { shrink->target_handle = kgem->has_handle_lut ? bo->base.target_handle : shrink->handle; for (n = 0; n < kgem->nreloc; n++) { if (kgem->reloc[n].target_handle == bo->base.target_handle) { uint64_t addr = (int)kgem->reloc[n].delta + shrink->presumed_offset; kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0])] = addr; if (kgem->gen >= 0100) kgem->batch[kgem->reloc[n].offset/sizeof(kgem->batch[0]) + 1] = addr >> 32; kgem->reloc[n].target_handle = shrink->target_handle; kgem->reloc[n].presumed_offset = shrink->presumed_offset; } } bo->base.exec->handle = shrink->handle; bo->base.exec->offset = shrink->presumed_offset; shrink->exec = bo->base.exec; shrink->rq = bo->base.rq; list_replace(&bo->base.request, &shrink->request); list_init(&bo->base.request); shrink->needs_flush = bo->base.gpu_dirty; bo->base.exec = NULL; bo->base.rq = NULL; bo->base.gpu_dirty = false; bo->base.needs_flush = false; bo->used = 0; goto decouple; } __kgem_bo_destroy(kgem, shrink); } } DBG(("%s: handle=%d, uploading %d/%d\n", __FUNCTION__, bo->base.handle, bo->used, bytes(&bo->base))); ASSERT_IDLE(kgem, bo->base.handle); assert(bo->used <= bytes(&bo->base)); gem_write__cachealigned(kgem->fd, bo->base.handle, 0, bo->used, bo->mem); bo->need_io = 0; decouple: DBG(("%s: releasing handle=%d\n", __FUNCTION__, bo->base.handle)); list_del(&bo->base.list); kgem_bo_unref(kgem, &bo->base); } } static void kgem_cleanup(struct kgem *kgem) { int n; for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) { while (!list_is_empty(&kgem->requests[n])) { struct kgem_request *rq; rq = list_first_entry(&kgem->requests[n], struct kgem_request, list); assert(rq->ring == n); while (!list_is_empty(&rq->buffers)) { struct kgem_bo *bo; bo = list_first_entry(&rq->buffers, struct kgem_bo, request); bo->exec = NULL; bo->gpu_dirty = false; __kgem_bo_clear_busy(bo); if (bo->refcnt == 0) kgem_bo_free(kgem, bo); } if (--rq->bo->refcnt == 0) kgem_bo_free(kgem, rq->bo); __kgem_request_free(rq); } } kgem_close_inactive(kgem); } static int kgem_batch_write(struct kgem *kgem, struct kgem_bo *bo, uint32_t size) { char *ptr; int ret; assert(bo->exec == NULL); assert(bo->rq == NULL); assert(!__kgem_busy(kgem, bo->handle)); #if DBG_NO_EXEC { uint32_t batch[] = { MI_BATCH_BUFFER_END, 0}; return gem_write(kgem->fd, bo->handle, 0, sizeof(batch), batch); } #endif assert(!bo->scanout); retry: ptr = NULL; if (bo->domain == DOMAIN_CPU || kgem->has_llc) { ptr = bo->map__cpu; if (ptr == NULL) ptr = __kgem_bo_map__cpu(kgem, bo); } else if (kgem->has_wc_mmap) { ptr = bo->map__wc; if (ptr == NULL) ptr = __kgem_bo_map__wc(kgem, bo); } if (ptr) { memcpy(ptr, kgem->batch, sizeof(uint32_t)*kgem->nbatch); if (kgem->surface != kgem->batch_size) { ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size); ret -= sizeof(uint32_t) * kgem->surface; ptr += size - ret; memcpy(ptr, kgem->batch + kgem->surface, (kgem->batch_size - kgem->surface)*sizeof(uint32_t)); } return 0; } /* If there is no surface data, just upload the batch */ if (kgem->surface == kgem->batch_size) { if ((ret = gem_write__cachealigned(kgem->fd, bo->handle, 0, sizeof(uint32_t)*kgem->nbatch, kgem->batch)) == 0) return 0; goto expire; } /* Are the batch pages conjoint with the surface pages? */ if (kgem->surface < kgem->nbatch + PAGE_SIZE/sizeof(uint32_t)) { assert(size == PAGE_ALIGN(kgem->batch_size*sizeof(uint32_t))); if ((ret = gem_write__cachealigned(kgem->fd, bo->handle, 0, kgem->batch_size*sizeof(uint32_t), kgem->batch)) == 0) return 0; goto expire; } /* Disjoint surface/batch, upload separately */ if ((ret = gem_write__cachealigned(kgem->fd, bo->handle, 0, sizeof(uint32_t)*kgem->nbatch, kgem->batch))) goto expire; ret = PAGE_ALIGN(sizeof(uint32_t) * kgem->batch_size); ret -= sizeof(uint32_t) * kgem->surface; assert(size-ret >= kgem->nbatch*sizeof(uint32_t)); if (gem_write(kgem->fd, bo->handle, size - ret, (kgem->batch_size - kgem->surface)*sizeof(uint32_t), kgem->batch + kgem->surface)) goto expire; return 0; expire: assert(ret != EINVAL); (void)__kgem_throttle_retire(kgem, 0); if (kgem_expire_cache(kgem)) goto retry; if (kgem_cleanup_cache(kgem)) goto retry; ERR(("%s: failed to write batch (handle=%d): %d\n", __FUNCTION__, bo->handle, -ret)); return ret; } void kgem_reset(struct kgem *kgem) { if (kgem->next_request) { struct kgem_request *rq = kgem->next_request; while (!list_is_empty(&rq->buffers)) { struct kgem_bo *bo = list_first_entry(&rq->buffers, struct kgem_bo, request); list_del(&bo->request); assert(RQ(bo->rq) == rq); bo->binding.offset = 0; bo->exec = NULL; bo->target_handle = -1; bo->gpu_dirty = false; if (bo->needs_flush && __kgem_busy(kgem, bo->handle)) { assert(bo->domain == DOMAIN_GPU || bo->domain == DOMAIN_NONE); list_add(&bo->request, &kgem->flushing); bo->rq = (void *)kgem; kgem->need_retire = true; } else __kgem_bo_clear_busy(bo); if (bo->refcnt || bo->rq) continue; kgem_bo_move_to_cache(kgem, bo); } if (rq != &kgem->static_request) { list_init(&rq->list); __kgem_request_free(rq); } } kgem->nfence = 0; kgem->nexec = 0; kgem->nreloc = 0; kgem->nreloc__self = 0; kgem->aperture = 0; kgem->aperture_fenced = 0; kgem->aperture_max_fence = 0; kgem->nbatch = 0; kgem->surface = kgem->batch_size; kgem->mode = KGEM_NONE; kgem->needs_semaphore = false; kgem->needs_reservation = false; kgem->flush = 0; kgem->batch_flags = kgem->batch_flags_base; assert(kgem->batch); kgem->next_request = __kgem_request_alloc(kgem); kgem_sna_reset(kgem); } static int compact_batch_surface(struct kgem *kgem, int *shrink) { int size, n; if (!kgem->has_relaxed_delta) return kgem->batch_size * sizeof(uint32_t); /* See if we can pack the contents into one or two pages */ n = ALIGN(kgem->batch_size, 1024); size = n - kgem->surface + kgem->nbatch; size = ALIGN(size, 1024); *shrink = (n - size) * sizeof(uint32_t); return size * sizeof(uint32_t); } static struct kgem_bo *first_available(struct kgem *kgem, struct list *list) { struct kgem_bo *bo; list_for_each_entry(bo, list, list) { assert(bo->refcnt > 0); if (bo->rq) { assert(RQ(bo->rq)->bo == bo); if (__kgem_busy(kgem, bo->handle)) break; __kgem_retire_rq(kgem, RQ(bo->rq)); assert(bo->rq == NULL); } if (bo->refcnt > 1) continue; list_move_tail(&bo->list, list); return kgem_bo_reference(bo); } return NULL; } static struct kgem_bo * kgem_create_batch(struct kgem *kgem) { struct kgem_bo *bo; int size, shrink = 0; #if !DBG_NO_SHRINK_BATCHES if (kgem->surface != kgem->batch_size) size = compact_batch_surface(kgem, &shrink); else size = kgem->nbatch * sizeof(uint32_t); if (size <= 4096) { bo = first_available(kgem, &kgem->pinned_batches[0]); if (bo) goto write; } if (size <= 16384) { bo = first_available(kgem, &kgem->pinned_batches[1]); if (bo) goto write; } if (kgem->gen == 020) { bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY); if (bo) goto write; /* Nothing available for reuse, rely on the kernel wa */ if (kgem->has_pinned_batches) { bo = kgem_create_linear(kgem, size, CREATE_CACHED | CREATE_TEMPORARY); if (bo) { kgem->batch_flags &= ~LOCAL_I915_EXEC_IS_PINNED; goto write; } } if (size < 16384) { bo = list_first_entry(&kgem->pinned_batches[size > 4096], struct kgem_bo, list); list_move_tail(&bo->list, &kgem->pinned_batches[size > 4096]); DBG(("%s: syncing due to busy batches\n", __FUNCTION__)); if (kgem_bo_wait(kgem, bo)) return NULL; kgem_retire(kgem); assert(bo->rq == NULL); bo = kgem_bo_reference(bo); goto write; } } #else if (kgem->surface != kgem->batch_size) size = kgem->batch_size * sizeof(uint32_t); else size = kgem->nbatch * sizeof(uint32_t); #endif if (!kgem->batch_bo || !kgem->has_llc) { bo = kgem_create_linear(kgem, size, CREATE_NO_THROTTLE); if (bo) { write: kgem_fixup_relocs(kgem, bo, shrink); if (kgem_batch_write(kgem, bo, size)) { kgem_bo_destroy(kgem, bo); return NULL; } return bo; } } return kgem_new_batch(kgem); } #if !NDEBUG static bool dump_file(const char *path) { FILE *file; size_t len = 0; char *line = NULL; file = fopen(path, "r"); if (file == NULL) return false; while (getline(&line, &len, file) != -1) ErrorF("%s", line); free(line); fclose(file); return true; } static void dump_debugfs(struct kgem *kgem, const char *name) { char path[80]; int minor = kgem_get_minor(kgem); if (minor < 0) return; sprintf(path, "/sys/kernel/debug/dri/%d/%s", minor, name); if (dump_file(path)) return; sprintf(path, "/debug/dri/%d/%s", minor, name); if (dump_file(path)) return; } static void dump_gtt_info(struct kgem *kgem) { dump_debugfs(kgem, "i915_gem_gtt"); } static void dump_fence_regs(struct kgem *kgem) { dump_debugfs(kgem, "i915_gem_fence_regs"); } #endif static int do_execbuf(struct kgem *kgem, struct drm_i915_gem_execbuffer2 *execbuf) { int ret; retry: ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); if (ret == 0) return 0; DBG(("%s: failed ret=%d, throttling and discarding cache\n", __FUNCTION__, ret)); (void)__kgem_throttle_retire(kgem, 0); if (kgem_expire_cache(kgem)) goto retry; if (kgem_cleanup_cache(kgem)) goto retry; /* last gasp */ ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); if (ret != -ENOSPC) return ret; /* One final trick up our sleeve for when we run out of space. * We turn everything off to free up our pinned framebuffers, * sprites and cursors, and try just one more time. */ xf86DrvMsg(kgem_get_screen_index(kgem), X_WARNING, "Failed to submit rendering commands, trying again with outputs disabled.\n"); if (sna_mode_disable(__to_sna(kgem))) { kgem_cleanup_cache(kgem); ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf); DBG(("%s: last_gasp ret=%d\n", __FUNCTION__, ret)); sna_mode_enable(__to_sna(kgem)); } return ret; } void _kgem_submit(struct kgem *kgem) { struct kgem_request *rq; uint32_t batch_end; int i, ret; assert(!DBG_NO_HW); assert(!kgem->wedged); assert(kgem->nbatch); assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem)); assert(kgem->nbatch <= kgem->surface); batch_end = kgem_end_batch(kgem); kgem_sna_flush(kgem); DBG(("batch[%d/%d, flags=%x]: %d %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d [fenced=%d]\n", kgem->mode, kgem->ring, kgem->batch_flags, batch_end, kgem->nbatch, kgem->surface, kgem->batch_size, kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced)); assert(kgem->nbatch <= kgem->batch_size); assert(kgem->nbatch <= kgem->surface); assert(kgem->nreloc <= ARRAY_SIZE(kgem->reloc)); assert(kgem->nexec < ARRAY_SIZE(kgem->exec)); assert(kgem->nfence <= kgem->fence_max); kgem_finish_buffers(kgem); #if SHOW_BATCH_BEFORE __kgem_batch_debug(kgem, batch_end); #endif rq = kgem->next_request; assert(rq->bo == NULL); rq->bo = kgem_create_batch(kgem); if (rq->bo) { struct drm_i915_gem_execbuffer2 execbuf; assert(!rq->bo->needs_flush); i = kgem->nexec++; kgem->exec[i].handle = rq->bo->handle; kgem->exec[i].relocation_count = kgem->nreloc; kgem->exec[i].relocs_ptr = (uintptr_t)kgem->reloc; kgem->exec[i].alignment = 0; kgem->exec[i].offset = rq->bo->presumed_offset; /* Make sure the kernel releases any fence, ignored if gen4+ */ kgem->exec[i].flags = EXEC_OBJECT_NEEDS_FENCE; kgem->exec[i].rsvd1 = 0; kgem->exec[i].rsvd2 = 0; rq->bo->exec = &kgem->exec[i]; rq->bo->rq = MAKE_REQUEST(rq, kgem->ring); /* useful sanity check */ list_add(&rq->bo->request, &rq->buffers); rq->ring = kgem->ring == KGEM_BLT; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)kgem->exec; execbuf.buffer_count = kgem->nexec; if (kgem->gen < 030) execbuf.batch_len = batch_end*sizeof(uint32_t); execbuf.flags = kgem->ring | kgem->batch_flags; if (DBG_DUMP) { int fd = open("/tmp/i915-batchbuffers.dump", O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd != -1) { ret = write(fd, kgem->batch, batch_end*sizeof(uint32_t)); fd = close(fd); } } ret = do_execbuf(kgem, &execbuf); } else ret = -ENOMEM; if (ret < 0) { kgem_throttle(kgem); if (!kgem->wedged) { xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR, "Failed to submit rendering commands (%s), disabling acceleration.\n", strerror(-ret)); __kgem_set_wedged(kgem); } #if !NDEBUG ErrorF("batch[%d/%d]: %d %d %d, nreloc=%d, nexec=%d, nfence=%d, aperture=%d, fenced=%d, high=%d,%d: errno=%d\n", kgem->mode, kgem->ring, batch_end, kgem->nbatch, kgem->surface, kgem->nreloc, kgem->nexec, kgem->nfence, kgem->aperture, kgem->aperture_fenced, kgem->aperture_high, kgem->aperture_total, -ret); for (i = 0; i < kgem->nexec; i++) { struct kgem_bo *bo, *found = NULL; list_for_each_entry(bo, &kgem->next_request->buffers, request) { if (bo->handle == kgem->exec[i].handle) { found = bo; break; } } ErrorF("exec[%d] = handle:%d, presumed offset: %x, size: %d, tiling %d, fenced %d, snooped %d, deleted %d\n", i, kgem->exec[i].handle, (int)kgem->exec[i].offset, found ? kgem_bo_size(found) : -1, found ? found->tiling : -1, (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE), found ? found->snoop : -1, found ? found->purged : -1); } for (i = 0; i < kgem->nreloc; i++) { ErrorF("reloc[%d] = pos:%d, target:%d, delta:%d, read:%x, write:%x, offset:%x\n", i, (int)kgem->reloc[i].offset, kgem->reloc[i].target_handle, kgem->reloc[i].delta, kgem->reloc[i].read_domains, kgem->reloc[i].write_domain, (int)kgem->reloc[i].presumed_offset); } { struct drm_i915_gem_get_aperture aperture; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) == 0) ErrorF("Aperture size %lld, available %lld\n", (long long)aperture.aper_size, (long long)aperture.aper_available_size); } if (ret == -ENOSPC) dump_gtt_info(kgem); if (ret == -EDEADLK) dump_fence_regs(kgem); if (DEBUG_SYNC) { int fd = open("/tmp/batchbuffer", O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd != -1) { int ignored = write(fd, kgem->batch, batch_end*sizeof(uint32_t)); assert(ignored == batch_end*sizeof(uint32_t)); close(fd); } FatalError("SNA: failed to submit batchbuffer, errno=%d\n", -ret); } #endif } else { if (DEBUG_SYNC) { struct drm_i915_gem_set_domain set_domain; VG_CLEAR(set_domain); set_domain.handle = rq->bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; ret = do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); } #if SHOW_BATCH_AFTER if (gem_read(kgem->fd, rq->bo->handle, kgem->batch, 0, batch_end*sizeof(uint32_t)) == 0) __kgem_batch_debug(kgem, batch_end); #endif kgem_commit(kgem); } if (unlikely(kgem->wedged)) kgem_cleanup(kgem); kgem_reset(kgem); assert(kgem->next_request != NULL); } void kgem_throttle(struct kgem *kgem) { if (unlikely(kgem->wedged)) return; if (__kgem_throttle(kgem, true)) { xf86DrvMsg(kgem_get_screen_index(kgem), X_ERROR, "Detected a hung GPU, disabling acceleration.\n"); __kgem_set_wedged(kgem); kgem->need_throttle = false; } } int kgem_is_wedged(struct kgem *kgem) { return __kgem_throttle(kgem, true); } static void kgem_purge_cache(struct kgem *kgem) { struct kgem_bo *bo, *next; int i; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) { list_for_each_entry_safe(bo, next, &kgem->inactive[i], list) { if (!kgem_bo_is_retained(kgem, bo)) { DBG(("%s: purging %d\n", __FUNCTION__, bo->handle)); kgem_bo_free(kgem, bo); } } } kgem->need_purge = false; } void kgem_clean_scanout_cache(struct kgem *kgem) { while (!list_is_empty(&kgem->scanout)) { struct kgem_bo *bo; bo = list_first_entry(&kgem->scanout, struct kgem_bo, list); assert(bo->scanout); assert(!bo->refcnt); assert(!bo->prime); assert(bo->proxy == NULL); if (bo->exec || __kgem_busy(kgem, bo->handle)) break; DBG(("%s: handle=%d, fb=%d (reusable=%d)\n", __FUNCTION__, bo->handle, bo->delta, bo->reusable)); list_del(&bo->list); kgem_bo_rmfb(kgem, bo); bo->scanout = false; if (!bo->purged) { bo->reusable = true; if (kgem->has_llc && !gem_set_caching(kgem->fd, bo->handle, SNOOPED)) bo->reusable = false; } __kgem_bo_destroy(kgem, bo); } } void kgem_clean_large_cache(struct kgem *kgem) { while (!list_is_empty(&kgem->large_inactive)) { kgem_bo_free(kgem, list_first_entry(&kgem->large_inactive, struct kgem_bo, list)); } } bool kgem_expire_cache(struct kgem *kgem) { time_t now, expire; struct kgem_bo *bo; unsigned int size = 0, count = 0; bool idle; unsigned int i; if (!time(&now)) return false; while (__kgem_freed_bo) { bo = __kgem_freed_bo; __kgem_freed_bo = *(struct kgem_bo **)bo; free(bo); } while (__kgem_freed_request) { struct kgem_request *rq = __kgem_freed_request; __kgem_freed_request = *(struct kgem_request **)rq; free(rq); } kgem_clean_large_cache(kgem); if (__to_sna(kgem)->scrn->vtSema) kgem_clean_scanout_cache(kgem); expire = 0; list_for_each_entry(bo, &kgem->snoop, list) { if (bo->delta) { expire = now - MAX_INACTIVE_TIME/2; break; } assert(now); bo->delta = now; } if (expire) { while (!list_is_empty(&kgem->snoop)) { bo = list_last_entry(&kgem->snoop, struct kgem_bo, list); if (bo->delta > expire) break; kgem_bo_free(kgem, bo); } } #ifdef DEBUG_MEMORY { long snoop_size = 0; int snoop_count = 0; list_for_each_entry(bo, &kgem->snoop, list) snoop_count++, snoop_size += bytes(bo); DBG(("%s: still allocated %d bo, %ld bytes, in snoop cache\n", __FUNCTION__, snoop_count, snoop_size)); } #endif kgem_retire(kgem); if (unlikely(kgem->wedged)) kgem_cleanup(kgem); kgem->expire(kgem); if (kgem->need_purge) kgem_purge_cache(kgem); if (kgem->need_retire) kgem_retire(kgem); expire = 0; idle = true; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) { idle &= list_is_empty(&kgem->inactive[i]); list_for_each_entry(bo, &kgem->inactive[i], list) { if (bo->delta) { expire = now - MAX_INACTIVE_TIME; break; } assert(now); kgem_bo_set_purgeable(kgem, bo); bo->delta = now; } } if (expire == 0) { DBG(("%s: idle? %d\n", __FUNCTION__, idle)); kgem->need_expire = !idle; return false; } idle = true; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) { struct list preserve; list_init(&preserve); while (!list_is_empty(&kgem->inactive[i])) { bo = list_last_entry(&kgem->inactive[i], struct kgem_bo, list); if (bo->delta > expire) { idle = false; break; } if (bo->map__cpu && bo->delta + MAP_PRESERVE_TIME > expire) { idle = false; list_move_tail(&bo->list, &preserve); } else { count++; size += bytes(bo); kgem_bo_free(kgem, bo); DBG(("%s: expiring handle=%d\n", __FUNCTION__, bo->handle)); } } list_splice_tail(&preserve, &kgem->inactive[i]); } #ifdef DEBUG_MEMORY { long inactive_size = 0; int inactive_count = 0; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) list_for_each_entry(bo, &kgem->inactive[i], list) inactive_count++, inactive_size += bytes(bo); DBG(("%s: still allocated %d bo, %ld bytes, in inactive cache\n", __FUNCTION__, inactive_count, inactive_size)); } #endif DBG(("%s: expired %d objects, %d bytes, idle? %d\n", __FUNCTION__, count, size, idle)); kgem->need_expire = !idle; return count; (void)count; (void)size; } bool kgem_cleanup_cache(struct kgem *kgem) { unsigned int i; int n; DBG(("%s\n", __FUNCTION__)); /* sync to the most recent request */ for (n = 0; n < ARRAY_SIZE(kgem->requests); n++) { if (!list_is_empty(&kgem->requests[n])) { struct kgem_request *rq; rq = list_last_entry(&kgem->requests[n], struct kgem_request, list); DBG(("%s: sync on cleanup\n", __FUNCTION__)); assert(rq->ring == n); assert(rq->bo); assert(RQ(rq->bo->rq) == rq); kgem_bo_wait(kgem, rq->bo); } assert(list_is_empty(&kgem->requests[n])); } kgem_retire(kgem); kgem_cleanup(kgem); DBG(("%s: need_expire?=%d\n", __FUNCTION__, kgem->need_expire)); if (!kgem->need_expire) return false; for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) { while (!list_is_empty(&kgem->inactive[i])) kgem_bo_free(kgem, list_last_entry(&kgem->inactive[i], struct kgem_bo, list)); } kgem_clean_large_cache(kgem); kgem_clean_scanout_cache(kgem); while (!list_is_empty(&kgem->snoop)) kgem_bo_free(kgem, list_last_entry(&kgem->snoop, struct kgem_bo, list)); while (__kgem_freed_bo) { struct kgem_bo *bo = __kgem_freed_bo; __kgem_freed_bo = *(struct kgem_bo **)bo; free(bo); } kgem->need_purge = false; kgem->need_expire = false; DBG(("%s: complete\n", __FUNCTION__)); return true; } static struct kgem_bo * search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags) { struct kgem_bo *bo, *first = NULL; bool use_active = (flags & CREATE_INACTIVE) == 0; struct list *cache; DBG(("%s: num_pages=%d, flags=%x, use_active? %d, use_large=%d [max=%d]\n", __FUNCTION__, num_pages, flags, use_active, num_pages >= MAX_CACHE_SIZE / PAGE_SIZE, MAX_CACHE_SIZE / PAGE_SIZE)); assert(num_pages); if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE) { DBG(("%s: searching large buffers\n", __FUNCTION__)); retry_large: cache = use_active ? &kgem->large : &kgem->large_inactive; list_for_each_entry_safe(bo, first, cache, list) { assert(bo->refcnt == 0); assert(bo->reusable); assert(!bo->scanout); if (num_pages > num_pages(bo)) goto discard; if (bo->tiling != I915_TILING_NONE) { if (use_active && kgem->gen < 040) goto discard; if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0)) goto discard; } assert(bo->tiling == I915_TILING_NONE); bo->pitch = 0; if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) goto discard; list_del(&bo->list); if (RQ(bo->rq) == (void *)kgem) { assert(bo->exec == NULL); list_del(&bo->request); } bo->delta = 0; assert_tiling(kgem, bo); return bo; discard: if (!use_active) kgem_bo_free(kgem, bo); } if (use_active) { use_active = false; goto retry_large; } if (__kgem_throttle_retire(kgem, flags)) goto retry_large; return NULL; } if (!use_active && list_is_empty(inactive(kgem, num_pages))) { DBG(("%s: inactive and cache bucket empty\n", __FUNCTION__)); if (flags & CREATE_NO_RETIRE) { DBG(("%s: can not retire\n", __FUNCTION__)); return NULL; } if (list_is_empty(active(kgem, num_pages, I915_TILING_NONE))) { DBG(("%s: active cache bucket empty\n", __FUNCTION__)); return NULL; } if (!__kgem_throttle_retire(kgem, flags)) { DBG(("%s: nothing retired\n", __FUNCTION__)); return NULL; } if (list_is_empty(inactive(kgem, num_pages))) { DBG(("%s: active cache bucket still empty after retire\n", __FUNCTION__)); return NULL; } } if (!use_active && flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { int for_cpu = !!(flags & CREATE_CPU_MAP); DBG(("%s: searching for inactive %s map\n", __FUNCTION__, for_cpu ? "cpu" : "gtt")); cache = &kgem->vma[for_cpu].inactive[cache_bucket(num_pages)]; list_for_each_entry(bo, cache, vma) { assert(for_cpu ? !!bo->map__cpu : (bo->map__gtt || bo->map__wc)); assert(bucket(bo) == cache_bucket(num_pages)); assert(bo->proxy == NULL); assert(bo->rq == NULL); assert(bo->exec == NULL); assert(!bo->scanout); if (num_pages > num_pages(bo)) { DBG(("inactive too small: %d < %d\n", num_pages(bo), num_pages)); continue; } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); break; } if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0)) { kgem_bo_free(kgem, bo); break; } kgem_bo_remove_from_inactive(kgem, bo); assert(list_is_empty(&bo->vma)); assert(list_is_empty(&bo->list)); assert(bo->tiling == I915_TILING_NONE); assert(bo->pitch == 0); bo->delta = 0; DBG((" %s: found handle=%d (num_pages=%d) in linear vma cache\n", __FUNCTION__, bo->handle, num_pages(bo))); assert(use_active || bo->domain != DOMAIN_GPU); assert(!bo->needs_flush); assert_tiling(kgem, bo); ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active); return bo; } if (flags & CREATE_EXACT) return NULL; if (flags & CREATE_CPU_MAP && !kgem->has_llc) return NULL; } cache = use_active ? active(kgem, num_pages, I915_TILING_NONE) : inactive(kgem, num_pages); list_for_each_entry(bo, cache, list) { assert(bo->refcnt == 0); assert(bo->reusable); assert(!!bo->rq == !!use_active); assert(bo->proxy == NULL); assert(!bo->scanout); if (num_pages > num_pages(bo)) continue; if (use_active && kgem->gen <= 040 && bo->tiling != I915_TILING_NONE) continue; if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); break; } if (I915_TILING_NONE != bo->tiling) { if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) continue; if (first) continue; if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0)) { kgem_bo_free(kgem, bo); break; } } assert(bo->tiling == I915_TILING_NONE); bo->pitch = 0; if (bo->map__gtt || bo->map__wc || bo->map__cpu) { if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { int for_cpu = !!(flags & CREATE_CPU_MAP); if (for_cpu ? !!bo->map__cpu : (bo->map__gtt || bo->map__wc)){ if (first != NULL) break; first = bo; continue; } } else { if (first != NULL) break; first = bo; continue; } } else { if (flags & CREATE_GTT_MAP && !kgem_bo_can_map(kgem, bo)) continue; if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { if (first != NULL) break; first = bo; continue; } } if (use_active) kgem_bo_remove_from_active(kgem, bo); else kgem_bo_remove_from_inactive(kgem, bo); assert(bo->tiling == I915_TILING_NONE); assert(bo->pitch == 0); bo->delta = 0; DBG((" %s: found handle=%d (num_pages=%d) in linear %s cache\n", __FUNCTION__, bo->handle, num_pages(bo), use_active ? "active" : "inactive")); assert(list_is_empty(&bo->list)); assert(list_is_empty(&bo->vma)); assert(use_active || bo->domain != DOMAIN_GPU); assert(!bo->needs_flush || use_active); assert_tiling(kgem, bo); ASSERT_MAYBE_IDLE(kgem, bo->handle, !use_active); return bo; } if (first) { assert(first->tiling == I915_TILING_NONE); if (use_active) kgem_bo_remove_from_active(kgem, first); else kgem_bo_remove_from_inactive(kgem, first); first->pitch = 0; first->delta = 0; DBG((" %s: found handle=%d (near-miss) (num_pages=%d) in linear %s cache\n", __FUNCTION__, first->handle, num_pages(first), use_active ? "active" : "inactive")); assert(list_is_empty(&first->list)); assert(list_is_empty(&first->vma)); assert(use_active || first->domain != DOMAIN_GPU); assert(!first->needs_flush || use_active); ASSERT_MAYBE_IDLE(kgem, first->handle, !use_active); return first; } return NULL; } struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name) { struct drm_gem_open open_arg; struct drm_i915_gem_get_tiling tiling; struct kgem_bo *bo; DBG(("%s(name=%d)\n", __FUNCTION__, name)); VG_CLEAR(open_arg); open_arg.name = name; if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) return NULL; DBG(("%s: new handle=%d\n", __FUNCTION__, open_arg.handle)); VG_CLEAR(tiling); tiling.handle = open_arg.handle; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) { DBG(("%s(name=%d) get-tiling failed, ret=%d\n", __FUNCTION__, name, errno)); gem_close(kgem->fd, open_arg.handle); return NULL; } DBG(("%s: handle=%d, tiling=%d\n", __FUNCTION__, tiling.handle, tiling.tiling_mode)); bo = __kgem_bo_alloc(open_arg.handle, open_arg.size / PAGE_SIZE); if (bo == NULL) { gem_close(kgem->fd, open_arg.handle); return NULL; } bo->unique_id = kgem_get_unique_id(kgem); bo->tiling = tiling.tiling_mode; bo->prime = true; bo->reusable = false; kgem_bo_unclean(kgem, bo); debug_alloc__bo(kgem, bo); return bo; } struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size) { #ifdef DRM_IOCTL_PRIME_FD_TO_HANDLE struct drm_prime_handle args; struct drm_i915_gem_get_tiling tiling; struct local_i915_gem_caching caching; struct kgem_bo *bo; off_t seek; DBG(("%s(name=%d)\n", __FUNCTION__, name)); VG_CLEAR(args); args.fd = name; args.flags = 0; if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args)) { DBG(("%s(name=%d) fd-to-handle failed, ret=%d\n", __FUNCTION__, name, errno)); return NULL; } VG_CLEAR(tiling); tiling.handle = args.handle; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling)) { DBG(("%s(name=%d) get-tiling failed, ret=%d\n", __FUNCTION__, name, errno)); gem_close(kgem->fd, args.handle); return NULL; } /* Query actual size, overriding specified if available */ seek = lseek(args.fd, 0, SEEK_END); DBG(("%s: estimated size=%ld, actual=%lld\n", __FUNCTION__, (long)size, (long long)seek)); if (seek != -1) { if (size > seek) { DBG(("%s(name=%d) estimated required size [%d] is larger than actual [%ld]\n", __FUNCTION__, name, size, (long)seek)); gem_close(kgem->fd, args.handle); return NULL; } size = seek; } DBG(("%s: new handle=%d, tiling=%d\n", __FUNCTION__, args.handle, tiling.tiling_mode)); bo = __kgem_bo_alloc(args.handle, NUM_PAGES(size)); if (bo == NULL) { gem_close(kgem->fd, args.handle); return NULL; } bo->unique_id = kgem_get_unique_id(kgem); bo->tiling = tiling.tiling_mode; bo->reusable = false; bo->prime = true; bo->domain = DOMAIN_NONE; /* is this a special bo (e.g. scanout or CPU coherent)? */ VG_CLEAR(caching); caching.handle = args.handle; caching.caching = kgem->has_llc; (void)drmIoctl(kgem->fd, LOCAL_IOCTL_I915_GEM_GET_CACHING, &caching); DBG(("%s: imported handle=%d has caching %d\n", __FUNCTION__, args.handle, caching.caching)); switch (caching.caching) { case 0: if (kgem->has_llc) { DBG(("%s: interpreting handle=%d as a foreign scanout\n", __FUNCTION__, args.handle)); bo->scanout = true; } break; case 1: if (!kgem->has_llc) { DBG(("%s: interpreting handle=%d as a foreign snooped buffer\n", __FUNCTION__, args.handle)); bo->snoop = true; if (bo->tiling) { DBG(("%s: illegal snooped tiled buffer\n", __FUNCTION__)); kgem_bo_free(kgem, bo); return NULL; } } break; case 2: DBG(("%s: interpreting handle=%d as a foreign scanout\n", __FUNCTION__, args.handle)); bo->scanout = true; break; } debug_alloc__bo(kgem, bo); return bo; #else return NULL; #endif } int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo) { #if defined(DRM_IOCTL_PRIME_HANDLE_TO_FD) && defined(O_CLOEXEC) struct drm_prime_handle args; assert(kgem_bo_is_fenced(kgem, bo)); VG_CLEAR(args); args.handle = bo->handle; args.flags = O_CLOEXEC; if (do_ioctl(kgem->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args)) return -1; bo->reusable = false; return args.fd; #else return -1; #endif } struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags) { struct kgem_bo *bo; uint32_t handle; DBG(("%s(%d)\n", __FUNCTION__, size)); assert(size); if (flags & CREATE_GTT_MAP && kgem->has_llc) { flags &= ~CREATE_GTT_MAP; flags |= CREATE_CPU_MAP; } size = NUM_PAGES(size); if ((flags & CREATE_UNCACHED) == 0) { bo = search_linear_cache(kgem, size, CREATE_INACTIVE | flags); if (bo) { assert(!bo->purged); assert(!bo->delta); assert(bo->domain != DOMAIN_GPU); ASSERT_IDLE(kgem, bo->handle); bo->refcnt = 1; return bo; } if (flags & CREATE_CACHED) return NULL; } handle = gem_create(kgem->fd, size); if (handle == 0) return NULL; DBG(("%s: new handle=%d, num_pages=%d\n", __FUNCTION__, handle, size)); bo = __kgem_bo_alloc(handle, size); if (bo == NULL) { gem_close(kgem->fd, handle); return NULL; } debug_alloc__bo(kgem, bo); return bo; } int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int bpp) { if (DBG_NO_TILING) return tiling < 0 ? tiling : I915_TILING_NONE; if (kgem->gen < 040) { if (tiling && width * bpp > 8192 * 8) { DBG(("%s: pitch too large for tliing [%d]\n", __FUNCTION__, width*bpp/8)); tiling = I915_TILING_NONE; goto done; } } else { if (width*bpp > (MAXSHORT-512) * 8) { if (tiling > 0) tiling = -tiling; else if (tiling == 0) tiling = -I915_TILING_X; DBG(("%s: large pitch [%d], forcing TILING [%d]\n", __FUNCTION__, width*bpp/8, tiling)); } else if (tiling && (width|height) > 8192) { DBG(("%s: large tiled buffer [%dx%d], forcing TILING_X\n", __FUNCTION__, width, height)); tiling = -I915_TILING_X; } /* fences limited to 128k (256k on ivb) */ assert(width * bpp <= 128 * 1024 * 8); } if (tiling < 0) return tiling; if (tiling == I915_TILING_Y && !kgem->can_render_y) tiling = I915_TILING_X; if (tiling && (height == 1 || width == 1)) { DBG(("%s: disabling tiling [%dx%d] for single row/col\n", __FUNCTION__,width, height)); tiling = I915_TILING_NONE; goto done; } if (tiling == I915_TILING_Y && height <= 16) { DBG(("%s: too short [%d] for TILING_Y\n", __FUNCTION__,height)); tiling = I915_TILING_X; } if (tiling && width * bpp > 8 * (4096 - 64)) { DBG(("%s: TLB miss between lines %dx%d (pitch=%d), forcing tiling %d\n", __FUNCTION__, width, height, width*bpp/8, tiling)); return -tiling; } if (tiling == I915_TILING_X && height < 4) { DBG(("%s: too short [%d] for TILING_X\n", __FUNCTION__, height)); tiling = I915_TILING_NONE; goto done; } if (tiling == I915_TILING_X && width * bpp <= 8*512) { DBG(("%s: too thin [width %d, %d bpp] for TILING_X\n", __FUNCTION__, width, bpp)); tiling = I915_TILING_NONE; goto done; } if (tiling == I915_TILING_Y && width * bpp < 8*128) { DBG(("%s: too thin [%d] for TILING_Y\n", __FUNCTION__, width)); tiling = I915_TILING_NONE; goto done; } if (tiling && ALIGN(height, 2) * ALIGN(width*bpp, 8*64) <= 4096 * 8) { DBG(("%s: too small [%d bytes] for TILING_%c\n", __FUNCTION__, ALIGN(height, 2) * ALIGN(width*bpp, 8*64) / 8, tiling == I915_TILING_X ? 'X' : 'Y')); tiling = I915_TILING_NONE; goto done; } if (tiling && width * bpp >= 8 * 4096 / 2) { DBG(("%s: TLB near-miss between lines %dx%d (pitch=%d), forcing tiling %d\n", __FUNCTION__, width, height, width*bpp/8, tiling)); return -tiling; } done: DBG(("%s: %dx%d -> %d\n", __FUNCTION__, width, height, tiling)); return tiling; } static int bits_per_pixel(int depth) { switch (depth) { case 8: return 8; case 15: case 16: return 16; case 24: case 30: case 32: return 32; default: return 0; } } unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth) { uint32_t pitch, size; unsigned flags = 0; int tiling; int bpp; DBG(("%s: %dx%d @ %d\n", __FUNCTION__, width, height, depth)); bpp = bits_per_pixel(depth); if (bpp == 0) { DBG(("%s: unhandled depth %d\n", __FUNCTION__, depth)); return 0; } if (width > MAXSHORT || height > MAXSHORT) { DBG(("%s: unhandled size %dx%d\n", __FUNCTION__, width, height)); return 0; } size = kgem_surface_size(kgem, false, 0, width, height, bpp, I915_TILING_NONE, &pitch); DBG(("%s: untiled size=%d\n", __FUNCTION__, size)); if (size > 0) { if (size <= kgem->max_cpu_size) flags |= KGEM_CAN_CREATE_CPU; if (size > 4096 && size <= kgem->max_gpu_size) flags |= KGEM_CAN_CREATE_GPU; if (size <= PAGE_SIZE*kgem->aperture_mappable/4 || kgem->has_wc_mmap) flags |= KGEM_CAN_CREATE_GTT; if (size > kgem->large_object_size) flags |= KGEM_CAN_CREATE_LARGE; if (size > kgem->max_object_size) { DBG(("%s: too large (untiled) %d > %d\n", __FUNCTION__, size, kgem->max_object_size)); return 0; } } tiling = kgem_choose_tiling(kgem, I915_TILING_X, width, height, bpp); if (tiling != I915_TILING_NONE) { size = kgem_surface_size(kgem, false, 0, width, height, bpp, tiling, &pitch); DBG(("%s: tiled[%d] size=%d\n", __FUNCTION__, tiling, size)); if (size > 0 && size <= kgem->max_gpu_size) flags |= KGEM_CAN_CREATE_GPU | KGEM_CAN_CREATE_TILED; if (size > 0 && size <= PAGE_SIZE*kgem->aperture_mappable/4) flags |= KGEM_CAN_CREATE_GTT; if (size > PAGE_SIZE*kgem->aperture_mappable/4) flags &= ~KGEM_CAN_CREATE_GTT; if (size > kgem->large_object_size) flags |= KGEM_CAN_CREATE_LARGE; if (size > kgem->max_object_size) { DBG(("%s: too large (tiled) %d > %d\n", __FUNCTION__, size, kgem->max_object_size)); return 0; } if (kgem->gen < 040) { int fence_size = 1024 * 1024; while (fence_size < size) fence_size <<= 1; if (fence_size > kgem->max_gpu_size) flags &= ~KGEM_CAN_CREATE_GPU | KGEM_CAN_CREATE_TILED; if (fence_size > PAGE_SIZE*kgem->aperture_fenceable/4) flags &= ~KGEM_CAN_CREATE_GTT; } } return flags; } inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo) { unsigned int size; assert(bo->tiling); assert_tiling(kgem, bo); assert(kgem->gen < 040); if (kgem->gen < 030) size = 512 * 1024 / PAGE_SIZE; else size = 1024 * 1024 / PAGE_SIZE; while (size < num_pages(bo)) size <<= 1; return size; } static struct kgem_bo * __kgem_bo_create_as_display(struct kgem *kgem, int size, int tiling, int pitch) { struct local_i915_gem_create2 args; struct kgem_bo *bo; if (!kgem->has_create2) return NULL; memset(&args, 0, sizeof(args)); args.size = size * PAGE_SIZE; args.placement = LOCAL_I915_CREATE_PLACEMENT_STOLEN; args.caching = DISPLAY; args.tiling_mode = tiling; args.stride = pitch; if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args)) { args.placement = LOCAL_I915_CREATE_PLACEMENT_SYSTEM; if (do_ioctl(kgem->fd, LOCAL_IOCTL_I915_GEM_CREATE2, &args)) return NULL; } bo = __kgem_bo_alloc(args.handle, size); if (bo == NULL) { gem_close(kgem->fd, args.handle); return NULL; } bo->unique_id = kgem_get_unique_id(kgem); bo->tiling = tiling; bo->pitch = pitch; if (args.placement == LOCAL_I915_CREATE_PLACEMENT_STOLEN) { bo->purged = true; /* for asserts against CPU access */ } bo->reusable = false; /* so that unclaimed scanouts are freed */ bo->domain = DOMAIN_NONE; if (__kgem_busy(kgem, bo->handle)) { assert(bo->exec == NULL); list_add(&bo->request, &kgem->flushing); bo->rq = (void *)kgem; kgem->need_retire = true; } assert_tiling(kgem, bo); debug_alloc__bo(kgem, bo); return bo; } static void __kgem_bo_make_scanout(struct kgem *kgem, struct kgem_bo *bo, int width, int height) { ScrnInfoPtr scrn = __to_sna(kgem)->scrn; struct drm_mode_fb_cmd arg; assert(bo->proxy == NULL); if (!scrn->vtSema) return; DBG(("%s: create fb %dx%d@%d/%d\n", __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel)); VG_CLEAR(arg); arg.width = width; arg.height = height; arg.pitch = bo->pitch; arg.bpp = scrn->bitsPerPixel; arg.depth = scrn->depth; arg.handle = bo->handle; /* First move the scanout out of cached memory */ if (kgem->has_llc) { if (!gem_set_caching(kgem->fd, bo->handle, DISPLAY) && !gem_set_caching(kgem->fd, bo->handle, UNCACHED)) return; } bo->scanout = true; /* Then pre-emptively move the object into the mappable * portion to avoid rebinding later when busy. */ if (bo->map__gtt == NULL) bo->map__gtt = __kgem_bo_map__gtt(kgem, bo); if (bo->map__gtt) { if (sigtrap_get() == 0) { *(uint32_t *)bo->map__gtt = 0; sigtrap_put(); } bo->domain = DOMAIN_GTT; } if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg) == 0) { DBG(("%s: attached fb=%d to handle=%d\n", __FUNCTION__, arg.fb_id, arg.handle)); bo->delta = arg.fb_id; } } static bool tiling_changed(struct kgem_bo *bo, int tiling, int pitch) { if (tiling != bo->tiling) return true; return tiling != I915_TILING_NONE && pitch != bo->pitch; } static void set_gpu_tiling(struct kgem *kgem, struct kgem_bo *bo, int tiling, int pitch) { DBG(("%s: handle=%d, tiling=%d, pitch=%d\n", __FUNCTION__, bo->handle, tiling, pitch)); if (tiling_changed(bo, tiling, pitch) && bo->map__gtt) { if (!list_is_empty(&bo->vma)) { list_del(&bo->vma); kgem->vma[0].count--; } munmap(bo->map__gtt, bytes(bo)); bo->map__gtt = NULL; } bo->tiling = tiling; bo->pitch = pitch; } bool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo) { struct drm_i915_gem_get_tiling tiling; assert(kgem); assert(bo); VG_CLEAR(tiling); tiling.handle = bo->handle; tiling.tiling_mode = 0; (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling); return tiling.tiling_mode == bo->tiling; /* assume pitch is fine! */ } struct kgem_bo *kgem_create_2d(struct kgem *kgem, int width, int height, int bpp, int tiling, uint32_t flags) { struct list *cache; struct kgem_bo *bo; uint32_t pitch, tiled_height, size; uint32_t handle; int i, bucket, retry; bool exact = flags & (CREATE_EXACT | CREATE_SCANOUT); if (tiling < 0) exact = true, tiling = -tiling; DBG(("%s(%dx%d, bpp=%d, tiling=%d, exact=%d, inactive=%d, cpu-mapping=%d, gtt-mapping=%d, scanout?=%d, prime?=%d, temp?=%d)\n", __FUNCTION__, width, height, bpp, tiling, exact, !!(flags & CREATE_INACTIVE), !!(flags & CREATE_CPU_MAP), !!(flags & CREATE_GTT_MAP), !!(flags & CREATE_SCANOUT), !!(flags & CREATE_PRIME), !!(flags & CREATE_TEMPORARY))); size = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags, width, height, bpp, tiling, &pitch); if (size == 0) { DBG(("%s: invalid surface size (too large?)\n", __FUNCTION__)); return NULL; } size /= PAGE_SIZE; bucket = cache_bucket(size); if (flags & CREATE_SCANOUT) { struct kgem_bo *last = NULL; list_for_each_entry_reverse(bo, &kgem->scanout, list) { assert(bo->scanout); assert(!bo->flush); assert(!bo->refcnt); assert_tiling(kgem, bo); if (size > num_pages(bo) || num_pages(bo) > 2*size) continue; if (bo->tiling != tiling || bo->pitch != pitch) /* No tiling/pitch without recreating fb */ continue; if (bo->delta && !check_scanout_size(kgem, bo, width, height)) continue; if (flags & CREATE_INACTIVE && bo->rq) { last = bo; continue; } list_del(&bo->list); bo->unique_id = kgem_get_unique_id(kgem); DBG((" 1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } if (last) { list_del(&last->list); last->unique_id = kgem_get_unique_id(kgem); DBG((" 1:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n", last->pitch, last->tiling, last->handle, last->unique_id)); assert(last->pitch*kgem_aligned_height(kgem, height, last->tiling) <= kgem_bo_size(last)); assert_tiling(kgem, last); last->refcnt = 1; return last; } if (__to_sna(kgem)->scrn->vtSema) { ScrnInfoPtr scrn = __to_sna(kgem)->scrn; list_for_each_entry_reverse(bo, &kgem->scanout, list) { struct drm_mode_fb_cmd arg; assert(bo->scanout); assert(!bo->refcnt); if (size > num_pages(bo) || num_pages(bo) > 2*size) continue; if (flags & CREATE_INACTIVE && bo->rq) continue; list_del(&bo->list); if (bo->tiling != tiling || bo->pitch != pitch) { if (bo->delta) { kgem_bo_rmfb(kgem, bo); bo->delta = 0; } if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { kgem_bo_free(kgem, bo); break; } } VG_CLEAR(arg); arg.width = width; arg.height = height; arg.pitch = bo->pitch; arg.bpp = scrn->bitsPerPixel; arg.depth = scrn->depth; arg.handle = bo->handle; if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg)) { kgem_bo_free(kgem, bo); break; } bo->delta = arg.fb_id; bo->unique_id = kgem_get_unique_id(kgem); DBG((" 2:from scanout: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } if (flags & CREATE_CACHED) return NULL; bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch); if (bo) return bo; flags |= CREATE_INACTIVE; } if (bucket >= NUM_CACHE_BUCKETS) { DBG(("%s: large bo num pages=%d, bucket=%d\n", __FUNCTION__, size, bucket)); if (flags & CREATE_INACTIVE) goto large_inactive; tiled_height = kgem_aligned_height(kgem, height, tiling); list_for_each_entry(bo, &kgem->large, list) { assert(!bo->purged); assert(!bo->scanout); assert(bo->refcnt == 0); assert(bo->reusable); assert_tiling(kgem, bo); if (kgem->gen < 040) { if (bo->pitch < pitch) { DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", bo->tiling, tiling, bo->pitch, pitch)); continue; } if (bo->pitch * tiled_height > bytes(bo)) continue; } else { if (num_pages(bo) < size) continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch) && !exact) set_gpu_tiling(kgem, bo, tiling, pitch); } kgem_bo_remove_from_active(kgem, bo); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } large_inactive: __kgem_throttle_retire(kgem, flags); list_for_each_entry(bo, &kgem->large_inactive, list) { assert(bo->refcnt == 0); assert(bo->reusable); assert(!bo->scanout); assert_tiling(kgem, bo); if (size > num_pages(bo)) continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { if (kgem->gen >= 040 && !exact) set_gpu_tiling(kgem, bo, tiling, pitch); else continue; } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); break; } list_del(&bo->list); assert(bo->domain != DOMAIN_GPU); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from large inactive: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; if (flags & CREATE_SCANOUT) __kgem_bo_make_scanout(kgem, bo, width, height); return bo; } goto create; } if (flags & (CREATE_CPU_MAP | CREATE_GTT_MAP)) { int for_cpu = !!(flags & CREATE_CPU_MAP); if (kgem->has_llc && tiling == I915_TILING_NONE) for_cpu = 1; /* We presume that we will need to upload to this bo, * and so would prefer to have an active VMA. */ cache = &kgem->vma[for_cpu].inactive[bucket]; do { list_for_each_entry(bo, cache, vma) { assert(bucket(bo) == bucket); assert(bo->refcnt == 0); assert(!bo->scanout); assert(for_cpu ? !!bo->map__cpu : (bo->map__gtt || bo->map__wc)); assert(bo->rq == NULL); assert(bo->exec == NULL); assert(list_is_empty(&bo->request)); assert(bo->flush == false); assert_tiling(kgem, bo); if (size > num_pages(bo)) { DBG(("inactive too small: %d < %d\n", num_pages(bo), size)); continue; } if (flags & UNCACHED && !kgem->has_llc && bo->domain != DOMAIN_CPU) continue; if (bo->tiling != tiling || (tiling != I915_TILING_NONE && bo->pitch != pitch)) { if (bo->map__gtt || !kgem_set_tiling(kgem, bo, tiling, pitch)) { DBG(("inactive GTT vma with wrong tiling: %d < %d\n", bo->tiling, tiling)); kgem_bo_free(kgem, bo); break; } } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); break; } if (tiling == I915_TILING_NONE) bo->pitch = pitch; assert(bo->tiling == tiling); assert(bo->pitch >= pitch); bo->delta = 0; bo->unique_id = kgem_get_unique_id(kgem); kgem_bo_remove_from_inactive(kgem, bo); assert(list_is_empty(&bo->list)); assert(list_is_empty(&bo->vma)); DBG((" from inactive vma: pitch=%d, tiling=%d: handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->reusable); assert(bo->domain != DOMAIN_GPU); ASSERT_IDLE(kgem, bo->handle); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } while (!list_is_empty(cache) && __kgem_throttle_retire(kgem, flags)); if (flags & CREATE_CPU_MAP && !kgem->has_llc) { if (list_is_empty(&kgem->active[bucket][tiling]) && list_is_empty(&kgem->inactive[bucket])) flags &= ~CREATE_CACHED; goto create; } } if (flags & CREATE_INACTIVE) goto skip_active_search; /* Best active match */ retry = NUM_CACHE_BUCKETS - bucket; if (retry > 3 && (flags & CREATE_TEMPORARY) == 0) retry = 3; search_active: assert(bucket < NUM_CACHE_BUCKETS); cache = &kgem->active[bucket][tiling]; if (tiling) { tiled_height = kgem_aligned_height(kgem, height, tiling); list_for_each_entry(bo, cache, list) { assert(!bo->purged); assert(bo->refcnt == 0); assert(bucket(bo) == bucket); assert(bo->reusable); assert(bo->tiling == tiling); assert(bo->flush == false); assert(!bo->scanout); assert_tiling(kgem, bo); if (kgem->gen < 040) { if (bo->pitch < pitch) { DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", bo->tiling, tiling, bo->pitch, pitch)); continue; } if (bo->pitch * tiled_height > bytes(bo)) continue; } else { if (num_pages(bo) < size) continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch) && !exact) set_gpu_tiling(kgem, bo, tiling, pitch); } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); kgem_bo_remove_from_active(kgem, bo); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } else { list_for_each_entry(bo, cache, list) { assert(bucket(bo) == bucket); assert(!bo->purged); assert(bo->refcnt == 0); assert(bo->reusable); assert(!bo->scanout); assert(bo->tiling == tiling); assert(bo->flush == false); assert_tiling(kgem, bo); if (num_pages(bo) < size) continue; kgem_bo_remove_from_active(kgem, bo); bo->pitch = pitch; bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } if (kgem->gen >= 040) { for (i = I915_TILING_Y; i >= I915_TILING_NONE; i--) { cache = &kgem->active[bucket][i]; list_for_each_entry(bo, cache, list) { assert(!bo->purged); assert(bo->refcnt == 0); assert(bo->reusable); assert(!bo->scanout); assert(bo->flush == false); assert_tiling(kgem, bo); if (num_pages(bo) < size) continue; if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { if (kgem->gen >= 040 && !exact) { set_gpu_tiling(kgem, bo, tiling, pitch); } else { kgem_bo_free(kgem, bo); break; } } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); kgem_bo_remove_from_active(kgem, bo); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } } else if (!exact) { /* allow an active near-miss? */ for (i = tiling; i >= I915_TILING_NONE; i--) { tiled_height = kgem_surface_size(kgem, kgem->has_relaxed_fencing, flags, width, height, bpp, tiling, &pitch); cache = active(kgem, tiled_height / PAGE_SIZE, i); tiled_height = kgem_aligned_height(kgem, height, i); list_for_each_entry(bo, cache, list) { assert(!bo->purged); assert(bo->refcnt == 0); assert(bo->reusable); assert(!bo->scanout); assert(bo->flush == false); assert_tiling(kgem, bo); if (bo->tiling) { if (bo->pitch < pitch) { DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n", bo->tiling, tiling, bo->pitch, pitch)); continue; } } else bo->pitch = pitch; if (bo->pitch * tiled_height > bytes(bo)) continue; kgem_bo_remove_from_active(kgem, bo); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 1:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; return bo; } } } if (--retry) { bucket++; goto search_active; } skip_active_search: bucket = cache_bucket(size); retry = NUM_CACHE_BUCKETS - bucket; if (retry > 3) retry = 3; search_inactive: /* Now just look for a close match and prefer any currently active */ assert(bucket < NUM_CACHE_BUCKETS); cache = &kgem->inactive[bucket]; list_for_each_entry(bo, cache, list) { assert(bucket(bo) == bucket); assert(bo->reusable); assert(!bo->scanout); assert(bo->flush == false); assert_tiling(kgem, bo); if (size > num_pages(bo)) { DBG(("inactive too small: %d < %d\n", num_pages(bo), size)); continue; } if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { if (kgem->gen >= 040 && !exact) { set_gpu_tiling(kgem, bo, tiling, pitch); } else { kgem_bo_free(kgem, bo); break; } } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { kgem_bo_free(kgem, bo); break; } kgem_bo_remove_from_inactive(kgem, bo); assert(list_is_empty(&bo->list)); assert(list_is_empty(&bo->vma)); assert(bo->tiling == tiling); assert(bo->pitch >= pitch); bo->delta = 0; bo->unique_id = kgem_get_unique_id(kgem); assert(bo->pitch); DBG((" from inactive: pitch=%d, tiling=%d: handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->refcnt == 0); assert(bo->reusable); assert((flags & CREATE_INACTIVE) == 0 || bo->domain != DOMAIN_GPU); ASSERT_MAYBE_IDLE(kgem, bo->handle, flags & CREATE_INACTIVE); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; if (flags & CREATE_SCANOUT) __kgem_bo_make_scanout(kgem, bo, width, height); return bo; } if ((flags & CREATE_NO_RETIRE) == 0) { list_for_each_entry_reverse(bo, &kgem->active[bucket][tiling], list) { if (bo->exec) break; if (size > num_pages(bo)) continue; if (__kgem_busy(kgem, bo->handle)) { if (flags & CREATE_NO_THROTTLE) goto no_retire; do { if (!kgem->need_throttle) { DBG(("%s: not throttling for active handle=%d\n", __FUNCTION__, bo->handle)); goto no_retire; } __kgem_throttle(kgem, false); } while (__kgem_busy(kgem, bo->handle)); } DBG(("%s: flushed active handle=%d\n", __FUNCTION__, bo->handle)); kgem_bo_remove_from_active(kgem, bo); __kgem_bo_clear_busy(bo); if (!kgem_set_tiling(kgem, bo, tiling, pitch)) { if (kgem->gen >= 040 && !exact) { set_gpu_tiling(kgem, bo, tiling, pitch); } else { kgem_bo_free(kgem, bo); goto no_retire; } } assert(bo->tiling == tiling); assert(bo->pitch >= pitch); bo->unique_id = kgem_get_unique_id(kgem); bo->delta = 0; DBG((" 2:from active: pitch=%d, tiling=%d, handle=%d, id=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id)); assert(bo->pitch*kgem_aligned_height(kgem, height, bo->tiling) <= kgem_bo_size(bo)); assert_tiling(kgem, bo); bo->refcnt = 1; if (flags & CREATE_SCANOUT) __kgem_bo_make_scanout(kgem, bo, width, height); return bo; } no_retire: flags |= CREATE_NO_RETIRE; } if (--retry) { bucket++; goto search_inactive; } create: if (flags & CREATE_CACHED) { DBG(("%s: no cached bo found, requested not to create a new bo\n", __FUNCTION__)); return NULL; } if (bucket >= NUM_CACHE_BUCKETS) size = ALIGN(size, 1024); handle = gem_create(kgem->fd, size); if (handle == 0) { DBG(("%s: kernel allocation (gem_create) failure\n", __FUNCTION__)); return NULL; } bo = __kgem_bo_alloc(handle, size); if (!bo) { DBG(("%s: malloc failed\n", __FUNCTION__)); gem_close(kgem->fd, handle); return NULL; } bo->unique_id = kgem_get_unique_id(kgem); if (kgem_set_tiling(kgem, bo, tiling, pitch)) { if (flags & CREATE_SCANOUT) __kgem_bo_make_scanout(kgem, bo, width, height); } else { if (kgem->gen >= 040) { assert(!kgem->can_fence); bo->tiling = tiling; bo->pitch = pitch; } else { if (flags & CREATE_EXACT) { DBG(("%s: failed to set exact tiling (gem_set_tiling)\n", __FUNCTION__)); gem_close(kgem->fd, handle); free(bo); return NULL; } } } assert(bytes(bo) >= bo->pitch * kgem_aligned_height(kgem, height, bo->tiling)); assert_tiling(kgem, bo); debug_alloc__bo(kgem, bo); DBG((" new pitch=%d, tiling=%d, handle=%d, id=%d, num_pages=%d [%d], bucket=%d\n", bo->pitch, bo->tiling, bo->handle, bo->unique_id, size, num_pages(bo), bucket(bo))); return bo; } struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem, int width, int height, int bpp, uint32_t flags) { struct kgem_bo *bo; int stride, size; if (DBG_NO_CPU) return NULL; DBG(("%s(%dx%d, bpp=%d)\n", __FUNCTION__, width, height, bpp)); if (kgem->has_llc) { bo = kgem_create_2d(kgem, width, height, bpp, I915_TILING_NONE, flags); if (bo == NULL) return bo; assert(bo->tiling == I915_TILING_NONE); assert_tiling(kgem, bo); if (kgem_bo_map__cpu(kgem, bo) == NULL) { kgem_bo_destroy(kgem, bo); return NULL; } return bo; } assert(width > 0 && height > 0); stride = ALIGN(width, 2) * bpp >> 3; stride = ALIGN(stride, 4); size = stride * ALIGN(height, 2); assert(size >= PAGE_SIZE); DBG(("%s: %dx%d, %d bpp, stride=%d\n", __FUNCTION__, width, height, bpp, stride)); bo = search_snoop_cache(kgem, NUM_PAGES(size), 0); if (bo) { assert(bo->tiling == I915_TILING_NONE); assert_tiling(kgem, bo); assert(bo->snoop); bo->refcnt = 1; bo->pitch = stride; bo->unique_id = kgem_get_unique_id(kgem); return bo; } if (kgem->has_caching) { bo = kgem_create_linear(kgem, size, flags); if (bo == NULL) return NULL; assert(bo->tiling == I915_TILING_NONE); assert_tiling(kgem, bo); assert(!__kgem_busy(kgem, bo->handle)); if (!gem_set_caching(kgem->fd, bo->handle, SNOOPED)) { kgem_bo_destroy(kgem, bo); return NULL; } bo->snoop = true; if (kgem_bo_map__cpu(kgem, bo) == NULL) { kgem_bo_destroy(kgem, bo); return NULL; } bo->pitch = stride; bo->unique_id = kgem_get_unique_id(kgem); return bo; } if (kgem->has_userptr) { void *ptr; /* XXX */ //if (posix_memalign(&ptr, 64, ALIGN(size, 64))) if (posix_memalign(&ptr, PAGE_SIZE, ALIGN(size, PAGE_SIZE))) return NULL; bo = kgem_create_map(kgem, ptr, size, false); if (bo == NULL) { free(ptr); return NULL; } bo->pitch = stride; bo->unique_id = kgem_get_unique_id(kgem); return bo; } return NULL; } void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, proxy? %d\n", __FUNCTION__, bo->handle, bo->proxy != NULL)); if (bo->proxy) { assert(!bo->reusable); kgem_bo_binding_free(kgem, bo); assert(list_is_empty(&bo->list)); _list_del(&bo->vma); _list_del(&bo->request); if (bo->io && bo->domain == DOMAIN_CPU) _kgem_bo_delete_buffer(kgem, bo); kgem_bo_unref(kgem, bo->proxy); if (DBG_NO_MALLOC_CACHE) { free(bo); } else { *(struct kgem_bo **)bo = __kgem_freed_bo; __kgem_freed_bo = bo; } } else __kgem_bo_destroy(kgem, bo); } static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->rq); assert(bo->exec == NULL); assert(bo->needs_flush); /* The kernel will emit a flush *and* update its own flushing lists. */ if (!__kgem_busy(kgem, bo->handle)) __kgem_bo_clear_busy(bo); DBG(("%s: handle=%d, busy?=%d\n", __FUNCTION__, bo->handle, bo->rq != NULL)); } void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo) { if (!bo->needs_flush && !bo->gtt_dirty) return; kgem_bo_submit(kgem, bo); /* If the kernel fails to emit the flush, then it will be forced when * we assume direct access. And as the usual failure is EIO, we do * not actually care. */ assert(bo->exec == NULL); if (bo->rq) __kgem_flush(kgem, bo); if (bo->scanout && kgem->needs_dirtyfb) { struct drm_mode_fb_dirty_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.fb_id = bo->delta; (void)drmIoctl(kgem->fd, DRM_IOCTL_MODE_DIRTYFB, &cmd); } /* Whatever actually happens, we can regard the GTT write domain * as being flushed. */ bo->gtt_dirty = false; bo->needs_flush = false; bo->domain = DOMAIN_NONE; } inline static bool nearly_idle(struct kgem *kgem) { int ring = kgem->ring == KGEM_BLT; assert(ring < ARRAY_SIZE(kgem->requests)); if (list_is_singular(&kgem->requests[ring])) return true; return __kgem_ring_is_idle(kgem, ring); } inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo) { if (kgem->needs_semaphore) return false; if (bo->rq == NULL || RQ_RING(bo->rq) == kgem->ring) return false; kgem->needs_semaphore = true; return true; } inline static bool needs_reservation(struct kgem *kgem, struct kgem_bo *bo) { if (kgem->needs_reservation) return false; if (bo->presumed_offset) return false; kgem->needs_reservation = true; return nearly_idle(kgem); } inline static bool needs_batch_flush(struct kgem *kgem, struct kgem_bo *bo) { bool flush = false; if (needs_semaphore(kgem, bo)) { DBG(("%s: flushing before handle=%d for required semaphore\n", __FUNCTION__, bo->handle)); flush = true; } if (needs_reservation(kgem, bo)) { DBG(("%s: flushing before handle=%d for new reservation\n", __FUNCTION__, bo->handle)); flush = true; } return kgem->nreloc ? flush : false; } static bool aperture_check(struct kgem *kgem, unsigned num_pages) { struct drm_i915_gem_get_aperture aperture; int reserve; if (kgem->aperture) return false; /* Leave some space in case of alignment issues */ reserve = kgem->aperture_mappable / 2; if (kgem->gen < 033 && reserve < kgem->aperture_max_fence) reserve = kgem->aperture_max_fence; if (!kgem->has_llc) reserve += kgem->nexec * PAGE_SIZE * 2; DBG(("%s: num_pages=%d, holding %d pages in reserve, total aperture %d\n", __FUNCTION__, num_pages, reserve, kgem->aperture_total)); num_pages += reserve; VG_CLEAR(aperture); aperture.aper_available_size = kgem->aperture_total; aperture.aper_available_size *= PAGE_SIZE; (void)do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture); DBG(("%s: aperture required %ld bytes, available %ld bytes\n", __FUNCTION__, (long)num_pages * PAGE_SIZE, (long)aperture.aper_available_size)); return num_pages <= aperture.aper_available_size / PAGE_SIZE; } static inline bool kgem_flush(struct kgem *kgem, bool flush) { if (unlikely(kgem->wedged)) return false; if (kgem->nreloc == 0) return true; if (__to_sna(kgem)->flags & SNA_POWERSAVE) return true; if (kgem->flush == flush && kgem->aperture < kgem->aperture_low) return true; DBG(("%s: opportunistic flushing? flush=%d,%d, aperture=%d/%d, idle?=%d\n", __FUNCTION__, kgem->flush, flush, kgem->aperture, kgem->aperture_low, kgem_ring_is_idle(kgem, kgem->ring))); return !kgem_ring_is_idle(kgem, kgem->ring); } bool kgem_check_bo(struct kgem *kgem, ...) { va_list ap; struct kgem_bo *bo; int num_exec = 0; int num_pages = 0; bool flush = false; bool busy = true; va_start(ap, kgem); while ((bo = va_arg(ap, struct kgem_bo *))) { while (bo->proxy) bo = bo->proxy; if (bo->exec) continue; if (needs_batch_flush(kgem, bo)) { va_end(ap); return false; } num_pages += num_pages(bo); num_exec++; flush |= bo->flush; busy &= bo->rq != NULL; } va_end(ap); DBG(("%s: num_pages=+%d, num_exec=+%d\n", __FUNCTION__, num_pages, num_exec)); if (!num_pages) return true; if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) { DBG(("%s: out of exec slots (%d + %d / %d)\n", __FUNCTION__, kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem))); return false; } if (num_pages + kgem->aperture > kgem->aperture_high) { DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n", __FUNCTION__, kgem->aperture, num_pages, kgem->aperture_high)); return aperture_check(kgem, num_pages); } if (busy) return true; return kgem_flush(kgem, flush); } bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt); while (bo->proxy) bo = bo->proxy; assert(bo->refcnt); if (bo->exec) { if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE && (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) { uint32_t size; assert(bo->tiling == I915_TILING_X); if (kgem->nfence >= kgem->fence_max) return false; if (kgem->aperture_fenced) { size = 3*kgem->aperture_fenced; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable && kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: opportunistic fence flush\n", __FUNCTION__)); return false; } } size = kgem_bo_fenced_size(kgem, bo); if (size > kgem->aperture_max_fence) kgem->aperture_max_fence = size; size += kgem->aperture_fenced; if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence) size = 2 * kgem->aperture_max_fence; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable) { DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds fenceable aperture %d\n", __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable)); return false; } } return true; } if (kgem->nexec >= KGEM_EXEC_SIZE(kgem) - 1) return false; if (needs_batch_flush(kgem, bo)) return false; assert_tiling(kgem, bo); if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) { uint32_t size; assert(bo->tiling == I915_TILING_X); if (kgem->nfence >= kgem->fence_max) return false; if (kgem->aperture_fenced) { size = 3*kgem->aperture_fenced; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable && kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: opportunistic fence flush\n", __FUNCTION__)); return false; } } size = kgem_bo_fenced_size(kgem, bo); if (size > kgem->aperture_max_fence) kgem->aperture_max_fence = size; size += kgem->aperture_fenced; if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence) size = 2 * kgem->aperture_max_fence; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable) { DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds fenceable aperture %d\n", __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable)); return false; } } if (kgem->aperture + kgem->aperture_fenced + num_pages(bo) > kgem->aperture_high) { DBG(("%s: final aperture usage (%d + %d) is greater than high water mark (%d)\n", __FUNCTION__, kgem->aperture, num_pages(bo), kgem->aperture_high)); return aperture_check(kgem, num_pages(bo)); } if (bo->rq) return true; return kgem_flush(kgem, bo->flush); } bool kgem_check_many_bo_fenced(struct kgem *kgem, ...) { va_list ap; struct kgem_bo *bo; int num_fence = 0; int num_exec = 0; int num_pages = 0; int fenced_size = 0; bool flush = false; bool busy = true; va_start(ap, kgem); while ((bo = va_arg(ap, struct kgem_bo *))) { assert(bo->refcnt); while (bo->proxy) bo = bo->proxy; assert(bo->refcnt); if (bo->exec) { if (kgem->gen >= 040 || bo->tiling == I915_TILING_NONE) continue; if ((bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) { fenced_size += kgem_bo_fenced_size(kgem, bo); num_fence++; } continue; } if (needs_batch_flush(kgem, bo)) { va_end(ap); return false; } assert_tiling(kgem, bo); num_pages += num_pages(bo); num_exec++; if (kgem->gen < 040 && bo->tiling) { uint32_t size = kgem_bo_fenced_size(kgem, bo); if (size > kgem->aperture_max_fence) kgem->aperture_max_fence = size; fenced_size += size; num_fence++; } flush |= bo->flush; busy &= bo->rq != NULL; } va_end(ap); if (num_fence) { uint32_t size; if (kgem->nfence + num_fence > kgem->fence_max) return false; if (kgem->aperture_fenced) { size = 3*kgem->aperture_fenced; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable && kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: opportunistic fence flush\n", __FUNCTION__)); return false; } } size = kgem->aperture_fenced; size += fenced_size; if (kgem->gen < 033 && size < 2 * kgem->aperture_max_fence) size = 2 * kgem->aperture_max_fence; if (kgem->aperture_total == kgem->aperture_mappable) size += kgem->aperture; if (size > kgem->aperture_fenceable) { DBG(("%s: estimated fence space required %d (fenced=%d, max_fence=%d, aperture=%d) exceeds fenceable aperture %d\n", __FUNCTION__, size, kgem->aperture_fenced, kgem->aperture_max_fence, kgem->aperture, kgem->aperture_fenceable)); return false; } } if (num_pages == 0) return true; if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) return false; if (num_pages + kgem->aperture > kgem->aperture_high - kgem->aperture_fenced) { DBG(("%s: final aperture usage (%d + %d + %d) is greater than high water mark (%d)\n", __FUNCTION__, kgem->aperture, kgem->aperture_fenced, num_pages, kgem->aperture_high)); return aperture_check(kgem, num_pages); } if (busy) return true; return kgem_flush(kgem, flush); } void __kgem_bcs_set_tiling(struct kgem *kgem, struct kgem_bo *src, struct kgem_bo *dst) { uint32_t state, *b; DBG(("%s: src handle=%d:tiling=%d, dst handle=%d:tiling=%d\n", __FUNCTION__, src ? src->handle : 0, src ? src->tiling : 0, dst ? dst->handle : 0, dst ? dst->tiling : 0)); assert(kgem->mode == KGEM_BLT); assert(dst == NULL || kgem_bo_can_blt(kgem, dst)); assert(src == NULL || kgem_bo_can_blt(kgem, src)); state = 0; if (dst && dst->tiling == I915_TILING_Y) state |= BCS_DST_Y; if (src && src->tiling == I915_TILING_Y) state |= BCS_SRC_Y; if (kgem->bcs_state == state) return; DBG(("%s: updating SWCTRL %x -> %x\n", __FUNCTION__, kgem->bcs_state, state)); /* Over-estimate space in case we need to re-emit the cmd packet */ if (!kgem_check_batch(kgem, 24)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); if (state == 0) return; } b = kgem->batch + kgem->nbatch; if (kgem->nbatch) { *b++ = MI_FLUSH_DW; *b++ = 0; *b++ = 0; *b++ = 0; } *b++ = MI_LOAD_REGISTER_IMM; *b++ = BCS_SWCTRL; *b++ = (BCS_SRC_Y | BCS_DST_Y) << 16 | state; kgem->nbatch = b - kgem->batch; kgem->bcs_state = state; } uint32_t kgem_add_reloc(struct kgem *kgem, uint32_t pos, struct kgem_bo *bo, uint32_t read_write_domain, uint32_t delta) { int index; DBG(("%s: handle=%d, pos=%d, delta=%d, domains=%08x\n", __FUNCTION__, bo ? bo->handle : 0, pos, delta, read_write_domain)); assert(kgem->gen < 0100); assert((read_write_domain & 0x7fff) == 0 || bo != NULL); index = kgem->nreloc++; assert(index < ARRAY_SIZE(kgem->reloc)); kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]); if (bo) { assert(kgem->mode != KGEM_NONE); assert(bo->refcnt); while (bo->proxy) { DBG(("%s: adding proxy [delta=%d] for handle=%d\n", __FUNCTION__, bo->delta, bo->handle)); delta += bo->delta; assert(bo->handle == bo->proxy->handle); /* need to release the cache upon batch submit */ if (bo->exec == NULL) { list_move_tail(&bo->request, &kgem->next_request->buffers); bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring); bo->exec = &_kgem_dummy_exec; bo->domain = DOMAIN_GPU; } if (read_write_domain & 0x7fff && !bo->gpu_dirty) __kgem_bo_mark_dirty(bo); bo = bo->proxy; assert(bo->refcnt); } assert(bo->refcnt); if (bo->exec == NULL) kgem_add_bo(kgem, bo); assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring)); assert(RQ_RING(bo->rq) == kgem->ring); if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) { if (bo->tiling && (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) { assert(bo->tiling == I915_TILING_X); assert(kgem->nfence < kgem->fence_max); kgem->aperture_fenced += kgem_bo_fenced_size(kgem, bo); kgem->nfence++; } bo->exec->flags |= EXEC_OBJECT_NEEDS_FENCE; } kgem->reloc[index].delta = delta; kgem->reloc[index].target_handle = bo->target_handle; kgem->reloc[index].presumed_offset = bo->presumed_offset; if (read_write_domain & 0x7fff && !bo->gpu_dirty) { assert(!bo->snoop || kgem->can_blt_cpu); __kgem_bo_mark_dirty(bo); } delta += bo->presumed_offset; } else { kgem->reloc[index].delta = delta; kgem->reloc[index].target_handle = ~0U; kgem->reloc[index].presumed_offset = 0; if (kgem->nreloc__self < 256) kgem->reloc__self[kgem->nreloc__self++] = index; } kgem->reloc[index].read_domains = read_write_domain >> 16; kgem->reloc[index].write_domain = read_write_domain & 0x7fff; return delta; } uint64_t kgem_add_reloc64(struct kgem *kgem, uint32_t pos, struct kgem_bo *bo, uint32_t read_write_domain, uint64_t delta) { int index; DBG(("%s: handle=%d, pos=%d, delta=%ld, domains=%08x\n", __FUNCTION__, bo ? bo->handle : 0, pos, (long)delta, read_write_domain)); assert(kgem->gen >= 0100); assert((read_write_domain & 0x7fff) == 0 || bo != NULL); index = kgem->nreloc++; assert(index < ARRAY_SIZE(kgem->reloc)); kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]); if (bo) { assert(kgem->mode != KGEM_NONE); assert(bo->refcnt); while (bo->proxy) { DBG(("%s: adding proxy [delta=%ld] for handle=%d\n", __FUNCTION__, (long)bo->delta, bo->handle)); delta += bo->delta; assert(bo->handle == bo->proxy->handle); /* need to release the cache upon batch submit */ if (bo->exec == NULL) { list_move_tail(&bo->request, &kgem->next_request->buffers); bo->rq = MAKE_REQUEST(kgem->next_request, kgem->ring); bo->exec = &_kgem_dummy_exec; bo->domain = DOMAIN_GPU; } if (read_write_domain & 0x7fff && !bo->gpu_dirty) __kgem_bo_mark_dirty(bo); bo = bo->proxy; assert(bo->refcnt); } assert(bo->refcnt); if (bo->exec == NULL) kgem_add_bo(kgem, bo); assert(bo->rq == MAKE_REQUEST(kgem->next_request, kgem->ring)); assert(RQ_RING(bo->rq) == kgem->ring); DBG(("%s[%d] = (delta=%d, target handle=%d, presumed=%llx)\n", __FUNCTION__, index, delta, bo->target_handle, (long long)bo->presumed_offset)); kgem->reloc[index].delta = delta; kgem->reloc[index].target_handle = bo->target_handle; kgem->reloc[index].presumed_offset = bo->presumed_offset; if (read_write_domain & 0x7fff && !bo->gpu_dirty) { assert(!bo->snoop || kgem->can_blt_cpu); __kgem_bo_mark_dirty(bo); } delta += bo->presumed_offset; } else { DBG(("%s[%d] = (delta=%d, target handle=batch)\n", __FUNCTION__, index, delta)); kgem->reloc[index].delta = delta; kgem->reloc[index].target_handle = ~0U; kgem->reloc[index].presumed_offset = 0; if (kgem->nreloc__self < 256) kgem->reloc__self[kgem->nreloc__self++] = index; } kgem->reloc[index].read_domains = read_write_domain >> 16; kgem->reloc[index].write_domain = read_write_domain & 0x7fff; return delta; } static void kgem_trim_vma_cache(struct kgem *kgem, int type, int bucket) { int i, j; DBG(("%s: type=%d, count=%d (bucket: %d)\n", __FUNCTION__, type, kgem->vma[type].count, bucket)); if (kgem->vma[type].count <= 0) return; if (kgem->need_purge) kgem_purge_cache(kgem); /* vma are limited on a per-process basis to around 64k. * This includes all malloc arenas as well as other file * mappings. In order to be fair and not hog the cache, * and more importantly not to exhaust that limit and to * start failing mappings, we keep our own number of open * vma to within a conservative value. */ i = 0; while (kgem->vma[type].count > 0) { struct kgem_bo *bo = NULL; for (j = 0; bo == NULL && j < ARRAY_SIZE(kgem->vma[type].inactive); j++) { struct list *head = &kgem->vma[type].inactive[i++%ARRAY_SIZE(kgem->vma[type].inactive)]; if (!list_is_empty(head)) bo = list_last_entry(head, struct kgem_bo, vma); } if (bo == NULL) break; DBG(("%s: discarding inactive %s vma cache for %d\n", __FUNCTION__, type ? "CPU" : "GTT", bo->handle)); assert(bo->rq == NULL); if (type) { VG(VALGRIND_MAKE_MEM_NOACCESS(MAP(bo->map__cpu), bytes(bo))); munmap(MAP(bo->map__cpu), bytes(bo)); bo->map__cpu = NULL; } else { if (bo->map__wc) { VG(VALGRIND_MAKE_MEM_NOACCESS(bo->map__wc, bytes(bo))); munmap(bo->map__wc, bytes(bo)); bo->map__wc = NULL; } if (bo->map__gtt) { munmap(bo->map__gtt, bytes(bo)); bo->map__gtt = NULL; } } list_del(&bo->vma); kgem->vma[type].count--; } } static void *__kgem_bo_map__gtt_or_wc(struct kgem *kgem, struct kgem_bo *bo) { void *ptr; DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(bo->proxy == NULL); assert(!bo->snoop); kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo)); if (bo->tiling || !kgem->has_wc_mmap) { assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y); warn_unless(num_pages(bo) <= kgem->aperture_mappable / 2); ptr = bo->map__gtt; if (ptr == NULL) ptr = __kgem_bo_map__gtt(kgem, bo); } else { ptr = bo->map__wc; if (ptr == NULL) ptr = __kgem_bo_map__wc(kgem, bo); } return ptr; } void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, offset=%ld, tiling=%d, map=%p:%p, domain=%d\n", __FUNCTION__, bo->handle, (long)bo->presumed_offset, bo->tiling, bo->map__gtt, bo->map__cpu, bo->domain)); assert(bo->proxy == NULL); assert(list_is_empty(&bo->list)); assert_tiling(kgem, bo); assert(!bo->purged || bo->reusable); if (bo->tiling == I915_TILING_NONE && !bo->scanout && kgem->has_llc) { DBG(("%s: converting request for GTT map into CPU map\n", __FUNCTION__)); return kgem_bo_map__cpu(kgem, bo); } return __kgem_bo_map__gtt_or_wc(kgem, bo); } void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo) { void *ptr; DBG(("%s: handle=%d, offset=%ld, tiling=%d, map=%p:%p, domain=%d\n", __FUNCTION__, bo->handle, (long)bo->presumed_offset, bo->tiling, bo->map__gtt, bo->map__cpu, bo->domain)); assert(bo->proxy == NULL); assert(list_is_empty(&bo->list)); assert(bo->exec == NULL); assert_tiling(kgem, bo); assert(!bo->purged || bo->reusable); if (bo->tiling == I915_TILING_NONE && !bo->scanout && (kgem->has_llc || bo->domain == DOMAIN_CPU)) { DBG(("%s: converting request for GTT map into CPU map\n", __FUNCTION__)); ptr = kgem_bo_map__cpu(kgem, bo); if (ptr) kgem_bo_sync__cpu(kgem, bo); return ptr; } ptr = __kgem_bo_map__gtt_or_wc(kgem, bo); if (bo->domain != DOMAIN_GTT || FORCE_MMAP_SYNC & (1 << DOMAIN_GTT)) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__, bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle))); /* XXX use PROT_READ to avoid the write flush? */ VG_CLEAR(set_domain); set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_GTT; bo->gtt_dirty = true; } return ptr; } void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, offset=%ld, tiling=%d, map=%p:%p, domain=%d\n", __FUNCTION__, bo->handle, (long)bo->presumed_offset, bo->tiling, bo->map__gtt, bo->map__cpu, bo->domain)); assert(bo->proxy == NULL); assert(bo->exec == NULL); assert(list_is_empty(&bo->list)); assert_tiling(kgem, bo); assert(!bo->purged || bo->reusable); return __kgem_bo_map__gtt_or_wc(kgem, bo); } void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, offset=%ld, tiling=%d, map=%p:%p, domain=%d\n", __FUNCTION__, bo->handle, (long)bo->presumed_offset, bo->tiling, bo->map__gtt, bo->map__cpu, bo->domain)); assert(bo->proxy == NULL); assert(list_is_empty(&bo->list)); assert_tiling(kgem, bo); assert(!bo->purged || bo->reusable); if (bo->map__wc) return bo->map__wc; if (!kgem->has_wc_mmap) return NULL; kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo)); return __kgem_bo_map__wc(kgem, bo); } void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s(handle=%d, size=%d, map=%p:%p)\n", __FUNCTION__, bo->handle, bytes(bo), bo->map__gtt, bo->map__cpu)); assert(!bo->purged); assert(list_is_empty(&bo->list)); assert(bo->proxy == NULL); assert_tiling(kgem, bo); if (bo->map__cpu) return MAP(bo->map__cpu); kgem_trim_vma_cache(kgem, MAP_CPU, bucket(bo)); return __kgem_bo_map__cpu(kgem, bo); } void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo) { void *ptr; if (bo->tiling == I915_TILING_NONE && kgem->has_llc) { ptr = MAP(bo->map__cpu); if (ptr == NULL) ptr = __kgem_bo_map__cpu(kgem, bo); } else if (bo->tiling || !kgem->has_wc_mmap) { ptr = bo->map__gtt; if (ptr == NULL) ptr = __kgem_bo_map__gtt(kgem, bo); } else { ptr = bo->map__wc; if (ptr == NULL) ptr = __kgem_bo_map__wc(kgem, bo); } return ptr; } uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo) { struct drm_gem_flink flink; assert(kgem_bo_is_fenced(kgem, bo)); VG_CLEAR(flink); flink.handle = bo->handle; if (do_ioctl(kgem->fd, DRM_IOCTL_GEM_FLINK, &flink)) return 0; DBG(("%s: flinked handle=%d to name=%d, marking non-reusable\n", __FUNCTION__, flink.handle, flink.name)); /* Ordinarily giving the name aware makes the buffer non-reusable. * However, we track the lifetime of all clients and their hold * on the buffer, and *presuming* they do not pass it on to a third * party, we track the lifetime accurately. */ bo->reusable = false; kgem_bo_unclean(kgem, bo); return flink.name; } struct kgem_bo *kgem_create_map(struct kgem *kgem, void *ptr, uint32_t size, bool read_only) { struct kgem_bo *bo; uintptr_t first_page, last_page; uint32_t handle; assert(MAP(ptr) == ptr); DBG(("%s(%p size=%d, read-only?=%d) - has_userptr?=%d\n", __FUNCTION__, ptr, size, read_only, kgem->has_userptr)); if (!kgem->has_userptr) return NULL; first_page = (uintptr_t)ptr; last_page = first_page + size + PAGE_SIZE - 1; first_page &= ~(uintptr_t)(PAGE_SIZE-1); last_page &= ~(uintptr_t)(PAGE_SIZE-1); assert(last_page > first_page); handle = gem_userptr(kgem->fd, (void *)first_page, last_page-first_page, read_only); if (handle == 0) { if (read_only && kgem->has_wc_mmap) { struct drm_i915_gem_set_domain set_domain; handle = gem_userptr(kgem->fd, (void *)first_page, last_page-first_page, false); VG_CLEAR(set_domain); set_domain.handle = handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = 0; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { gem_close(kgem->fd, handle); handle = 0; } } if (handle == 0) { DBG(("%s: import failed, errno=%d\n", __FUNCTION__, errno)); return NULL; } } bo = __kgem_bo_alloc(handle, (last_page - first_page) / PAGE_SIZE); if (bo == NULL) { gem_close(kgem->fd, handle); return NULL; } bo->unique_id = kgem_get_unique_id(kgem); bo->snoop = !kgem->has_llc; debug_alloc__bo(kgem, bo); if (first_page != (uintptr_t)ptr) { struct kgem_bo *proxy; proxy = kgem_create_proxy(kgem, bo, (uintptr_t)ptr - first_page, size); kgem_bo_destroy(kgem, bo); if (proxy == NULL) return NULL; bo = proxy; } bo->map__cpu = MAKE_USER_MAP(ptr); DBG(("%s(ptr=%p, size=%d, pages=%d, read_only=%d) => handle=%d (proxy? %d)\n", __FUNCTION__, ptr, size, NUM_PAGES(size), read_only, handle, bo->proxy != NULL)); return bo; } void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(!bo->scanout); assert_tiling(kgem, bo); kgem_bo_submit(kgem, bo); /* SHM pixmaps use proxies for subpage offsets */ assert(!bo->purged); while (bo->proxy) bo = bo->proxy; assert(!bo->purged); if (bo->domain != DOMAIN_CPU || FORCE_MMAP_SYNC & (1 << DOMAIN_CPU)) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__, bo->handle, bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle))); VG_CLEAR(set_domain); set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_CPU; set_domain.write_domain = I915_GEM_DOMAIN_CPU; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_CPU; } } void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(!bo->scanout || !write); assert_tiling(kgem, bo); if (write || bo->needs_flush) kgem_bo_submit(kgem, bo); /* SHM pixmaps use proxies for subpage offsets */ assert(!bo->purged); assert(bo->refcnt); while (bo->proxy) bo = bo->proxy; assert(bo->refcnt); assert(!bo->purged); if (bo->rq == NULL && (kgem->has_llc || bo->snoop) && !write) return; if (bo->domain != DOMAIN_CPU || FORCE_MMAP_SYNC & (1 << DOMAIN_CPU)) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__, bo->handle, bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle))); VG_CLEAR(set_domain); set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_CPU; set_domain.write_domain = write ? I915_GEM_DOMAIN_CPU : 0; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } if (write) { bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_CPU; } else { if (bo->exec == NULL) kgem_bo_maybe_retire(kgem, bo); bo->domain = DOMAIN_NONE; } } } void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(bo->refcnt); assert(bo->proxy == NULL); assert_tiling(kgem, bo); assert(!bo->snoop); kgem_bo_submit(kgem, bo); if (bo->domain != DOMAIN_GTT || FORCE_MMAP_SYNC & (1 << DOMAIN_GTT)) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: SYNC: handle=%d, needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__, bo->handle, bo->needs_flush, bo->domain, __kgem_busy(kgem, bo->handle))); VG_CLEAR(set_domain); set_domain.handle = bo->handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } bo->needs_flush = false; kgem_bo_retire(kgem, bo); bo->domain = DOMAIN_GTT; bo->gtt_dirty = true; } } void kgem_clear_dirty(struct kgem *kgem) { struct list * const buffers = &kgem->next_request->buffers; struct kgem_bo *bo; list_for_each_entry(bo, buffers, request) { if (!bo->gpu_dirty) break; bo->gpu_dirty = false; } } struct kgem_bo *kgem_create_proxy(struct kgem *kgem, struct kgem_bo *target, int offset, int length) { struct kgem_bo *bo; DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n", __FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1, offset, length, target->io)); bo = __kgem_bo_alloc(target->handle, length); if (bo == NULL) return NULL; bo->unique_id = kgem_get_unique_id(kgem); bo->reusable = false; bo->size.bytes = length; bo->io = target->io && target->proxy == NULL; bo->gpu_dirty = target->gpu_dirty; bo->tiling = target->tiling; bo->pitch = target->pitch; bo->flush = target->flush; bo->snoop = target->snoop; assert(!bo->scanout); bo->proxy = kgem_bo_reference(target); bo->delta = offset; /* Proxies are only tracked for busyness on the current rq */ if (target->exec && !bo->io) { assert(RQ(target->rq) == kgem->next_request); list_move_tail(&bo->request, &kgem->next_request->buffers); bo->exec = &_kgem_dummy_exec; bo->rq = target->rq; } return bo; } static struct kgem_buffer * buffer_alloc(void) { struct kgem_buffer *bo; bo = malloc(sizeof(*bo)); if (bo == NULL) return NULL; bo->mem = NULL; bo->need_io = false; bo->mmapped = MMAPPED_CPU; return bo; } static struct kgem_buffer * buffer_alloc_with_data(int num_pages) { struct kgem_buffer *bo; bo = malloc(sizeof(*bo) + 2*UPLOAD_ALIGNMENT + num_pages * PAGE_SIZE); if (bo == NULL) return NULL; bo->mem = (void *)ALIGN((uintptr_t)bo + sizeof(*bo), UPLOAD_ALIGNMENT); bo->mmapped = false; return bo; } static inline bool use_snoopable_buffer(struct kgem *kgem, uint32_t flags) { if ((flags & KGEM_BUFFER_WRITE) == 0) return kgem->gen >= 030; return true; } static void init_buffer_from_bo(struct kgem_buffer *bo, struct kgem_bo *old) { DBG(("%s: reusing handle=%d for buffer\n", __FUNCTION__, old->handle)); assert(old->proxy == NULL); assert(list_is_empty(&old->list)); memcpy(&bo->base, old, sizeof(*old)); if (old->rq) list_replace(&old->request, &bo->base.request); else list_init(&bo->base.request); list_replace(&old->vma, &bo->base.vma); list_init(&bo->base.list); free(old); assert(bo->base.tiling == I915_TILING_NONE); bo->base.refcnt = 1; } static struct kgem_buffer * search_snoopable_buffer(struct kgem *kgem, unsigned alloc) { struct kgem_buffer *bo; struct kgem_bo *old; old = search_snoop_cache(kgem, alloc, 0); if (old) { if (!old->io) { bo = buffer_alloc(); if (bo == NULL) return NULL; init_buffer_from_bo(bo, old); } else { bo = (struct kgem_buffer *)old; bo->base.refcnt = 1; } DBG(("%s: created CPU handle=%d for buffer, size %d\n", __FUNCTION__, bo->base.handle, num_pages(&bo->base))); assert(bo->base.snoop); assert(bo->base.tiling == I915_TILING_NONE); assert(num_pages(&bo->base) >= alloc); assert(bo->mmapped == MMAPPED_CPU); assert(bo->need_io == false); bo->mem = kgem_bo_map__cpu(kgem, &bo->base); if (bo->mem == NULL) { bo->base.refcnt = 0; kgem_bo_free(kgem, &bo->base); bo = NULL; } return bo; } return NULL; } static struct kgem_buffer * create_snoopable_buffer(struct kgem *kgem, unsigned alloc) { struct kgem_buffer *bo; uint32_t handle; if (kgem->has_llc) { struct kgem_bo *old; bo = buffer_alloc(); if (bo == NULL) return NULL; old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT); if (old) { init_buffer_from_bo(bo, old); } else { handle = gem_create(kgem->fd, alloc); if (handle == 0) { free(bo); return NULL; } __kgem_bo_init(&bo->base, handle, alloc); debug_alloc__bo(kgem, &bo->base); DBG(("%s: created CPU (LLC) handle=%d for buffer, size %d\n", __FUNCTION__, bo->base.handle, alloc)); } assert(bo->base.refcnt == 1); assert(bo->mmapped == MMAPPED_CPU); assert(bo->need_io == false); bo->mem = kgem_bo_map__cpu(kgem, &bo->base); if (bo->mem != NULL) return bo; bo->base.refcnt = 0; /* for valgrind */ kgem_bo_free(kgem, &bo->base); } if (kgem->has_caching) { struct kgem_bo *old; bo = buffer_alloc(); if (bo == NULL) return NULL; old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP | CREATE_EXACT); if (old) { init_buffer_from_bo(bo, old); } else { handle = gem_create(kgem->fd, alloc); if (handle == 0) { free(bo); return NULL; } __kgem_bo_init(&bo->base, handle, alloc); debug_alloc__bo(kgem, &bo->base); DBG(("%s: created CPU handle=%d for buffer, size %d\n", __FUNCTION__, bo->base.handle, alloc)); } assert(bo->base.refcnt == 1); assert(bo->mmapped == MMAPPED_CPU); assert(bo->need_io == false); assert(!__kgem_busy(kgem, bo->base.handle)); if (!gem_set_caching(kgem->fd, bo->base.handle, SNOOPED)) goto free_caching; bo->base.snoop = true; bo->mem = kgem_bo_map__cpu(kgem, &bo->base); if (bo->mem == NULL) goto free_caching; return bo; free_caching: bo->base.refcnt = 0; /* for valgrind */ kgem_bo_free(kgem, &bo->base); } if (kgem->has_userptr) { bo = buffer_alloc(); if (bo == NULL) return NULL; //if (posix_memalign(&ptr, 64, ALIGN(size, 64))) if (posix_memalign(&bo->mem, PAGE_SIZE, alloc * PAGE_SIZE)) { free(bo); return NULL; } handle = gem_userptr(kgem->fd, bo->mem, alloc * PAGE_SIZE, false); if (handle == 0) { free(bo->mem); free(bo); return NULL; } __kgem_bo_init(&bo->base, handle, alloc); debug_alloc__bo(kgem, &bo->base); DBG(("%s: created snoop handle=%d for buffer\n", __FUNCTION__, bo->base.handle)); assert(bo->mmapped == MMAPPED_CPU); assert(bo->need_io == false); bo->base.refcnt = 1; bo->base.snoop = true; bo->base.map__cpu = MAKE_USER_MAP(bo->mem); return bo; } return NULL; } struct kgem_bo *kgem_create_buffer(struct kgem *kgem, uint32_t size, uint32_t flags, void **ret) { struct kgem_buffer *bo; unsigned offset, alloc; struct kgem_bo *old; DBG(("%s: size=%d, flags=%x [write?=%d, inplace?=%d, last?=%d]\n", __FUNCTION__, size, flags, !!(flags & KGEM_BUFFER_WRITE), !!(flags & KGEM_BUFFER_INPLACE), !!(flags & KGEM_BUFFER_LAST))); assert(size); /* we should never be asked to create anything TOO large */ assert(size <= kgem->max_object_size); #if !DBG_NO_UPLOAD_CACHE list_for_each_entry(bo, &kgem->batch_buffers, base.list) { assert(bo->base.io); assert(bo->base.refcnt >= 1); /* We can reuse any write buffer which we can fit */ if (flags == KGEM_BUFFER_LAST && bo->write == KGEM_BUFFER_WRITE && bo->base.refcnt == 1 && bo->mmapped == MMAPPED_NONE && size <= bytes(&bo->base)) { DBG(("%s: reusing write buffer for read of %d bytes? used=%d, total=%d\n", __FUNCTION__, size, bo->used, bytes(&bo->base))); gem_write__cachealigned(kgem->fd, bo->base.handle, 0, bo->used, bo->mem); assert(list_is_empty(&bo->base.vma)); bo->need_io = 0; bo->write = 0; offset = 0; bo->used = size; goto done; } if (flags & KGEM_BUFFER_WRITE) { if ((bo->write & KGEM_BUFFER_WRITE) == 0 || (((bo->write & ~flags) & KGEM_BUFFER_INPLACE) && !bo->base.snoop)) { DBG(("%s: skip write %x buffer, need %x\n", __FUNCTION__, bo->write, flags)); continue; } assert(bo->mmapped || bo->need_io); } else { if (bo->write & KGEM_BUFFER_WRITE) { DBG(("%s: skip write %x buffer, need %x\n", __FUNCTION__, bo->write, flags)); continue; } } if (bo->used + size <= bytes(&bo->base)) { DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n", __FUNCTION__, bo->used, size, bytes(&bo->base))); offset = bo->used; bo->used += size; goto done; } } if (flags & KGEM_BUFFER_WRITE) { list_for_each_entry(bo, &kgem->active_buffers, base.list) { assert(bo->base.io); assert(bo->base.refcnt >= 1); assert(bo->base.exec == NULL); assert(bo->mmapped); assert(bo->mmapped == MMAPPED_GTT || kgem->has_llc || bo->base.snoop); if ((bo->write & ~flags) & KGEM_BUFFER_INPLACE && !bo->base.snoop) { DBG(("%s: skip write %x buffer, need %x\n", __FUNCTION__, bo->write, flags)); continue; } if (bo->used + size <= bytes(&bo->base)) { DBG(("%s: reusing buffer? used=%d + size=%d, total=%d\n", __FUNCTION__, bo->used, size, bytes(&bo->base))); offset = bo->used; bo->used += size; list_move(&bo->base.list, &kgem->batch_buffers); goto done; } if (bo->base.refcnt == 1 && size <= bytes(&bo->base) && (bo->base.rq == NULL || !__kgem_busy(kgem, bo->base.handle))) { DBG(("%s: reusing whole buffer? size=%d, total=%d\n", __FUNCTION__, size, bytes(&bo->base))); __kgem_bo_clear_busy(&bo->base); assert(list_is_empty(&bo->base.vma)); switch (bo->mmapped) { case MMAPPED_CPU: kgem_bo_sync__cpu(kgem, &bo->base); break; case MMAPPED_GTT: kgem_bo_sync__gtt(kgem, &bo->base); break; } offset = 0; bo->used = size; list_move(&bo->base.list, &kgem->batch_buffers); goto done; } } } #endif #if !DBG_NO_MAP_UPLOAD /* Be a little more generous and hope to hold fewer mmappings */ alloc = ALIGN(2*size, kgem->buffer_size); if (alloc > MAX_CACHE_SIZE) alloc = ALIGN(size, kgem->buffer_size); if (alloc > MAX_CACHE_SIZE) alloc = PAGE_ALIGN(size); assert(alloc); alloc /= PAGE_SIZE; if (alloc > kgem->aperture_mappable / 4 && !kgem->has_wc_mmap) flags &= ~KGEM_BUFFER_INPLACE; if (kgem->has_llc && (flags & KGEM_BUFFER_WRITE_INPLACE) != KGEM_BUFFER_WRITE_INPLACE) { bo = buffer_alloc(); if (bo == NULL) goto skip_llc; old = NULL; if ((flags & KGEM_BUFFER_WRITE) == 0) old = search_linear_cache(kgem, alloc, CREATE_CPU_MAP); if (old == NULL) old = search_linear_cache(kgem, alloc, CREATE_INACTIVE | CREATE_CPU_MAP); if (old == NULL) old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_INACTIVE | CREATE_CPU_MAP); if (old) { DBG(("%s: found LLC handle=%d for buffer\n", __FUNCTION__, old->handle)); init_buffer_from_bo(bo, old); } else { uint32_t handle = gem_create(kgem->fd, alloc); if (handle == 0) { free(bo); goto skip_llc; } __kgem_bo_init(&bo->base, handle, alloc); debug_alloc__bo(kgem, &bo->base); DBG(("%s: created LLC handle=%d for buffer\n", __FUNCTION__, bo->base.handle)); } assert(bo->mmapped); assert(!bo->need_io); bo->mem = kgem_bo_map__cpu(kgem, &bo->base); if (bo->mem) { if (flags & KGEM_BUFFER_WRITE) kgem_bo_sync__cpu(kgem, &bo->base); flags &= ~KGEM_BUFFER_INPLACE; goto init; } else { bo->base.refcnt = 0; /* for valgrind */ kgem_bo_free(kgem, &bo->base); } } skip_llc: if ((flags & KGEM_BUFFER_WRITE_INPLACE) == KGEM_BUFFER_WRITE_INPLACE) { /* The issue with using a GTT upload buffer is that we may * cause eviction-stalls in order to free up some GTT space. * An is-mappable? ioctl could help us detect when we are * about to block, or some per-page magic in the kernel. * * XXX This is especially noticeable on memory constrained * devices like gen2 or with relatively slow gpu like i3. */ DBG(("%s: searching for an inactive GTT map for upload\n", __FUNCTION__)); old = search_linear_cache(kgem, alloc, CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP); #if HAVE_I915_GEM_BUFFER_INFO if (old) { struct drm_i915_gem_buffer_info info; /* An example of such a non-blocking ioctl might work */ VG_CLEAR(info); info.handle = handle; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_BUFFER_INFO, &fino) == 0) { old->presumed_offset = info.addr; if ((info.flags & I915_GEM_MAPPABLE) == 0) { kgem_bo_move_to_inactive(kgem, old); old = NULL; } } } #endif if (old == NULL) old = search_linear_cache(kgem, NUM_PAGES(size), CREATE_EXACT | CREATE_INACTIVE | CREATE_GTT_MAP); if (old == NULL) { old = search_linear_cache(kgem, alloc, CREATE_INACTIVE); if (old && !kgem_bo_can_map(kgem, old)) { _kgem_bo_destroy(kgem, old); old = NULL; } } if (old) { DBG(("%s: reusing handle=%d for buffer\n", __FUNCTION__, old->handle)); assert(kgem_bo_can_map(kgem, old)); assert(!old->snoop); assert(old->rq == NULL); bo = buffer_alloc(); if (bo == NULL) return NULL; init_buffer_from_bo(bo, old); assert(num_pages(&bo->base) >= NUM_PAGES(size)); assert(bo->mmapped); assert(bo->base.refcnt == 1); bo->mem = kgem_bo_map(kgem, &bo->base); if (bo->mem) { if (bo->mem == MAP(bo->base.map__cpu)) flags &= ~KGEM_BUFFER_INPLACE; else bo->mmapped = MMAPPED_GTT; goto init; } else { bo->base.refcnt = 0; kgem_bo_free(kgem, &bo->base); } } } #else flags &= ~KGEM_BUFFER_INPLACE; #endif /* Be more parsimonious with pwrite/pread/cacheable buffers */ if ((flags & KGEM_BUFFER_INPLACE) == 0) alloc = NUM_PAGES(size); if (use_snoopable_buffer(kgem, flags)) { bo = search_snoopable_buffer(kgem, alloc); if (bo) { if (flags & KGEM_BUFFER_WRITE) kgem_bo_sync__cpu(kgem, &bo->base); flags &= ~KGEM_BUFFER_INPLACE; goto init; } if ((flags & KGEM_BUFFER_INPLACE) == 0) { bo = create_snoopable_buffer(kgem, alloc); if (bo) goto init; } } flags &= ~KGEM_BUFFER_INPLACE; old = NULL; if ((flags & KGEM_BUFFER_WRITE) == 0) old = search_linear_cache(kgem, alloc, 0); if (old == NULL) old = search_linear_cache(kgem, alloc, CREATE_INACTIVE); if (old) { DBG(("%s: reusing ordinary handle %d for io\n", __FUNCTION__, old->handle)); bo = buffer_alloc_with_data(num_pages(old)); if (bo == NULL) return NULL; init_buffer_from_bo(bo, old); bo->need_io = flags & KGEM_BUFFER_WRITE; } else { unsigned hint; if (use_snoopable_buffer(kgem, flags)) { bo = create_snoopable_buffer(kgem, alloc); if (bo) goto init; } bo = buffer_alloc(); if (bo == NULL) return NULL; hint = CREATE_INACTIVE; if (flags & KGEM_BUFFER_WRITE) hint |= CREATE_CPU_MAP; old = search_linear_cache(kgem, alloc, hint); if (old) { DBG(("%s: reusing handle=%d for buffer\n", __FUNCTION__, old->handle)); init_buffer_from_bo(bo, old); } else { uint32_t handle = gem_create(kgem->fd, alloc); if (handle == 0) { free(bo); return NULL; } DBG(("%s: created handle=%d for buffer\n", __FUNCTION__, handle)); __kgem_bo_init(&bo->base, handle, alloc); debug_alloc__bo(kgem, &bo->base); } assert(bo->mmapped); assert(!bo->need_io); assert(bo->base.refcnt == 1); if (flags & KGEM_BUFFER_WRITE) { bo->mem = kgem_bo_map__cpu(kgem, &bo->base); if (bo->mem != NULL) { kgem_bo_sync__cpu(kgem, &bo->base); goto init; } } DBG(("%s: failing back to new pwrite buffer\n", __FUNCTION__)); old = &bo->base; bo = buffer_alloc_with_data(num_pages(old)); if (bo == NULL) { old->refcnt= 0; kgem_bo_free(kgem, old); return NULL; } init_buffer_from_bo(bo, old); assert(bo->mem); assert(!bo->mmapped); assert(bo->base.refcnt == 1); bo->need_io = flags & KGEM_BUFFER_WRITE; } init: bo->base.io = true; assert(bo->base.refcnt == 1); assert(num_pages(&bo->base) >= NUM_PAGES(size)); assert(!bo->need_io || !bo->base.needs_flush); assert(!bo->need_io || bo->base.domain != DOMAIN_GPU); assert(bo->mem); assert(bo->mmapped != MMAPPED_GTT || bo->base.map__gtt == bo->mem || bo->base.map__wc == bo->mem); assert(bo->mmapped != MMAPPED_CPU || MAP(bo->base.map__cpu) == bo->mem); bo->used = size; bo->write = flags & KGEM_BUFFER_WRITE_INPLACE; offset = 0; assert(list_is_empty(&bo->base.list)); list_add(&bo->base.list, &kgem->batch_buffers); DBG(("%s(pages=%d [%d]) new handle=%d, used=%d, write=%d\n", __FUNCTION__, num_pages(&bo->base), alloc, bo->base.handle, bo->used, bo->write)); done: bo->used = ALIGN(bo->used, UPLOAD_ALIGNMENT); assert(bo->used && bo->used <= bytes(&bo->base)); assert(bo->mem); *ret = (char *)bo->mem + offset; return kgem_create_proxy(kgem, &bo->base, offset, size); } bool kgem_buffer_is_inplace(struct kgem_bo *_bo) { struct kgem_buffer *bo = (struct kgem_buffer *)_bo->proxy; return bo->write & KGEM_BUFFER_WRITE_INPLACE; } struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, int width, int height, int bpp, uint32_t flags, void **ret) { struct kgem_bo *bo; int stride; assert(width > 0 && height > 0); assert(ret != NULL); stride = ALIGN(width, 2) * bpp >> 3; stride = ALIGN(stride, kgem->gen >= 0100 ? 32 : 4); DBG(("%s: %dx%d, %d bpp, stride=%d\n", __FUNCTION__, width, height, bpp, stride)); bo = kgem_create_buffer(kgem, stride * ALIGN(height, 2), flags, ret); if (bo == NULL) { DBG(("%s: allocation failure for upload buffer\n", __FUNCTION__)); return NULL; } assert(*ret != NULL); assert(bo->proxy != NULL); if (height & 1) { struct kgem_buffer *io = (struct kgem_buffer *)bo->proxy; int min; assert(io->used); /* Having padded this surface to ensure that accesses to * the last pair of rows is valid, remove the padding so * that it can be allocated to other pixmaps. */ min = bo->delta + height * stride; min = ALIGN(min, UPLOAD_ALIGNMENT); if (io->used != min) { DBG(("%s: trimming buffer from %d to %d\n", __FUNCTION__, io->used, min)); io->used = min; } bo->size.bytes -= stride; } bo->map__cpu = *ret; bo->pitch = stride; bo->unique_id = kgem_get_unique_id(kgem); return bo; } struct kgem_bo *kgem_upload_source_image(struct kgem *kgem, const void *data, const BoxRec *box, int stride, int bpp) { int width = box->x2 - box->x1; int height = box->y2 - box->y1; struct kgem_bo *bo; void *dst; if (!kgem_can_create_2d(kgem, width, height, bpp)) return NULL; DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp)); assert(data); assert(width > 0); assert(height > 0); assert(stride); assert(bpp); bo = kgem_create_buffer_2d(kgem, width, height, bpp, KGEM_BUFFER_WRITE_INPLACE, &dst); if (bo == NULL) return NULL; if (sigtrap_get()) { kgem_bo_destroy(kgem, bo); return NULL; } memcpy_blt(data, dst, bpp, stride, bo->pitch, box->x1, box->y1, 0, 0, width, height); sigtrap_put(); return bo; } void kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(bo->map__gtt == NULL); assert(bo->proxy); list_add(&bo->vma, &bo->proxy->vma); bo->map__gtt = ptr; *ptr = kgem_bo_reference(bo); } void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *_bo) { struct kgem_buffer *bo; uint32_t offset = _bo->delta, length = _bo->size.bytes; /* We expect the caller to have already submitted the batch */ assert(_bo->io); assert(_bo->exec == NULL); assert(_bo->rq == NULL); assert(_bo->proxy); _bo = _bo->proxy; assert(_bo->proxy == NULL); assert(_bo->exec == NULL); bo = (struct kgem_buffer *)_bo; DBG(("%s(offset=%d, length=%d, snooped=%d)\n", __FUNCTION__, offset, length, bo->base.snoop)); if (bo->mmapped) { struct drm_i915_gem_set_domain set_domain; DBG(("%s: sync: needs_flush? %d, domain? %d, busy? %d\n", __FUNCTION__, bo->base.needs_flush, bo->base.domain, __kgem_busy(kgem, bo->base.handle))); assert(bo->mmapped == MMAPPED_GTT || bo->base.snoop || kgem->has_llc); VG_CLEAR(set_domain); set_domain.handle = bo->base.handle; set_domain.write_domain = 0; set_domain.read_domains = bo->mmapped == MMAPPED_CPU ? I915_GEM_DOMAIN_CPU : I915_GEM_DOMAIN_GTT; if (do_ioctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { DBG(("%s: sync: GPU hang detected\n", __FUNCTION__)); kgem_throttle(kgem); } } else { if (gem_read(kgem->fd, bo->base.handle, (char *)bo->mem+offset, offset, length)) return; } kgem_bo_maybe_retire(kgem, &bo->base); bo->base.domain = DOMAIN_NONE; } uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format) { struct kgem_bo_binding *b; assert(bo->refcnt); for (b = &bo->binding; b && b->offset; b = b->next) if (format == b->format) return b->offset; return 0; } void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset) { struct kgem_bo_binding *b; assert(bo->refcnt); for (b = &bo->binding; b; b = b->next) { if (b->offset) continue; b->offset = offset; b->format = format; if (b->next) b->next->offset = 0; return; } b = malloc(sizeof(*b)); if (b) { b->next = bo->binding.next; b->format = format; b->offset = offset; bo->binding.next = b; } } struct kgem_bo * kgem_replace_bo(struct kgem *kgem, struct kgem_bo *src, uint32_t width, uint32_t height, uint32_t pitch, uint32_t bpp) { struct kgem_bo *dst; uint32_t br00, br13; uint32_t handle; uint32_t size; uint32_t *b; DBG(("%s: replacing bo handle=%d, size=%dx%d pitch=%d, with pitch=%d\n", __FUNCTION__, src->handle, width, height, src->pitch, pitch)); /* We only expect to be called to fixup small buffers, hence why * we only attempt to allocate a linear bo. */ assert(src->tiling == I915_TILING_NONE); assert(kgem_bo_can_blt(kgem, src)); size = height * pitch; size = NUM_PAGES(size); dst = search_linear_cache(kgem, size, 0); if (dst == NULL) dst = search_linear_cache(kgem, size, CREATE_INACTIVE); if (dst == NULL) { handle = gem_create(kgem->fd, size); if (handle == 0) return NULL; dst = __kgem_bo_alloc(handle, size); if (dst == NULL) { gem_close(kgem->fd, handle); return NULL; } debug_alloc__bo(kgem, dst); } dst->pitch = pitch; dst->unique_id = kgem_get_unique_id(kgem); dst->refcnt = 1; assert(dst->tiling == I915_TILING_NONE); assert(kgem_bo_can_blt(kgem, dst)); kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc(kgem, 2) || !kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { kgem_bo_destroy(kgem, dst); return NULL; } _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(kgem, src, dst); br00 = XY_SRC_COPY_BLT_CMD; br13 = pitch; pitch = src->pitch; if (kgem->gen >= 040 && src->tiling) { br00 |= BLT_SRC_TILED; pitch >>= 2; } br13 |= 0xcc << 16; switch (bpp) { default: case 32: br00 |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } b = kgem->batch + kgem->nbatch; if (kgem->gen >= 0100) { b[0] = br00 | 8; b[1] = br13; b[2] = 0; b[3] = height << 16 | width; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = 0; b[7] = pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; } else { b[0] = br00 | 6; b[1] = br13; b[2] = 0; b[3] = height << 16 | width; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = 0; b[6] = pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; } return dst; } bool kgem_bo_convert_to_gpu(struct kgem *kgem, struct kgem_bo *bo, unsigned flags) { DBG(("%s: converting handle=%d from CPU to GPU, flags=%x, busy?=%d\n", __FUNCTION__, bo->handle, flags, __kgem_bo_is_busy(kgem, bo))); assert(bo->tiling == I915_TILING_NONE); if (flags & (__MOVE_PRIME | __MOVE_SCANOUT)) return false; if (kgem->has_llc) return true; if (flags & MOVE_ASYNC_HINT && __kgem_bo_is_busy(kgem, bo)) return false; assert(bo->snoop); kgem_bo_submit(kgem, bo); if (!gem_set_caching(kgem->fd, bo->handle, UNCACHED)) return false; bo->snoop = false; return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem.h000066400000000000000000000555471267532330400227570ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifndef KGEM_H #define KGEM_H #include #include #include #include #include "compiler.h" #include "debug.h" struct kgem_bo { struct kgem_request *rq; #define RQ(rq) ((struct kgem_request *)((uintptr_t)(rq) & ~3)) #define RQ_RING(rq) ((uintptr_t)(rq) & 3) #define RQ_IS_BLT(rq) (RQ_RING(rq) == KGEM_BLT) #define RQ_IS_RENDER(rq) (RQ_RING(rq) == KGEM_RENDER) #define MAKE_REQUEST(rq, ring) ((struct kgem_request *)((uintptr_t)(rq) | (ring))) struct drm_i915_gem_exec_object2 *exec; struct kgem_bo *proxy; struct list list; struct list request; struct list vma; void *map__cpu; void *map__gtt; void *map__wc; #define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3)) struct kgem_bo_binding { struct kgem_bo_binding *next; uint32_t format; uint16_t offset; } binding; uint64_t presumed_offset; uint32_t unique_id; uint32_t refcnt; uint32_t handle; uint32_t target_handle; uint32_t delta; uint32_t active_scanout; union { struct { uint32_t count:27; #define PAGE_SIZE 4096 uint32_t bucket:5; #define NUM_CACHE_BUCKETS 16 #define MAX_CACHE_SIZE (1 << (NUM_CACHE_BUCKETS+12)) } pages; uint32_t bytes; } size; uint32_t pitch : 18; /* max 128k */ uint32_t tiling : 2; uint32_t reusable : 1; uint32_t gpu_dirty : 1; uint32_t gtt_dirty : 1; uint32_t domain : 2; uint32_t needs_flush : 1; uint32_t snoop : 1; uint32_t io : 1; uint32_t flush : 1; uint32_t scanout : 1; uint32_t prime : 1; uint32_t purged : 1; }; #define DOMAIN_NONE 0 #define DOMAIN_CPU 1 #define DOMAIN_GTT 2 #define DOMAIN_GPU 3 struct kgem_request { struct list list; struct kgem_bo *bo; struct list buffers; unsigned ring; }; enum { MAP_GTT = 0, MAP_CPU, NUM_MAP_TYPES, }; struct kgem { unsigned wedged; int fd; unsigned gen; uint32_t unique_id; uint16_t nbatch; uint16_t surface; uint16_t nexec; uint16_t nreloc; uint16_t nreloc__self; uint16_t nfence; uint16_t batch_size; uint32_t *batch; enum kgem_mode { /* order matches I915_EXEC_RING ordering */ KGEM_NONE = 0, KGEM_RENDER, KGEM_BSD, KGEM_BLT, } mode, ring; struct list flushing; struct list large; struct list large_inactive; struct list active[NUM_CACHE_BUCKETS][3]; struct list inactive[NUM_CACHE_BUCKETS]; struct list pinned_batches[2]; struct list snoop; struct list scanout; struct list batch_buffers, active_buffers; struct list requests[2]; struct kgem_request *fence[2]; struct kgem_request *next_request; struct kgem_request static_request; struct { struct list inactive[NUM_CACHE_BUCKETS]; int16_t count; } vma[NUM_MAP_TYPES]; uint32_t bcs_state; uint32_t batch_flags; uint32_t batch_flags_base; #define I915_EXEC_SECURE (1<<9) #define LOCAL_EXEC_OBJECT_WRITE (1<<2) uint32_t flush:1; uint32_t need_expire:1; uint32_t need_purge:1; uint32_t need_retire:1; uint32_t need_throttle:1; uint32_t needs_semaphore:1; uint32_t needs_reservation:1; uint32_t scanout_busy:1; uint32_t busy:1; uint32_t has_create2 :1; uint32_t has_userptr :1; uint32_t has_blt :1; uint32_t has_relaxed_fencing :1; uint32_t has_relaxed_delta :1; uint32_t has_semaphores :1; uint32_t has_secure_batches :1; uint32_t has_pinned_batches :1; uint32_t has_caching :1; uint32_t has_llc :1; uint32_t has_wt :1; uint32_t has_no_reloc :1; uint32_t has_handle_lut :1; uint32_t has_wc_mmap :1; uint32_t has_dirtyfb :1; uint32_t can_fence :1; uint32_t can_blt_cpu :1; uint32_t can_blt_y :1; uint32_t can_render_y :1; uint32_t can_scanout_y :1; uint32_t needs_dirtyfb :1; uint16_t fence_max; uint16_t half_cpu_cache_pages; uint32_t aperture_total, aperture_high, aperture_low, aperture_mappable, aperture_fenceable; uint32_t aperture, aperture_fenced, aperture_max_fence; uint32_t max_upload_tile_size, max_copy_tile_size; uint32_t max_gpu_size, max_cpu_size; uint32_t large_object_size, max_object_size; uint32_t buffer_size; void (*context_switch)(struct kgem *kgem, int new_mode); void (*retire)(struct kgem *kgem); void (*expire)(struct kgem *kgem); void (*memcpy_to_tiled_x)(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height); void (*memcpy_from_tiled_x)(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height); struct kgem_bo *batch_bo; uint16_t reloc__self[256]; struct drm_i915_gem_exec_object2 exec[384] page_aligned; struct drm_i915_gem_relocation_entry reloc[8192] page_aligned; #ifdef DEBUG_MEMORY struct { int bo_allocs; size_t bo_bytes; } debug_memory; #endif }; #define KGEM_MAX_DEFERRED_VBO 16 #define KGEM_BATCH_RESERVED 8 /* LRI(SWCTRL) + END */ #define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO) #define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO) #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) #endif #define KGEM_BATCH_SIZE(K) ((K)->batch_size-KGEM_BATCH_RESERVED) #define KGEM_EXEC_SIZE(K) (int)(ARRAY_SIZE((K)->exec)-KGEM_EXEC_RESERVED) #define KGEM_RELOC_SIZE(K) (int)(ARRAY_SIZE((K)->reloc)-KGEM_RELOC_RESERVED) void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen); void kgem_reset(struct kgem *kgem); struct kgem_bo *kgem_create_map(struct kgem *kgem, void *ptr, uint32_t size, bool read_only); struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name); struct kgem_bo *kgem_create_for_prime(struct kgem *kgem, int name, uint32_t size); int kgem_bo_export_to_prime(struct kgem *kgem, struct kgem_bo *bo); struct kgem_bo *kgem_create_linear(struct kgem *kgem, int size, unsigned flags); struct kgem_bo *kgem_create_proxy(struct kgem *kgem, struct kgem_bo *target, int offset, int length); struct kgem_bo *kgem_upload_source_image(struct kgem *kgem, const void *data, const BoxRec *box, int stride, int bpp); void kgem_proxy_bo_attach(struct kgem_bo *bo, struct kgem_bo **ptr); int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int bpp); unsigned kgem_can_create_2d(struct kgem *kgem, int width, int height, int depth); #define KGEM_CAN_CREATE_GPU 0x1 #define KGEM_CAN_CREATE_CPU 0x2 #define KGEM_CAN_CREATE_LARGE 0x4 #define KGEM_CAN_CREATE_GTT 0x8 #define KGEM_CAN_CREATE_TILED 0x10 bool kgem_check_surface_size(struct kgem *kgem, uint32_t width, uint32_t height, uint32_t bpp, uint32_t tiling, uint32_t pitch, uint32_t size); struct kgem_bo * kgem_replace_bo(struct kgem *kgem, struct kgem_bo *src, uint32_t width, uint32_t height, uint32_t pitch, uint32_t bpp); enum { CREATE_EXACT = 0x1, CREATE_INACTIVE = 0x2, CREATE_CPU_MAP = 0x4, CREATE_GTT_MAP = 0x8, CREATE_SCANOUT = 0x10, CREATE_PRIME = 0x20, CREATE_TEMPORARY = 0x40, CREATE_CACHED = 0x80, CREATE_UNCACHED = 0x100, CREATE_NO_RETIRE = 0x200, CREATE_NO_THROTTLE = 0x400, }; struct kgem_bo *kgem_create_2d(struct kgem *kgem, int width, int height, int bpp, int tiling, uint32_t flags); struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem, int width, int height, int bpp, uint32_t flags); bool kgem_bo_convert_to_gpu(struct kgem *kgem, struct kgem_bo *bo, unsigned flags); bool kgem_bo_is_fenced(struct kgem *kgem, struct kgem_bo *bo); uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format); void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset); bool kgem_retire(struct kgem *kgem); void kgem_retire__buffers(struct kgem *kgem); static inline bool kgem_bo_discard_cache(struct kgem_bo *bo, bool force) { if (bo == NULL || bo->proxy == NULL) return false; if (force) return true; if (bo->proxy->rq) return false; return bo->snoop; } bool __kgem_ring_is_idle(struct kgem *kgem, int ring); static inline bool kgem_ring_is_idle(struct kgem *kgem, int ring) { ring = ring == KGEM_BLT; if (kgem->needs_semaphore && !list_is_empty(&kgem->requests[!ring]) && !__kgem_ring_is_idle(kgem, !ring)) return false; if (list_is_empty(&kgem->requests[ring])) return true; return __kgem_ring_is_idle(kgem, ring); } static inline bool kgem_is_idle(struct kgem *kgem) { if (!kgem->need_retire) return true; return kgem_ring_is_idle(kgem, kgem->ring); } static inline bool __kgem_ring_empty(struct kgem *kgem) { return list_is_empty(&kgem->requests[kgem->ring == KGEM_BLT]); } void _kgem_submit(struct kgem *kgem); static inline void kgem_submit(struct kgem *kgem) { if (kgem->nbatch) _kgem_submit(kgem); } static inline void kgem_bo_submit(struct kgem *kgem, struct kgem_bo *bo) { if (bo->exec == NULL) return; assert(bo->refcnt); _kgem_submit(kgem); } void kgem_scanout_flush(struct kgem *kgem, struct kgem_bo *bo); static inline struct kgem_bo *kgem_bo_reference(struct kgem_bo *bo) { assert(bo->refcnt); bo->refcnt++; return bo; } void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo); static inline void kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt); assert(bo->refcnt > bo->active_scanout); if (--bo->refcnt == 0) _kgem_bo_destroy(kgem, bo); } void kgem_clear_dirty(struct kgem *kgem); static inline void kgem_set_mode(struct kgem *kgem, enum kgem_mode mode, struct kgem_bo *bo) { warn_unless(!kgem->wedged); #if DEBUG_FLUSH_BATCH kgem_submit(kgem); #endif if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: flushing before new bo\n", __FUNCTION__)); _kgem_submit(kgem); } if (kgem->mode == mode) return; kgem->context_switch(kgem, mode); kgem->mode = mode; } static inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode) { assert(kgem->mode == KGEM_NONE); assert(kgem->nbatch == 0); warn_unless(!kgem->wedged); kgem->context_switch(kgem, mode); kgem->mode = mode; } static inline int kgem_batch_space(struct kgem *kgem) { int rem = kgem->surface - kgem->nbatch; assert(rem > 0); return rem - KGEM_BATCH_RESERVED; } static inline bool kgem_check_batch(struct kgem *kgem, int num_dwords) { assert(num_dwords > 0); assert(kgem->nbatch < kgem->surface); assert(kgem->surface <= kgem->batch_size); return likely(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED <= kgem->surface); } static inline bool kgem_check_reloc(struct kgem *kgem, int n) { assert(kgem->nreloc <= KGEM_RELOC_SIZE(kgem)); return likely(kgem->nreloc + n <= KGEM_RELOC_SIZE(kgem)); } static inline bool kgem_check_exec(struct kgem *kgem, int n) { assert(kgem->nexec <= KGEM_EXEC_SIZE(kgem)); return likely(kgem->nexec + n <= KGEM_EXEC_SIZE(kgem)); } static inline bool kgem_check_reloc_and_exec(struct kgem *kgem, int n) { return kgem_check_reloc(kgem, n) && kgem_check_exec(kgem, n); } static inline bool kgem_check_batch_with_surfaces(struct kgem *kgem, int num_dwords, int num_surfaces) { return (int)(kgem->nbatch + num_dwords + KGEM_BATCH_RESERVED) <= (int)(kgem->surface - num_surfaces*8) && kgem_check_reloc(kgem, num_surfaces) && kgem_check_exec(kgem, num_surfaces); } static inline uint32_t *kgem_get_batch(struct kgem *kgem) { if (kgem->nreloc) { unsigned mode = kgem->mode; _kgem_submit(kgem); _kgem_set_mode(kgem, mode); } return kgem->batch + kgem->nbatch; } bool kgem_check_bo(struct kgem *kgem, ...) __attribute__((sentinel(0))); bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo); bool kgem_check_many_bo_fenced(struct kgem *kgem, ...) __attribute__((sentinel(0))); #define KGEM_RELOC_FENCED 0x8000 uint32_t kgem_add_reloc(struct kgem *kgem, uint32_t pos, struct kgem_bo *bo, uint32_t read_write_domains, uint32_t delta); uint64_t kgem_add_reloc64(struct kgem *kgem, uint32_t pos, struct kgem_bo *bo, uint32_t read_write_domains, uint64_t delta); void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__async(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__gtt(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__wc(struct kgem *kgem, struct kgem_bo *bo); void kgem_bo_sync__gtt(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__debug(struct kgem *kgem, struct kgem_bo *bo); void *kgem_bo_map__cpu(struct kgem *kgem, struct kgem_bo *bo); void kgem_bo_sync__cpu(struct kgem *kgem, struct kgem_bo *bo); void kgem_bo_sync__cpu_full(struct kgem *kgem, struct kgem_bo *bo, bool write); uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo); bool kgem_bo_write(struct kgem *kgem, struct kgem_bo *bo, const void *data, int length); int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo); void kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch, int *tile_width, int *tile_height, int *tile_size); static inline int __kgem_buffer_size(struct kgem_bo *bo) { assert(bo->proxy != NULL); return bo->size.bytes; } static inline int __kgem_bo_size(struct kgem_bo *bo) { assert(bo->proxy == NULL); return PAGE_SIZE * bo->size.pages.count; } static inline int __kgem_bo_num_pages(struct kgem_bo *bo) { assert(bo->proxy == NULL); return bo->size.pages.count; } static inline int kgem_bo_size(struct kgem_bo *bo) { if (bo->proxy) return __kgem_buffer_size(bo); else return __kgem_bo_size(bo); } static inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem, struct kgem_bo *bo) { int pitch = bo->pitch; if (kgem->gen >= 0100 && pitch & (1 << 4)) { /* bdw is broken */ DBG(("%s: can not blt to handle=%d, pitch=%d\n", __FUNCTION__, bo->handle, pitch)); return false; } if (kgem->gen >= 040 && bo->tiling) pitch /= 4; if (pitch > MAXSHORT) { DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n", __FUNCTION__, bo->handle, pitch)); return false; } return true; } static inline bool kgem_bo_can_blt(struct kgem *kgem, struct kgem_bo *bo) { assert(bo->refcnt); if (bo->tiling == I915_TILING_Y && !kgem->can_blt_y) { DBG(("%s: can not blt to handle=%d, tiling=Y\n", __FUNCTION__, bo->handle)); return false; } if (kgem->gen >= 0100 && bo->proxy && bo->delta & (1 << 4)) { DBG(("%s: can not blt to handle=%d, delta=%d\n", __FUNCTION__, bo->handle, bo->delta)); return false; } return kgem_bo_blt_pitch_is_ok(kgem, bo); } void __kgem_bcs_set_tiling(struct kgem *kgem, struct kgem_bo *src, struct kgem_bo *dst); inline static void kgem_bcs_set_tiling(struct kgem *kgem, struct kgem_bo *src, struct kgem_bo *dst) { assert(kgem->mode == KGEM_BLT); if (!kgem->can_blt_y) return; __kgem_bcs_set_tiling(kgem, src, dst); } static inline bool kgem_bo_is_snoop(struct kgem_bo *bo) { assert(bo->refcnt); while (bo->proxy) bo = bo->proxy; return bo->snoop; } void kgem_bo_undo(struct kgem *kgem, struct kgem_bo *bo); void kgem_bo_pair_undo(struct kgem *kgem, struct kgem_bo *a, struct kgem_bo *b); bool __kgem_busy(struct kgem *kgem, int handle); static inline void kgem_bo_mark_busy(struct kgem *kgem, struct kgem_bo *bo, int ring) { assert(bo->refcnt); bo->needs_flush = true; if (bo->rq) { bo->rq = MAKE_REQUEST(RQ(bo->rq), ring); } else { bo->rq = MAKE_REQUEST(kgem, ring); list_add(&bo->request, &kgem->flushing); kgem->need_retire = true; } } inline static void __kgem_bo_clear_busy(struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); bo->rq = NULL; list_del(&bo->request); bo->domain = DOMAIN_NONE; bo->needs_flush = false; bo->gtt_dirty = false; } static inline bool kgem_bo_is_busy(struct kgem_bo *bo) { DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); assert(bo->refcnt); return bo->rq; } bool __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_bo *bo); static inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); assert(bo->refcnt); if (bo->exec) return true; if (bo->rq == NULL) return false; if (__kgem_busy(kgem, bo->handle)) return true; return __kgem_retire_requests_upto(kgem, bo); } static inline bool kgem_bo_is_render(struct kgem_bo *bo) { DBG(("%s: handle=%d, rq? %d [%d]\n", __FUNCTION__, bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq))); assert(bo->refcnt); return bo->rq && RQ_RING(bo->rq) != KGEM_BLT; } static inline bool kgem_bo_is_blt(struct kgem_bo *bo) { DBG(("%s: handle=%d, rq? %d\n", __FUNCTION__, bo->handle, bo->rq != NULL, (int)RQ_RING(bo->rq))); assert(bo->refcnt); return RQ_RING(bo->rq) == KGEM_BLT; } static inline void kgem_bo_mark_unreusable(struct kgem_bo *bo) { assert(bo->refcnt); while (bo->proxy) { bo->flush = true; bo = bo->proxy; assert(bo->refcnt); } bo->flush = true; bo->reusable = false; } static inline bool kgem_bo_is_dirty(struct kgem_bo *bo) { if (bo == NULL) return false; assert(bo->refcnt); return bo->gpu_dirty; } static inline void kgem_bo_unclean(struct kgem *kgem, struct kgem_bo *bo) { /* The bo is outside of our control, so presume it is written to */ bo->needs_flush = true; if (bo->rq == NULL) bo->rq = (void *)kgem; if (bo->domain != DOMAIN_GPU) bo->domain = DOMAIN_NONE; } static inline void __kgem_bo_mark_dirty(struct kgem_bo *bo) { DBG(("%s: handle=%d (proxy? %d)\n", __FUNCTION__, bo->handle, bo->proxy != NULL)); assert(bo->refcnt); assert(bo->exec); assert(bo->rq); bo->exec->flags |= LOCAL_EXEC_OBJECT_WRITE; bo->needs_flush = bo->gpu_dirty = true; list_move(&bo->request, &RQ(bo->rq)->buffers); } static inline void kgem_bo_mark_dirty(struct kgem_bo *bo) { assert(bo->refcnt); do { assert(bo->exec); assert(bo->rq); if (bo->gpu_dirty) return; __kgem_bo_mark_dirty(bo); } while ((bo = bo->proxy)); } static inline bool kgem_bo_mapped(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, map=%p:%p, tiling=%d, domain=%d\n", __FUNCTION__, bo->handle, bo->map__gtt, bo->map__cpu, bo->tiling, bo->domain)); assert(bo->proxy == NULL); if (bo->tiling == I915_TILING_NONE && (bo->domain == DOMAIN_CPU || kgem->has_llc)) return bo->map__cpu != NULL; if (bo->tiling == I915_TILING_NONE && bo->map__wc) return true; return bo->map__gtt != NULL; } static inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d, map=%p:%p:%p, tiling=%d, domain=%d, offset=%ld\n", __FUNCTION__, bo->handle, bo->map__gtt, bo->map__wc, bo->map__cpu, bo->tiling, bo->domain, (long)bo->presumed_offset)); if (!bo->tiling && (kgem->has_llc || bo->domain == DOMAIN_CPU)) return true; assert(bo->proxy == NULL); if (bo->map__gtt != NULL) return true; if (kgem->gen == 021 && bo->tiling == I915_TILING_Y) return false; if (!bo->tiling && kgem->has_wc_mmap) return true; return __kgem_bo_num_pages(bo) <= kgem->aperture_mappable / 4; } static inline bool kgem_bo_can_map__cpu(struct kgem *kgem, struct kgem_bo *bo, bool write) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); assert(bo->refcnt); if (bo->purged || (bo->scanout && write)) { DBG(("%s: no, writing to scanout? %d, or is stolen [inaccessible via CPU]? %d\n", __FUNCTION__, bo->scanout && write, bo->purged)); return false; } if (kgem->has_llc) { DBG(("%s: yes, has LLC and target is in LLC\n", __FUNCTION__)); return true; } DBG(("%s: non-LLC - CPU domain? %d, clean? %d\n", __FUNCTION__, bo->domain == DOMAIN_CPU, !write || bo->exec == NULL)); if (bo->domain != DOMAIN_CPU) return false; return !write || bo->exec == NULL; } #define KGEM_BUFFER_WRITE 0x1 #define KGEM_BUFFER_INPLACE 0x2 #define KGEM_BUFFER_LAST 0x4 #define KGEM_BUFFER_WRITE_INPLACE (KGEM_BUFFER_WRITE | KGEM_BUFFER_INPLACE) struct kgem_bo *kgem_create_buffer(struct kgem *kgem, uint32_t size, uint32_t flags, void **ret); struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, int width, int height, int bpp, uint32_t flags, void **ret); bool kgem_buffer_is_inplace(struct kgem_bo *bo); void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo); int kgem_is_wedged(struct kgem *kgem); void kgem_throttle(struct kgem *kgem); #define MAX_INACTIVE_TIME 10 bool kgem_expire_cache(struct kgem *kgem); bool kgem_cleanup_cache(struct kgem *kgem); void kgem_clean_scanout_cache(struct kgem *kgem); void kgem_clean_large_cache(struct kgem *kgem); #if HAS_DEBUG_FULL void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch); #else static inline void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch) { (void)kgem; (void)nbatch; } #endif static inline void memcpy_to_tiled_x(struct kgem *kgem, const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { assert(kgem->memcpy_to_tiled_x); assert(src_x >= 0 && src_y >= 0); assert(dst_x >= 0 && dst_y >= 0); assert(8*src_stride >= (src_x+width) * bpp); assert(8*dst_stride >= (dst_x+width) * bpp); return kgem->memcpy_to_tiled_x(src, dst, bpp, src_stride, dst_stride, src_x, src_y, dst_x, dst_y, width, height); } static inline void memcpy_from_tiled_x(struct kgem *kgem, const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { assert(kgem->memcpy_from_tiled_x); assert(src_x >= 0 && src_y >= 0); assert(dst_x >= 0 && dst_y >= 0); assert(8*src_stride >= (src_x+width) * bpp); assert(8*dst_stride >= (dst_x+width) * bpp); return kgem->memcpy_from_tiled_x(src, dst, bpp, src_stride, dst_stride, src_x, src_y, dst_x, dst_y, width, height); } void choose_memcpy_tiled_x(struct kgem *kgem, int swizzling); #endif /* KGEM_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug.c000066400000000000000000000424701267532330400241070ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "kgem_debug.h" struct drm_i915_gem_relocation_entry * kgem_debug_get_reloc_entry(struct kgem *kgem, uint32_t offset) { int i; offset *= sizeof(uint32_t); for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == offset) return kgem->reloc+i; assert(!"valid relocation entry, unknown batch offset"); return NULL; } struct kgem_bo * kgem_debug_get_bo_for_reloc_entry(struct kgem *kgem, struct drm_i915_gem_relocation_entry *reloc) { struct kgem_bo *bo; if (reloc == NULL) return NULL; list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->target_handle == reloc->target_handle && bo->proxy == NULL) break; assert(&bo->request != &kgem->next_request->buffers); return bo; } static int kgem_debug_handle_is_fenced(struct kgem *kgem, uint32_t handle) { int i; if (kgem->has_handle_lut) return kgem->exec[handle].flags & EXEC_OBJECT_NEEDS_FENCE; for (i = 0; i < kgem->nexec; i++) if (kgem->exec[i].handle == handle) return kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE; return 0; } static int kgem_debug_handle_tiling(struct kgem *kgem, uint32_t handle) { struct kgem_bo *bo; list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->target_handle == handle) return bo->tiling; return 0; } void kgem_debug_print(const uint32_t *data, uint32_t offset, unsigned int index, const char *fmt, ...) { va_list va; char buf[240]; int len; len = snprintf(buf, sizeof(buf), "0x%08x: 0x%08x: %s", (offset + index) * 4, data[index], index == 0 ? "" : " "); va_start(va, fmt); vsnprintf(buf + len, sizeof(buf) - len, fmt, va); va_end(va); ErrorF("%s", buf); } static int decode_nop(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; kgem_debug_print(data, offset, 0, "UNKNOWN\n"); assert(0); return 1; } static int decode_mi(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int len_mask; int min_len; int max_len; const char *name; } opcodes[] = { { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" }, { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, { 0x30, 0x3f, 3, 3, "MI_BATCH_BUFFER" }, { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" }, { 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, { 0x04, 0, 1, 1, "MI_FLUSH" }, { 0x22, 0x1f, 3, 3, "MI_LOAD_REGISTER_IMM" }, { 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, { 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, { 0x00, 0, 1, 1, "MI_NOOP" }, { 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" }, { 0x07, 0, 1, 1, "MI_REPORT_HEAD" }, { 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" }, { 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" }, { 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" }, { 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" }, { 0x02, 0, 1, 1, "MI_USER_INTERRUPT" }, { 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" }, { 0x16, 0x7f, 3, 3, "MI_SEMAPHORE_MBOX" }, { 0x26, 0x1f, 3, 4, "MI_FLUSH_DW" }, { 0x0b, 0, 1, 1, "MI_SUSPEND_FLUSH" }, }; uint32_t *data = kgem->batch + offset; int op; for (op = 0; op < ARRAY_SIZE(opcodes); op++) { if ((data[0] & 0x1f800000) >> 23 == opcodes[op].opcode) { unsigned int len = 1, i; kgem_debug_print(data, offset, 0, "%s\n", opcodes[op].name); if (opcodes[op].max_len > 1) { len = (data[0] & opcodes[op].len_mask) + 2; if (len < opcodes[op].min_len || len > opcodes[op].max_len) { ErrorF("Bad length (%d) in %s, [%d, %d]\n", len, opcodes[op].name, opcodes[op].min_len, opcodes[op].max_len); assert(0); } } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "MI UNKNOWN\n"); assert(0); return 1; } static int __decode_2d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x40, 5, 5, "COLOR_BLT" }, { 0x43, 6, 6, "SRC_COPY_BLT" }, { 0x01, 8, 8, "XY_SETUP_BLT" }, { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, { 0x24, 2, 2, "XY_PIXEL_BLT" }, { 0x25, 3, 3, "XY_SCANLINES_BLT" }, { 0x26, 4, 4, "Y_TEXT_BLT" }, { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, { 0x50, 6, 6, "XY_COLOR_BLT" }, { 0x51, 6, 6, "XY_PAT_BLT" }, { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, { 0x55, 9, 9, "XY_FULL_BLT" }, { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, }; unsigned int op, len; const char *format = NULL; uint32_t *data = kgem->batch + offset; struct drm_i915_gem_relocation_entry *reloc; /* Special case the two most common ops that we detail in full */ switch ((data[0] & 0x1fc00000) >> 22) { case 0x50: kgem_debug_print(data, offset, 0, "XY_COLOR_BLT (rgb %sabled, alpha %sabled, dst tile %d)\n", (data[0] & (1 << 20)) ? "en" : "dis", (data[0] & (1 << 21)) ? "en" : "dis", (data[0] >> 11) & 1); len = (data[0] & 0x000000ff) + 2; assert(len == 6); switch ((data[1] >> 24) & 0x3) { case 0: format="8"; break; case 1: format="565"; break; case 2: format="1555"; break; case 3: format="8888"; break; } kgem_debug_print(data, offset, 1, "format %s, rop %x, pitch %d, " "clipping %sabled\n", format, (data[1] >> 16) & 0xff, (short)(data[1] & 0xffff), data[1] & (1 << 30) ? "en" : "dis"); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "(%d,%d)\n", data[3] & 0xffff, data[3] >> 16); reloc = kgem_debug_get_reloc_entry(kgem, offset+4); kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n", data[4], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); kgem_debug_print(data, offset, 5, "color\n"); assert(kgem->gen >= 040 || kgem_debug_handle_is_fenced(kgem, reloc->target_handle)); return len; case 0x53: kgem_debug_print(data, offset, 0, "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled, " "src tile %d, dst tile %d)\n", (data[0] & (1 << 20)) ? "en" : "dis", (data[0] & (1 << 21)) ? "en" : "dis", (data[0] >> 15) & 1, (data[0] >> 11) & 1); len = (data[0] & 0x000000ff) + 2; assert(len == 8); switch ((data[1] >> 24) & 0x3) { case 0: format="8"; break; case 1: format="565"; break; case 2: format="1555"; break; case 3: format="8888"; break; } kgem_debug_print(data, offset, 1, "format %s, rop %x, dst pitch %d, " "clipping %sabled\n", format, (data[1] >> 16) & 0xff, (short)(data[1] & 0xffff), data[1] & (1 << 30) ? "en" : "dis"); kgem_debug_print(data, offset, 2, "dst (%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "dst (%d,%d)\n", data[3] & 0xffff, data[3] >> 16); reloc = kgem_debug_get_reloc_entry(kgem, offset+4); assert(reloc); kgem_debug_print(data, offset, 4, "dst offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x, (fenced? %d, tiling? %d)]\n", data[4], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); assert(kgem->gen >= 040 || kgem_debug_handle_is_fenced(kgem, reloc->target_handle)); kgem_debug_print(data, offset, 5, "src (%d,%d)\n", data[5] & 0xffff, data[5] >> 16); kgem_debug_print(data, offset, 6, "src pitch %d\n", (short)(data[6] & 0xffff)); reloc = kgem_debug_get_reloc_entry(kgem, offset+7); assert(reloc); kgem_debug_print(data, offset, 7, "src offset 0x%08x [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n", data[7], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); assert(kgem->gen >= 040 || kgem_debug_handle_is_fenced(kgem, reloc->target_handle)); return len; } for (op = 0; op < ARRAY_SIZE(opcodes); op++) { if ((data[0] & 0x1fc00000) >> 22 == opcodes[op].opcode) { unsigned int i; len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcodes[op].name); if (opcodes[op].max_len > 1) { len = (data[0] & 0x000000ff) + 2; assert(len >= opcodes[op].min_len && len <= opcodes[op].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "2D UNKNOWN\n"); assert(0); return 1; } static int __decode_2d_gen8(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x43, 8, 8, "SRC_COPY_BLT" }, { 0x01, 8, 8, "XY_SETUP_BLT" }, { 0x11, 10, 10, "XY_SETUP_MONO_PATTERN_SL_BLT" }, { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, { 0x24, 2, 2, "XY_PIXEL_BLT" }, { 0x25, 3, 3, "XY_SCANLINES_BLT" }, { 0x26, 4, 4, "Y_TEXT_BLT" }, { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, { 0x50, 7, 7, "XY_COLOR_BLT" }, { 0x51, 6, 6, "XY_PAT_BLT" }, { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, { 0x55, 9, 9, "XY_FULL_BLT" }, { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, }; unsigned int op, len; const char *format = NULL; uint32_t *data = kgem->batch + offset; struct drm_i915_gem_relocation_entry *reloc; /* Special case the two most common ops that we detail in full */ switch ((data[0] & 0x1fc00000) >> 22) { case 0x50: kgem_debug_print(data, offset, 0, "XY_COLOR_BLT (rgb %sabled, alpha %sabled, dst tile %d)\n", (data[0] & (1 << 20)) ? "en" : "dis", (data[0] & (1 << 21)) ? "en" : "dis", (data[0] >> 11) & 1); len = (data[0] & 0x000000ff) + 2; assert(len == 7); switch ((data[1] >> 24) & 0x3) { case 0: format="8"; break; case 1: format="565"; break; case 2: format="1555"; break; case 3: format="8888"; break; } kgem_debug_print(data, offset, 1, "format %s, rop %x, pitch %d, " "clipping %sabled\n", format, (data[1] >> 16) & 0xff, (short)(data[1] & 0xffff), data[1] & (1 << 30) ? "en" : "dis"); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "(%d,%d)\n", data[3] & 0xffff, data[3] >> 16); reloc = kgem_debug_get_reloc_entry(kgem, offset+4); kgem_debug_print(data, offset, 4, "dst offset 0x%016llx [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n", (long long)*(uint64_t *)&data[4], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); kgem_debug_print(data, offset, 6, "color\n"); return len; case 0x53: kgem_debug_print(data, offset, 0, "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled, " "src tile %d, dst tile %d)\n", (data[0] & (1 << 20)) ? "en" : "dis", (data[0] & (1 << 21)) ? "en" : "dis", (data[0] >> 15) & 1, (data[0] >> 11) & 1); len = (data[0] & 0x000000ff) + 2; assert(len == 10); switch ((data[1] >> 24) & 0x3) { case 0: format="8"; break; case 1: format="565"; break; case 2: format="1555"; break; case 3: format="8888"; break; } kgem_debug_print(data, offset, 1, "format %s, rop %x, dst pitch %d, " "clipping %sabled\n", format, (data[1] >> 16) & 0xff, (short)(data[1] & 0xffff), data[1] & (1 << 30) ? "en" : "dis"); kgem_debug_print(data, offset, 2, "dst (%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "dst (%d,%d)\n", data[3] & 0xffff, data[3] >> 16); reloc = kgem_debug_get_reloc_entry(kgem, offset+4); assert(reloc); kgem_debug_print(data, offset, 4, "dst offset 0x%016llx [handle=%d, delta=%d, read=%x, write=%x, (fenced? %d, tiling? %d)]\n", (long long)*(uint64_t *)&data[4], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); kgem_debug_print(data, offset, 6, "src (%d,%d)\n", data[6] & 0xffff, data[6] >> 16); kgem_debug_print(data, offset, 7, "src pitch %d\n", (short)(data[7] & 0xffff)); reloc = kgem_debug_get_reloc_entry(kgem, offset+8); assert(reloc); kgem_debug_print(data, offset, 8, "src offset 0x%016llx [handle=%d, delta=%d, read=%x, write=%x (fenced? %d, tiling? %d)]\n", (long long)*(uint64_t *)&data[8], reloc->target_handle, reloc->delta, reloc->read_domains, reloc->write_domain, kgem_debug_handle_is_fenced(kgem, reloc->target_handle), kgem_debug_handle_tiling(kgem, reloc->target_handle)); return len; } for (op = 0; op < ARRAY_SIZE(opcodes); op++) { if ((data[0] & 0x1fc00000) >> 22 == opcodes[op].opcode) { unsigned int i; len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcodes[op].name); if (opcodes[op].max_len > 1) { len = (data[0] & 0x000000ff) + 2; assert(len >= opcodes[op].min_len && len <= opcodes[op].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "2D UNKNOWN\n"); assert(0); return 1; } static int (*decode_2d(int gen))(struct kgem*, uint32_t) { if (gen >= 0100) return __decode_2d_gen8; else return __decode_2d; } static int kgem_nop_decode_3d(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; return (data[0] & 0xf) + 2; } static void kgem_nop_finish_state(struct kgem *kgem) { } static int (*decode_3d(int gen))(struct kgem*, uint32_t) { if (gen >= 0100) { return kgem_nop_decode_3d; } else if (gen >= 070) { return kgem_gen7_decode_3d; } else if (gen >= 060) { return kgem_gen6_decode_3d; } else if (gen >= 050) { return kgem_gen5_decode_3d; } else if (gen >= 040) { return kgem_gen4_decode_3d; } else if (gen >= 030) { return kgem_gen3_decode_3d; } else if (gen >= 020) { return kgem_gen2_decode_3d; } assert(0); } static void (*finish_state(int gen))(struct kgem*) { if (gen >= 0100) { return kgem_nop_finish_state; } else if (gen >= 070) { return kgem_gen7_finish_state; } else if (gen >= 060) { return kgem_gen6_finish_state; } else if (gen >= 050) { return kgem_gen5_finish_state; } else if (gen >= 040) { return kgem_gen4_finish_state; } else if (gen >= 030) { return kgem_gen3_finish_state; } else if (gen >= 020) { return kgem_gen2_finish_state; } assert(0); } void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch) { int (*const decode[])(struct kgem *, uint32_t) = { decode_mi, decode_nop, decode_2d(kgem->gen), decode_3d(kgem->gen), }; uint32_t offset = 0; while (offset < nbatch) { int class = (kgem->batch[offset] & 0xe0000000) >> 29; assert(class < ARRAY_SIZE(decode)); offset += decode[class](kgem, offset); } finish_state(kgem->gen)(kgem); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug.h000066400000000000000000000020301267532330400241000ustar00rootroot00000000000000#ifndef KGEM_DEBUG_H #define KGEM_DEBUG_H void kgem_debug_print(const uint32_t *data, uint32_t offset, unsigned int index, const char *fmt, ...); struct drm_i915_gem_relocation_entry * kgem_debug_get_reloc_entry(struct kgem *kgem, uint32_t offset); struct kgem_bo * kgem_debug_get_bo_for_reloc_entry(struct kgem *kgem, struct drm_i915_gem_relocation_entry *reloc); int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen7_finish_state(struct kgem *kgem); int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen6_finish_state(struct kgem *kgem); int kgem_gen5_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen5_finish_state(struct kgem *kgem); int kgem_gen4_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen4_finish_state(struct kgem *kgem); int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen3_finish_state(struct kgem *kgem); int kgem_gen2_decode_3d(struct kgem *kgem, uint32_t offset); void kgem_gen2_finish_state(struct kgem *kgem); #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen2.c000066400000000000000000000501131267532330400250130ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "gen2_render.h" #include "kgem_debug.h" static struct state { int vertex_format; } state; static inline float int_as_float(uint32_t dw) { union { float f; uint32_t dw; } u; u.dw = dw; return u.f; } static int decode_3d_primitive(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; char immediate = (data[0] & (1 << 23)) == 0; unsigned int len; const char *primtype; switch ((data[0] >> 18) & 0xf) { case 0x0: primtype = "TRILIST"; break; case 0x1: primtype = "TRISTRIP"; break; case 0x2: primtype = "TRISTRIP_REVERSE"; break; case 0x3: primtype = "TRIFAN"; break; case 0x4: primtype = "POLYGON"; break; case 0x5: primtype = "LINELIST"; break; case 0x6: primtype = "LINESTRIP"; break; case 0x7: primtype = "RECTLIST"; break; case 0x8: primtype = "POINTLIST"; break; case 0x9: primtype = "DIB"; break; case 0xa: primtype = "CLEAR_RECT"; break; default: primtype = "unknown"; break; } /* XXX: 3DPRIM_DIB not supported */ if (immediate) { len = (data[0] & 0x0003ffff) + 2; kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype); #if 0 if (!saved_s2_set || !saved_s4_set) { fprintf(out, "unknown vertex format\n"); for (i = 1; i < len; i++) { kgem_debug_print(data, offset, i, " vertex data (%f float)\n", int_as_float(data[i])); } } else { unsigned int vertex = 0; for (i = 1; i < len;) { unsigned int tc; #define VERTEX_OUT(fmt, ...) do { \ if (i < len) \ kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ else \ fprintf(out, " missing data in V%d\n", vertex); \ i++; \ } while (0) VERTEX_OUT("X = %f", int_as_float(data[i])); VERTEX_OUT("Y = %f", int_as_float(data[i])); switch (saved_s4 >> 6 & 0x7) { case 0x1: VERTEX_OUT("Z = %f", int_as_float(data[i])); break; case 0x2: VERTEX_OUT("Z = %f", int_as_float(data[i])); VERTEX_OUT("W = %f", int_as_float(data[i])); break; case 0x3: break; case 0x4: VERTEX_OUT("W = %f", int_as_float(data[i])); break; default: fprintf(out, "bad S4 position mask\n"); } if (saved_s4 & (1 << 10)) { VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " "B=0x%02x)", data[i] >> 24, (data[i] >> 16) & 0xff, (data[i] >> 8) & 0xff, data[i] & 0xff); } if (saved_s4 & (1 << 11)) { VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " "B=0x%02x)", data[i] >> 24, (data[i] >> 16) & 0xff, (data[i] >> 8) & 0xff, data[i] & 0xff); } if (saved_s4 & (1 << 12)) VERTEX_OUT("width = 0x%08x)", data[i]); for (tc = 0; tc <= 7; tc++) { switch ((saved_s2 >> (tc * 4)) & 0xf) { case 0x0: VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); break; case 0x1: VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); break; case 0x2: VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); break; case 0x3: VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); break; case 0x4: VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); break; case 0x5: VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); break; case 0xf: break; default: fprintf(out, "bad S2.T%d format\n", tc); } } vertex++; } } #endif } else { /* indirect vertices */ len = data[0] & 0x0000ffff; /* index count */ #if 0 if (data[0] & (1 << 17)) { /* random vertex access */ kgem_debug_print(data, offset, 0, "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); if (len == 0) { /* vertex indices continue until 0xffff is found */ for (i = 1; i < count; i++) { if ((data[i] & 0xffff) == 0xffff) { kgem_debug_print(data, offset, i, " indices: (terminator)\n"); ret = i; goto out; } else if ((data[i] >> 16) == 0xffff) { kgem_debug_print(data, offset, i, " indices: 0x%04x, (terminator)\n", data[i] & 0xffff); ret = i; goto out; } else { kgem_debug_print(data, offset, i, " indices: 0x%04x, 0x%04x\n", data[i] & 0xffff, data[i] >> 16); } } fprintf(out, "3DPRIMITIVE: no terminator found in index buffer\n"); ret = count; goto out; } else { /* fixed size vertex index buffer */ for (j = 1, i = 0; i < len; i += 2, j++) { if (i * 2 == len - 1) { kgem_debug_print(data, offset, j, " indices: 0x%04x\n", data[j] & 0xffff); } else { kgem_debug_print(data, offset, j, " indices: 0x%04x, 0x%04x\n", data[j] & 0xffff, data[j] >> 16); } } } ret = (len + 1) / 2 + 1; goto out; } else { /* sequential vertex access */ kgem_debug_print(data, offset, 0, "3DPRIMITIVE sequential indirect %s, %d starting from " "%d\n", primtype, len, data[1] & 0xffff); kgem_debug_print(data, offset, 1, " start\n"); ret = 2; goto out; } #endif } return len; } static int decode_3d_1d(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; unsigned int len, i, idx, word, map; const char *format, *zformat, *type; uint32_t opcode; static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes_3d_1d[] = { { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, { 0x8c, 2, 2, "3DSTATE_MAP_COORD_TRANSFORM" }, { 0x8b, 2, 2, "3DSTATE_MAP_VERTEX_TRANSFORM" }, { 0x8d, 3, 3, "3DSTATE_W_STATE" }, { 0x01, 2, 2, "3DSTATE_COLOR_FACTOR" }, { 0x02, 2, 2, "3DSTATE_MAP_COORD_SETBIND" }, }, *opcode_3d_1d; opcode = (data[0] & 0x00ff0000) >> 16; switch (opcode) { case 0x07: /* This instruction is unusual. A 0 length means just 1 DWORD instead of * 2. The 0 length is specified in one place to be unsupported, but * stated to be required in another, and 0 length LOAD_INDIRECTs appear * to cause no harm at least. */ kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n"); len = (data[0] & 0x000000ff) + 1; i = 1; if (data[0] & (0x01 << 8)) { kgem_debug_print(data, offset, i++, "SIS.0\n"); kgem_debug_print(data, offset, i++, "SIS.1\n"); } if (data[0] & (0x02 << 8)) { kgem_debug_print(data, offset, i++, "DIS.0\n"); } if (data[0] & (0x04 << 8)) { kgem_debug_print(data, offset, i++, "SSB.0\n"); kgem_debug_print(data, offset, i++, "SSB.1\n"); } if (data[0] & (0x08 << 8)) { kgem_debug_print(data, offset, i++, "MSB.0\n"); kgem_debug_print(data, offset, i++, "MSB.1\n"); } if (data[0] & (0x10 << 8)) { kgem_debug_print(data, offset, i++, "PSP.0\n"); kgem_debug_print(data, offset, i++, "PSP.1\n"); } if (data[0] & (0x20 << 8)) { kgem_debug_print(data, offset, i++, "PSC.0\n"); kgem_debug_print(data, offset, i++, "PSC.1\n"); } assert(len == i); return len; case 0x04: kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); len = (data[0] & 0x0000000f) + 2; i = 1; for (word = 0; word <= 8; word++) { if (data[0] & (1 << (4 + word))) { kgem_debug_print(data, offset, i, "S%d: 0x%08x\n", i, data[i]); i++; } } assert (len ==i); return len; case 0x03: kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n"); len = (data[0] & 0x0000000f) + 2; i = 1; for (word = 6; word <= 14; word++) { if (data[0] & (1 << word)) { if (word == 6) kgem_debug_print(data, offset, i++, "TBCF\n"); else if (word >= 7 && word <= 10) { kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7); kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7); } else if (word >= 11 && word <= 14) { kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n", word - 11, data[i]&0xfffffffe, data[i]&1?"use fence":""); i++; kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n", word - 11, data[i]>>21, (data[i]>>10)&0x3ff, data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):""); i++; kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n", word - 11, ((data[i]>>21) + 1)*4); i++; kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11); kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11); } } } assert (len == i); return len; case 0x00: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n"); len = (data[0] & 0x0000003f) + 2; kgem_debug_print(data, offset, 1, "mask\n"); i = 2; for (map = 0; map <= 15; map++) { if (data[1] & (1 << map)) { int width, height, pitch, dword; const char *tiling; dword = data[i]; kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s\n", map, dword&(1<<31)?"untrusted surface, ":"", dword&(1<<1)?"vertical line stride enable, ":"", dword&(1<<0)?"vertical ofs enable, ":""); dword = data[i]; width = ((dword >> 10) & ((1 << 11) - 1))+1; height = ((dword >> 21) & ((1 << 11) - 1))+1; tiling = "none"; if (dword & (1 << 2)) tiling = "fenced"; else if (dword & (1 << 1)) tiling = dword & (1 << 0) ? "Y" : "X"; type = " BAD"; format = "BAD"; switch ((dword>>7) & 0x7) { case 1: type = "8b"; switch ((dword>>3) & 0xf) { case 0: format = "I"; break; case 1: format = "L"; break; case 2: format = "A"; break; case 3: format = " mono"; break; } break; case 2: type = "16b"; switch ((dword>>3) & 0xf) { case 0: format = " rgb565"; break; case 1: format = " argb1555"; break; case 2: format = " argb4444"; break; case 5: format = " ay88"; break; case 6: format = " bump655"; break; case 7: format = "I"; break; case 8: format = "L"; break; case 9: format = "A"; break; } break; case 3: type = "32b"; switch ((dword>>3) & 0xf) { case 0: format = " argb8888"; break; case 1: format = " abgr8888"; break; case 2: format = " xrgb8888"; break; case 3: format = " xbgr8888"; break; case 4: format = " qwvu8888"; break; case 5: format = " axvu8888"; break; case 6: format = " lxvu8888"; break; case 7: format = " xlvu8888"; break; case 8: format = " argb2101010"; break; case 9: format = " abgr2101010"; break; case 10: format = " awvu2101010"; break; case 11: format = " gr1616"; break; case 12: format = " vu1616"; break; case 13: format = " xI824"; break; case 14: format = " xA824"; break; case 15: format = " xL824"; break; } break; case 5: type = "422"; switch ((dword>>3) & 0xf) { case 0: format = " yuv_swapy"; break; case 1: format = " yuv"; break; case 2: format = " yuv_swapuv"; break; case 3: format = " yuv_swapuvy"; break; } break; case 6: type = "compressed"; switch ((dword>>3) & 0x7) { case 0: format = " dxt1"; break; case 1: format = " dxt2_3"; break; case 2: format = " dxt4_5"; break; case 3: format = " fxt1"; break; case 4: format = " dxt1_rb"; break; } break; case 7: type = "4b indexed"; switch ((dword>>3) & 0xf) { case 7: format = " argb8888"; break; } break; } dword = data[i]; kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n", map, width, height, type, format, tiling, dword&(1<<9)?" palette select":""); dword = data[i]; pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1); kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n", map, pitch, (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f, dword&(1<<8)?"miplayout legacy":"miplayout right"); } } assert (len == i); return len; case 0x85: len = (data[0] & 0x0000000f) + 2; assert (len == 2); kgem_debug_print(data, offset, 0, "3DSTATE_DEST_BUFFER_VARIABLES\n"); switch ((data[1] >> 8) & 0xf) { case 0x0: format = "g8"; break; case 0x1: format = "x1r5g5b5"; break; case 0x2: format = "r5g6b5"; break; case 0x3: format = "a8r8g8b8"; break; case 0x4: format = "ycrcb_swapy"; break; case 0x5: format = "ycrcb_normal"; break; case 0x6: format = "ycrcb_swapuv"; break; case 0x7: format = "ycrcb_swapuvy"; break; case 0x8: format = "a4r4g4b4"; break; case 0x9: format = "a1r5g5b5"; break; case 0xa: format = "a2r10g10b10"; break; default: format = "BAD"; break; } switch ((data[1] >> 2) & 0x3) { case 0x0: zformat = "u16"; break; case 0x1: zformat = "f16"; break; case 0x2: zformat = "u24x8"; break; default: zformat = "BAD"; break; } kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n", format, zformat, (data[1] & (1 << 31)) ? "en" : "dis"); return len; case 0x8e: { const char *name, *tiling; len = (data[0] & 0x0000000f) + 2; assert (len == 3); switch((data[1] >> 24) & 0x7) { case 0x3: name = "color"; break; case 0x7: name = "depth"; break; default: name = "unknown"; break; } tiling = "none"; if (data[1] & (1 << 23)) tiling = "fenced"; else if (data[1] & (1 << 22)) tiling = data[1] & (1 << 21) ? "Y" : "X"; kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n"); kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff); kgem_debug_print(data, offset, 2, "address\n"); return len; } case 0x81: len = (data[0] & 0x0000000f) + 2; assert (len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "(%d,%d)\n", data[1] & 0xffff, data[1] >> 16); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); return len; case 0x80: len = (data[0] & 0x0000000f) + 2; assert (len == 5); kgem_debug_print(data, offset, 0, "3DSTATE_DRAWING_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "%s\n", data[1]&(1<<30)?"depth ofs disabled ":""); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "(%d,%d)\n", data[3] & 0xffff, data[3] >> 16); kgem_debug_print(data, offset, 4, "(%d,%d)\n", data[4] & 0xffff, data[4] >> 16); return len; case 0x9c: len = (data[0] & 0x0000000f) + 2; assert (len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_CLEAR_PARAMETERS\n"); kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n", data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT", data[1]&(1<<2)?"color,":"", data[1]&(1<<1)?"depth,":"", data[1]&(1<<0)?"stencil,":""); kgem_debug_print(data, offset, 2, "clear color\n"); kgem_debug_print(data, offset, 3, "clear depth/stencil\n"); kgem_debug_print(data, offset, 4, "color value (rgba8888)\n"); kgem_debug_print(data, offset, 5, "depth value %f\n", int_as_float(data[5])); kgem_debug_print(data, offset, 6, "clear stencil\n"); return len; } for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) { opcode_3d_1d = &opcodes_3d_1d[idx]; if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) { len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name); if (opcode_3d_1d->max_len > 1) { len = (data[0] & 0x0000ffff) + 2; assert (len >= opcode_3d_1d->min_len && len <= opcode_3d_1d->max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode); return 1; } static int decode_3d_1c(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; uint32_t opcode; opcode = (data[0] & 0x00f80000) >> 19; switch (opcode) { case 0x11: kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n"); return 1; case 0x10: kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n", data[0]&1?"enabled":"disabled"); return 1; case 0x01: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n"); return 1; case 0x0a: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n"); return 1; case 0x05: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n"); return 1; } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n", opcode); return 1; } int kgem_gen2_decode_3d(struct kgem *kgem, uint32_t offset) { const static struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x02, 1, 1, "3DSTATE_MODES_3" }, { 0x03, 1, 1, "3DSTATE_ENABLES_1"}, { 0x04, 1, 1, "3DSTATE_ENABLES_2"}, { 0x05, 1, 1, "3DSTATE_VFT0"}, { 0x06, 1, 1, "3DSTATE_AA"}, { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, { 0x08, 1, 1, "3DSTATE_MODES_1" }, { 0x09, 1, 1, "3DSTATE_STENCIL_TEST" }, { 0x0a, 1, 1, "3DSTATE_VFT1"}, { 0x0b, 1, 1, "3DSTATE_INDPT_ALPHA_BLEND" }, { 0x0c, 1, 1, "3DSTATE_MODES_5" }, { 0x0d, 1, 1, "3DSTATE_MAP_BLEND_OP" }, { 0x0e, 1, 1, "3DSTATE_MAP_BLEND_ARG" }, { 0x0f, 1, 1, "3DSTATE_MODES_2" }, { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, { 0x16, 1, 1, "3DSTATE_MODES_4" }, }; uint32_t *data = kgem->batch + offset; uint32_t opcode = (data[0] & 0x1f000000) >> 24; uint32_t idx; switch (opcode) { case 0x1f: return decode_3d_primitive(kgem, offset); case 0x1d: return decode_3d_1d(kgem, offset); case 0x1c: return decode_3d_1c(kgem, offset); } /* Catch the known instructions */ for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) { if (opcode == opcodes[idx].opcode) { unsigned int len = 1, i; kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name); if (opcodes[idx].max_len > 1) { len = (data[0] & 0xf) + 2; assert(len >= opcodes[idx].min_len && len <= opcodes[idx].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode); return 1; } void kgem_gen2_finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen3.c000066400000000000000000001264501267532330400250240ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "gen3_render.h" #include "kgem_debug.h" enum type { T_FLOAT32, T_FLOAT16, }; static struct state { struct vertex_buffer { int handle; void *base; const char *ptr; int pitch; struct kgem_bo *current; } vb; struct vertex_elements { int offset; bool valid; enum type type; int size; uint8_t swizzle[4]; } ve[33]; int num_ve; } state; static float int_as_float(int i) { union { float f; int i; } x; x.i = i; return x.f; } static void gen3_update_vertex_buffer_addr(struct kgem *kgem, uint32_t offset) { uint32_t handle; struct kgem_bo *bo = NULL; void *base, *ptr; int i; offset *= sizeof(uint32_t); for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == offset) break; assert(i < kgem->nreloc); handle = kgem->reloc[i].target_handle; if (handle == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == handle) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } ptr = (char *)base + kgem->reloc[i].delta; state.vb.current = bo; state.vb.base = base; state.vb.ptr = ptr; } static void gen3_update_vertex_buffer_pitch(struct kgem *kgem, uint32_t offset) { state.vb.pitch = kgem->batch[offset] >> 16 & 0x3f; state.vb.pitch *= sizeof(uint32_t); } static void gen3_update_vertex_elements(struct kgem *kgem, uint32_t data) { state.ve[1].valid = 1; switch ((data >> 6) & 7) { case 1: state.ve[1].type = T_FLOAT32; state.ve[1].size = 3; state.ve[1].swizzle[0] = 1; state.ve[1].swizzle[1] = 1; state.ve[1].swizzle[2] = 1; state.ve[1].swizzle[3] = 3; break; case 2: state.ve[1].type = T_FLOAT32; state.ve[1].size = 4; state.ve[1].swizzle[0] = 1; state.ve[1].swizzle[1] = 1; state.ve[1].swizzle[2] = 1; state.ve[1].swizzle[3] = 1; break; case 3: state.ve[1].type = T_FLOAT32; state.ve[1].size = 2; state.ve[1].swizzle[0] = 1; state.ve[1].swizzle[1] = 1; state.ve[1].swizzle[2] = 2; state.ve[1].swizzle[3] = 3; break; case 4: state.ve[1].type = T_FLOAT32; state.ve[1].size = 3; state.ve[1].swizzle[0] = 1; state.ve[1].swizzle[1] = 1; state.ve[1].swizzle[2] = 3; state.ve[1].swizzle[3] = 1; break; } state.ve[2].valid = 0; state.ve[3].valid = 0; } static void gen3_update_vertex_texcoords(struct kgem *kgem, uint32_t data) { int id; for (id = 0; id < 8; id++) { uint32_t fmt = (data >> (id*4)) & 0xf; int width; state.ve[id+4].valid = fmt != 0xf; width = 0; switch (fmt) { case 0: state.ve[id+4].type = T_FLOAT32; width = state.ve[id+4].size = 2; break; case 1: state.ve[id+4].type = T_FLOAT32; width = state.ve[id+4].size = 3; break; case 2: state.ve[id+4].type = T_FLOAT32; width = state.ve[id+4].size = 4; break; case 3: state.ve[id+4].type = T_FLOAT32; width = state.ve[id+4].size = 1; break; case 4: state.ve[id+4].type = T_FLOAT16; width = state.ve[id+4].size = 2; break; case 5: state.ve[id+4].type = T_FLOAT16; width = state.ve[id+4].size = 4; break; } state.ve[id+4].swizzle[0] = width > 0 ? 1 : 2; state.ve[id+4].swizzle[1] = width > 1 ? 1 : 2; state.ve[id+4].swizzle[2] = width > 2 ? 1 : 2; state.ve[id+4].swizzle[3] = width > 3 ? 1 : 2; } } static void gen3_update_vertex_elements_offsets(struct kgem *kgem) { int i, offset; for (i = offset = 0; i < ARRAY_SIZE(state.ve); i++) { if (!state.ve[i].valid) continue; state.ve[i].offset = offset; offset += 4 * state.ve[i].size; state.num_ve = i; } } static void vertices_float32_out(const struct vertex_elements *ve, const float *f, int max) { int c; ErrorF("("); for (c = 0; c < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%f", f[c]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < max-1) ErrorF(", "); } ErrorF(")"); } static void ve_out(const struct vertex_elements *ve, const void *ptr) { switch (ve->type) { case T_FLOAT32: vertices_float32_out(ve, ptr, ve->size); break; case T_FLOAT16: //vertices_float16_out(ve, ptr, ve->size); break; } } static void indirect_vertex_out(struct kgem *kgem, uint32_t v) { const struct vertex_buffer *vb = &state.vb; int i = 1; do { const struct vertex_elements *ve = &state.ve[i]; const void *ptr = vb->ptr + v * vb->pitch + ve->offset; if (!ve->valid) continue; ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); } static int inline_vertex_out(struct kgem *kgem, void *base) { const struct vertex_buffer *vb = &state.vb; int i = 1; do { const struct vertex_elements *ve = &state.ve[i]; const void *ptr = (char *)base + ve->offset; if (!ve->valid) continue; ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); return vb->pitch; } static int gen3_decode_3d_1c(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; uint32_t opcode; opcode = (data[0] & 0x00f80000) >> 19; switch (opcode) { case 0x11: kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n"); return 1; case 0x10: kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n", data[0]&1?"enabled":"disabled"); return 1; case 0x01: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n"); return 1; case 0x0a: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n"); return 1; case 0x05: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n"); return 1; } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n", opcode); assert(0); return 1; } /** Sets the string dstname to describe the destination of the PS instruction */ static void gen3_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask) { uint32_t a0 = data[i]; int dst_nr = (a0 >> 14) & 0xf; char dstmask[8]; const char *sat; if (do_mask) { if (((a0 >> 10) & 0xf) == 0xf) { dstmask[0] = 0; } else { int dstmask_index = 0; dstmask[dstmask_index++] = '.'; if (a0 & (1 << 10)) dstmask[dstmask_index++] = 'x'; if (a0 & (1 << 11)) dstmask[dstmask_index++] = 'y'; if (a0 & (1 << 12)) dstmask[dstmask_index++] = 'z'; if (a0 & (1 << 13)) dstmask[dstmask_index++] = 'w'; dstmask[dstmask_index++] = 0; } if (a0 & (1 << 22)) sat = ".sat"; else sat = ""; } else { dstmask[0] = 0; sat = ""; } switch ((a0 >> 19) & 0x7) { case 0: assert(dst_nr <= 15); sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat); break; case 4: assert(dst_nr == 0); sprintf(dstname, "oC%s%s", dstmask, sat); break; case 5: assert(dst_nr == 0); sprintf(dstname, "oD%s%s", dstmask, sat); break; case 6: assert(dst_nr <= 3); sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat); break; default: sprintf(dstname, "RESERVED"); break; } } static const char * gen3_get_channel_swizzle(uint32_t select) { switch (select & 0x7) { case 0: return (select & 8) ? "-x" : "x"; case 1: return (select & 8) ? "-y" : "y"; case 2: return (select & 8) ? "-z" : "z"; case 3: return (select & 8) ? "-w" : "w"; case 4: return (select & 8) ? "-0" : "0"; case 5: return (select & 8) ? "-1" : "1"; default: return (select & 8) ? "-bad" : "bad"; } } static void gen3_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name) { switch (src_type) { case 0: sprintf(name, "R%d", src_nr); assert(src_nr <= 15); break; case 1: if (src_nr < 8) sprintf(name, "T%d", src_nr); else if (src_nr == 8) sprintf(name, "DIFFUSE"); else if (src_nr == 9) sprintf(name, "SPECULAR"); else if (src_nr == 10) sprintf(name, "FOG"); else { assert(0); sprintf(name, "RESERVED"); } break; case 2: sprintf(name, "C%d", src_nr); assert(src_nr <= 31); break; case 4: sprintf(name, "oC"); assert(src_nr == 0); break; case 5: sprintf(name, "oD"); assert(src_nr == 0); break; case 6: sprintf(name, "U%d", src_nr); assert(src_nr <= 3); break; default: sprintf(name, "RESERVED"); assert(0); break; } } static void gen3_get_instruction_src0(uint32_t *data, int i, char *srcname) { uint32_t a0 = data[i]; uint32_t a1 = data[i + 1]; int src_nr = (a0 >> 2) & 0x1f; const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 28) & 0xf); const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 24) & 0xf); const char *swizzle_z = gen3_get_channel_swizzle((a1 >> 20) & 0xf); const char *swizzle_w = gen3_get_channel_swizzle((a1 >> 16) & 0xf); char swizzle[100]; gen3_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname); sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } static void gen3_get_instruction_src1(uint32_t *data, int i, char *srcname) { uint32_t a1 = data[i + 1]; uint32_t a2 = data[i + 2]; int src_nr = (a1 >> 8) & 0x1f; const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 4) & 0xf); const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 0) & 0xf); const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 28) & 0xf); const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 24) & 0xf); char swizzle[100]; gen3_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname); sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } static void gen3_get_instruction_src2(uint32_t *data, int i, char *srcname) { uint32_t a2 = data[i + 2]; int src_nr = (a2 >> 16) & 0x1f; const char *swizzle_x = gen3_get_channel_swizzle((a2 >> 12) & 0xf); const char *swizzle_y = gen3_get_channel_swizzle((a2 >> 8) & 0xf); const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 4) & 0xf); const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 0) & 0xf); char swizzle[100]; gen3_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname); sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } static void gen3_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name) { switch (src_type) { case 0: sprintf(name, "R%d", src_nr); assert(src_nr <= 15); break; case 1: if (src_nr < 8) sprintf(name, "T%d", src_nr); else if (src_nr == 8) sprintf(name, "DIFFUSE"); else if (src_nr == 9) sprintf(name, "SPECULAR"); else if (src_nr == 10) sprintf(name, "FOG"); else { assert(0); sprintf(name, "RESERVED"); } break; case 4: sprintf(name, "oC"); assert(src_nr == 0); break; case 5: sprintf(name, "oD"); assert(src_nr == 0); break; default: assert(0); sprintf(name, "RESERVED"); break; } } static void gen3_decode_alu1(uint32_t *data, uint32_t offset, int i, char *instr_prefix, const char *op_name) { char dst[100], src0[100]; gen3_get_instruction_dst(data, i, dst, 1); gen3_get_instruction_src0(data, i, src0); kgem_debug_print(data, offset, i++, "%s: %s %s, %s\n", instr_prefix, op_name, dst, src0); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); } static void gen3_decode_alu2(uint32_t *data, uint32_t offset, int i, char *instr_prefix, const char *op_name) { char dst[100], src0[100], src1[100]; gen3_get_instruction_dst(data, i, dst, 1); gen3_get_instruction_src0(data, i, src0); gen3_get_instruction_src1(data, i, src1); kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s\n", instr_prefix, op_name, dst, src0, src1); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); } static void gen3_decode_alu3(uint32_t *data, uint32_t offset, int i, char *instr_prefix, const char *op_name) { char dst[100], src0[100], src1[100], src2[100]; gen3_get_instruction_dst(data, i, dst, 1); gen3_get_instruction_src0(data, i, src0); gen3_get_instruction_src1(data, i, src1); gen3_get_instruction_src2(data, i, src2); kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix, op_name, dst, src0, src1, src2); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); } static void gen3_decode_tex(uint32_t *data, uint32_t offset, int i, char *instr_prefix, const char *tex_name) { uint32_t t0 = data[i]; uint32_t t1 = data[i + 1]; char dst_name[100]; char addr_name[100]; int sampler_nr; gen3_get_instruction_dst(data, i, dst_name, 0); gen3_get_instruction_addr((t1 >> 24) & 0x7, (t1 >> 17) & 0xf, addr_name); sampler_nr = t0 & 0xf; kgem_debug_print(data, offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix, tex_name, dst_name, sampler_nr, addr_name); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); } static void gen3_decode_dcl(uint32_t *data, uint32_t offset, int i, char *instr_prefix) { uint32_t d0 = data[i]; const char *sampletype; int dcl_nr = (d0 >> 14) & 0xf; const char *dcl_x = d0 & (1 << 10) ? "x" : ""; const char *dcl_y = d0 & (1 << 11) ? "y" : ""; const char *dcl_z = d0 & (1 << 12) ? "z" : ""; const char *dcl_w = d0 & (1 << 13) ? "w" : ""; char dcl_mask[10]; switch ((d0 >> 19) & 0x3) { case 1: sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w); assert (strcmp(dcl_mask, ".")); assert(dcl_nr <= 10); if (dcl_nr < 8) { if (strcmp(dcl_mask, ".x") != 0 && strcmp(dcl_mask, ".xy") != 0 && strcmp(dcl_mask, ".xz") != 0 && strcmp(dcl_mask, ".w") != 0 && strcmp(dcl_mask, ".xyzw") != 0) { assert(0); } kgem_debug_print(data, offset, i++, "%s: DCL T%d%s\n", instr_prefix, dcl_nr, dcl_mask); } else { if (strcmp(dcl_mask, ".xz") == 0) assert(0); else if (strcmp(dcl_mask, ".xw") == 0) assert(0); else if (strcmp(dcl_mask, ".xzw") == 0) assert(0); if (dcl_nr == 8) { kgem_debug_print(data, offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix, dcl_mask); } else if (dcl_nr == 9) { kgem_debug_print(data, offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix, dcl_mask); } else if (dcl_nr == 10) { kgem_debug_print(data, offset, i++, "%s: DCL FOG%s\n", instr_prefix, dcl_mask); } } kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); break; case 3: switch ((d0 >> 22) & 0x3) { case 0: sampletype = "2D"; break; case 1: sampletype = "CUBE"; break; case 2: sampletype = "3D"; break; default: sampletype = "RESERVED"; break; } assert(dcl_nr <= 15); kgem_debug_print(data, offset, i++, "%s: DCL S%d %s\n", instr_prefix, dcl_nr, sampletype); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); break; default: kgem_debug_print(data, offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); } } static void gen3_decode_instruction(uint32_t *data, uint32_t offset, int i, char *instr_prefix) { switch ((data[i] >> 24) & 0x1f) { case 0x0: kgem_debug_print(data, offset, i++, "%s: NOP\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); break; case 0x01: gen3_decode_alu2(data, offset, i, instr_prefix, "ADD"); break; case 0x02: gen3_decode_alu1(data, offset, i, instr_prefix, "MOV"); break; case 0x03: gen3_decode_alu2(data, offset, i, instr_prefix, "MUL"); break; case 0x04: gen3_decode_alu3(data, offset, i, instr_prefix, "MAD"); break; case 0x05: gen3_decode_alu3(data, offset, i, instr_prefix, "DP2ADD"); break; case 0x06: gen3_decode_alu2(data, offset, i, instr_prefix, "DP3"); break; case 0x07: gen3_decode_alu2(data, offset, i, instr_prefix, "DP4"); break; case 0x08: gen3_decode_alu1(data, offset, i, instr_prefix, "FRC"); break; case 0x09: gen3_decode_alu1(data, offset, i, instr_prefix, "RCP"); break; case 0x0a: gen3_decode_alu1(data, offset, i, instr_prefix, "RSQ"); break; case 0x0b: gen3_decode_alu1(data, offset, i, instr_prefix, "EXP"); break; case 0x0c: gen3_decode_alu1(data, offset, i, instr_prefix, "LOG"); break; case 0x0d: gen3_decode_alu2(data, offset, i, instr_prefix, "CMP"); break; case 0x0e: gen3_decode_alu2(data, offset, i, instr_prefix, "MIN"); break; case 0x0f: gen3_decode_alu2(data, offset, i, instr_prefix, "MAX"); break; case 0x10: gen3_decode_alu1(data, offset, i, instr_prefix, "FLR"); break; case 0x11: gen3_decode_alu1(data, offset, i, instr_prefix, "MOD"); break; case 0x12: gen3_decode_alu1(data, offset, i, instr_prefix, "TRC"); break; case 0x13: gen3_decode_alu2(data, offset, i, instr_prefix, "SGE"); break; case 0x14: gen3_decode_alu2(data, offset, i, instr_prefix, "SLT"); break; case 0x15: gen3_decode_tex(data, offset, i, instr_prefix, "TEXLD"); break; case 0x16: gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDP"); break; case 0x17: gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDB"); break; case 0x19: gen3_decode_dcl(data, offset, i, instr_prefix); break; default: kgem_debug_print(data, offset, i++, "%s: unknown\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); kgem_debug_print(data, offset, i++, "%s\n", instr_prefix); break; } } static const char * gen3_decode_compare_func(uint32_t op) { switch (op&0x7) { case 0: return "always"; case 1: return "never"; case 2: return "less"; case 3: return "equal"; case 4: return "lequal"; case 5: return "greater"; case 6: return "notequal"; case 7: return "gequal"; } return ""; } static const char * gen3_decode_stencil_op(uint32_t op) { switch (op&0x7) { case 0: return "keep"; case 1: return "zero"; case 2: return "replace"; case 3: return "incr_sat"; case 4: return "decr_sat"; case 5: return "greater"; case 6: return "incr"; case 7: return "decr"; } return ""; } #if 0 /* part of MODES_4 */ static const char * gen3_decode_logic_op(uint32_t op) { switch (op&0xf) { case 0: return "clear"; case 1: return "nor"; case 2: return "and_inv"; case 3: return "copy_inv"; case 4: return "and_rvrse"; case 5: return "inv"; case 6: return "xor"; case 7: return "nand"; case 8: return "and"; case 9: return "equiv"; case 10: return "noop"; case 11: return "or_inv"; case 12: return "copy"; case 13: return "or_rvrse"; case 14: return "or"; case 15: return "set"; } return ""; } #endif static const char * gen3_decode_blend_fact(uint32_t op) { switch (op&0xf) { case 1: return "zero"; case 2: return "one"; case 3: return "src_colr"; case 4: return "inv_src_colr"; case 5: return "src_alpha"; case 6: return "inv_src_alpha"; case 7: return "dst_alpha"; case 8: return "inv_dst_alpha"; case 9: return "dst_colr"; case 10: return "inv_dst_colr"; case 11: return "src_alpha_sat"; case 12: return "cnst_colr"; case 13: return "inv_cnst_colr"; case 14: return "cnst_alpha"; case 15: return "inv_const_alpha"; } return ""; } static const char * decode_tex_coord_mode(uint32_t mode) { switch (mode&0x7) { case 0: return "wrap"; case 1: return "mirror"; case 2: return "clamp_edge"; case 3: return "cube"; case 4: return "clamp_border"; case 5: return "mirror_once"; } return ""; } static const char * gen3_decode_sample_filter(uint32_t mode) { switch (mode&0x7) { case 0: return "nearest"; case 1: return "linear"; case 2: return "anisotropic"; case 3: return "4x4_1"; case 4: return "4x4_2"; case 5: return "4x4_flat"; case 6: return "6x5_mono"; } return ""; } static int gen3_decode_load_state_immediate_1(struct kgem *kgem, uint32_t offset) { const uint32_t *data = kgem->batch + offset; int len, i, word; kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); len = (data[0] & 0x0000000f) + 2; i = 1; for (word = 0; word <= 8; word++) { if (data[0] & (1 << (4 + word))) { switch (word) { case 0: kgem_debug_print(data, offset, i, "S0: vbo offset: 0x%08x%s\n", data[i]&(~1),data[i]&1?", auto cache invalidate disabled":""); gen3_update_vertex_buffer_addr(kgem, offset + i); break; case 1: kgem_debug_print(data, offset, i, "S1: vertex width: %i, vertex pitch: %i\n", (data[i]>>24)&0x3f,(data[i]>>16)&0x3f); gen3_update_vertex_buffer_pitch(kgem, offset + i); break; case 2: { char buf[200]; int len = 0; int tex_num; for (tex_num = 0; tex_num < 8; tex_num++) { switch((data[i]>>tex_num*4)&0xf) { case 0: len += sprintf(buf + len, "%i=2D ", tex_num); break; case 1: len += sprintf(buf + len, "%i=3D ", tex_num); break; case 2: len += sprintf(buf + len, "%i=4D ", tex_num); break; case 3: len += sprintf(buf + len, "%i=1D ", tex_num); break; case 4: len += sprintf(buf + len, "%i=2D_16 ", tex_num); break; case 5: len += sprintf(buf + len, "%i=4D_16 ", tex_num); break; case 0xf: len += sprintf(buf + len, "%i=NP ", tex_num); break; } } kgem_debug_print(data, offset, i, "S2: texcoord formats: %s\n", buf); gen3_update_vertex_texcoords(kgem, data[i]); } break; case 3: kgem_debug_print(data, offset, i, "S3: not documented\n"); break; case 4: { const char *cullmode = ""; const char *vfmt_xyzw = ""; switch((data[i]>>13)&0x3) { case 0: cullmode = "both"; break; case 1: cullmode = "none"; break; case 2: cullmode = "cw"; break; case 3: cullmode = "ccw"; break; } switch(data[i] & (7<<6 | 1<<2)) { case 1<<6: vfmt_xyzw = "XYZ,"; break; case 2<<6: vfmt_xyzw = "XYZW,"; break; case 3<<6: vfmt_xyzw = "XY,"; break; case 4<<6: vfmt_xyzw = "XYW,"; break; case 1<<6 | 1<<2: vfmt_xyzw = "XYZF,"; break; case 2<<6 | 1<<2: vfmt_xyzw = "XYZWF,"; break; case 3<<6 | 1<<2: vfmt_xyzw = "XYF,"; break; case 4<<6 | 1<<2: vfmt_xyzw = "XYWF,"; break; } kgem_debug_print(data, offset, i, "S4: point_width=%i, line_width=%.1f," "%s%s%s%s%s cullmode=%s, vfmt=%s%s%s%s%s%s%s%s " "%s%s%s\n", (data[i]>>23)&0x1ff, ((data[i]>>19)&0xf) / 2.0, data[i]&(0xf<<15)?" flatshade=":"", data[i]&(1<<18)?"Alpha,":"", data[i]&(1<<17)?"Fog,":"", data[i]&(1<<16)?"Specular,":"", data[i]&(1<<15)?"Color,":"", cullmode, data[i]&(1<<12)?"PointWidth,":"", data[i]&(1<<11)?"SpecFog,":"", data[i]&(1<<10)?"Color,":"", data[i]&(1<<9)?"DepthOfs,":"", vfmt_xyzw, data[i]&(1<<9)?"FogParam,":"", data[i]&(1<<5)?"force default diffuse, ":"", data[i]&(1<<4)?"force default specular, ":"", data[i]&(1<<3)?"local depth ofs enable, ":"", data[i]&(1<<1)?"point sprite enable, ":"", data[i]&(1<<0)?"line AA enable, ":""); gen3_update_vertex_elements(kgem, data[i]); break; } case 5: { kgem_debug_print(data, offset, i, "S5:%s%s%s%s%s" "%s%s%s%s stencil_ref=0x%x, stencil_test=%s, " "stencil_fail=%s, stencil_pass_z_fail=%s, " "stencil_pass_z_pass=%s, %s%s%s%s\n", data[i]&(0xf<<28)?" write_disable=":"", data[i]&(1<<31)?"Alpha,":"", data[i]&(1<<30)?"Red,":"", data[i]&(1<<29)?"Green,":"", data[i]&(1<<28)?"Blue,":"", data[i]&(1<<27)?" force default point size,":"", data[i]&(1<<26)?" last pixel enable,":"", data[i]&(1<<25)?" global depth ofs enable,":"", data[i]&(1<<24)?" fog enable,":"", (data[i]>>16)&0xff, gen3_decode_compare_func(data[i]>>13), gen3_decode_stencil_op(data[i]>>10), gen3_decode_stencil_op(data[i]>>7), gen3_decode_stencil_op(data[i]>>4), data[i]&(1<<3)?"stencil write enable, ":"", data[i]&(1<<2)?"stencil test enable, ":"", data[i]&(1<<1)?"color dither enable, ":"", data[i]&(1<<0)?"logicop enable, ":""); } break; case 6: kgem_debug_print(data, offset, i, "S6: %salpha_test=%s, alpha_ref=0x%x, " "depth_test=%s, %ssrc_blnd_fct=%s, dst_blnd_fct=%s, " "%s%stristrip_provoking_vertex=%i\n", data[i]&(1<<31)?"alpha test enable, ":"", gen3_decode_compare_func(data[i]>>28), data[i]&(0xff<<20), gen3_decode_compare_func(data[i]>>16), data[i]&(1<<15)?"cbuf blend enable, ":"", gen3_decode_blend_fact(data[i]>>8), gen3_decode_blend_fact(data[i]>>4), data[i]&(1<<3)?"depth write enable, ":"", data[i]&(1<<2)?"cbuf write enable, ":"", data[i]&(0x3)); break; case 7: kgem_debug_print(data, offset, i, "S7: depth offset constant: 0x%08x\n", data[i]); break; } i++; } } assert(len == i); return len; } static int gen3_decode_3d_1d(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; unsigned int len, i, c, idx, word, map, sampler, instr; const char *format, *zformat, *type; uint32_t opcode; static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes_3d_1d[] = { { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, }, *opcode_3d_1d; opcode = (data[0] & 0x00ff0000) >> 16; switch (opcode) { case 0x07: /* This instruction is unusual. A 0 length means just 1 DWORD instead of * 2. The 0 length is specified in one place to be unsupported, but * stated to be required in another, and 0 length LOAD_INDIRECTs appear * to cause no harm at least. */ kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n"); len = (data[0] & 0x000000ff) + 1; i = 1; if (data[0] & (0x01 << 8)) { kgem_debug_print(data, offset, i++, "SIS.0\n"); kgem_debug_print(data, offset, i++, "SIS.1\n"); } if (data[0] & (0x02 << 8)) { kgem_debug_print(data, offset, i++, "DIS.0\n"); } if (data[0] & (0x04 << 8)) { kgem_debug_print(data, offset, i++, "SSB.0\n"); kgem_debug_print(data, offset, i++, "SSB.1\n"); } if (data[0] & (0x08 << 8)) { kgem_debug_print(data, offset, i++, "MSB.0\n"); kgem_debug_print(data, offset, i++, "MSB.1\n"); } if (data[0] & (0x10 << 8)) { kgem_debug_print(data, offset, i++, "PSP.0\n"); kgem_debug_print(data, offset, i++, "PSP.1\n"); } if (data[0] & (0x20 << 8)) { kgem_debug_print(data, offset, i++, "PSC.0\n"); kgem_debug_print(data, offset, i++, "PSC.1\n"); } assert(len == i); return len; case 0x04: return gen3_decode_load_state_immediate_1(kgem, offset); case 0x03: kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n"); len = (data[0] & 0x0000000f) + 2; i = 1; for (word = 6; word <= 14; word++) { if (data[0] & (1 << word)) { if (word == 6) kgem_debug_print(data, offset, i++, "TBCF\n"); else if (word >= 7 && word <= 10) { kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7); kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7); } else if (word >= 11 && word <= 14) { kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n", word - 11, data[i]&0xfffffffe, data[i]&1?"use fence":""); i++; kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n", word - 11, data[i]>>21, (data[i]>>10)&0x3ff, data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):""); i++; kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n", word - 11, ((data[i]>>21) + 1)*4); i++; kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11); kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11); } } } assert(len == i); return len; case 0x00: kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n"); len = (data[0] & 0x0000003f) + 2; kgem_debug_print(data, offset, 1, "mask\n"); i = 2; for (map = 0; map <= 15; map++) { if (data[1] & (1 << map)) { int width, height, pitch, dword; struct drm_i915_gem_relocation_entry *reloc; const char *tiling; reloc = kgem_debug_get_reloc_entry(kgem, &data[i] - kgem->batch); assert(reloc->target_handle); dword = data[i]; kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s, handle=%d\n", map, dword&(1<<31)?"untrusted surface, ":"", dword&(1<<1)?"vertical line stride enable, ":"", dword&(1<<0)?"vertical ofs enable, ":"", reloc->target_handle); dword = data[i]; width = ((dword >> 10) & ((1 << 11) - 1))+1; height = ((dword >> 21) & ((1 << 11) - 1))+1; tiling = "none"; if (dword & (1 << 2)) tiling = "fenced"; else if (dword & (1 << 1)) tiling = dword & (1 << 0) ? "Y" : "X"; type = " BAD"; format = " (invalid)"; switch ((dword>>7) & 0x7) { case 1: type = "8"; switch ((dword>>3) & 0xf) { case 0: format = "I"; break; case 1: format = "L"; break; case 4: format = "A"; break; case 5: format = " mono"; break; } break; case 2: type = "16"; switch ((dword>>3) & 0xf) { case 0: format = " rgb565"; break; case 1: format = " argb1555"; break; case 2: format = " argb4444"; break; case 3: format = " ay88"; break; case 5: format = " 88dvdu"; break; case 6: format = " bump655"; break; case 7: format = "I"; break; case 8: format = "L"; break; case 9: format = "A"; break; } break; case 3: type = "32"; switch ((dword>>3) & 0xf) { case 0: format = " argb8888"; break; case 1: format = " abgr8888"; break; case 2: format = " xrgb8888"; break; case 3: format = " xbgr8888"; break; case 4: format = " qwvu8888"; break; case 5: format = " axvu8888"; break; case 6: format = " lxvu8888"; break; case 7: format = " xlvu8888"; break; case 8: format = " argb2101010"; break; case 9: format = " abgr2101010"; break; case 10: format = " awvu2101010"; break; case 11: format = " gr1616"; break; case 12: format = " vu1616"; break; case 13: format = " xI824"; break; case 14: format = " xA824"; break; case 15: format = " xL824"; break; } break; case 5: type = "422"; switch ((dword>>3) & 0xf) { case 0: format = " yuv_swapy"; break; case 1: format = " yuv"; break; case 2: format = " yuv_swapuv"; break; case 3: format = " yuv_swapuvy"; break; } break; case 6: type = "compressed"; switch ((dword>>3) & 0x7) { case 0: format = " dxt1"; break; case 1: format = " dxt2_3"; break; case 2: format = " dxt4_5"; break; case 3: format = " fxt1"; break; case 4: format = " dxt1_rb"; break; } break; case 7: type = "4b indexed"; switch ((dword>>3) & 0xf) { case 7: format = " argb8888"; break; } break; default: format = "BAD"; break; } dword = data[i]; kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n", map, width, height, type, format, tiling, dword&(1<<9)?" palette select":""); dword = data[i]; pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1); kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n", map, pitch, (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f, dword&(1<<8)?"miplayout legacy":"miplayout right"); } } assert(len == i); return len; case 0x06: kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); len = (data[0] & 0x000000ff) + 2; i = 2; for (c = 0; c <= 31; c++) { if (data[1] & (1 << c)) { kgem_debug_print(data, offset, i, "C%d.X = %f\n", c, int_as_float(data[i])); i++; kgem_debug_print(data, offset, i, "C%d.Y = %f\n", c, int_as_float(data[i])); i++; kgem_debug_print(data, offset, i, "C%d.Z = %f\n", c, int_as_float(data[i])); i++; kgem_debug_print(data, offset, i, "C%d.W = %f\n", c, int_as_float(data[i])); i++; } } assert(len == i); return len; case 0x05: kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); len = (data[0] & 0x000000ff) + 2; assert(((len-1) % 3) == 0); assert(len <= 370); i = 1; for (instr = 0; instr < (len - 1) / 3; instr++) { char instr_prefix[10]; sprintf(instr_prefix, "PS%03d", instr); gen3_decode_instruction(data, offset, i, instr_prefix); i += 3; } return len; case 0x01: kgem_debug_print(data, offset, 0, "3DSTATE_SAMPLER_STATE\n"); kgem_debug_print(data, offset, 1, "mask\n"); len = (data[0] & 0x0000003f) + 2; i = 2; for (sampler = 0; sampler <= 15; sampler++) { if (data[1] & (1 << sampler)) { uint32_t dword; const char *mip_filter = ""; dword = data[i]; switch ((dword>>20)&0x3) { case 0: mip_filter = "none"; break; case 1: mip_filter = "nearest"; break; case 3: mip_filter = "linear"; break; } kgem_debug_print(data, offset, i++, "sampler %d SS2:%s%s%s " "base_mip_level=%i, mip_filter=%s, mag_filter=%s, min_filter=%s " "lod_bias=%.2f,%s max_aniso=%i, shadow_func=%s\n", sampler, dword&(1<<31)?" reverse gamma,":"", dword&(1<<30)?" packed2planar,":"", dword&(1<<29)?" colorspace conversion,":"", (dword>>22)&0x1f, mip_filter, gen3_decode_sample_filter(dword>>17), gen3_decode_sample_filter(dword>>14), ((dword>>5)&0x1ff)/(0x10*1.0), dword&(1<<4)?" shadow,":"", dword&(1<<3)?4:2, gen3_decode_compare_func(dword)); dword = data[i]; kgem_debug_print(data, offset, i++, "sampler %d SS3: min_lod=%.2f,%s " "tcmode_x=%s, tcmode_y=%s, tcmode_z=%s,%s texmap_idx=%i,%s\n", sampler, ((dword>>24)&0xff)/(0x10*1.0), dword&(1<<17)?" kill pixel enable,":"", decode_tex_coord_mode(dword>>12), decode_tex_coord_mode(dword>>9), decode_tex_coord_mode(dword>>6), dword&(1<<5)?" normalized coords,":"", (dword>>1)&0xf, dword&(1<<0)?" deinterlacer,":""); kgem_debug_print(data, offset, i++, "sampler %d SS4: border color\n", sampler); } } assert(len == i); return len; case 0x85: len = (data[0] & 0x0000000f) + 2; assert(len == 2); kgem_debug_print(data, offset, 0, "3DSTATE_DEST_BUFFER_VARIABLES\n"); switch ((data[1] >> 8) & 0xf) { case 0x0: format = "g8"; break; case 0x1: format = "x1r5g5b5"; break; case 0x2: format = "r5g6b5"; break; case 0x3: format = "a8r8g8b8"; break; case 0x4: format = "ycrcb_swapy"; break; case 0x5: format = "ycrcb_normal"; break; case 0x6: format = "ycrcb_swapuv"; break; case 0x7: format = "ycrcb_swapuvy"; break; case 0x8: format = "a4r4g4b4"; break; case 0x9: format = "a1r5g5b5"; break; case 0xa: format = "a2r10g10b10"; break; default: format = "BAD"; break; } switch ((data[1] >> 2) & 0x3) { case 0x0: zformat = "u16"; break; case 0x1: zformat = "f16"; break; case 0x2: zformat = "u24x8"; break; default: zformat = "BAD"; break; } kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n", format, zformat, (data[1] & (1 << 31)) ? "en" : "dis"); return len; case 0x8e: { const char *name, *tiling; len = (data[0] & 0x0000000f) + 2; assert(len == 3); switch((data[1] >> 24) & 0x7) { case 0x3: name = "color"; break; case 0x7: name = "depth"; break; default: name = "unknown"; break; } tiling = "none"; if (data[1] & (1 << 23)) tiling = "fenced"; else if (data[1] & (1 << 22)) tiling = data[1] & (1 << 21) ? "Y" : "X"; kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n"); kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff); kgem_debug_print(data, offset, 2, "address\n"); return len; } case 0x81: len = (data[0] & 0x0000000f) + 2; assert(len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "(%d,%d)\n", data[1] & 0xffff, data[1] >> 16); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); return len; case 0x80: len = (data[0] & 0x0000000f) + 2; assert(len == 5); kgem_debug_print(data, offset, 0, "3DSTATE_DRAWING_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "%s\n", data[1]&(1<<30)?"depth ofs disabled ":""); kgem_debug_print(data, offset, 2, "(%d,%d)\n", data[2] & 0xffff, data[2] >> 16); kgem_debug_print(data, offset, 3, "(%d,%d)\n", data[3] & 0xffff, data[3] >> 16); kgem_debug_print(data, offset, 4, "(%d,%d)\n", (int16_t)(data[4] & 0xffff), (int16_t)(data[4] >> 16)); return len; case 0x9c: len = (data[0] & 0x0000000f) + 2; assert(len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_CLEAR_PARAMETERS\n"); kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n", data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT", data[1]&(1<<2)?"color,":"", data[1]&(1<<1)?"depth,":"", data[1]&(1<<0)?"stencil,":""); kgem_debug_print(data, offset, 2, "clear color\n"); kgem_debug_print(data, offset, 3, "clear depth/stencil\n"); kgem_debug_print(data, offset, 4, "color value (rgba8888)\n"); kgem_debug_print(data, offset, 5, "depth value %f\n", int_as_float(data[5])); kgem_debug_print(data, offset, 6, "clear stencil\n"); return len; } for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) { opcode_3d_1d = &opcodes_3d_1d[idx]; if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) { len = (data[0] & 0xf) + 2; kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name); for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode); assert(0); return 1; } #define VERTEX_OUT(fmt, ...) do { \ kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ i++; \ } while (0) static int gen3_decode_3d_primitive(struct kgem *kgem, uint32_t offset) { uint32_t *data = kgem->batch + offset; char immediate = (data[0] & (1 << 23)) == 0; unsigned int len, i, ret; const char *primtype; unsigned int vertex = 0; switch ((data[0] >> 18) & 0xf) { case 0x0: primtype = "TRILIST"; break; case 0x1: primtype = "TRISTRIP"; break; case 0x2: primtype = "TRISTRIP_REVERSE"; break; case 0x3: primtype = "TRIFAN"; break; case 0x4: primtype = "POLYGON"; break; case 0x5: primtype = "LINELIST"; break; case 0x6: primtype = "LINESTRIP"; break; case 0x7: primtype = "RECTLIST"; break; case 0x8: primtype = "POINTLIST"; break; case 0x9: primtype = "DIB"; break; case 0xa: primtype = "CLEAR_RECT"; assert(0); break; default: primtype = "unknown"; break; } gen3_update_vertex_elements_offsets(kgem); /* XXX: 3DPRIM_DIB not supported */ if (immediate) { len = (data[0] & 0x0003ffff) + 2; kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype); for (i = 1; i < len; ) { ErrorF(" [%d]: ", vertex); i += inline_vertex_out(kgem, data + i) / sizeof(uint32_t); ErrorF("\n"); vertex++; } ret = len; } else { /* indirect vertices */ len = data[0] & 0x0000ffff; /* index count */ if (data[0] & (1 << 17)) { /* random vertex access */ kgem_debug_print(data, offset, 0, "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); assert(0); if (len == 0) { /* vertex indices continue until 0xffff is found */ } else { /* fixed size vertex index buffer */ } ret = (len + 1) / 2 + 1; goto out; } else { /* sequential vertex access */ vertex = data[1] & 0xffff; kgem_debug_print(data, offset, 0, "3DPRIMITIVE sequential indirect %s, %d starting from " "%d\n", primtype, len, vertex); kgem_debug_print(data, offset, 1, " start\n"); for (i = 0; i < len; i++) { ErrorF(" [%d]: ", vertex); indirect_vertex_out(kgem, vertex++); ErrorF("\n"); } ret = 2; goto out; } } out: return ret; } int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, { 0x0d, 1, 1, "3DSTATE_MODES_4" }, { 0x0c, 1, 1, "3DSTATE_MODES_5" }, { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, }; uint32_t *data = kgem->batch + offset; uint32_t opcode; unsigned int idx; opcode = (data[0] & 0x1f000000) >> 24; switch (opcode) { case 0x1f: return gen3_decode_3d_primitive(kgem, offset); case 0x1d: return gen3_decode_3d_1d(kgem, offset); case 0x1c: return gen3_decode_3d_1c(kgem, offset); } for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) { if (opcode == opcodes[idx].opcode) { unsigned int len = 1, i; kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name); if (opcodes[idx].max_len > 1) { len = (data[0] & 0xff) + 2; assert(len >= opcodes[idx].min_len || len <= opcodes[idx].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } } kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode); return 1; } void kgem_gen3_finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen4.c000066400000000000000000000444041267532330400250230ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "gen4_render.h" #include "kgem_debug.h" static struct state { struct vertex_buffer { int handle; void *base; const char *ptr; int pitch; struct kgem_bo *current; } vb[33]; struct vertex_elements { int buffer; int offset; bool valid; uint32_t type; uint8_t swizzle[4]; } ve[33]; int num_ve; struct dynamic_state { struct kgem_bo *current; void *base, *ptr; } dynamic_state; } state; static void gen4_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) { uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch); struct kgem_bo *bo = NULL; void *base, *ptr; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == reloc) break; assert(i < kgem->nreloc); reloc = kgem->reloc[i].target_handle; if (reloc == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == reloc) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } ptr = (char *)base + kgem->reloc[i].delta; i = data[0] >> 27; state.vb[i].current = bo; state.vb[i].base = base; state.vb[i].ptr = ptr; state.vb[i].pitch = data[0] & 0x7ff; } static uint32_t get_ve_component(uint32_t data, int component) { return (data >> (16 + (3 - component) * 4)) & 0x7; } static void gen4_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) { state.ve[id].buffer = data[0] >> 27; state.ve[id].valid = !!(data[0] & (1 << 26)); state.ve[id].type = (data[0] >> 16) & 0x1ff; state.ve[id].offset = data[0] & 0x7ff; state.ve[id].swizzle[0] = get_ve_component(data[1], 0); state.ve[id].swizzle[1] = get_ve_component(data[1], 1); state.ve[id].swizzle[2] = get_ve_component(data[1], 2); state.ve[id].swizzle[3] = get_ve_component(data[1], 3); } static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) { int c; ErrorF("("); for (c = 0; c < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%d", v[c]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) { int c, o; ErrorF("("); for (c = o = 0; c < 4 && o < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%f", f[o++]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void ve_out(const struct vertex_elements *ve, const void *ptr) { switch (ve->type) { case GEN4_SURFACEFORMAT_R32_FLOAT: vertices_float_out(ve, ptr, 1); break; case GEN4_SURFACEFORMAT_R32G32_FLOAT: vertices_float_out(ve, ptr, 2); break; case GEN4_SURFACEFORMAT_R32G32B32_FLOAT: vertices_float_out(ve, ptr, 3); break; case GEN4_SURFACEFORMAT_R32G32B32A32_FLOAT: vertices_float_out(ve, ptr, 4); break; case GEN4_SURFACEFORMAT_R16_SINT: vertices_sint16_out(ve, ptr, 1); break; case GEN4_SURFACEFORMAT_R16G16_SINT: vertices_sint16_out(ve, ptr, 2); break; case GEN4_SURFACEFORMAT_R16G16B16A16_SINT: vertices_sint16_out(ve, ptr, 4); break; case GEN4_SURFACEFORMAT_R16_SSCALED: vertices_sint16_out(ve, ptr, 1); break; case GEN4_SURFACEFORMAT_R16G16_SSCALED: vertices_sint16_out(ve, ptr, 2); break; case GEN4_SURFACEFORMAT_R16G16B16A16_SSCALED: vertices_sint16_out(ve, ptr, 4); break; } } static void indirect_vertex_out(struct kgem *kgem, uint32_t v) { int i = 0; do { const struct vertex_elements *ve = &state.ve[i]; const struct vertex_buffer *vb = &state.vb[ve->buffer]; const void *ptr = vb->ptr + v * vb->pitch + ve->offset; if (!ve->valid) continue; ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); } static void primitive_out(struct kgem *kgem, uint32_t *data) { int n; assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ for (n = 0; n < data[1]; n++) { int v = data[2] + n; ErrorF(" [%d:%d] = ", n, v); indirect_vertex_out(kgem, v); ErrorF("\n"); } } static void state_base_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state base address 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state base not updated\n", name); } static void state_max_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] == 1) kgem_debug_print(data, offset, index, "%s state upper bound disabled\n", name); else if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state upper bound 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state upper bound not updated\n", name); } static const char * get_965_surfacetype(unsigned int surfacetype) { switch (surfacetype) { case 0: return "1D"; case 1: return "2D"; case 2: return "3D"; case 3: return "CUBE"; case 4: return "BUFFER"; case 7: return "NULL"; default: return "unknown"; } } static const char * get_965_depthformat(unsigned int depthformat) { switch (depthformat) { case 0: return "s8_z24float"; case 1: return "z32float"; case 2: return "z24s8"; case 5: return "z16"; default: return "unknown"; } } static const char * get_965_element_component(uint32_t data, int component) { uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; switch (component_control) { case 0: return "nostore"; case 1: switch (component) { case 0: return "X"; case 1: return "Y"; case 2: return "Z"; case 3: return "W"; default: return "fail"; } case 2: return "0.0"; case 3: return "1.0"; case 4: return "0x1"; case 5: return "VID"; default: return "fail"; } } static const char * get_965_prim_type(uint32_t data) { uint32_t primtype = (data >> 10) & 0x1f; switch (primtype) { case 0x01: return "point list"; case 0x02: return "line list"; case 0x03: return "line strip"; case 0x04: return "tri list"; case 0x05: return "tri strip"; case 0x06: return "tri fan"; case 0x07: return "quad list"; case 0x08: return "quad strip"; case 0x09: return "line list adj"; case 0x0a: return "line strip adj"; case 0x0b: return "tri list adj"; case 0x0c: return "tri strip adj"; case 0x0d: return "tri strip reverse"; case 0x0e: return "polygon"; case 0x0f: return "rect list"; case 0x10: return "line loop"; case 0x11: return "point list bf"; case 0x12: return "line strip cont"; case 0x13: return "line strip bf"; case 0x14: return "line strip cont bf"; case 0x15: return "tri fan no stipple"; default: return "fail"; } } #if 0 struct reloc { struct kgem_bo *bo; void *base; }; static void * get_reloc(struct kgem *kgem, void *base, const uint32_t *reloc, struct reloc *r) { uint32_t delta = *reloc; memset(r, 0, sizeof(*r)); if (base == 0) { uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); struct kgem_bo *bo = NULL; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == handle) break; assert(i < kgem->nreloc); handle = kgem->reloc[i].target_handle; delta = kgem->reloc[i].delta; if (handle == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == handle) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); r->bo = bo; r->base = base; } } return (char *)base + delta; } #endif int kgem_gen4_decode_3d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x6000, 3, 3, "URB_FENCE" }, { 0x6001, 2, 2, "CS_URB_FENCE" }, { 0x6002, 2, 2, "CONSTANT_BUFFER" }, { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, { 0x6102, 2, 2 , "STATE_SIP" }, { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" }, { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, { 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" }, { 0x7910, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x7b00, 6, 6, "3DPRIMITIVE" }, { 0x7805, 3, 3, "3DSTATE_URB" }, { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" }, { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, { 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" }, { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, }; uint32_t *data = kgem->batch + offset; uint32_t op; unsigned int len; int i; const char *desc1 = NULL; len = (data[0] & 0xff) + 2; op = (data[0] & 0xffff0000) >> 16; switch (op) { case 0x6000: assert(len == 3); kgem_debug_print(data, offset, 0, "URB_FENCE: %s%s%s%s%s%s\n", (data[0] >> 13) & 1 ? "cs " : "", (data[0] >> 12) & 1 ? "vfe " : "", (data[0] >> 11) & 1 ? "sf " : "", (data[0] >> 10) & 1 ? "clip " : "", (data[0] >> 9) & 1 ? "gs " : "", (data[0] >> 8) & 1 ? "vs " : ""); kgem_debug_print(data, offset, 1, "vs fence: %d, gs_fence: %d, clip_fence: %d\n", data[1] & 0x3ff, (data[1] >> 10) & 0x3ff, (data[1] >> 20) & 0x3ff); kgem_debug_print(data, offset, 2, "sf fence: %d, vfe_fence: %d, cs_fence: %d\n", data[2] & 0x3ff, (data[2] >> 10) & 0x3ff, (data[2] >> 20) & 0x7ff); return len; case 0x6001: kgem_debug_print(data, offset, 0, "CS_URB_STATE\n"); kgem_debug_print(data, offset, 1, "entry_size: %d [%d bytes], n_entries: %d\n", (data[1] >> 4) & 0x1f, (((data[1] >> 4) & 0x1f) + 1) * 64, data[1] & 0x7); return len; case 0x6002: kgem_debug_print(data, offset, 0, "CONSTANT_BUFFER: %s\n", (data[0] >> 8) & 1 ? "valid" : "invalid"); kgem_debug_print(data, offset, 1, "offset: 0x%08x, length: %d bytes\n", data[1] & ~0x3f, ((data[1] & 0x3f) + 1) * 64); return len; case 0x6101: i = 0; kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); assert(len == 6); state_base_out(data, offset, i++, "general"); state_base_out(data, offset, i++, "surface"); state_base_out(data, offset, i++, "media"); state_max_out(data, offset, i++, "general"); state_max_out(data, offset, i++, "media"); return len; case 0x7801: assert(len == 6); kgem_debug_print(data, offset, 0, "3DSTATE_BINDING_TABLE_POINTERS\n"); kgem_debug_print(data, offset, 1, "VS binding table\n"); kgem_debug_print(data, offset, 2, "GS binding table\n"); kgem_debug_print(data, offset, 3, "CLIP binding table\n"); kgem_debug_print(data, offset, 4, "SF binding table\n"); kgem_debug_print(data, offset, 5, "WM binding table\n"); return len; case 0x7808: assert((len - 1) % 4 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); for (i = 1; i < len;) { gen4_update_vertex_buffer(kgem, data + i); kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", data[i] >> 27, data[i] & (1 << 20) ? "random" : "sequential", data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i++, "buffer address\n"); kgem_debug_print(data, offset, i++, "max index\n"); kgem_debug_print(data, offset, i++, "mbz\n"); } return len; case 0x7809: assert((len + 1) % 2 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); memset(state.ve, 0, sizeof(state.ve)); /* XXX? */ for (i = 1; i < len;) { gen4_update_vertex_elements(kgem, (i - 1)/2, data + i); kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, " "src offset 0x%04x bytes\n", data[i] >> 27, data[i] & (1 << 26) ? "" : "in", (data[i] >> 16) & 0x1ff, data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), " "dst offset 0x%02x bytes\n", get_965_element_component(data[i], 0), get_965_element_component(data[i], 1), get_965_element_component(data[i], 2), get_965_element_component(data[i], 3), (data[i] & 0xff) * 4); i++; } state.num_ve = (len - 1) / 2; /* XXX? */ return len; case 0x780a: assert(len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); kgem_debug_print(data, offset, 1, "beginning buffer address\n"); kgem_debug_print(data, offset, 2, "ending buffer address\n"); return len; case 0x7900: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_DRAWING_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "top left: %d,%d\n", data[1] & 0xffff, (data[1] >> 16) & 0xffff); kgem_debug_print(data, offset, 2, "bottom right: %d,%d\n", data[2] & 0xffff, (data[2] >> 16) & 0xffff); kgem_debug_print(data, offset, 3, "origin: %d,%d\n", (int)data[3] & 0xffff, ((int)data[3] >> 16) & 0xffff); return len; case 0x7905: assert(len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_BUFFER\n"); kgem_debug_print(data, offset, 1, "%s, %s, pitch = %d bytes, %stiled, HiZ %d, Separate Stencil %d\n", get_965_surfacetype(data[1] >> 29), get_965_depthformat((data[1] >> 18) & 0x7), (data[1] & 0x0001ffff) + 1, data[1] & (1 << 27) ? "" : "not ", (data[1] & (1 << 22)) != 0, (data[1] & (1 << 21)) != 0); kgem_debug_print(data, offset, 2, "depth offset\n"); kgem_debug_print(data, offset, 3, "%dx%d\n", ((data[3] & 0x0007ffc0) >> 6) + 1, ((data[3] & 0xfff80000) >> 19) + 1); kgem_debug_print(data, offset, 4, "volume depth\n"); kgem_debug_print(data, offset, 5, "\n"); kgem_debug_print(data, offset, 6, "\n"); return len; case 0x7a00: assert(len == 4 || len == 5); switch ((data[1] >> 14) & 0x3) { case 0: desc1 = "no write"; break; case 1: desc1 = "qword write"; break; case 2: desc1 = "PS_DEPTH_COUNT write"; break; case 3: desc1 = "TIMESTAMP write"; break; } kgem_debug_print(data, offset, 0, "PIPE_CONTROL\n"); kgem_debug_print(data, offset, 1, "%s, %scs stall, %stlb invalidate, " "%ssync gfdt, %sdepth stall, %sRC write flush, " "%sinst flush, %sTC flush\n", desc1, data[1] & (1 << 20) ? "" : "no ", data[1] & (1 << 18) ? "" : "no ", data[1] & (1 << 17) ? "" : "no ", data[1] & (1 << 13) ? "" : "no ", data[1] & (1 << 12) ? "" : "no ", data[1] & (1 << 11) ? "" : "no ", data[1] & (1 << 10) ? "" : "no "); if (len == 5) { kgem_debug_print(data, offset, 2, "destination address\n"); kgem_debug_print(data, offset, 3, "immediate dword low\n"); kgem_debug_print(data, offset, 4, "immediate dword high\n"); } else { for (i = 2; i < len; i++) { kgem_debug_print(data, offset, i, "\n"); } } return len; case 0x7b00: assert(len == 6); kgem_debug_print(data, offset, 0, "3DPRIMITIVE: %s %s\n", get_965_prim_type(data[0]), (data[0] & (1 << 15)) ? "random" : "sequential"); kgem_debug_print(data, offset, 1, "vertex count\n"); kgem_debug_print(data, offset, 2, "start vertex\n"); kgem_debug_print(data, offset, 3, "instance count\n"); kgem_debug_print(data, offset, 4, "start instance\n"); kgem_debug_print(data, offset, 5, "index bias\n"); primitive_out(kgem, data); return len; } /* For the rest, just dump the bytes */ for (i = 0; i < ARRAY_SIZE(opcodes); i++) if (op == opcodes[i].opcode) break; assert(i < ARRAY_SIZE(opcodes)); len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); if (opcodes[i].max_len > 1) { len = (data[0] & 0xff) + 2; assert(len >= opcodes[i].min_len && len <= opcodes[i].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } void kgem_gen4_finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen5.c000066400000000000000000000434551267532330400250310ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "gen5_render.h" #include "kgem_debug.h" static struct state { struct vertex_buffer { int handle; void *base; int size; const char *ptr; int pitch; struct kgem_bo *current; } vb[17]; struct vertex_elements { int buffer; int offset; bool valid; uint32_t type; uint8_t swizzle[4]; } ve[17]; int num_ve; struct dynamic_state { struct kgem_bo *current; void *base, *ptr; } dynamic_state; } state; static void gen5_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) { struct drm_i915_gem_relocation_entry *reloc; struct kgem_bo *bo = NULL; void *base, *ptr; int i, size; reloc = kgem_debug_get_reloc_entry(kgem, &data[1] - kgem->batch); if (reloc->target_handle == -1) { base = kgem->batch; size = kgem->nbatch * sizeof(uint32_t); } else { bo = kgem_debug_get_bo_for_reloc_entry(kgem, reloc); base = kgem_bo_map__debug(kgem, bo); size = kgem_bo_size(bo); } ptr = (char *)base + reloc->delta; i = data[0] >> 27; state.vb[i].handle = reloc->target_handle; state.vb[i].current = bo; state.vb[i].base = base; state.vb[i].ptr = ptr; state.vb[i].pitch = data[0] & 0x7ff; state.vb[i].size = size; } static uint32_t get_ve_component(uint32_t data, int component) { return (data >> (16 + (3 - component) * 4)) & 0x7; } static void gen5_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) { state.ve[id].buffer = data[0] >> 27; state.ve[id].valid = !!(data[0] & (1 << 26)); state.ve[id].type = (data[0] >> 16) & 0x1ff; state.ve[id].offset = data[0] & 0x7ff; state.ve[id].swizzle[0] = get_ve_component(data[1], 0); state.ve[id].swizzle[1] = get_ve_component(data[1], 1); state.ve[id].swizzle[2] = get_ve_component(data[1], 2); state.ve[id].swizzle[3] = get_ve_component(data[1], 3); } static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) { int c, o; ErrorF("("); for (c = o = 0; c < 4 && o < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%d", v[o++]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (o < max) ErrorF(", "); } ErrorF(")"); } static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) { int c, o; ErrorF("("); for (c = o = 0; c < 4 && o < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%f", f[o++]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (o < max) ErrorF(", "); } ErrorF(")"); } static void ve_out(const struct vertex_elements *ve, const void *ptr) { switch (ve->type) { case GEN5_SURFACEFORMAT_R32_FLOAT: vertices_float_out(ve, ptr, 1); break; case GEN5_SURFACEFORMAT_R32G32_FLOAT: vertices_float_out(ve, ptr, 2); break; case GEN5_SURFACEFORMAT_R32G32B32_FLOAT: vertices_float_out(ve, ptr, 3); break; case GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT: vertices_float_out(ve, ptr, 4); break; case GEN5_SURFACEFORMAT_R16_SINT: vertices_sint16_out(ve, ptr, 1); break; case GEN5_SURFACEFORMAT_R16G16_SINT: vertices_sint16_out(ve, ptr, 2); break; case GEN5_SURFACEFORMAT_R16G16B16A16_SINT: vertices_sint16_out(ve, ptr, 4); break; case GEN5_SURFACEFORMAT_R16_SSCALED: vertices_sint16_out(ve, ptr, 1); break; case GEN5_SURFACEFORMAT_R16G16_SSCALED: vertices_sint16_out(ve, ptr, 2); break; case GEN5_SURFACEFORMAT_R16G16B16A16_SSCALED: vertices_sint16_out(ve, ptr, 4); break; } } static void indirect_vertex_out(struct kgem *kgem, uint32_t v) { int i = 1; do { const struct vertex_elements *ve = &state.ve[i]; const struct vertex_buffer *vb = &state.vb[ve->buffer]; const void *ptr = vb->ptr + v * vb->pitch + ve->offset; if (!ve->valid) continue; assert(vb->pitch); assert(ve->offset + v*vb->pitch < vb->size); ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); } static void primitive_out(struct kgem *kgem, uint32_t *data) { int n; assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ for (n = 0; n < data[1]; n++) { int v = data[2] + n; ErrorF(" [%d:%d] = ", n, v); indirect_vertex_out(kgem, v); ErrorF("\n"); } } static void state_base_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state base address 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state base not updated\n", name); } static void state_max_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] == 1) kgem_debug_print(data, offset, index, "%s state upper bound disabled\n", name); else if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state upper bound 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state upper bound not updated\n", name); } static const char * get_965_surfacetype(unsigned int surfacetype) { switch (surfacetype) { case 0: return "1D"; case 1: return "2D"; case 2: return "3D"; case 3: return "CUBE"; case 4: return "BUFFER"; case 7: return "NULL"; default: return "unknown"; } } static const char * get_965_depthformat(unsigned int depthformat) { switch (depthformat) { case 0: return "s8_z24float"; case 1: return "z32float"; case 2: return "z24s8"; case 5: return "z16"; default: return "unknown"; } } static const char * get_965_element_component(uint32_t data, int component) { uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; switch (component_control) { case 0: return "nostore"; case 1: switch (component) { case 0: return "X"; case 1: return "Y"; case 2: return "Z"; case 3: return "W"; default: return "fail"; } case 2: return "0.0"; case 3: return "1.0"; case 4: return "0x1"; case 5: return "VID"; default: return "fail"; } } static const char * get_965_prim_type(uint32_t data) { uint32_t primtype = (data >> 10) & 0x1f; switch (primtype) { case 0x01: return "point list"; case 0x02: return "line list"; case 0x03: return "line strip"; case 0x04: return "tri list"; case 0x05: return "tri strip"; case 0x06: return "tri fan"; case 0x07: return "quad list"; case 0x08: return "quad strip"; case 0x09: return "line list adj"; case 0x0a: return "line strip adj"; case 0x0b: return "tri list adj"; case 0x0c: return "tri strip adj"; case 0x0d: return "tri strip reverse"; case 0x0e: return "polygon"; case 0x0f: return "rect list"; case 0x10: return "line loop"; case 0x11: return "point list bf"; case 0x12: return "line strip cont"; case 0x13: return "line strip bf"; case 0x14: return "line strip cont bf"; case 0x15: return "tri fan no stipple"; default: return "fail"; } } #if 0 struct reloc { struct kgem_bo *bo; void *base; }; static void * get_reloc(struct kgem *kgem, void *base, const uint32_t *reloc, struct reloc *r) { uint32_t delta = *reloc; memset(r, 0, sizeof(*r)); if (base == 0) { uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); struct kgem_bo *bo = NULL; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == handle) break; assert(i < kgem->nreloc); handle = kgem->reloc[i].target_handle; delta = kgem->reloc[i].delta; if (handle == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == handle) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map(kgem, bo, PROT_READ); r->bo = bo; r->base = base; } } return (char *)base + delta; } #endif int kgem_gen5_decode_3d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x6000, 3, 3, "URB_FENCE" }, { 0x6001, 2, 2, "CS_URB_FENCE" }, { 0x6002, 2, 2, "CONSTANT_BUFFER" }, { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, { 0x6102, 2, 2 , "STATE_SIP" }, { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" }, { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, { 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" }, { 0x7910, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x7b00, 6, 6, "3DPRIMITIVE" }, { 0x7805, 3, 3, "3DSTATE_URB" }, { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" }, { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, { 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" }, { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, }; uint32_t *data = kgem->batch + offset; uint32_t op; unsigned int len; int i; const char *desc1 = NULL; len = (data[0] & 0xff) + 2; op = (data[0] & 0xffff0000) >> 16; switch (op) { case 0x6000: assert(len == 3); kgem_debug_print(data, offset, 0, "URB_FENCE: %s%s%s%s%s%s\n", (data[0] >> 13) & 1 ? "cs " : "", (data[0] >> 12) & 1 ? "vfe " : "", (data[0] >> 11) & 1 ? "sf " : "", (data[0] >> 10) & 1 ? "clip " : "", (data[0] >> 9) & 1 ? "gs " : "", (data[0] >> 8) & 1 ? "vs " : ""); kgem_debug_print(data, offset, 1, "vs fence: %d, gs_fence: %d, clip_fence: %d\n", data[1] & 0x3ff, (data[1] >> 10) & 0x3ff, (data[1] >> 20) & 0x3ff); kgem_debug_print(data, offset, 2, "sf fence: %d, vfe_fence: %d, cs_fence: %d\n", data[2] & 0x3ff, (data[2] >> 10) & 0x3ff, (data[2] >> 20) & 0x7ff); return len; case 0x6001: kgem_debug_print(data, offset, 0, "CS_URB_STATE\n"); kgem_debug_print(data, offset, 1, "entry_size: %d [%d bytes], n_entries: %d\n", (data[1] >> 4) & 0x1f, (((data[1] >> 4) & 0x1f) + 1) * 64, data[1] & 0x7); return len; case 0x6002: kgem_debug_print(data, offset, 0, "CONSTANT_BUFFER: %s\n", (data[0] >> 8) & 1 ? "valid" : "invalid"); kgem_debug_print(data, offset, 1, "offset: 0x%08x, length: %d bytes\n", data[1] & ~0x3f, ((data[1] & 0x3f) + 1) * 64); return len; case 0x6101: i = 0; kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); assert(len == 8); state_base_out(data, offset, i++, "general"); state_base_out(data, offset, i++, "surface"); state_base_out(data, offset, i++, "media"); state_base_out(data, offset, i++, "instruction"); state_max_out(data, offset, i++, "general"); state_max_out(data, offset, i++, "media"); state_max_out(data, offset, i++, "instruction"); return len; case 0x7801: assert(len == 6); kgem_debug_print(data, offset, 0, "3DSTATE_BINDING_TABLE_POINTERS\n"); kgem_debug_print(data, offset, 1, "VS binding table\n"); kgem_debug_print(data, offset, 2, "GS binding table\n"); kgem_debug_print(data, offset, 3, "CLIP binding table\n"); kgem_debug_print(data, offset, 4, "SF binding table\n"); kgem_debug_print(data, offset, 5, "WM binding table\n"); return len; case 0x7808: assert((len - 1) % 4 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); for (i = 1; i < len;) { gen5_update_vertex_buffer(kgem, data + i); kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", data[i] >> 27, data[i] & (1 << 20) ? "random" : "sequential", data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i++, "buffer address\n"); kgem_debug_print(data, offset, i++, "max index\n"); kgem_debug_print(data, offset, i++, "mbz\n"); } return len; case 0x7809: assert((len + 1) % 2 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); memset(state.ve, 0, sizeof(state.ve)); /* XXX? */ for (i = 1; i < len;) { gen5_update_vertex_elements(kgem, (i - 1)/2, data + i); kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, " "src offset 0x%04x bytes\n", data[i] >> 27, data[i] & (1 << 26) ? "" : "in", (data[i] >> 16) & 0x1ff, data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i, "(%s, %s, %s, %s)\n", get_965_element_component(data[i], 0), get_965_element_component(data[i], 1), get_965_element_component(data[i], 2), get_965_element_component(data[i], 3)); i++; } state.num_ve = (len - 1) / 2; /* XXX? */ return len; case 0x780a: assert(len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); kgem_debug_print(data, offset, 1, "beginning buffer address\n"); kgem_debug_print(data, offset, 2, "ending buffer address\n"); return len; case 0x7900: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_DRAWING_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "top left: %d,%d\n", data[1] & 0xffff, (data[1] >> 16) & 0xffff); kgem_debug_print(data, offset, 2, "bottom right: %d,%d\n", data[2] & 0xffff, (data[2] >> 16) & 0xffff); kgem_debug_print(data, offset, 3, "origin: %d,%d\n", (int)data[3] & 0xffff, ((int)data[3] >> 16) & 0xffff); return len; case 0x7905: assert(len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_BUFFER\n"); kgem_debug_print(data, offset, 1, "%s, %s, pitch = %d bytes, %stiled, HiZ %d, Separate Stencil %d\n", get_965_surfacetype(data[1] >> 29), get_965_depthformat((data[1] >> 18) & 0x7), (data[1] & 0x0001ffff) + 1, data[1] & (1 << 27) ? "" : "not ", (data[1] & (1 << 22)) != 0, (data[1] & (1 << 21)) != 0); kgem_debug_print(data, offset, 2, "depth offset\n"); kgem_debug_print(data, offset, 3, "%dx%d\n", ((data[3] & 0x0007ffc0) >> 6) + 1, ((data[3] & 0xfff80000) >> 19) + 1); kgem_debug_print(data, offset, 4, "volume depth\n"); kgem_debug_print(data, offset, 5, "\n"); kgem_debug_print(data, offset, 6, "\n"); return len; case 0x7a00: assert(len == 4 || len == 5); switch ((data[1] >> 14) & 0x3) { case 0: desc1 = "no write"; break; case 1: desc1 = "qword write"; break; case 2: desc1 = "PS_DEPTH_COUNT write"; break; case 3: desc1 = "TIMESTAMP write"; break; } kgem_debug_print(data, offset, 0, "PIPE_CONTROL\n"); kgem_debug_print(data, offset, 1, "%s, %scs stall, %stlb invalidate, " "%ssync gfdt, %sdepth stall, %sRC write flush, " "%sinst flush, %sTC flush\n", desc1, data[1] & (1 << 20) ? "" : "no ", data[1] & (1 << 18) ? "" : "no ", data[1] & (1 << 17) ? "" : "no ", data[1] & (1 << 13) ? "" : "no ", data[1] & (1 << 12) ? "" : "no ", data[1] & (1 << 11) ? "" : "no ", data[1] & (1 << 10) ? "" : "no "); if (len == 5) { kgem_debug_print(data, offset, 2, "destination address\n"); kgem_debug_print(data, offset, 3, "immediate dword low\n"); kgem_debug_print(data, offset, 4, "immediate dword high\n"); } else { for (i = 2; i < len; i++) { kgem_debug_print(data, offset, i, "\n"); } } return len; case 0x7b00: assert(len == 6); kgem_debug_print(data, offset, 0, "3DPRIMITIVE: %s %s\n", get_965_prim_type(data[0]), (data[0] & (1 << 15)) ? "random" : "sequential"); kgem_debug_print(data, offset, 1, "vertex count\n"); kgem_debug_print(data, offset, 2, "start vertex\n"); kgem_debug_print(data, offset, 3, "instance count\n"); kgem_debug_print(data, offset, 4, "start instance\n"); kgem_debug_print(data, offset, 5, "index bias\n"); primitive_out(kgem, data); return len; } /* For the rest, just dump the bytes */ for (i = 0; i < ARRAY_SIZE(opcodes); i++) if (op == opcodes[i].opcode) break; assert(i < ARRAY_SIZE(opcodes)); len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); if (opcodes[i].max_len > 1) { len = (data[0] & 0xff) + 2; assert(len >= opcodes[i].min_len && len <= opcodes[i].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } void kgem_gen5_finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen6.c000066400000000000000000000757321267532330400250350ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "gen6_render.h" #include "kgem_debug.h" static struct state { struct vertex_buffer { int handle; const char *ptr; int pitch; struct kgem_bo *current; } vb[33]; struct vertex_elements { int buffer; int offset; bool valid; uint32_t type; uint8_t swizzle[4]; } ve[33]; int num_ve; struct dynamic_state { struct kgem_bo *current; void *base, *ptr; } dynamic_state; } state; static void gen6_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) { uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch); struct kgem_bo *bo = NULL; void *base; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == reloc) break; assert(i < kgem->nreloc); reloc = kgem->reloc[i].target_handle; if (reloc == -1) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->target_handle == reloc) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } base = (char *)base + kgem->reloc[i].delta; i = data[0] >> 26; state.vb[i].current = bo; state.vb[i].ptr = base; state.vb[i].pitch = data[0] & 0x7ff; } static void gen6_update_dynamic_buffer(struct kgem *kgem, const uint32_t offset) { uint32_t reloc = sizeof(uint32_t) * offset; struct kgem_bo *bo = NULL; void *base, *ptr; int i; if ((kgem->batch[offset] & 1) == 0) return; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == reloc) break; if(i < kgem->nreloc) { reloc = kgem->reloc[i].target_handle; if (reloc == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == reloc) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } ptr = (char *)base + (kgem->reloc[i].delta & ~1); } else { bo = NULL; base = NULL; ptr = NULL; } state.dynamic_state.current = bo; state.dynamic_state.base = base; state.dynamic_state.ptr = ptr; } static uint32_t get_ve_component(uint32_t data, int component) { return (data >> (16 + (3 - component) * 4)) & 0x7; } static void gen6_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) { state.ve[id].buffer = data[0] >> 26; state.ve[id].valid = !!(data[0] & (1 << 25)); state.ve[id].type = (data[0] >> 16) & 0x1ff; state.ve[id].offset = data[0] & 0x7ff; state.ve[id].swizzle[0] = get_ve_component(data[1], 0); state.ve[id].swizzle[1] = get_ve_component(data[1], 1); state.ve[id].swizzle[2] = get_ve_component(data[1], 2); state.ve[id].swizzle[3] = get_ve_component(data[1], 3); } static void gen6_update_sf_state(struct kgem *kgem, uint32_t *data) { state.num_ve = 1 + ((data[1] >> 22) & 0x3f); } static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) { int c; ErrorF("("); for (c = 0; c < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%d", v[c]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) { int c, o; ErrorF("("); for (c = o = 0; c < 4 && o < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%f", f[o++]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void ve_out(const struct vertex_elements *ve, const void *ptr) { switch (ve->type) { case GEN6_SURFACEFORMAT_R32_FLOAT: vertices_float_out(ve, ptr, 1); break; case GEN6_SURFACEFORMAT_R32G32_FLOAT: vertices_float_out(ve, ptr, 2); break; case GEN6_SURFACEFORMAT_R32G32B32_FLOAT: vertices_float_out(ve, ptr, 3); break; case GEN6_SURFACEFORMAT_R32G32B32A32_FLOAT: vertices_float_out(ve, ptr, 4); break; case GEN6_SURFACEFORMAT_R16_SINT: vertices_sint16_out(ve, ptr, 1); break; case GEN6_SURFACEFORMAT_R16G16_SINT: vertices_sint16_out(ve, ptr, 2); break; case GEN6_SURFACEFORMAT_R16G16B16A16_SINT: vertices_sint16_out(ve, ptr, 4); break; case GEN6_SURFACEFORMAT_R16_SSCALED: vertices_sint16_out(ve, ptr, 1); break; case GEN6_SURFACEFORMAT_R16G16_SSCALED: vertices_sint16_out(ve, ptr, 2); break; case GEN6_SURFACEFORMAT_R16G16B16A16_SSCALED: vertices_sint16_out(ve, ptr, 4); break; } } static void indirect_vertex_out(struct kgem *kgem, uint32_t v) { int i = 1; do { const struct vertex_elements *ve = &state.ve[i]; const struct vertex_buffer *vb = &state.vb[ve->buffer]; const void *ptr = vb->ptr + v * vb->pitch + ve->offset; if (ve->valid) ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); } static void primitive_out(struct kgem *kgem, uint32_t *data) { int n; assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ for (n = 0; n < data[1]; n++) { int v = data[2] + n; ErrorF(" [%d:%d] = ", n, v); indirect_vertex_out(kgem, v); ErrorF("\n"); } } static void finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } static void state_base_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state base address 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state base not updated\n", name); } static void state_max_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] == 1) kgem_debug_print(data, offset, index, "%s state upper bound disabled\n", name); else if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state upper bound 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state upper bound not updated\n", name); } static const char * get_965_surfacetype(unsigned int surfacetype) { switch (surfacetype) { case 0: return "1D"; case 1: return "2D"; case 2: return "3D"; case 3: return "CUBE"; case 4: return "BUFFER"; case 7: return "NULL"; default: return "unknown"; } } static const char * get_965_depthformat(unsigned int depthformat) { switch (depthformat) { case 0: return "s8_z24float"; case 1: return "z32float"; case 2: return "z24s8"; case 5: return "z16"; default: return "unknown"; } } static const char * get_965_element_component(uint32_t data, int component) { uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; switch (component_control) { case 0: return "nostore"; case 1: switch (component) { case 0: return "X"; case 1: return "Y"; case 2: return "Z"; case 3: return "W"; default: return "fail"; } case 2: return "0.0"; case 3: return "1.0"; case 4: return "0x1"; case 5: return "VID"; default: return "fail"; } } static const char * get_965_prim_type(uint32_t data) { uint32_t primtype = (data >> 10) & 0x1f; switch (primtype) { case 0x01: return "point list"; case 0x02: return "line list"; case 0x03: return "line strip"; case 0x04: return "tri list"; case 0x05: return "tri strip"; case 0x06: return "tri fan"; case 0x07: return "quad list"; case 0x08: return "quad strip"; case 0x09: return "line list adj"; case 0x0a: return "line strip adj"; case 0x0b: return "tri list adj"; case 0x0c: return "tri strip adj"; case 0x0d: return "tri strip reverse"; case 0x0e: return "polygon"; case 0x0f: return "rect list"; case 0x10: return "line loop"; case 0x11: return "point list bf"; case 0x12: return "line strip cont"; case 0x13: return "line strip bf"; case 0x14: return "line strip cont bf"; case 0x15: return "tri fan no stipple"; default: return "fail"; } } struct reloc { struct kgem_bo *bo; void *base; }; static void * get_reloc(struct kgem *kgem, void *base, const uint32_t *reloc, struct reloc *r) { uint32_t delta = *reloc; memset(r, 0, sizeof(*r)); if (base == 0) { uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); struct kgem_bo *bo = NULL; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == handle) break; assert(i < kgem->nreloc); handle = kgem->reloc[i].target_handle; delta = kgem->reloc[i].delta; if (handle == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == handle) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); r->bo = bo; r->base = base; } } return (char *)base + (delta & ~3); } static const char * gen6_filter_to_string(uint32_t filter) { switch (filter) { default: case GEN6_MAPFILTER_NEAREST: return "nearest"; case GEN6_MAPFILTER_LINEAR: return "linear"; } } static const char * gen6_repeat_to_string(uint32_t repeat) { switch (repeat) { default: case GEN6_TEXCOORDMODE_CLAMP_BORDER: return "border"; case GEN6_TEXCOORDMODE_WRAP: return "wrap"; case GEN6_TEXCOORDMODE_CLAMP: return "clamp"; case GEN6_TEXCOORDMODE_MIRROR: return "mirror"; } } static void gen6_decode_sampler_state(struct kgem *kgem, const uint32_t *reloc) { const struct gen6_sampler_state *ss; struct reloc r; const char *min, *mag; const char *s_wrap, *t_wrap, *r_wrap; ss = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); min = gen6_filter_to_string(ss->ss0.min_filter); mag = gen6_filter_to_string(ss->ss0.mag_filter); s_wrap = gen6_repeat_to_string(ss->ss1.s_wrap_mode); t_wrap = gen6_repeat_to_string(ss->ss1.t_wrap_mode); r_wrap = gen6_repeat_to_string(ss->ss1.r_wrap_mode); ErrorF(" Sampler 0:\n"); ErrorF(" filter: min=%s, mag=%s\n", min, mag); ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); ss++; min = gen6_filter_to_string(ss->ss0.min_filter); mag = gen6_filter_to_string(ss->ss0.mag_filter); s_wrap = gen6_repeat_to_string(ss->ss1.s_wrap_mode); t_wrap = gen6_repeat_to_string(ss->ss1.t_wrap_mode); r_wrap = gen6_repeat_to_string(ss->ss1.r_wrap_mode); ErrorF(" Sampler 1:\n"); ErrorF(" filter: min=%s, mag=%s\n", min, mag); ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); } static const char * gen6_blend_factor_to_string(uint32_t v) { switch (v) { #define C(x) case GEN6_BLENDFACTOR_##x: return #x; C(ONE); C(SRC_COLOR); C(SRC_ALPHA); C(DST_ALPHA); C(DST_COLOR); C(SRC_ALPHA_SATURATE); C(CONST_COLOR); C(CONST_ALPHA); C(SRC1_COLOR); C(SRC1_ALPHA); C(ZERO); C(INV_SRC_COLOR); C(INV_SRC_ALPHA); C(INV_DST_ALPHA); C(INV_DST_COLOR); C(INV_CONST_COLOR); C(INV_CONST_ALPHA); C(INV_SRC1_COLOR); C(INV_SRC1_ALPHA); #undef C default: return "???"; } } static const char * gen6_blend_function_to_string(uint32_t v) { switch (v) { #define C(x) case GEN6_BLENDFUNCTION_##x: return #x; C(ADD); C(SUBTRACT); C(REVERSE_SUBTRACT); C(MIN); C(MAX); #undef C default: return "???"; } } static float unpack_float(uint32_t dw) { union { float f; uint32_t dw; } u; u.dw = dw; return u.f; } static void gen6_decode_blend(struct kgem *kgem, const uint32_t *reloc) { const struct gen6_blend_state *blend; struct reloc r; const char *dst, *src; const char *func; blend = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); dst = gen6_blend_factor_to_string(blend->blend0.dest_blend_factor); src = gen6_blend_factor_to_string(blend->blend0.source_blend_factor); func = gen6_blend_function_to_string(blend->blend0.blend_func); ErrorF(" Blend (%s): function %s, src=%s, dst=%s\n", blend->blend0.blend_enable ? "enabled" : "disabled", func, src, dst); } int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, { 0x6102, 2, 2 , "STATE_SIP" }, { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" }, { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, { 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" }, { 0x7910, 2, 2, "3DSTATE_CLEAR_PARAMS" }, { 0x7b00, 6, 6, "3DPRIMITIVE" }, { 0x7802, 4, 4, "3DSTATE_SAMPLER_STATE_POINTERS" }, { 0x7805, 3, 3, "3DSTATE_URB" }, { 0x780d, 4, 4, "3DSTATE_VIEWPORT_STATE_POINTERS" }, { 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" }, { 0x780f, 2, 2, "3DSTATE_SCISSOR_STATE_POINTERS" }, { 0x7810, 6, 6, "3DSTATE_VS_STATE" }, { 0x7811, 7, 7, "3DSTATE_GS_STATE" }, { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" }, { 0x7813, 20, 20, "3DSTATE_SF_STATE" }, { 0x7814, 9, 9, "3DSTATE_WM_STATE" }, { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" }, { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, { 0x7817, 5, 5, "3DSTATE_CONSTANT_WM_STATE" }, { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, }; uint32_t *data = kgem->batch + offset; uint32_t op; unsigned int len; int i, j; const char *desc1 = NULL; len = (data[0] & 0xff) + 2; op = (data[0] & 0xffff0000) >> 16; switch (op) { case 0x6101: i = 0; kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); if (kgem->gen >= 060) { assert(len == 10); state_base_out(data, offset, i++, "general"); state_base_out(data, offset, i++, "surface"); state_base_out(data, offset, i++, "dynamic"); state_base_out(data, offset, i++, "indirect"); state_base_out(data, offset, i++, "instruction"); state_max_out(data, offset, i++, "general"); state_max_out(data, offset, i++, "dynamic"); state_max_out(data, offset, i++, "indirect"); state_max_out(data, offset, i++, "instruction"); gen6_update_dynamic_buffer(kgem, offset + 3); } else if (kgem->gen >= 050) { assert(len == 8); state_base_out(data, offset, i++, "general"); state_base_out(data, offset, i++, "surface"); state_base_out(data, offset, i++, "media"); state_base_out(data, offset, i++, "instruction"); state_max_out(data, offset, i++, "general"); state_max_out(data, offset, i++, "media"); state_max_out(data, offset, i++, "instruction"); } return len; case 0x7801: if (kgem->gen >= 060) { assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_BINDING_TABLE_POINTERS: VS mod %d, " "GS mod %d, WM mod %d\n", (data[0] & (1 << 8)) != 0, (data[0] & (1 << 9)) != 0, (data[0] & (1 << 12)) != 0); kgem_debug_print(data, offset, 1, "VS binding table\n"); kgem_debug_print(data, offset, 2, "GS binding table\n"); kgem_debug_print(data, offset, 3, "WM binding table\n"); } else if (kgem->gen >= 040) { assert(len == 6); kgem_debug_print(data, offset, 0, "3DSTATE_BINDING_TABLE_POINTERS\n"); kgem_debug_print(data, offset, 1, "VS binding table\n"); kgem_debug_print(data, offset, 2, "GS binding table\n"); kgem_debug_print(data, offset, 3, "CLIP binding table\n"); kgem_debug_print(data, offset, 4, "SF binding table\n"); kgem_debug_print(data, offset, 5, "WM binding table\n"); } return len; case 0x7802: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_SAMPLER_STATE_POINTERS: VS mod %d, " "GS mod %d, WM mod %d\n", (data[0] & (1 << 8)) != 0, (data[0] & (1 << 9)) != 0, (data[0] & (1 << 12)) != 0); kgem_debug_print(data, offset, 1, "VS sampler state\n"); kgem_debug_print(data, offset, 2, "GS sampler state\n"); kgem_debug_print(data, offset, 3, "WM sampler state\n"); gen6_decode_sampler_state(kgem, &data[3]); return len; case 0x7808: assert((len - 1) % 4 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); for (i = 1; i < len;) { gen6_update_vertex_buffer(kgem, data + i); kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", data[i] >> 26, data[i] & (1 << 20) ? "random" : "sequential", data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i++, "buffer address\n"); kgem_debug_print(data, offset, i++, "max index\n"); kgem_debug_print(data, offset, i++, "mbz\n"); } return len; case 0x7809: assert((len + 1) % 2 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); for (i = 1; i < len;) { gen6_update_vertex_elements(kgem, (i - 1)/2, data + i); kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, " "src offset 0x%04x bytes\n", data[i] >> 26, data[i] & (1 << 25) ? "" : "in", (data[i] >> 16) & 0x1ff, data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), " "dst offset 0x%02x bytes\n", get_965_element_component(data[i], 0), get_965_element_component(data[i], 1), get_965_element_component(data[i], 2), get_965_element_component(data[i], 3), (data[i] & 0xff) * 4); i++; } return len; case 0x780d: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_VIEWPORT_STATE_POINTERS\n"); kgem_debug_print(data, offset, 1, "clip\n"); kgem_debug_print(data, offset, 2, "sf\n"); kgem_debug_print(data, offset, 3, "cc\n"); return len; case 0x780a: assert(len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); kgem_debug_print(data, offset, 1, "beginning buffer address\n"); kgem_debug_print(data, offset, 2, "ending buffer address\n"); return len; case 0x780e: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_CC_STATE_POINTERS\n"); kgem_debug_print(data, offset, 1, "blend%s\n", data[1] & 1 ? " update" : ""); if (data[1] & 1) gen6_decode_blend(kgem, data+1); kgem_debug_print(data, offset, 2, "depth+stencil%s\n", data[2] & 1 ? " update" : ""); kgem_debug_print(data, offset, 3, "cc%s\n", data[3] & 1 ? " update" : ""); return len; case 0x780f: assert(len == 2); kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_POINTERS\n"); kgem_debug_print(data, offset, 1, "scissor rect offset\n"); return len; case 0x7810: assert(len == 6); kgem_debug_print(data, offset, 0, "3DSTATE_VS\n"); kgem_debug_print(data, offset, 1, "kernel pointer\n"); kgem_debug_print(data, offset, 2, "SPF=%d, VME=%d, Sampler Count %d, " "Binding table count %d\n", (data[2] >> 31) & 1, (data[2] >> 30) & 1, (data[2] >> 27) & 7, (data[2] >> 18) & 0xff); kgem_debug_print(data, offset, 3, "scratch offset\n"); kgem_debug_print(data, offset, 4, "Dispatch GRF start %d, VUE read length %d, " "VUE read offset %d\n", (data[4] >> 20) & 0x1f, (data[4] >> 11) & 0x3f, (data[4] >> 4) & 0x3f); kgem_debug_print(data, offset, 5, "Max Threads %d, Vertex Cache %sable, " "VS func %sable\n", ((data[5] >> 25) & 0x7f) + 1, (data[5] & (1 << 1)) != 0 ? "dis" : "en", (data[5] & 1) != 0 ? "en" : "dis"); return len; case 0x7811: assert(len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_GS\n"); kgem_debug_print(data, offset, 1, "kernel pointer\n"); kgem_debug_print(data, offset, 2, "SPF=%d, VME=%d, Sampler Count %d, " "Binding table count %d\n", (data[2] >> 31) & 1, (data[2] >> 30) & 1, (data[2] >> 27) & 7, (data[2] >> 18) & 0xff); kgem_debug_print(data, offset, 3, "scratch offset\n"); kgem_debug_print(data, offset, 4, "Dispatch GRF start %d, VUE read length %d, " "VUE read offset %d\n", (data[4] & 0xf), (data[4] >> 11) & 0x3f, (data[4] >> 4) & 0x3f); kgem_debug_print(data, offset, 5, "Max Threads %d, Rendering %sable\n", ((data[5] >> 25) & 0x7f) + 1, (data[5] & (1 << 8)) != 0 ? "en" : "dis"); kgem_debug_print(data, offset, 6, "Reorder %sable, Discard Adjaceny %sable, " "GS %sable\n", (data[6] & (1 << 30)) != 0 ? "en" : "dis", (data[6] & (1 << 29)) != 0 ? "en" : "dis", (data[6] & (1 << 15)) != 0 ? "en" : "dis"); return len; case 0x7812: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_CLIP\n"); kgem_debug_print(data, offset, 1, "UserClip distance cull test mask 0x%x\n", data[1] & 0xff); kgem_debug_print(data, offset, 2, "Clip %sable, API mode %s, Viewport XY test %sable, " "Viewport Z test %sable, Guardband test %sable, Clip mode %d, " "Perspective Divide %sable, Non-Perspective Barycentric %sable, " "Tri Provoking %d, Line Provoking %d, Trifan Provoking %d\n", (data[2] & (1 << 31)) != 0 ? "en" : "dis", (data[2] & (1 << 30)) != 0 ? "D3D" : "OGL", (data[2] & (1 << 28)) != 0 ? "en" : "dis", (data[2] & (1 << 27)) != 0 ? "en" : "dis", (data[2] & (1 << 26)) != 0 ? "en" : "dis", (data[2] >> 13) & 7, (data[2] & (1 << 9)) != 0 ? "dis" : "en", (data[2] & (1 << 8)) != 0 ? "en" : "dis", (data[2] >> 4) & 3, (data[2] >> 2) & 3, (data[2] & 3)); kgem_debug_print(data, offset, 3, "Min PointWidth %d, Max PointWidth %d, " "Force Zero RTAIndex %sable, Max VPIndex %d\n", (data[3] >> 17) & 0x7ff, (data[3] >> 6) & 0x7ff, (data[3] & (1 << 5)) != 0 ? "en" : "dis", (data[3] & 0xf)); return len; case 0x7813: gen6_update_sf_state(kgem, data); assert(len == 20); kgem_debug_print(data, offset, 0, "3DSTATE_SF\n"); kgem_debug_print(data, offset, 1, "Attrib Out %d, Attrib Swizzle %sable, VUE read length %d, " "VUE read offset %d\n", (data[1] >> 22) & 0x3f, (data[1] & (1 << 21)) != 0 ? "en" : "dis", (data[1] >> 11) & 0x1f, (data[1] >> 4) & 0x3f); kgem_debug_print(data, offset, 2, "Legacy Global DepthBias %sable, FrontFace fill %d, BF fill %d, " "VP transform %sable, FrontWinding_%s\n", (data[2] & (1 << 11)) != 0 ? "en" : "dis", (data[2] >> 5) & 3, (data[2] >> 3) & 3, (data[2] & (1 << 1)) != 0 ? "en" : "dis", (data[2] & 1) != 0 ? "CCW" : "CW"); kgem_debug_print(data, offset, 3, "AA %sable, CullMode %d, Scissor %sable, Multisample m ode %d\n", (data[3] & (1 << 31)) != 0 ? "en" : "dis", (data[3] >> 29) & 3, (data[3] & (1 << 11)) != 0 ? "en" : "dis", (data[3] >> 8) & 3); kgem_debug_print(data, offset, 4, "Last Pixel %sable, SubPixel Precision %d, Use PixelWidth %d\n", (data[4] & (1 << 31)) != 0 ? "en" : "dis", (data[4] & (1 << 12)) != 0 ? 4 : 8, (data[4] & (1 << 11)) != 0); kgem_debug_print(data, offset, 5, "Global Depth Offset Constant %f\n", unpack_float(data[5])); kgem_debug_print(data, offset, 6, "Global Depth Offset Scale %f\n", unpack_float(data[6])); kgem_debug_print(data, offset, 7, "Global Depth Offset Clamp %f\n", unpack_float(data[7])); for (i = 0, j = 0; i < 8; i++, j+=2) kgem_debug_print(data, offset, i+8, "Attrib %d (Override %s%s%s%s, Const Source %d, Swizzle Select %d, " "Source %d); Attrib %d (Override %s%s%s%s, Const Source %d, Swizzle Select %d, Source %d)\n", j+1, (data[8+i] & (1 << 31)) != 0 ? "W":"", (data[8+i] & (1 << 30)) != 0 ? "Z":"", (data[8+i] & (1 << 29)) != 0 ? "Y":"", (data[8+i] & (1 << 28)) != 0 ? "X":"", (data[8+i] >> 25) & 3, (data[8+i] >> 22) & 3, (data[8+i] >> 16) & 0x1f, j, (data[8+i] & (1 << 15)) != 0 ? "W":"", (data[8+i] & (1 << 14)) != 0 ? "Z":"", (data[8+i] & (1 << 13)) != 0 ? "Y":"", (data[8+i] & (1 << 12)) != 0 ? "X":"", (data[8+i] >> 9) & 3, (data[8+i] >> 6) & 3, (data[8+i] & 0x1f)); kgem_debug_print(data, offset, 16, "Point Sprite TexCoord Enable\n"); kgem_debug_print(data, offset, 17, "Const Interp Enable\n"); kgem_debug_print(data, offset, 18, "Attrib 7-0 WrapShortest Enable\n"); kgem_debug_print(data, offset, 19, "Attrib 15-8 WrapShortest Enable\n"); return len; case 0x7814: assert(len == 9); kgem_debug_print(data, offset, 0, "3DSTATE_WM\n"); kgem_debug_print(data, offset, 1, "kernel start pointer 0\n"); kgem_debug_print(data, offset, 2, "SPF=%d, VME=%d, Sampler Count %d, " "Binding table count %d\n", (data[2] >> 31) & 1, (data[2] >> 30) & 1, (data[2] >> 27) & 7, (data[2] >> 18) & 0xff); kgem_debug_print(data, offset, 3, "scratch offset\n"); kgem_debug_print(data, offset, 4, "Depth Clear %d, Depth Resolve %d, HiZ Resolve %d, " "Dispatch GRF start[0] %d, start[1] %d, start[2] %d\n", (data[4] & (1 << 30)) != 0, (data[4] & (1 << 28)) != 0, (data[4] & (1 << 27)) != 0, (data[4] >> 16) & 0x7f, (data[4] >> 8) & 0x7f, (data[4] & 0x7f)); kgem_debug_print(data, offset, 5, "MaxThreads %d, PS KillPixel %d, PS computed Z %d, " "PS use sourceZ %d, Thread Dispatch %d, PS use sourceW %d, Dispatch32 %d, " "Dispatch16 %d, Dispatch8 %d\n", ((data[5] >> 25) & 0x7f) + 1, (data[5] & (1 << 22)) != 0, (data[5] & (1 << 21)) != 0, (data[5] & (1 << 20)) != 0, (data[5] & (1 << 19)) != 0, (data[5] & (1 << 8)) != 0, (data[5] & (1 << 2)) != 0, (data[5] & (1 << 1)) != 0, (data[5] & (1 << 0)) != 0); kgem_debug_print(data, offset, 6, "Num SF output %d, Pos XY offset %d, ZW interp mode %d , " "Barycentric interp mode 0x%x, Point raster rule %d, Multisample mode %d, " "Multisample Dispatch mode %d\n", (data[6] >> 20) & 0x3f, (data[6] >> 18) & 3, (data[6] >> 16) & 3, (data[6] >> 10) & 0x3f, (data[6] & (1 << 9)) != 0, (data[6] >> 1) & 3, (data[6] & 1)); kgem_debug_print(data, offset, 7, "kernel start pointer 1\n"); kgem_debug_print(data, offset, 8, "kernel start pointer 2\n"); return len; case 0x7900: assert(len == 4); kgem_debug_print(data, offset, 0, "3DSTATE_DRAWING_RECTANGLE\n"); kgem_debug_print(data, offset, 1, "top left: %d, %d\n", (uint16_t)(data[1] & 0xffff), (uint16_t)(data[1] >> 16)); kgem_debug_print(data, offset, 2, "bottom right: %d, %d\n", (uint16_t)(data[2] & 0xffff), (uint16_t)(data[2] >> 16)); kgem_debug_print(data, offset, 3, "origin: %d, %d\n", (int16_t)(data[3] & 0xffff), (int16_t)(data[3] >> 16)); return len; case 0x7905: assert(len == 7); kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_BUFFER\n"); kgem_debug_print(data, offset, 1, "%s, %s, pitch = %d bytes, %stiled, HiZ %d, Separate Stencil %d\n", get_965_surfacetype(data[1] >> 29), get_965_depthformat((data[1] >> 18) & 0x7), (data[1] & 0x0001ffff) + 1, data[1] & (1 << 27) ? "" : "not ", (data[1] & (1 << 22)) != 0, (data[1] & (1 << 21)) != 0); kgem_debug_print(data, offset, 2, "depth offset\n"); kgem_debug_print(data, offset, 3, "%dx%d\n", ((data[3] & 0x0007ffc0) >> 6) + 1, ((data[3] & 0xfff80000) >> 19) + 1); kgem_debug_print(data, offset, 4, "volume depth\n"); kgem_debug_print(data, offset, 5, "\n"); kgem_debug_print(data, offset, 6, "\n"); return len; case 0x7a00: assert(len == 4 || len == 5); switch ((data[1] >> 14) & 0x3) { case 0: desc1 = "no write"; break; case 1: desc1 = "qword write"; break; case 2: desc1 = "PS_DEPTH_COUNT write"; break; case 3: desc1 = "TIMESTAMP write"; break; } kgem_debug_print(data, offset, 0, "PIPE_CONTROL\n"); kgem_debug_print(data, offset, 1, "%s, %scs stall, %stlb invalidate, " "%ssync gfdt, %sdepth stall, %sRC write flush, " "%sinst flush, %sTC flush\n", desc1, data[1] & (1 << 20) ? "" : "no ", data[1] & (1 << 18) ? "" : "no ", data[1] & (1 << 17) ? "" : "no ", data[1] & (1 << 13) ? "" : "no ", data[1] & (1 << 12) ? "" : "no ", data[1] & (1 << 11) ? "" : "no ", data[1] & (1 << 10) ? "" : "no "); if (len == 5) { kgem_debug_print(data, offset, 2, "destination address\n"); kgem_debug_print(data, offset, 3, "immediate dword low\n"); kgem_debug_print(data, offset, 4, "immediate dword high\n"); } else { for (i = 2; i < len; i++) { kgem_debug_print(data, offset, i, "\n"); } } return len; case 0x7b00: assert(len == 6); kgem_debug_print(data, offset, 0, "3DPRIMITIVE: %s %s\n", get_965_prim_type(data[0]), (data[0] & (1 << 15)) ? "random" : "sequential"); kgem_debug_print(data, offset, 1, "vertex count\n"); kgem_debug_print(data, offset, 2, "start vertex\n"); kgem_debug_print(data, offset, 3, "instance count\n"); kgem_debug_print(data, offset, 4, "start instance\n"); kgem_debug_print(data, offset, 5, "index bias\n"); primitive_out(kgem, data); return len; } /* For the rest, just dump the bytes */ for (i = 0; i < ARRAY_SIZE(opcodes); i++) if (op == opcodes[i].opcode) break; assert(i < ARRAY_SIZE(opcodes)); len = 1; kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); if (opcodes[i].max_len > 1) { len = (data[0] & 0xff) + 2; assert(len >= opcodes[i].min_len && len <= opcodes[i].max_len); } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } void kgem_gen6_finish_state(struct kgem *kgem) { finish_state(kgem); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/kgem_debug_gen7.c000066400000000000000000000424151267532330400250260ustar00rootroot00000000000000/* * Copyright © 2007-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "sna.h" #include "sna_reg.h" #include "gen7_render.h" #include "kgem_debug.h" static struct state { struct vertex_buffer { int handle; void *base; const char *ptr; int pitch; struct kgem_bo *current; } vb[33]; struct vertex_elements { int buffer; int offset; bool valid; uint32_t type; uint8_t swizzle[4]; } ve[33]; int num_ve; struct dynamic_state { struct kgem_bo *current; void *base, *ptr; } dynamic_state; } state; static void gen7_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) { uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch); struct kgem_bo *bo = NULL; void *base, *ptr; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == reloc) break; assert(i < kgem->nreloc); reloc = kgem->reloc[i].target_handle; if (reloc == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == reloc) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } ptr = (char *)base + kgem->reloc[i].delta; i = data[0] >> 26; state.vb[i].current = bo; state.vb[i].base = base; state.vb[i].ptr = ptr; state.vb[i].pitch = data[0] & 0x7ff; } static void gen7_update_dynamic_buffer(struct kgem *kgem, const uint32_t offset) { uint32_t reloc = sizeof(uint32_t) * offset; struct kgem_bo *bo = NULL; void *base, *ptr; int i; if ((kgem->batch[offset] & 1) == 0) return; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == reloc) break; if(i < kgem->nreloc) { reloc = kgem->reloc[i].target_handle; if (reloc == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == reloc) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); } ptr = (char *)base + (kgem->reloc[i].delta & ~1); } else { bo = NULL; base = NULL; ptr = NULL; } state.dynamic_state.current = bo; state.dynamic_state.base = base; state.dynamic_state.ptr = ptr; } static uint32_t get_ve_component(uint32_t data, int component) { return (data >> (16 + (3 - component) * 4)) & 0x7; } static void gen7_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) { state.ve[id].buffer = data[0] >> 26; state.ve[id].valid = !!(data[0] & (1 << 25)); state.ve[id].type = (data[0] >> 16) & 0x1ff; state.ve[id].offset = data[0] & 0x7ff; state.ve[id].swizzle[0] = get_ve_component(data[1], 0); state.ve[id].swizzle[1] = get_ve_component(data[1], 1); state.ve[id].swizzle[2] = get_ve_component(data[1], 2); state.ve[id].swizzle[3] = get_ve_component(data[1], 3); } static void gen7_update_sf_state(struct kgem *kgem, uint32_t *data) { state.num_ve = 1 + ((data[1] >> 22) & 0x3f); } static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) { int c; ErrorF("("); for (c = 0; c < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%d", v[c]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) { int c, o; ErrorF("("); for (c = o = 0; c < 4 && o < max; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("%f", f[o++]); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } for (; c < 4; c++) { switch (ve->swizzle[c]) { case 0: ErrorF("#"); break; case 1: ErrorF("1.0"); break; case 2: ErrorF("0.0"); break; case 3: ErrorF("1.0"); break; case 4: ErrorF("0x1"); break; case 5: break; default: ErrorF("?"); } if (c < 3) ErrorF(", "); } ErrorF(")"); } static void ve_out(const struct vertex_elements *ve, const void *ptr) { switch (ve->type) { case GEN7_SURFACEFORMAT_R32_FLOAT: vertices_float_out(ve, ptr, 1); break; case GEN7_SURFACEFORMAT_R32G32_FLOAT: vertices_float_out(ve, ptr, 2); break; case GEN7_SURFACEFORMAT_R32G32B32_FLOAT: vertices_float_out(ve, ptr, 3); break; case GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT: vertices_float_out(ve, ptr, 4); break; case GEN7_SURFACEFORMAT_R16_SINT: vertices_sint16_out(ve, ptr, 1); break; case GEN7_SURFACEFORMAT_R16G16_SINT: vertices_sint16_out(ve, ptr, 2); break; case GEN7_SURFACEFORMAT_R16G16B16A16_SINT: vertices_sint16_out(ve, ptr, 4); break; case GEN7_SURFACEFORMAT_R16_SSCALED: vertices_sint16_out(ve, ptr, 1); break; case GEN7_SURFACEFORMAT_R16G16_SSCALED: vertices_sint16_out(ve, ptr, 2); break; case GEN7_SURFACEFORMAT_R16G16B16A16_SSCALED: vertices_sint16_out(ve, ptr, 4); break; } } static void indirect_vertex_out(struct kgem *kgem, uint32_t v) { int i = 1; do { const struct vertex_elements *ve = &state.ve[i]; const struct vertex_buffer *vb = &state.vb[ve->buffer]; const void *ptr = vb->ptr + v * vb->pitch + ve->offset; if (!ve->valid) continue; ve_out(ve, ptr); while (++i <= state.num_ve && !state.ve[i].valid) ; if (i <= state.num_ve) ErrorF(", "); } while (i <= state.num_ve); } static void primitive_out(struct kgem *kgem, uint32_t *data) { int n; assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ for (n = 0; n < data[2]; n++) { int v = data[3] + n; ErrorF(" [%d:%d] = ", n, v); indirect_vertex_out(kgem, v); ErrorF("\n"); } } static void finish_state(struct kgem *kgem) { memset(&state, 0, sizeof(state)); } static void state_base_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state base address 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state base not updated\n", name); } static void state_max_out(uint32_t *data, uint32_t offset, unsigned int index, const char *name) { if (data[index] == 1) kgem_debug_print(data, offset, index, "%s state upper bound disabled\n", name); else if (data[index] & 1) kgem_debug_print(data, offset, index, "%s state upper bound 0x%08x\n", name, data[index] & ~1); else kgem_debug_print(data, offset, index, "%s state upper bound not updated\n", name); } static const char * get_965_surfacetype(unsigned int surfacetype) { switch (surfacetype) { case 0: return "1D"; case 1: return "2D"; case 2: return "3D"; case 3: return "CUBE"; case 4: return "BUFFER"; case 7: return "NULL"; default: return "unknown"; } } static const char * get_965_depthformat(unsigned int depthformat) { switch (depthformat) { case 0: return "s8_z24float"; case 1: return "z32float"; case 2: return "z24s8"; case 5: return "z16"; default: return "unknown"; } } static const char * get_element_component(uint32_t data, int component) { uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; switch (component_control) { case 0: return "nostore"; case 1: switch (component) { case 0: return "X"; case 1: return "Y"; case 2: return "Z"; case 3: return "W"; default: return "fail"; } case 2: return "0.0"; case 3: return "1.0"; case 4: return "0x1"; case 5: return "VID"; default: return "fail"; } } static const char * get_prim_type(uint32_t data) { uint32_t primtype = data & 0x1f; switch (primtype) { case 0x01: return "point list"; case 0x02: return "line list"; case 0x03: return "line strip"; case 0x04: return "tri list"; case 0x05: return "tri strip"; case 0x06: return "tri fan"; case 0x07: return "quad list"; case 0x08: return "quad strip"; case 0x09: return "line list adj"; case 0x0a: return "line strip adj"; case 0x0b: return "tri list adj"; case 0x0c: return "tri strip adj"; case 0x0d: return "tri strip reverse"; case 0x0e: return "polygon"; case 0x0f: return "rect list"; case 0x10: return "line loop"; case 0x11: return "point list bf"; case 0x12: return "line strip cont"; case 0x13: return "line strip bf"; case 0x14: return "line strip cont bf"; case 0x15: return "tri fan no stipple"; default: return "fail"; } } struct reloc { struct kgem_bo *bo; void *base; }; static void * get_reloc(struct kgem *kgem, void *base, const uint32_t *reloc, struct reloc *r) { uint32_t delta = *reloc; memset(r, 0, sizeof(*r)); if (base == 0) { uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); struct kgem_bo *bo = NULL; int i; for (i = 0; i < kgem->nreloc; i++) if (kgem->reloc[i].offset == handle) break; assert(i < kgem->nreloc); handle = kgem->reloc[i].target_handle; delta = kgem->reloc[i].delta; if (handle == 0) { base = kgem->batch; } else { list_for_each_entry(bo, &kgem->next_request->buffers, request) if (bo->handle == handle) break; assert(&bo->request != &kgem->next_request->buffers); base = kgem_bo_map__debug(kgem, bo); r->bo = bo; r->base = base; } } return (char *)base + (delta & ~3); } static const char * gen7_filter_to_string(uint32_t filter) { switch (filter) { default: case GEN7_MAPFILTER_NEAREST: return "nearest"; case GEN7_MAPFILTER_LINEAR: return "linear"; } } static const char * gen7_repeat_to_string(uint32_t repeat) { switch (repeat) { default: case GEN7_TEXCOORDMODE_CLAMP_BORDER: return "border"; case GEN7_TEXCOORDMODE_WRAP: return "wrap"; case GEN7_TEXCOORDMODE_CLAMP: return "clamp"; case GEN7_TEXCOORDMODE_MIRROR: return "mirror"; } } static void gen7_decode_sampler_state(struct kgem *kgem, const uint32_t *reloc) { const struct gen7_sampler_state *ss; struct reloc r; const char *min, *mag; const char *s_wrap, *t_wrap, *r_wrap; ss = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); min = gen7_filter_to_string(ss->ss0.min_filter); mag = gen7_filter_to_string(ss->ss0.mag_filter); s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode); t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode); r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode); ErrorF(" Sampler 0:\n"); ErrorF(" filter: min=%s, mag=%s\n", min, mag); ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); ss++; min = gen7_filter_to_string(ss->ss0.min_filter); mag = gen7_filter_to_string(ss->ss0.mag_filter); s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode); t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode); r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode); ErrorF(" Sampler 1:\n"); ErrorF(" filter: min=%s, mag=%s\n", min, mag); ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); } static const char * gen7_blend_factor_to_string(uint32_t v) { switch (v) { #define C(x) case GEN7_BLENDFACTOR_##x: return #x; C(ONE); C(SRC_COLOR); C(SRC_ALPHA); C(DST_ALPHA); C(DST_COLOR); C(SRC_ALPHA_SATURATE); C(CONST_COLOR); C(CONST_ALPHA); C(SRC1_COLOR); C(SRC1_ALPHA); C(ZERO); C(INV_SRC_COLOR); C(INV_SRC_ALPHA); C(INV_DST_ALPHA); C(INV_DST_COLOR); C(INV_CONST_COLOR); C(INV_CONST_ALPHA); C(INV_SRC1_COLOR); C(INV_SRC1_ALPHA); #undef C default: return "???"; } } static const char * gen7_blend_function_to_string(uint32_t v) { switch (v) { #define C(x) case GEN7_BLENDFUNCTION_##x: return #x; C(ADD); C(SUBTRACT); C(REVERSE_SUBTRACT); C(MIN); C(MAX); #undef C default: return "???"; } } static void gen7_decode_blend(struct kgem *kgem, const uint32_t *reloc) { const struct gen7_blend_state *blend; struct reloc r; const char *dst, *src; const char *func; blend = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); dst = gen7_blend_factor_to_string(blend->blend0.dest_blend_factor); src = gen7_blend_factor_to_string(blend->blend0.source_blend_factor); func = gen7_blend_function_to_string(blend->blend0.blend_func); ErrorF(" Blend (%s): function %s, src=%s, dst=%s\n", blend->blend0.blend_enable ? "enabled" : "disabled", func, src, dst); } int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset) { static const struct { uint32_t opcode; int min_len; int max_len; const char *name; } opcodes[] = { { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, { 0x6102, 2, 2 , "STATE_SIP" }, { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, }; uint32_t *data = kgem->batch + offset; uint32_t op; unsigned int len; int i; const char *name; len = (data[0] & 0xff) + 2; op = (data[0] & 0xffff0000) >> 16; switch (op) { case 0x6101: i = 0; kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); assert(len == 10); state_base_out(data, offset, i++, "general"); state_base_out(data, offset, i++, "surface"); state_base_out(data, offset, i++, "dynamic"); state_base_out(data, offset, i++, "indirect"); state_base_out(data, offset, i++, "instruction"); state_max_out(data, offset, i++, "general"); state_max_out(data, offset, i++, "dynamic"); state_max_out(data, offset, i++, "indirect"); state_max_out(data, offset, i++, "instruction"); gen7_update_dynamic_buffer(kgem, offset + 3); return len; case 0x7808: assert((len - 1) % 4 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); for (i = 1; i < len;) { gen7_update_vertex_buffer(kgem, data + i); kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", data[i] >> 26, data[i] & (1 << 20) ? "random" : "sequential", data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i++, "buffer address\n"); kgem_debug_print(data, offset, i++, "max index\n"); kgem_debug_print(data, offset, i++, "mbz\n"); } return len; case 0x7809: assert((len + 1) % 2 == 0); kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); for (i = 1; i < len;) { gen7_update_vertex_elements(kgem, (i - 1)/2, data + i); kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, " "src offset 0x%04x bytes\n", data[i] >> 26, data[i] & (1 << 25) ? "" : "in", (data[i] >> 16) & 0x1ff, data[i] & 0x07ff); i++; kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), " "dst offset 0x%02x bytes\n", get_element_component(data[i], 0), get_element_component(data[i], 1), get_element_component(data[i], 2), get_element_component(data[i], 3), (data[i] & 0xff) * 4); i++; } return len; case 0x780a: assert(len == 3); kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); kgem_debug_print(data, offset, 1, "beginning buffer address\n"); kgem_debug_print(data, offset, 2, "ending buffer address\n"); return len; case 0x7b00: assert(len == 7); kgem_debug_print(data, offset, 0, "3DPRIMITIVE\n"); kgem_debug_print(data, offset, 1, "type %s, %s\n", get_prim_type(data[1]), (data[1] & (1 << 15)) ? "random" : "sequential"); kgem_debug_print(data, offset, 2, "vertex count\n"); kgem_debug_print(data, offset, 3, "start vertex\n"); kgem_debug_print(data, offset, 4, "instance count\n"); kgem_debug_print(data, offset, 5, "start instance\n"); kgem_debug_print(data, offset, 6, "index bias\n"); primitive_out(kgem, data); return len; } /* For the rest, just dump the bytes */ name = NULL; for (i = 0; i < ARRAY_SIZE(opcodes); i++) if (op == opcodes[i].opcode) { name = opcodes[i].name; break; } len = (data[0] & 0xff) + 2; if (name == NULL) { kgem_debug_print(data, offset, 0, "unknown\n"); } else { kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); if (opcodes[i].max_len > 1) { assert(len >= opcodes[i].min_len && len <= opcodes[i].max_len); } } for (i = 1; i < len; i++) kgem_debug_print(data, offset, i, "dword %d\n", i); return len; } void kgem_gen7_finish_state(struct kgem *kgem) { finish_state(kgem); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/rop.h000066400000000000000000000144561267532330400226260ustar00rootroot00000000000000#ifndef ROP_H #define ROP_H #define ROP_0 0x00 #define ROP_DPSoon 0x01 #define ROP_DPSona 0x02 #define ROP_PSon 0x03 #define ROP_SDPona 0x04 #define ROP_DPon 0x05 #define ROP_PDSxnon 0x06 #define ROP_PDSaon 0x07 #define ROP_SDPnaa 0x08 #define ROP_PDSxon 0x09 #define ROP_DPna 0x0A #define ROP_PSDnaon 0x0B #define ROP_SPna 0x0C #define ROP_PDSnaon 0x0D #define ROP_PDSonon 0x0E #define ROP_Pn 0x0F #define ROP_PDSona 0x10 #define ROP_DSon 0x11 #define ROP_SDPxnon 0x12 #define ROP_SDPaon 0x13 #define ROP_DPSxnon 0x14 #define ROP_DPSaon 0x15 #define ROP_PSDPSanaxx 0x16 #define ROP_SSPxDSxaxn 0x17 #define ROP_SPxPDxa 0x18 #define ROP_SDPSanaxn 0x19 #define ROP_PDSPaox 0x1A #define ROP_SDPSxaxn 0x1B #define ROP_PSDPaox 0x1C #define ROP_DSPDxaxn 0x1D #define ROP_PDSox 0x1E #define ROP_PDSoan 0x1F #define ROP_DPSnaa 0x20 #define ROP_SDPxon 0x21 #define ROP_DSna 0x22 #define ROP_SPDnaon 0x23 #define ROP_SPxDSxa 0x24 #define ROP_PDSPanaxn 0x25 #define ROP_SDPSaox 0x26 #define ROP_SDPSxnox 0x27 #define ROP_DPSxa 0x28 #define ROP_PSDPSaoxxn 0x29 #define ROP_DPSana 0x2A #define ROP_SSPxPDxaxn 0x2B #define ROP_SPDSoax 0x2C #define ROP_PSDnox 0x2D #define ROP_PSDPxox 0x2E #define ROP_PSDnoan 0x2F #define ROP_PSna 0x30 #define ROP_SDPnaon 0x31 #define ROP_SDPSoox 0x32 #define ROP_Sn 0x33 #define ROP_SPDSaox 0x34 #define ROP_SPDSxnox 0x35 #define ROP_SDPox 0x36 #define ROP_SDPoan 0x37 #define ROP_PSDPoax 0x38 #define ROP_SPDnox 0x39 #define ROP_SPDSxox 0x3A #define ROP_SPDnoan 0x3B #define ROP_PSx 0x3C #define ROP_SPDSonox 0x3D #define ROP_SPDSnaox 0x3E #define ROP_PSan 0x3F #define ROP_PSDnaa 0x40 #define ROP_DPSxon 0x41 #define ROP_SDxPDxa 0x42 #define ROP_SPDSanaxn 0x43 #define ROP_SDna 0x44 #define ROP_DPSnaon 0x45 #define ROP_DSPDaox 0x46 #define ROP_PSDPxaxn 0x47 #define ROP_SDPxa 0x48 #define ROP_PDSPDaoxxn 0x49 #define ROP_DPSDoax 0x4A #define ROP_PDSnox 0x4B #define ROP_SDPana 0x4C #define ROP_SSPxDSxoxn 0x4D #define ROP_PDSPxox 0x4E #define ROP_PDSnoan 0x4F #define ROP_PDna 0x50 #define ROP_DSPnaon 0x51 #define ROP_DPSDaox 0x52 #define ROP_SPDSxaxn 0x53 #define ROP_DPSonon 0x54 #define ROP_Dn 0x55 #define ROP_DPSox 0x56 #define ROP_DPSoan 0x57 #define ROP_PDSPoax 0x58 #define ROP_DPSnox 0x59 #define ROP_DPx 0x5A #define ROP_DPSDonox 0x5B #define ROP_DPSDxox 0x5C #define ROP_DPSnoan 0x5D #define ROP_DPSDnaox 0x5E #define ROP_DPan 0x5F #define ROP_PDSxa 0x60 #define ROP_DSPDSaoxxn 0x61 #define ROP_DSPDoax 0x62 #define ROP_SDPnox 0x63 #define ROP_SDPSoax 0x64 #define ROP_DSPnox 0x65 #define ROP_DSx 0x66 #define ROP_SDPSonox 0x67 #define ROP_DSPDSonoxxn 0x68 #define ROP_PDSxxn 0x69 #define ROP_DPSax 0x6A #define ROP_PSDPSoaxxn 0x6B #define ROP_SDPax 0x6C #define ROP_PDSPDoaxxn 0x6D #define ROP_SDPSnoax 0x6E #define ROP_PDSxnan 0x6F #define ROP_PDSana 0x70 #define ROP_SSDxPDxaxn 0x71 #define ROP_SDPSxox 0x72 #define ROP_SDPnoan 0x73 #define ROP_DSPDxox 0x74 #define ROP_DSPnoan 0x75 #define ROP_SDPSnaox 0x76 #define ROP_DSan 0x77 #define ROP_PDSax 0x78 #define ROP_DSPDSoaxxn 0x79 #define ROP_DPSDnoax 0x7A #define ROP_SDPxnan 0x7B #define ROP_SPDSnoax 0x7C #define ROP_DPSxnan 0x7D #define ROP_SPxDSxo 0x7E #define ROP_DPSaan 0x7F #define ROP_DPSaa 0x80 #define ROP_SPxDSxon 0x81 #define ROP_DPSxna 0x82 #define ROP_SPDSnoaxn 0x83 #define ROP_SDPxna 0x84 #define ROP_PDSPnoaxn 0x85 #define ROP_DSPDSoaxx 0x86 #define ROP_PDSaxn 0x87 #define ROP_DSa 0x88 #define ROP_SDPSnaoxn 0x89 #define ROP_DSPnoa 0x8A #define ROP_DSPDxoxn 0x8B #define ROP_SDPnoa 0x8C #define ROP_SDPSxoxn 0x8D #define ROP_SSDxPDxax 0x8E #define ROP_PDSanan 0x8F #define ROP_PDSxna 0x90 #define ROP_SDPSnoaxn 0x91 #define ROP_DPSDPoaxx 0x92 #define ROP_SPDaxn 0x93 #define ROP_PSDPSoaxx 0x94 #define ROP_DPSaxn 0x95 #define ROP_DPSxx 0x96 #define ROP_PSDPSonoxx 0x97 #define ROP_SDPSonoxn 0x98 #define ROP_DSxn 0x99 #define ROP_DPSnax 0x9A #define ROP_SDPSoaxn 0x9B #define ROP_SPDnax 0x9C #define ROP_DSPDoaxn 0x9D #define ROP_DSPDSaoxx 0x9E #define ROP_PDSxan 0x9F #define ROP_DPa 0xA0 #define ROP_PDSPnaoxn 0xA1 #define ROP_DPSnoa 0xA2 #define ROP_DPSDxoxn 0xA3 #define ROP_PDSPonoxn 0xA4 #define ROP_PDxn 0xA5 #define ROP_DSPnax 0xA6 #define ROP_PDSPoaxn 0xA7 #define ROP_DPSoa 0xA8 #define ROP_DPSoxn 0xA9 #define ROP_D 0xAA #define ROP_DPSono 0xAB #define ROP_SPDSxax 0xAC #define ROP_DPSDaoxn 0xAD #define ROP_DSPnao 0xAE #define ROP_DPno 0xAF #define ROP_PDSnoa 0xB0 #define ROP_PDSPxoxn 0xB1 #define ROP_SSPxDSxox 0xB2 #define ROP_SDPanan 0xB3 #define ROP_PSDnax 0xB4 #define ROP_DPSDoaxn 0xB5 #define ROP_DPSDPaoxx 0xB6 #define ROP_SDPxan 0xB7 #define ROP_PSDPxax 0xB8 #define ROP_DSPDaoxn 0xB9 #define ROP_DPSnao 0xBA #define ROP_DSno 0xBB #define ROP_SPDSanax 0xBC #define ROP_SDxPDxan 0xBD #define ROP_DPSxo 0xBE #define ROP_DPSano 0xBF #define ROP_Psa 0xC0 #define ROP_SPDSnaoxn 0xC1 #define ROP_SPDSonoxn 0xC2 #define ROP_PSxn 0xC3 #define ROP_SPDnoa 0xC4 #define ROP_SPDSxoxn 0xC5 #define ROP_SDPnax 0xC6 #define ROP_PSDPoaxn 0xC7 #define ROP_SDPoa 0xC8 #define ROP_SPDoxn 0xC9 #define ROP_DPSDxax 0xCA #define ROP_SPDSaoxn 0xCB #define ROP_S 0xCC #define ROP_SDPono 0xCD #define ROP_SDPnao 0xCE #define ROP_SPno 0xCF #define ROP_PSDnoa 0xD0 #define ROP_PSDPxoxn 0xD1 #define ROP_PDSnax 0xD2 #define ROP_SPDSoaxn 0xD3 #define ROP_SSPxPDxax 0xD4 #define ROP_DPSanan 0xD5 #define ROP_PSDPSaoxx 0xD6 #define ROP_DPSxan 0xD7 #define ROP_PDSPxax 0xD8 #define ROP_SDPSaoxn 0xD9 #define ROP_DPSDanax 0xDA #define ROP_SPxDSxan 0xDB #define ROP_SPDnao 0xDC #define ROP_SDno 0xDD #define ROP_SDPxo 0xDE #define ROP_SDPano 0xDF #define ROP_PDSoa 0xE0 #define ROP_PDSoxn 0xE1 #define ROP_DSPDxax 0xE2 #define ROP_PSDPaoxn 0xE3 #define ROP_SDPSxax 0xE4 #define ROP_PDSPaoxn 0xE5 #define ROP_SDPSanax 0xE6 #define ROP_SPxPDxan 0xE7 #define ROP_SSPxDSxax 0xE8 #define ROP_DSPDSanaxxn 0xE9 #define ROP_DPSao 0xEA #define ROP_DPSxno 0xEB #define ROP_SDPao 0xEC #define ROP_SDPxno 0xED #define ROP_DSo 0xEE #define ROP_SDPnoo 0xEF #define ROP_P 0xF0 #define ROP_PDSono 0xF1 #define ROP_PDSnao 0xF2 #define ROP_PSno 0xF3 #define ROP_PSDnao 0xF4 #define ROP_PDno 0xF5 #define ROP_PDSxo 0xF6 #define ROP_PDSano 0xF7 #define ROP_PDSao 0xF8 #define ROP_PDSxno 0xF9 #define ROP_DPo 0xFA #define ROP_DPSnoo 0xFB #define ROP_PSo 0xFC #define ROP_PSDnoo 0xFD #define ROP_DPSoo 0xFE #define ROP_1 0xFF #define NO_SRC_ROP(rop) \ ((rop == GXnoop) || (rop == GXset) || (rop == GXclear) || (rop == GXinvert)) #endif /* ROP_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna.h000066400000000000000000001032571267532330400226050ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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: * Keith Whitwell * David Dawes * */ #ifndef _SNA_H_ #define _SNA_H_ #include #include #include #include #if XF86_CRTC_VERSION >= 5 #define HAS_PIXMAP_SHARING 1 #endif #include #include #include #include #include #include #include #include "../compat-api.h" #include #include #if HAVE_DRI2 #include #endif #if HAVE_DRI3 #include #endif #if HAVE_UDEV #include #endif #include #include #include "xassert.h" #include "compiler.h" #include "debug.h" #define DEBUG_NO_BLT 0 #define DEBUG_FLUSH_BATCH 0 #define TEST_ALL 0 #define TEST_ACCEL (TEST_ALL || 0) #define TEST_BATCH (TEST_ALL || 0) #define TEST_BLT (TEST_ALL || 0) #define TEST_COMPOSITE (TEST_ALL || 0) #define TEST_DAMAGE (TEST_ALL || 0) #define TEST_GRADIENT (TEST_ALL || 0) #define TEST_GLYPHS (TEST_ALL || 0) #define TEST_IO (TEST_ALL || 0) #define TEST_KGEM (TEST_ALL || 0) #define TEST_RENDER (TEST_ALL || 0) #include "intel_driver.h" #include "intel_list.h" #include "kgem.h" #include "sna_damage.h" #include "sna_render.h" #include "fb/fb.h" struct sna_cursor; struct sna_crtc; struct sna_client { struct list events; int is_compositor; /* only 4 bits used */ }; extern DevPrivateKeyRec sna_client_key; pure static inline struct sna_client *sna_client(ClientPtr client) { return __get_private(client, sna_client_key); } struct sna_cow { struct kgem_bo *bo; struct list list; int refcnt; }; struct sna_pixmap { PixmapPtr pixmap; struct kgem_bo *gpu_bo, *cpu_bo; struct sna_damage *gpu_damage, *cpu_damage; struct sna_cow *cow; void *ptr; #define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1)) bool (*move_to_gpu)(struct sna *, struct sna_pixmap *, unsigned); void *move_to_gpu_data; struct list flush_list; struct list cow_list; uint32_t stride; uint32_t clear_color; #define SOURCE_BIAS 4 uint8_t source_count; uint8_t pinned :4; #define PIN_SCANOUT 0x1 #define PIN_DRI2 0x2 #define PIN_DRI3 0x4 #define PIN_PRIME 0x8 uint8_t create :4; uint8_t mapped :2; #define MAPPED_NONE 0 #define MAPPED_GTT 1 #define MAPPED_CPU 2 uint8_t flush :2; #define FLUSH_READ 1 #define FLUSH_WRITE 2 uint8_t shm :1; uint8_t clear :1; uint8_t header :1; uint8_t cpu :1; }; #define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1) #define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1)) struct sna_glyph { PicturePtr atlas; struct sna_coordinate coordinate; uint16_t size, pos; pixman_image_t *image; }; static inline WindowPtr get_root_window(ScreenPtr screen) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0) return screen->root; #else return WindowTable[screen->myNum]; #endif } #if !NDEBUG static PixmapPtr check_pixmap(PixmapPtr pixmap) { if (pixmap != NULL) { assert(pixmap->refcnt >= 1); assert(pixmap->devKind != 0xdeadbeef); } return pixmap; } #else #define check_pixmap(p) p #endif static inline PixmapPtr get_window_pixmap(WindowPtr window) { assert(window); assert(window->drawable.type != DRAWABLE_PIXMAP); return check_pixmap(fbGetWindowPixmap(window)); } static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) { assert(drawable); if (drawable->type == DRAWABLE_PIXMAP) return check_pixmap((PixmapPtr)drawable); else return get_window_pixmap((WindowPtr)drawable); } extern DevPrivateKeyRec sna_pixmap_key; pure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap) { return ((void **)__get_private(pixmap, sna_pixmap_key))[1]; } static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable) { return sna_pixmap(get_drawable_pixmap(drawable)); } struct sna_gc { long changes; long serial; const GCFuncs *old_funcs; void *priv; }; static inline struct sna_gc *sna_gc(GCPtr gc) { return (struct sna_gc *)__get_private(gc, sna_gc_key); } enum { FLUSH_TIMER = 0, THROTTLE_TIMER, EXPIRE_TIMER, #if DEBUG_MEMORY DEBUG_MEMORY_TIMER, #endif NUM_TIMERS }; struct sna { struct kgem kgem; ScrnInfoPtr scrn; struct intel_device *dev; unsigned flags; #define SNA_IS_SLAVED 0x1 #define SNA_IS_HOSTED 0x2 #define SNA_NO_WAIT 0x10 #define SNA_NO_FLIP 0x20 #define SNA_NO_VSYNC 0x40 #define SNA_TRIPLE_BUFFER 0x80 #define SNA_TEAR_FREE 0x100 #define SNA_FORCE_SHADOW 0x200 #define SNA_FLUSH_GTT 0x400 #define SNA_PERFORMANCE 0x1000 #define SNA_POWERSAVE 0x2000 #define SNA_HAS_FLIP 0x10000 #define SNA_HAS_ASYNC_FLIP 0x20000 #define SNA_LINEAR_FB 0x40000 #define SNA_REPROBE 0x80000000 unsigned cpu_features; #define MMX 0x1 #define SSE 0x2 #define SSE2 0x4 #define SSE3 0x8 #define SSSE3 0x10 #define SSE4_1 0x20 #define SSE4_2 0x40 #define AVX 0x80 #define AVX2 0x100 bool ignore_copy_area : 1; unsigned watch_flush; struct timeval timer_tv; uint32_t timer_expire[NUM_TIMERS]; uint16_t timer_active; int vblank_interval; struct list flush_pixmaps; struct list active_pixmaps; PixmapPtr front; PixmapPtr freed_pixmap; struct sna_mode { DamagePtr shadow_damage; struct kgem_bo *shadow; unsigned front_active; unsigned shadow_active; unsigned rr_active; unsigned flip_active; unsigned hidden; bool shadow_enabled; bool shadow_wait; bool dirty; int max_crtc_width, max_crtc_height; RegionRec shadow_region; RegionRec shadow_cancel; struct list shadow_crtc; bool shadow_dirty; unsigned num_real_crtc; unsigned num_real_output; unsigned num_real_encoder; unsigned num_fake; unsigned serial; uint32_t *encoders; #if HAVE_UDEV struct udev_monitor *backlight_monitor; pointer backlight_handler; #endif Bool (*rrGetInfo)(ScreenPtr, Rotation *); } mode; struct { struct sna_cursor *cursors; xf86CursorInfoPtr info; CursorPtr ref; unsigned serial; uint32_t fg, bg; int size; bool disable; bool active; int last_x; int last_y; unsigned max_size; bool use_gtt; int num_stash; struct sna_cursor *stash; void *scratch; } cursor; struct sna_dri2 { bool available; bool open; #if HAVE_DRI2 void *flip_pending; unsigned client_count; #endif } dri2; struct sna_dri3 { bool available; bool open; #if HAVE_DRI3 SyncScreenCreateFenceFunc create_fence; struct list pixmaps; #endif } dri3; struct sna_present { bool available; bool open; #if HAVE_PRESENT struct list vblank_queue; uint64_t unflip; #endif } present; struct sna_xv { XvAdaptorPtr adaptors; int num_adaptors; } xv; EntityInfoPtr pEnt; const struct intel_device_info *info; ScreenBlockHandlerProcPtr BlockHandler; ScreenWakeupHandlerProcPtr WakeupHandler; CloseScreenProcPtr CloseScreen; PicturePtr clear; struct { uint32_t fill_bo; uint32_t fill_pixel; uint32_t fill_alu; } blt_state; union { unsigned gt; struct gen2_render_state gen2; struct gen3_render_state gen3; struct gen4_render_state gen4; struct gen5_render_state gen5; struct gen6_render_state gen6; struct gen7_render_state gen7; struct gen8_render_state gen8; } render_state; /* Broken-out options. */ OptionInfoPtr Options; /* Driver phase/state information */ bool suspended; #if HAVE_UDEV struct udev_monitor *uevent_monitor; pointer uevent_handler; #endif struct { int fd; uint8_t offset; uint8_t remain; char event[256]; } acpi; struct sna_render render; #if DEBUG_MEMORY struct { int pixmap_allocs; int pixmap_cached; int cpu_bo_allocs; size_t shadow_pixels_bytes; size_t cpu_bo_bytes; } debug_memory; #endif }; bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); bool sna_mode_fake_init(struct sna *sna, int num_fake); bool sna_mode_wants_tear_free(struct sna *sna); void sna_mode_adjust_frame(struct sna *sna, int x, int y); extern void sna_mode_discover(struct sna *sna, bool tell); extern void sna_mode_check(struct sna *sna); extern bool sna_mode_disable(struct sna *sna); extern void sna_mode_enable(struct sna *sna); extern void sna_mode_reset(struct sna *sna); extern int sna_mode_wakeup(struct sna *sna); extern void sna_mode_redisplay(struct sna *sna); extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo); extern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list); extern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list); extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, const RegionRec *region); extern void sna_mode_set_primary(struct sna *sna); extern void sna_mode_close(struct sna *sna); extern void sna_mode_fini(struct sna *sna); extern void sna_crtc_config_notify(ScreenPtr screen); extern bool sna_cursors_init(ScreenPtr screen, struct sna *sna); typedef void (*sna_flip_handler_t)(struct drm_event_vblank *e, void *data); extern int sna_page_flip(struct sna *sna, struct kgem_bo *bo, sna_flip_handler_t handler, void *data); pure static inline struct sna * to_sna(ScrnInfoPtr scrn) { return (struct sna *)(scrn->driverPrivate); } pure static inline struct sna * to_sna_from_screen(ScreenPtr screen) { return to_sna(xf86ScreenToScrn(screen)); } pure static inline ScreenPtr to_screen_from_sna(struct sna *sna) { return xf86ScrnToScreen(sna->scrn); } pure static inline struct sna * to_sna_from_pixmap(PixmapPtr pixmap) { return ((void **)__get_private(pixmap, sna_pixmap_key))[0]; } pure static inline struct sna * to_sna_from_drawable(DrawablePtr drawable) { return to_sna_from_screen(drawable->pScreen); } static inline struct sna * to_sna_from_kgem(struct kgem *kgem) { return container_of(kgem, struct sna, kgem); } #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif #ifndef ALIGN #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #endif #ifndef MIN #define MIN(a,b) ((a) <= (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a,b) ((a) >= (b) ? (a) : (b)) #endif extern xf86CrtcPtr sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired); extern xf86CrtcPtr sna_primary_crtc(struct sna *sna); extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap, xf86CrtcPtr crtc, const BoxRec *clip); const struct ust_msc { uint64_t msc; int tv_sec; int tv_usec; } *sna_crtc_last_swap(xf86CrtcPtr crtc); uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, int tv_sec, int tv_usec, unsigned seq); static inline uint64_t sna_crtc_record_vblank(xf86CrtcPtr crtc, const union drm_wait_vblank *vbl) { return sna_crtc_record_swap(crtc, vbl->reply.tval_sec, vbl->reply.tval_usec, vbl->reply.sequence); } static inline uint64_t sna_crtc_record_event(xf86CrtcPtr crtc, struct drm_event_vblank *event) { return sna_crtc_record_swap(crtc, event->tv_sec, event->tv_usec, event->sequence); } static inline uint64_t ust64(int tv_sec, int tv_usec) { return (uint64_t)tv_sec * 1000000 + tv_usec; } static inline uint64_t swap_ust(const struct ust_msc *swap) { return ust64(swap->tv_sec, swap->tv_usec); } #if HAVE_DRI2 bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen); void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event); void sna_dri2_vblank_handler(struct drm_event_vblank *event); void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo); void sna_dri2_decouple_window(WindowPtr win); void sna_dri2_destroy_window(WindowPtr win); void sna_dri2_close(struct sna *sna, ScreenPtr pScreen); #else static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return false; } static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { } static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { } static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { } static inline void sna_dri2_decouple_window(WindowPtr win) { } static inline void sna_dri2_destroy_window(WindowPtr win) { } static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { } #endif #if HAVE_DRI3 bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen); void sna_dri3_close(struct sna *sna, ScreenPtr pScreen); #else static inline bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen) { return false; } static inline void sna_dri3_close(struct sna *sna, ScreenPtr pScreen) { } #endif #if HAVE_PRESENT bool sna_present_open(struct sna *sna, ScreenPtr pScreen); void sna_present_update(struct sna *sna); void sna_present_close(struct sna *sna, ScreenPtr pScreen); void sna_present_vblank_handler(struct drm_event_vblank *event); void sna_present_cancel_flip(struct sna *sna); #else static inline bool sna_present_open(struct sna *sna, ScreenPtr pScreen) { return false; } static inline void sna_present_update(struct sna *sna) { } static inline void sna_present_close(struct sna *sna, ScreenPtr pScreen) { } static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { } static inline void sna_present_cancel_flip(struct sna *sna) { } #endif extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation); extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); #define CRTC_VBLANK 0x3 #define CRTC_ON 0x80000000 static inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc) { unsigned long *flags = crtc->driver_private; assert(flags); return flags; } static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc) { return *sna_crtc_flags(crtc) >> 8 & 0xff; } static inline unsigned sna_crtc_id(xf86CrtcPtr crtc) { return *sna_crtc_flags(crtc) >> 16 & 0xff; } static inline bool sna_crtc_is_on(xf86CrtcPtr crtc) { return *sna_crtc_flags(crtc) & CRTC_ON; } static inline void sna_crtc_set_vblank(xf86CrtcPtr crtc) { assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < 3); ++*sna_crtc_flags(crtc); } static inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc) { assert(*sna_crtc_flags(crtc) & CRTC_VBLANK); --*sna_crtc_flags(crtc); } static inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc) { return *sna_crtc_flags(crtc) & CRTC_VBLANK; } CARD32 sna_format_for_depth(int depth); CARD32 sna_render_format_for_depth(int depth); void sna_debug_flush(struct sna *sna); static inline bool get_window_deltas(PixmapPtr pixmap, int16_t *x, int16_t *y) { #ifdef COMPOSITE *x = -pixmap->screen_x; *y = -pixmap->screen_y; return pixmap->screen_x | pixmap->screen_y; #else *x = *y = 0; return false; #endif } static inline bool get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y) { #ifdef COMPOSITE if (drawable->type == DRAWABLE_WINDOW) return get_window_deltas(pixmap, x, y); #endif *x = *y = 0; return false; } static inline int get_drawable_dx(DrawablePtr drawable) { #ifdef COMPOSITE if (drawable->type == DRAWABLE_WINDOW) return -get_drawable_pixmap(drawable)->screen_x; #endif return 0; } static inline int get_drawable_dy(DrawablePtr drawable) { #ifdef COMPOSITE if (drawable->type == DRAWABLE_WINDOW) return -get_drawable_pixmap(drawable)->screen_y; #endif return 0; } struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo); static inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap) { return (pixmap == sna->front && !sna->mode.shadow_active && (sna->flags & SNA_NO_WAIT) == 0); } static inline int sna_max_tile_copy_size(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst) { int min_object; int max_size; max_size = sna->kgem.aperture_high * PAGE_SIZE; max_size -= MAX(kgem_bo_size(src), kgem_bo_size(dst)); if (max_size <= 0) { DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__)); return 0; } if (max_size > sna->kgem.max_copy_tile_size) max_size = sna->kgem.max_copy_tile_size; min_object = MIN(kgem_bo_size(src), kgem_bo_size(dst)) / 2; if (max_size > min_object) max_size = min_object; if (max_size <= 4096) max_size = 0; DBG(("%s: using max tile size of %d\n", __FUNCTION__, max_size)); return max_size; } PixmapPtr sna_pixmap_create_upload(ScreenPtr screen, int width, int height, int depth, unsigned flags); PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, int width, int height, int depth); void sna_pixmap_destroy(PixmapPtr pixmap); #define assert_pixmap_map(pixmap, priv) do { \ assert(priv->mapped != MAPPED_NONE || pixmap->devPrivate.ptr == PTR(priv->ptr)); \ assert(priv->mapped != MAPPED_CPU || pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)); \ assert(priv->mapped != MAPPED_GTT || pixmap->devPrivate.ptr == priv->gpu_bo->map__gtt || pixmap->devPrivate.ptr == priv->gpu_bo->map__wc); \ } while (0) static inline void sna_pixmap_unmap(PixmapPtr pixmap, struct sna_pixmap *priv) { if (priv->mapped == MAPPED_NONE) { assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); return; } DBG(("%s: pixmap=%ld dropping %s mapping\n", __FUNCTION__, pixmap->drawable.serialNumber, priv->mapped == MAPPED_CPU ? "cpu" : "gtt")); assert_pixmap_map(pixmap, priv); pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; priv->mapped = MAPPED_NONE; } bool sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags); #define MOVE_WRITE 0x1 #define MOVE_READ 0x2 #define MOVE_INPLACE_HINT 0x4 #define MOVE_ASYNC_HINT 0x8 #define MOVE_SOURCE_HINT 0x10 #define MOVE_WHOLE_HINT 0x20 #define __MOVE_FORCE 0x40 #define __MOVE_DRI 0x80 #define __MOVE_SCANOUT 0x100 #define __MOVE_TILED 0x200 #define __MOVE_PRIME 0x400 struct sna_pixmap * sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags); struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags); static inline struct sna_pixmap * sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags) { /* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */ DBG(("%s(pixmap=%ld, flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, flags)); return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE); } bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags); static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags) { if (flags == MOVE_READ) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return true; } return _sna_pixmap_move_to_cpu(pixmap, flags); } bool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable, RegionPtr region, unsigned flags); bool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags); static inline bool must_check sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags) { return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL; } void sna_add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv, struct kgem_bo *bo); struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); #define PREFER_GPU 0x1 #define FORCE_GPU 0x2 #define RENDER_GPU 0x4 #define IGNORE_DAMAGE 0x8 #define REPLACES 0x10 struct kgem_bo * sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, struct sna_damage ***damage); inline static int16_t bound(int16_t a, uint16_t b) { int v = (int)a + (int)b; if (v > MAXSHORT) return MAXSHORT; return v; } inline static int16_t clamp(int16_t a, int16_t b) { int v = (int)a + (int)b; if (v > MAXSHORT) return MAXSHORT; if (v < MINSHORT) return MINSHORT; return v; } static inline bool box_empty(const BoxRec *box) { return box->x2 <= box->x1 || box->y2 <= box->y1; } static inline bool box_covers_pixmap(PixmapPtr pixmap, const BoxRec *box) { int w = box->x2 - box->x1; int h = box->y2 - box->y1; return pixmap->drawable.width <= w && pixmap->drawable.height <= h; } static inline bool box_inplace(PixmapPtr pixmap, const BoxRec *box) { struct sna *sna = to_sna_from_pixmap(pixmap); return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; } static inline bool whole_pixmap_inplace(PixmapPtr pixmap) { struct sna *sna = to_sna_from_pixmap(pixmap); return ((int)pixmap->drawable.width * (int)pixmap->drawable.height * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; } static inline bool region_subsumes_drawable(RegionPtr region, DrawablePtr drawable) { const BoxRec *extents; if (region->data) return false; extents = RegionExtents(region); return extents->x1 <= 0 && extents->y1 <= 0 && extents->x2 >= drawable->width && extents->y2 >= drawable->height; } static inline bool region_subsumes_pixmap(const RegionRec *region, PixmapPtr pixmap) { if (region->data) return false; return (region->extents.x2 - region->extents.x1 >= pixmap->drawable.width && region->extents.y2 - region->extents.y1 >= pixmap->drawable.height); } static inline bool region_subsumes_damage(const RegionRec *region, struct sna_damage *damage) { const BoxRec *re, *de; DBG(("%s?\n", __FUNCTION__)); assert(damage); re = ®ion->extents; de = &DAMAGE_PTR(damage)->extents; DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n", __FUNCTION__, re->x1, re->y1, re->x2, re->y2, de->x1, de->y1, de->x2, de->y2)); if (re->x2 < de->x2 || re->x1 > de->x1 || re->y2 < de->y2 || re->y1 > de->y1) { DBG(("%s: not contained\n", __FUNCTION__)); return false; } if (region->data == NULL) { DBG(("%s: singular region contains damage\n", __FUNCTION__)); return true; } return pixman_region_contains_rectangle((RegionPtr)region, (BoxPtr)de) == PIXMAN_REGION_IN; } static inline bool sna_drawable_is_clear(DrawablePtr d) { struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); return priv && priv->clear && priv->clear_color == 0; } static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap) { return sna_pixmap(pixmap)->gpu_bo; } static inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d) { struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); return priv ? priv->gpu_bo : NULL; } static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags) { struct sna_pixmap *priv; priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ); if (!priv) return NULL; priv->pinned |= flags; return priv->gpu_bo; } static inline bool _sna_transform_point(const PictTransform *transform, int64_t x, int64_t y, int64_t result[3]) { int j; for (j = 0; j < 3; j++) result[j] = (transform->matrix[j][0] * x + transform->matrix[j][1] * y + transform->matrix[j][2]); return result[2] != 0; } static inline void _sna_get_transformed_coordinates(int x, int y, const PictTransform *transform, float *x_out, float *y_out) { int64_t result[3]; _sna_transform_point(transform, x, y, result); *x_out = result[0] / (double)result[2]; *y_out = result[1] / (double)result[2]; } static inline void _sna_get_transformed_scaled(int x, int y, const PictTransform *transform, const float *sf, float *x_out, float *y_out) { *x_out = sf[0] * (transform->matrix[0][0] * x + transform->matrix[0][1] * y + transform->matrix[0][2]); *y_out = sf[1] * (transform->matrix[1][0] * x + transform->matrix[1][1] * y + transform->matrix[1][2]); } void sna_get_transformed_coordinates(int x, int y, const PictTransform *transform, float *x_out, float *y_out); void sna_get_transformed_coordinates_3d(int x, int y, const PictTransform *transform, float *x_out, float *y_out, float *z_out); bool sna_transform_is_affine(const PictTransform *t); bool sna_transform_is_translation(const PictTransform *t, pixman_fixed_t *tx, pixman_fixed_t *ty); bool sna_transform_is_integer_translation(const PictTransform *t, int16_t *tx, int16_t *ty); bool sna_transform_is_imprecise_integer_translation(const PictTransform *t, int filter, bool precise, int16_t *tx, int16_t *ty); static inline bool sna_affine_transform_is_rotation(const PictTransform *t) { assert(sna_transform_is_affine(t)); return t->matrix[0][1] | t->matrix[1][0]; } static inline bool sna_transform_equal(const PictTransform *a, const PictTransform *b) { if (a == b) return true; if (a == NULL || b == NULL) return false; return memcmp(a, b, sizeof(*a)) == 0; } static inline bool sna_picture_alphamap_equal(PicturePtr a, PicturePtr b) { if (a->alphaMap != b->alphaMap) return false; if (a->alphaMap) return false; return (a->alphaOrigin.x == b->alphaOrigin.x && a->alphaOrigin.y == b->alphaOrigin.y); } static inline bool wedged(struct sna *sna) { return unlikely(sna->kgem.wedged); } static inline bool can_render(struct sna *sna) { return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER); } static inline uint32_t pixmap_size(PixmapPtr pixmap) { return (pixmap->drawable.height - 1) * pixmap->devKind + pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8; } bool sna_accel_init(ScreenPtr sreen, struct sna *sna); void sna_accel_create(struct sna *sna); void sna_accel_block(struct sna *sna, struct timeval **tv); void sna_accel_watch_flush(struct sna *sna, int enable); void sna_accel_flush(struct sna *sna); void sna_accel_enter(struct sna *sna); void sna_accel_leave(struct sna *sna); void sna_accel_close(struct sna *sna); void sna_accel_free(struct sna *sna); void sna_copy_fbcon(struct sna *sna); bool sna_composite_create(struct sna *sna); void sna_composite_close(struct sna *sna); void sna_composite(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height); void sna_composite_fb(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, RegionPtr region, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height); void sna_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor *color, int num_rects, xRectangle *rects); void sna_composite_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps); void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t); void sna_composite_triangles(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle *tri); void sna_composite_tristrip(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int npoints, xPointFixed *points); void sna_composite_trifan(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int npoints, xPointFixed *points); bool sna_gradients_create(struct sna *sna); void sna_gradients_close(struct sna *sna); bool sna_glyphs_create(struct sna *sna); void sna_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); void sna_glyphs__shared(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs); void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); void sna_glyphs_close(struct sna *sna); void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, const BoxRec *box, int n); bool sna_write_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const void *src, int stride, int16_t src_dx, int16_t src_dy, const BoxRec *box, int n); bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const void *src, int stride, int16_t src_dx, int16_t src_dy, const BoxRec *box, int nbox, uint32_t and, uint32_t or); bool sna_replace(struct sna *sna, PixmapPtr pixmap, const void *src, int stride); bool sna_replace__xor(struct sna *sna, PixmapPtr pixmap, const void *src, int stride, uint32_t and, uint32_t or); bool sna_compute_composite_extents(BoxPtr extents, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height); bool sna_compute_composite_region(RegionPtr region, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height); void memcpy_blt(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height); void affine_blt(const void *src, void *dst, int bpp, int16_t src_x, int16_t src_y, int16_t src_width, int16_t src_height, int32_t src_stride, int16_t dst_x, int16_t dst_y, uint16_t dst_width, uint16_t dst_height, int32_t dst_stride, const struct pixman_f_transform *t); void memmove_box(const void *src, void *dst, int bpp, int32_t stride, const BoxRec *box, int dx, int dy); void memcpy_xor(const void *src, void *dst, int bpp, int32_t src_stride, int32_t dst_stride, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height, uint32_t and, uint32_t or); #define SNA_CREATE_FB 0x10 #define SNA_CREATE_SCRATCH 0x11 inline static bool is_power_of_two(unsigned x) { return (x & (x-1)) == 0; } inline static bool is_clipped(const RegionRec *r, const DrawableRec *d) { DBG(("%s: region[%d]x(%d, %d),(%d, %d) against drawable %dx%d\n", __FUNCTION__, region_num_rects(r), r->extents.x1, r->extents.y1, r->extents.x2, r->extents.y2, d->width, d->height)); return (r->data || r->extents.x2 - r->extents.x1 != d->width || r->extents.y2 - r->extents.y1 != d->height); } inline static bool box_intersect(BoxPtr a, const BoxRec *b) { if (a->x1 < b->x1) a->x1 = b->x1; if (a->x2 > b->x2) a->x2 = b->x2; if (a->x1 >= a->x2) return false; if (a->y1 < b->y1) a->y1 = b->y1; if (a->y2 > b->y2) a->y2 = b->y2; if (a->y1 >= a->y2) return false; return true; } const BoxRec * __find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y); inline static const BoxRec * find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y) { /* Special case for incremental trapezoid clipping */ if (begin == end) return end; /* Quick test if scanline is within range of clip boxes */ if (begin->y2 > y) { assert(end == begin + 1 || __find_clip_box_for_y(begin, end, y) == begin); return begin; } if (y >= end[-1].y2) { assert(end == begin + 1 || __find_clip_box_for_y(begin, end, y) == end); return end; } /* Otherwise bisect to find the first box crossing y */ return __find_clip_box_for_y(begin, end, y); } unsigned sna_cpu_detect(void); char *sna_cpu_features_to_string(unsigned features, char *line); /* sna_acpi.c */ int sna_acpi_open(void); void sna_acpi_init(struct sna *sna); void _sna_acpi_wakeup(struct sna *sna); static inline void sna_acpi_wakeup(struct sna *sna, void *read_mask) { if (sna->acpi.fd >= 0 && FD_ISSET(sna->acpi.fd, (fd_set*)read_mask)) _sna_acpi_wakeup(sna); } void sna_acpi_fini(struct sna *sna); void sna_threads_init(void); int sna_use_threads (int width, int height, int threshold); void sna_threads_run(int id, void (*func)(void *arg), void *arg); void sna_threads_trap(int sig); void sna_threads_wait(void); void sna_threads_kill(void); void sna_image_composite(pixman_op_t op, pixman_image_t *src, pixman_image_t *mask, pixman_image_t *dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height); extern jmp_buf sigjmp[4]; extern volatile sig_atomic_t sigtrap; #define sigtrap_assert_inactive() assert(sigtrap == 0) #define sigtrap_assert_active() assert(sigtrap > 0 && sigtrap <= ARRAY_SIZE(sigjmp)) #define sigtrap_get() sigsetjmp(sigjmp[sigtrap++], 1) static inline void sigtrap_put(void) { sigtrap_assert_active(); --sigtrap; } #define RR_Rotate_All (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270) #define RR_Reflect_All (RR_Reflect_X | RR_Reflect_Y) #ifndef HAVE_GETLINE #include extern int getline(char **line, size_t *len, FILE *file); #endif #endif /* _SNA_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_accel.c000066400000000000000000016507221267532330400237340ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_reg.h" #include "sna_video.h" #include "rop.h" #include "intel_options.h" #include #include #include #include #include #include #include #ifdef RENDER #include #endif #include #include #include #include #include #ifdef HAVE_VALGRIND #include #include #endif #define FAULT_INJECTION 0 #define FORCE_INPLACE 0 #define FORCE_FALLBACK 0 #define FORCE_FLUSH 0 #define FORCE_FULL_SYNC 0 /* https://bugs.freedesktop.org/show_bug.cgi?id=61628 */ #define DEFAULT_PIXMAP_TILING I915_TILING_X #define DEFAULT_SCANOUT_TILING I915_TILING_X #define USE_INPLACE 1 #define USE_SPANS 0 /* -1 force CPU, 1 force GPU */ #define USE_CPU_BO 1 #define USE_USERPTR_UPLOADS 1 #define USE_USERPTR_DOWNLOADS 1 #define USE_COW 1 #define UNDO 1 #define MIGRATE_ALL 0 #define DBG_NO_PARTIAL_MOVE_TO_CPU 0 #define DBG_NO_CPU_UPLOAD 0 #define DBG_NO_CPU_DOWNLOAD 0 #define ACCEL_FILL_SPANS 1 #define ACCEL_SET_SPANS 1 #define ACCEL_PUT_IMAGE 1 #define ACCEL_GET_IMAGE 1 #define ACCEL_COPY_AREA 1 #define ACCEL_COPY_PLANE 1 #define ACCEL_COPY_WINDOW 1 #define ACCEL_POLY_POINT 1 #define ACCEL_POLY_LINE 1 #define ACCEL_POLY_SEGMENT 1 #define ACCEL_POLY_RECTANGLE 1 #define ACCEL_POLY_ARC 1 #define ACCEL_POLY_FILL_POLYGON 1 #define ACCEL_POLY_FILL_RECT 1 #define ACCEL_POLY_FILL_ARC 1 #define ACCEL_POLY_TEXT8 1 #define ACCEL_POLY_TEXT16 1 #define ACCEL_POLY_GLYPH 1 #define ACCEL_IMAGE_TEXT8 1 #define ACCEL_IMAGE_TEXT16 1 #define ACCEL_IMAGE_GLYPH 1 #define ACCEL_PUSH_PIXELS 1 #define NO_TILE_8x8 0 #define NO_STIPPLE_8x8 0 #define IS_COW_OWNER(ptr) ((uintptr_t)(ptr) & 1) #define MAKE_COW_OWNER(ptr) ((void*)((uintptr_t)(ptr) | 1)) #define COW(ptr) (void *)((uintptr_t)(ptr) & ~1) #define IS_CLIPPED 0x2 #define RECTILINEAR 0x4 #define OVERWRITES 0x8 #if 0 static void __sna_fallback_flush(DrawablePtr d) { PixmapPtr pixmap = get_drawable_pixmap(d); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; BoxRec box; PixmapPtr tmp; int i, j; char *src, *dst; DBG(("%s: uploading CPU damage...\n", __FUNCTION__)); priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ); if (priv == NULL) return; DBG(("%s: downloading GPU damage...\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return; box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; tmp = sna_pixmap_create_unattached(pixmap->drawable.pScreen, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth, 0); DBG(("%s: comparing with direct read...\n", __FUNCTION__)); sna_read_boxes(sna, tmp, priv->gpu_bo, &box, 1); src = pixmap->devPrivate.ptr; dst = tmp->devPrivate.ptr; for (i = 0; i < tmp->drawable.height; i++) { if (memcmp(src, dst, tmp->drawable.width * tmp->drawable.bitsPerPixel >> 3)) { for (j = 0; src[j] == dst[j]; j++) ; ERR(("mismatch at (%d, %d)\n", 8*j / tmp->drawable.bitsPerPixel, i)); abort(); } src += pixmap->devKind; dst += tmp->devKind; } tmp->drawable.pScreen->DestroyPixmap(tmp); } #define FALLBACK_FLUSH(d) __sna_fallback_flush(d) #else #define FALLBACK_FLUSH(d) #endif static int sna_font_key; static const uint8_t copy_ROP[] = { ROP_0, /* GXclear */ ROP_DSa, /* GXand */ ROP_SDna, /* GXandReverse */ ROP_S, /* GXcopy */ ROP_DSna, /* GXandInverted */ ROP_D, /* GXnoop */ ROP_DSx, /* GXxor */ ROP_DSo, /* GXor */ ROP_DSon, /* GXnor */ ROP_DSxn, /* GXequiv */ ROP_Dn, /* GXinvert */ ROP_SDno, /* GXorReverse */ ROP_Sn, /* GXcopyInverted */ ROP_DSno, /* GXorInverted */ ROP_DSan, /* GXnand */ ROP_1 /* GXset */ }; static const uint8_t fill_ROP[] = { ROP_0, ROP_DPa, ROP_PDna, ROP_P, ROP_DPna, ROP_D, ROP_DPx, ROP_DPo, ROP_DPon, ROP_PDxn, ROP_Dn, ROP_PDno, ROP_Pn, ROP_DPno, ROP_DPan, ROP_1 }; static const GCOps sna_gc_ops; static const GCOps sna_gc_ops__cpu; static GCOps sna_gc_ops__tmp; static const GCFuncs sna_gc_funcs; static const GCFuncs sna_gc_funcs__cpu; static void sna_poly_fill_rect__gpu(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect); static inline void region_set(RegionRec *r, const BoxRec *b) { r->extents = *b; r->data = NULL; } static inline bool region_maybe_clip(RegionRec *r, RegionRec *clip) { if (clip->data && !RegionIntersect(r, r, clip)) return false; return !box_empty(&r->extents); } static inline bool region_is_singular(const RegionRec *r) { return r->data == NULL; } static inline bool region_is_unclipped(const RegionRec *r, int w, int h) { return (region_is_singular(r) && w == r->extents.x2 - r->extents.x1 && h == r->extents.y2 - r->extents.y1); } typedef struct box32 { int32_t x1, y1, x2, y2; } Box32Rec; #define PM_IS_SOLID(_draw, _pm) \ (((_pm) & FbFullMask((_draw)->depth)) == FbFullMask((_draw)->depth)) #ifndef NDEBUG static void _assert_pixmap_contains_box(PixmapPtr pixmap, const BoxRec *box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box [(%d, %d), (%d, %d)] is beyond the pixmap=%ld size=%dx%d\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height); } } static void _assert_pixmap_contains_damage(PixmapPtr pixmap, struct sna_damage *damage, const char *function) { if (damage == NULL) return; _assert_pixmap_contains_box(pixmap, &DAMAGE_PTR(damage)->extents, function); } #define assert_pixmap_contains_damage(p,d) _assert_pixmap_contains_damage(p, d, __FUNCTION__) #else #define assert_pixmap_contains_damage(p,d) #endif #define __assert_pixmap_damage(p) do { \ struct sna_pixmap *priv__ = sna_pixmap(p); \ if (priv__) { \ assert(priv__->gpu_damage == NULL || priv__->gpu_bo); \ assert(priv__->gpu_bo == NULL || priv__->gpu_bo->refcnt); \ assert(priv__->cpu_bo == NULL || priv__->cpu_bo->refcnt); \ assert_pixmap_contains_damage(p, priv__->gpu_damage); \ assert_pixmap_contains_damage(p, priv__->cpu_damage); \ assert_pixmap_map(p, priv__); \ } \ } while (0) #ifdef DEBUG_PIXMAP static void _assert_pixmap_contains_box_with_offset(PixmapPtr pixmap, const BoxRec *box, int dx, int dy, const char *function) { BoxRec b = *box; b.x1 += dx; b.x2 += dx; b.y1 += dy; b.y2 += dy; _assert_pixmap_contains_box(pixmap, &b, function); } static void _assert_pixmap_contains_boxes(PixmapPtr pixmap, const BoxRec *box, int n, int dx, int dy, const char *function) { BoxRec extents; extents = *box; while (--n) { ++box; if (box->x1 < extents.x1) extents.x1 = box->x1; if (box->x2 > extents.x2) extents.x2 = box->x2; if (box->y1 < extents.y1) extents.y1 = box->y1; if (box->y2 > extents.y2) extents.y2 = box->y2; } extents.x1 += dx; extents.x2 += dx; extents.y1 += dy; extents.y2 += dy; _assert_pixmap_contains_box(pixmap, &extents, function); } static void _assert_pixmap_contains_points(PixmapPtr pixmap, const DDXPointRec *pt, int n, int dx, int dy, const char *function) { BoxRec extents; extents.x2 = extents.x1 = pt->x; extents.y2 = extents.y1 = pt->y; while (--n) { ++pt; if (pt->x < extents.x1) extents.x1 = pt->x; else if (pt->x > extents.x2) extents.x2 = pt->x; if (pt->y < extents.y1) extents.y1 = pt->y; else if (pt->y > extents.y2) extents.y2 = pt->y; } extents.x1 += dx; extents.x2 += dx + 1; extents.y1 += dy; extents.y2 += dy + 1; _assert_pixmap_contains_box(pixmap, &extents, function); } static void _assert_drawable_contains_box(DrawablePtr drawable, const BoxRec *box, const char *function) { if (box->x1 < drawable->x || box->y1 < drawable->y || box->x2 > drawable->x + drawable->width || box->y2 > drawable->y + drawable->height) { FatalError("%s: damage box is beyond the drawable: box=(%d, %d), (%d, %d), drawable=(%d, %d)x(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, drawable->x, drawable->y, drawable->width, drawable->height); } } static void assert_pixmap_damage(PixmapPtr p) { struct sna_pixmap *priv; RegionRec reg, cpu, gpu; priv = sna_pixmap(p); if (priv == NULL) return; __assert_pixmap_damage(p); if (priv->clear) { assert(DAMAGE_IS_ALL(priv->gpu_damage)); assert(priv->cpu_damage == NULL); } if (DAMAGE_IS_ALL(priv->gpu_damage) && DAMAGE_IS_ALL(priv->cpu_damage)) { /* special upload buffer */ assert(priv->gpu_bo && priv->gpu_bo->proxy); assert(priv->cpu_bo == NULL); return; } assert(!DAMAGE_IS_ALL(priv->gpu_damage) || priv->cpu_damage == NULL); assert(!DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL); /* Avoid reducing damage to minimise interferrence */ RegionNull(®); RegionNull(&gpu); RegionNull(&cpu); if (priv->gpu_damage) _sna_damage_debug_get_region(DAMAGE_PTR(priv->gpu_damage), &gpu); if (priv->cpu_damage) _sna_damage_debug_get_region(DAMAGE_PTR(priv->cpu_damage), &cpu); RegionIntersect(®, &cpu, &gpu); assert(RegionNil(®)); RegionUninit(®); RegionUninit(&gpu); RegionUninit(&cpu); } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #define assert_pixmap_contains_box_with_offset(p, b, dx, dy) _assert_pixmap_contains_box_with_offset(p, b, dx, dy, __FUNCTION__) #define assert_drawable_contains_box(d, b) _assert_drawable_contains_box(d, b, __FUNCTION__) #define assert_pixmap_contains_boxes(p, b, n, x, y) _assert_pixmap_contains_boxes(p, b, n, x, y, __FUNCTION__) #define assert_pixmap_contains_points(p, pt, n, x, y) _assert_pixmap_contains_points(p, pt, n, x, y, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #define assert_pixmap_contains_box_with_offset(p, b, dx, dy) #define assert_pixmap_contains_boxes(p, b, n, x, y) #define assert_pixmap_contains_points(p, pt, n, x, y) #define assert_drawable_contains_box(d, b) #ifndef NDEBUG #define assert_pixmap_damage(p) __assert_pixmap_damage(p) #else #define assert_pixmap_damage(p) #endif #endif jmp_buf sigjmp[4]; volatile sig_atomic_t sigtrap; static int sigtrap_handler(int sig) { /* XXX rate-limited squawk? */ DBG(("%s(sig=%d) sigtrap=%d\n", __FUNCTION__, sig, sigtrap)); sna_threads_trap(sig); if (sigtrap) siglongjmp(sigjmp[--sigtrap], sig); return -1; } static void sigtrap_init(void) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0) OsRegisterSigWrapper(sigtrap_handler); #endif } inline static bool sna_fill_init_blt(struct sna_fill_op *fill, struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo, uint8_t alu, uint32_t pixel, unsigned flags) { return sna->render.fill(sna, alu, pixmap, bo, pixel, flags, fill); } static bool sna_copy_init_blt(struct sna_copy_op *copy, struct sna *sna, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, uint8_t alu) { memset(copy, 0, sizeof(*copy)); return sna->render.copy(sna, alu, src, src_bo, dst, dst_bo, copy); } static void sna_pixmap_free_gpu(struct sna *sna, struct sna_pixmap *priv) { DBG(("%s: handle=%d (pinned? %d)\n", __FUNCTION__, priv->gpu_bo ? priv->gpu_bo->handle : 0, priv->pinned)); assert(priv->gpu_damage == NULL || priv->gpu_bo); if (priv->cow) sna_pixmap_undo_cow(sna, priv, MOVE_WRITE); assert(priv->cow == NULL); if (priv->move_to_gpu) { sna_pixmap_discard_shadow_damage(priv, NULL); priv->move_to_gpu(sna, priv, MOVE_WRITE); } sna_damage_destroy(&priv->gpu_damage); priv->clear = false; if (priv->gpu_bo) { if (!priv->pinned) { assert(!priv->flush); assert(!priv->move_to_gpu); sna_pixmap_unmap(priv->pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } else kgem_bo_undo(&sna->kgem, priv->gpu_bo); } /* and reset the upload counter */ priv->source_count = SOURCE_BIAS; } static bool must_check sna_pixmap_alloc_cpu(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, unsigned flags) { /* Restore after a GTT mapping? */ assert(priv->gpu_damage == NULL || priv->gpu_bo); assert(!priv->shm); if (priv->ptr) goto done; DBG(("%s: pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(priv->stride); if (priv->create & KGEM_CAN_CREATE_CPU) { unsigned hint; DBG(("%s: allocating CPU buffer (%dx%d)\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); hint = CREATE_CPU_MAP | CREATE_INACTIVE | CREATE_NO_THROTTLE; if ((flags & MOVE_ASYNC_HINT) || (priv->gpu_damage && !priv->clear && kgem_bo_is_busy(priv->gpu_bo) && sna->kgem.can_blt_cpu)) hint = 0; priv->cpu_bo = kgem_create_cpu_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, hint); if (priv->cpu_bo) { priv->ptr = kgem_bo_map__cpu(&sna->kgem, priv->cpu_bo); if (priv->ptr) { DBG(("%s: allocated CPU handle=%d (snooped? %d)\n", __FUNCTION__, priv->cpu_bo->handle, priv->cpu_bo->snoop)); priv->stride = priv->cpu_bo->pitch; #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs++; sna->debug_memory.cpu_bo_bytes += kgem_bo_size(priv->cpu_bo); #endif } else { kgem_bo_destroy(&sna->kgem, priv->cpu_bo); priv->cpu_bo = NULL; } } } if (priv->ptr == NULL) { DBG(("%s: allocating ordinary memory for shadow pixels [%d bytes]\n", __FUNCTION__, priv->stride * pixmap->drawable.height)); priv->ptr = malloc(priv->stride * pixmap->drawable.height); } done: assert(priv->stride); assert(!priv->mapped); pixmap->devPrivate.ptr = PTR(priv->ptr); pixmap->devKind = priv->stride; return priv->ptr != NULL; } static void __sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv) { if (priv->cpu_bo) { DBG(("%s: discarding CPU buffer, handle=%d, size=%d\n", __FUNCTION__, priv->cpu_bo->handle, kgem_bo_size(priv->cpu_bo))); #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs--; sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo); #endif if (priv->cpu_bo->flush) { assert(!priv->cpu_bo->reusable); kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); sna_accel_watch_flush(sna, -1); } kgem_bo_destroy(&sna->kgem, priv->cpu_bo); } else if (!IS_STATIC_PTR(priv->ptr)) free(priv->ptr); } static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool active) { if (active) return false; if (IS_STATIC_PTR(priv->ptr)) return false; if (priv->ptr == NULL) return true; DBG(("%s(pixmap=%ld)\n", __FUNCTION__, priv->pixmap->drawable.serialNumber)); __sna_pixmap_free_cpu(sna, priv); priv->cpu_bo = NULL; priv->ptr = NULL; if (priv->mapped == MAPPED_NONE) priv->pixmap->devPrivate.ptr = NULL; return true; } static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap) { #if DEFAULT_PIXMAP_TILING == I915_TILING_NONE return I915_TILING_NONE; #elif DEFAULT_PIXMAP_TILING == I915_TILING_X return I915_TILING_X; #else /* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */ if (sna->kgem.gen == 021) return I915_TILING_X; /* Only on later generations was the render pipeline * more flexible than the BLT. So on gen2/3, prefer to * keep large objects accessible through the BLT. */ if (sna->kgem.gen < 040 && (pixmap->drawable.width > sna->render.max_3d_size || pixmap->drawable.height > sna->render.max_3d_size)) return I915_TILING_X; return I915_TILING_Y; #endif } pure static uint32_t sna_pixmap_default_tiling(struct sna *sna, PixmapPtr pixmap) { /* Also adjust tiling if it is not supported or likely to * slow us down, */ return kgem_choose_tiling(&sna->kgem, default_tiling(sna, pixmap), pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel); } struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna *sna = to_sna_from_pixmap(pixmap); struct kgem_bo *bo; BoxRec box; DBG(("%s: changing tiling %d -> %d for %dx%d pixmap\n", __FUNCTION__, priv->gpu_bo->tiling, tiling, pixmap->drawable.width, pixmap->drawable.height)); assert(priv->gpu_damage == NULL || priv->gpu_bo); assert(priv->gpu_bo->tiling != tiling); if (priv->pinned) { DBG(("%s: can't convert pinned bo\n", __FUNCTION__)); return NULL; } if (wedged(sna)) { DBG(("%s: can't convert bo, wedged\n", __FUNCTION__)); return NULL; } assert_pixmap_damage(pixmap); assert(!priv->move_to_gpu); bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, tiling, 0); if (bo == NULL) { DBG(("%s: allocation failed\n", __FUNCTION__)); return NULL; } if (bo->tiling == priv->gpu_bo->tiling) { DBG(("%s: tiling request failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); return NULL; } box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (!sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); return NULL; } sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); return priv->gpu_bo = bo; } static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna) { ((void **)__get_private(pixmap, sna_pixmap_key))[1] = sna; assert(sna_pixmap(pixmap) == sna); } static struct sna_pixmap * _sna_pixmap_init(struct sna_pixmap *priv, PixmapPtr pixmap) { list_init(&priv->flush_list); list_init(&priv->cow_list); priv->source_count = SOURCE_BIAS; priv->pixmap = pixmap; return priv; } static struct sna_pixmap * _sna_pixmap_reset(PixmapPtr pixmap) { struct sna_pixmap *priv; assert(pixmap->drawable.type == DRAWABLE_PIXMAP); assert(pixmap->drawable.class == 0); assert(pixmap->drawable.x == 0); assert(pixmap->drawable.y == 0); priv = sna_pixmap(pixmap); assert(priv != NULL); memset(priv, 0, sizeof(*priv)); return _sna_pixmap_init(priv, pixmap); } static struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap) { struct sna_pixmap *priv; priv = calloc(1, sizeof(*priv)); if (!priv) return NULL; sna_set_pixmap(pixmap, priv); return _sna_pixmap_init(priv, pixmap); } struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo) { struct sna_pixmap *priv; assert(bo); assert(bo->proxy == NULL); assert(bo->unique_id); priv = sna_pixmap_attach(pixmap); if (!priv) return NULL; DBG(("%s: attaching %s handle=%d to pixmap=%ld\n", __FUNCTION__, bo->snoop ? "CPU" : "GPU", bo->handle, pixmap->drawable.serialNumber)); assert(!priv->mapped); assert(!priv->move_to_gpu); if (bo->snoop) { priv->cpu_bo = bo; sna_damage_all(&priv->cpu_damage, pixmap); } else { priv->gpu_bo = bo; sna_damage_all(&priv->gpu_damage, pixmap); } return priv; } static int bits_per_pixel(int depth) { switch (depth) { case 1: return 1; case 4: case 8: return 8; case 15: case 16: return 16; case 24: case 30: case 32: return 32; default: return 0; } } static PixmapPtr create_pixmap(struct sna *sna, ScreenPtr screen, int width, int height, int depth, unsigned usage_hint) { PixmapPtr pixmap; size_t datasize; size_t stride; int base, bpp; bpp = bits_per_pixel(depth); if (bpp == 0) return NullPixmap; stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); if (stride / 4 > 32767 || height > 32767) return NullPixmap; datasize = height * stride; base = screen->totalPixmapSize; if (datasize && base & 15) { int adjust = 16 - (base & 15); base += adjust; datasize += adjust; } DBG(("%s: allocating pixmap %dx%d, depth=%d/%d, size=%ld\n", __FUNCTION__, width, height, depth, bpp, (long)datasize)); pixmap = AllocatePixmap(screen, datasize); if (!pixmap) return NullPixmap; ((void **)__get_private(pixmap, sna_pixmap_key))[0] = sna; assert(to_sna_from_pixmap(pixmap) == sna); pixmap->drawable.type = DRAWABLE_PIXMAP; pixmap->drawable.class = 0; pixmap->drawable.pScreen = screen; pixmap->drawable.depth = depth; pixmap->drawable.bitsPerPixel = bpp; pixmap->drawable.id = 0; pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pixmap->drawable.x = 0; pixmap->drawable.y = 0; pixmap->drawable.width = width; pixmap->drawable.height = height; pixmap->devKind = stride; pixmap->refcnt = 1; pixmap->devPrivate.ptr = datasize ? (char *)pixmap + base : NULL; #ifdef COMPOSITE pixmap->screen_x = 0; pixmap->screen_y = 0; #endif pixmap->usage_hint = usage_hint; #if DEBUG_MEMORY sna->debug_memory.pixmap_allocs++; #endif DBG(("%s: serial=%ld, usage=%d, %dx%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint, pixmap->drawable.width, pixmap->drawable.height)); return pixmap; } static PixmapPtr __pop_freed_pixmap(struct sna *sna) { PixmapPtr pixmap; assert(sna->freed_pixmap); pixmap = sna->freed_pixmap; sna->freed_pixmap = pixmap->devPrivate.ptr; DBG(("%s: reusing freed pixmap=%ld header\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(pixmap->refcnt == 0); assert(pixmap->devKind = 0xdeadbeef); assert(sna_pixmap(pixmap)); assert(sna_pixmap(pixmap)->header); #if DEBUG_MEMORY sna->debug_memory.pixmap_cached--; #endif return pixmap; } inline static PixmapPtr create_pixmap_hdr(struct sna *sna, ScreenPtr screen, int width, int height, int depth, int usage, struct sna_pixmap **priv) { PixmapPtr pixmap; if (sna->freed_pixmap == NULL) { pixmap = create_pixmap(sna, screen, 0, 0, depth, usage); if (pixmap == NullPixmap) return NullPixmap; *priv = sna_pixmap_attach(pixmap); if (!*priv) { FreePixmap(pixmap); return NullPixmap; } } else { pixmap = __pop_freed_pixmap(sna); *priv = _sna_pixmap_reset(pixmap); assert(pixmap->drawable.type == DRAWABLE_PIXMAP); assert(pixmap->drawable.class == 0); assert(pixmap->drawable.pScreen == screen); assert(pixmap->drawable.x == 0); assert(pixmap->drawable.y == 0); pixmap->drawable.id = 0; pixmap->drawable.depth = depth; pixmap->drawable.bitsPerPixel = bits_per_pixel(depth); pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pixmap->devKind = 0; pixmap->devPrivate.ptr = NULL; #ifdef COMPOSITE pixmap->screen_x = 0; pixmap->screen_y = 0; #endif #if DEBUG_MEMORY sna->debug_memory.pixmap_allocs++; #endif pixmap->refcnt = 1; } DBG(("%s: pixmap=%ld, width=%d, height=%d, usage=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, width, height, usage)); pixmap->drawable.width = width; pixmap->drawable.height = height; pixmap->usage_hint = usage; (*priv)->header = true; return pixmap; } static PixmapPtr sna_pixmap_create_shm(ScreenPtr screen, int width, int height, int depth, char *addr) { struct sna *sna = to_sna_from_screen(screen); int bpp = bits_per_pixel(depth); int pitch = PixmapBytePad(width, depth); struct sna_pixmap *priv; PixmapPtr pixmap; DBG(("%s(%dx%d, depth=%d, bpp=%d, pitch=%d)\n", __FUNCTION__, width, height, depth, bpp, pitch)); if (wedged(sna) || bpp == 0 || pitch*height < 4096) { fallback: pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); if (pixmap == NULL) return NULL; if (!screen->ModifyPixmapHeader(pixmap, width, height, depth, bpp, pitch, addr)) { screen->DestroyPixmap(pixmap); return NULL; } return pixmap; } pixmap = create_pixmap_hdr(sna, screen, width, height, depth, 0, &priv); if (pixmap == NullPixmap) { DBG(("%s: allocation failed\n", __FUNCTION__)); goto fallback; } priv->cpu_bo = kgem_create_map(&sna->kgem, addr, pitch*height, false); if (priv->cpu_bo == NULL) { DBG(("%s: mapping SHM segment failed\n", __FUNCTION__)); sna_pixmap_destroy(pixmap); goto fallback; } priv->cpu_bo->pitch = pitch; kgem_bo_mark_unreusable(priv->cpu_bo); sna_accel_watch_flush(sna, 1); #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs++; sna->debug_memory.cpu_bo_bytes += kgem_bo_size(priv->cpu_bo); #endif /* Be wary as we cannot cache SHM Pixmap in our freed cache */ priv->header = false; priv->cpu = true; priv->shm = true; priv->stride = pitch; priv->ptr = MAKE_STATIC_PTR(addr); sna_damage_all(&priv->cpu_damage, pixmap); pixmap->devKind = pitch; pixmap->devPrivate.ptr = addr; DBG(("%s: serial=%ld, %dx%d, usage=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, pixmap->usage_hint)); return pixmap; } PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, int width, int height, int depth) { return create_pixmap(to_sna_from_screen(screen), screen, width, height, depth, -1); } static PixmapPtr sna_pixmap_create_scratch(ScreenPtr screen, int width, int height, int depth, uint32_t tiling) { struct sna *sna = to_sna_from_screen(screen); struct sna_pixmap *priv; PixmapPtr pixmap; int bpp; DBG(("%s(%d, %d, %d, tiling=%d)\n", __FUNCTION__, width, height, depth, tiling)); bpp = bits_per_pixel(depth); if (tiling == I915_TILING_Y && (sna->render.prefer_gpu & PREFER_GPU_RENDER) == 0) tiling = I915_TILING_X; if (tiling == I915_TILING_Y && (width > sna->render.max_3d_size || height > sna->render.max_3d_size)) tiling = I915_TILING_X; tiling = kgem_choose_tiling(&sna->kgem, tiling, width, height, bpp); /* you promise never to access this via the cpu... */ pixmap = create_pixmap_hdr(sna, screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH, &priv); if (pixmap == NullPixmap) return NullPixmap; priv->stride = PixmapBytePad(width, depth); priv->gpu_bo = kgem_create_2d(&sna->kgem, width, height, bpp, tiling, CREATE_TEMPORARY); if (priv->gpu_bo == NULL) { free(priv); FreePixmap(pixmap); return NullPixmap; } sna_damage_all(&priv->gpu_damage, pixmap); assert(to_sna_from_pixmap(pixmap) == sna); assert(pixmap->drawable.pScreen == screen); assert(pixmap->refcnt == 1); DBG(("%s: serial=%ld, %dx%d, usage=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, pixmap->usage_hint)); return pixmap; } static unsigned small_copy(const RegionRec *region) { if ((region->extents.x2 - region->extents.x1)*(region->extents.y2 - region->extents.y1) < 1024) { DBG(("%s: region:%dx%d\n", __FUNCTION__, (region->extents.x2 - region->extents.x1), (region->extents.y2 - region->extents.y1))); return COPY_SMALL; } return 0; } #ifdef CREATE_PIXMAP_USAGE_SHARED static Bool sna_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave, void **fd_handle) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; int fd; DBG(("%s: pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE | __MOVE_DRI | __MOVE_PRIME | __MOVE_FORCE); if (priv == NULL) return FALSE; assert(!priv->shm); assert(priv->gpu_bo); assert(priv->stride); /* XXX negotiate format and stride restrictions */ if (priv->gpu_bo->tiling != I915_TILING_NONE || priv->gpu_bo->pitch & 255) { struct kgem_bo *bo; BoxRec box; DBG(("%s: removing tiling %d, and aligning pitch %d for %dx%d pixmap=%ld\n", __FUNCTION__, priv->gpu_bo->tiling, priv->gpu_bo->pitch, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.serialNumber)); if (priv->pinned) { DBG(("%s: can't convert pinned %x bo\n", __FUNCTION__, priv->pinned)); return FALSE; } assert_pixmap_damage(pixmap); bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, I915_TILING_NONE, CREATE_GTT_MAP | CREATE_SCANOUT | CREATE_PRIME | CREATE_EXACT); if (bo == NULL) { DBG(("%s: allocation failed\n", __FUNCTION__)); return FALSE; } box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; assert(!wedged(sna)); /* XXX */ if (!sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); return FALSE; } sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; } assert(priv->gpu_bo->tiling == I915_TILING_NONE); assert((priv->gpu_bo->pitch & 255) == 0); /* And export the bo->pitch via pixmap->devKind */ if (!priv->mapped) { void *ptr; ptr = kgem_bo_map__async(&sna->kgem, priv->gpu_bo); if (ptr == NULL) return FALSE; pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = ptr == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; } assert_pixmap_map(pixmap, priv); fd = kgem_bo_export_to_prime(&sna->kgem, priv->gpu_bo); if (fd == -1) return FALSE; priv->pinned |= PIN_PRIME; *fd_handle = (void *)(intptr_t)fd; return TRUE; } static Bool sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; struct kgem_bo *bo; DBG(("%s: pixmap=%ld, size=%dx%d, depth=%d/%d, stride=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth, pixmap->drawable.bitsPerPixel, pixmap->devKind)); priv = sna_pixmap(pixmap); if (priv == NULL) return FALSE; assert(!priv->pinned); assert(priv->gpu_bo == NULL); assert(priv->cpu_bo == NULL); assert(priv->cpu_damage == NULL); assert(priv->gpu_damage == NULL); bo = kgem_create_for_prime(&sna->kgem, (intptr_t)fd_handle, pixmap->devKind * pixmap->drawable.height); if (bo == NULL) return FALSE; sna_damage_all(&priv->gpu_damage, pixmap); bo->pitch = pixmap->devKind; priv->stride = pixmap->devKind; assert(!priv->mapped); priv->gpu_bo = bo; priv->pinned |= PIN_PRIME; close((intptr_t)fd_handle); return TRUE; } static PixmapPtr sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen, int width, int height, int depth) { PixmapPtr pixmap; struct sna_pixmap *priv; DBG(("%s: width=%d, height=%d, depth=%d\n", __FUNCTION__, width, height, depth)); /* Create a stub to be attached later */ pixmap = create_pixmap_hdr(sna, screen, width, height, depth, 0, &priv); if (pixmap == NullPixmap) return NullPixmap; assert(!priv->mapped); priv->stride = 0; priv->create = 0; if (width|height) { priv->gpu_bo = kgem_create_2d(&sna->kgem, width, height, pixmap->drawable.bitsPerPixel, I915_TILING_NONE, CREATE_GTT_MAP | CREATE_SCANOUT | CREATE_PRIME | CREATE_EXACT); if (priv->gpu_bo == NULL) { free(priv); FreePixmap(pixmap); return NullPixmap; } /* minimal interface for sharing is linear, 256 byte pitch */ assert(priv->gpu_bo->tiling == I915_TILING_NONE); assert((priv->gpu_bo->pitch & 255) == 0); pixmap->devPrivate.ptr = kgem_bo_map__async(&sna->kgem, priv->gpu_bo); if (pixmap->devPrivate.ptr == NULL) { kgem_bo_destroy(&sna->kgem, priv->gpu_bo); free(priv); FreePixmap(pixmap); return FALSE; } pixmap->devKind = priv->gpu_bo->pitch; priv->stride = priv->gpu_bo->pitch; priv->mapped = pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; assert_pixmap_map(pixmap, priv); sna_damage_all(&priv->gpu_damage, pixmap); } return pixmap; } #endif static PixmapPtr sna_create_pixmap(ScreenPtr screen, int width, int height, int depth, unsigned int usage) { struct sna *sna = to_sna_from_screen(screen); PixmapPtr pixmap; struct sna_pixmap *priv; unsigned flags; int pad; void *ptr; DBG(("%s(%d, %d, %d, usage=%x)\n", __FUNCTION__, width, height, depth, usage)); #ifdef CREATE_PIXMAP_USAGE_SHARED if (usage == CREATE_PIXMAP_USAGE_SHARED) return sna_create_pixmap_shared(sna, screen, width, height, depth); #endif if ((width|height) == 0) { usage = -1; goto fallback; } assert(width && height); flags = kgem_can_create_2d(&sna->kgem, width, height, depth); if (flags == 0) { DBG(("%s: can not use GPU, just creating shadow\n", __FUNCTION__)); goto fallback; } if (unlikely((sna->render.prefer_gpu & PREFER_GPU_RENDER) == 0)) flags &= ~KGEM_CAN_CREATE_GPU; if (wedged(sna) && usage != SNA_CREATE_FB) flags &= ~KGEM_CAN_CREATE_GTT; DBG(("%s: usage=%d, flags=%x\n", __FUNCTION__, usage, flags)); switch (usage) { case CREATE_PIXMAP_USAGE_SCRATCH: if (flags & KGEM_CAN_CREATE_GPU) return sna_pixmap_create_scratch(screen, width, height, depth, I915_TILING_X); else goto fallback; case SNA_CREATE_SCRATCH: if (flags & (KGEM_CAN_CREATE_CPU | KGEM_CAN_CREATE_GPU)) return sna_pixmap_create_scratch(screen, width, height, depth, I915_TILING_Y); else return NullPixmap; } if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE) flags &= ~KGEM_CAN_CREATE_GPU; if (usage == CREATE_PIXMAP_USAGE_BACKING_PIXMAP) usage = 0; pad = PixmapBytePad(width, depth); if (pad * height < 4096) { DBG(("%s: small buffer [%d], attaching to shadow pixmap\n", __FUNCTION__, pad * height)); pixmap = create_pixmap(sna, screen, width, height, depth, usage); if (pixmap == NullPixmap) return NullPixmap; ptr = MAKE_STATIC_PTR(pixmap->devPrivate.ptr); pad = pixmap->devKind; flags &= ~(KGEM_CAN_CREATE_GPU | KGEM_CAN_CREATE_CPU); priv = sna_pixmap_attach(pixmap); if (priv == NULL) { free(pixmap); goto fallback; } } else { DBG(("%s: creating GPU pixmap %dx%d, stride=%d, flags=%x\n", __FUNCTION__, width, height, pad, flags)); pixmap = create_pixmap_hdr(sna, screen, width, height, depth, usage, &priv); if (pixmap == NullPixmap) return NullPixmap; ptr = NULL; } priv->stride = pad; priv->create = flags; priv->ptr = ptr; assert(to_sna_from_pixmap(pixmap) == sna); assert(pixmap->drawable.pScreen == screen); assert(pixmap->refcnt == 1); DBG(("%s: serial=%ld, %dx%d, usage=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, pixmap->usage_hint)); return pixmap; fallback: return create_pixmap(sna, screen, width, height, depth, usage); } void sna_add_flush_pixmap(struct sna *sna, struct sna_pixmap *priv, struct kgem_bo *bo) { DBG(("%s: marking pixmap=%ld for flushing\n", __FUNCTION__, priv->pixmap->drawable.serialNumber)); assert(bo); assert(bo->flush); assert(priv->gpu_damage == NULL || priv->gpu_bo); list_move(&priv->flush_list, &sna->flush_pixmaps); if (bo->exec == NULL && sna->kgem.nbatch && kgem_is_idle(&sna->kgem)) { DBG(("%s: new flush bo, flushing before\n", __FUNCTION__)); _kgem_submit(&sna->kgem); } } static void __sna_free_pixmap(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv) { DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber)); list_del(&priv->flush_list); assert(priv->gpu_damage == NULL); assert(priv->cpu_damage == NULL); __sna_pixmap_free_cpu(sna, priv); if (priv->flush) sna_accel_watch_flush(sna, -1); #if !NDEBUG pixmap->devKind = 0xdeadbeef; #endif if (priv->header) { assert(pixmap->drawable.pScreen == to_screen_from_sna(sna)); assert(!priv->shm); pixmap->devPrivate.ptr = sna->freed_pixmap; sna->freed_pixmap = pixmap; #if DEBUG_MEMORY sna->debug_memory.pixmap_cached++; #endif } else { free(priv); FreePixmap(pixmap); } } static Bool sna_destroy_pixmap(PixmapPtr pixmap) { struct sna *sna; struct sna_pixmap *priv; assert(pixmap->refcnt > 0); if (--pixmap->refcnt) return TRUE; #if DEBUG_MEMORY to_sna_from_pixmap(pixmap)->debug_memory.pixmap_allocs--; #endif priv = sna_pixmap(pixmap); DBG(("%s: pixmap=%ld, attached?=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, priv != NULL)); if (priv == NULL) { FreePixmap(pixmap); return TRUE; } assert_pixmap_damage(pixmap); sna = to_sna_from_pixmap(pixmap); sna_damage_destroy(&priv->gpu_damage); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->cow_list); if (priv->cow) { struct sna_cow *cow = COW(priv->cow); DBG(("%s: pixmap=%ld discarding cow, refcnt=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, cow->refcnt)); assert(cow->refcnt); if (!--cow->refcnt) free(cow); priv->cow = NULL; } else kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (priv->move_to_gpu) (void)priv->move_to_gpu(sna, priv, 0); /* Always release the gpu bo back to the lower levels of caching */ if (priv->gpu_bo) { sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } if (priv->shm && kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: deferring release of active SHM pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); kgem_bo_submit(&sna->kgem, priv->cpu_bo); /* XXX ShmDetach */ } else __sna_free_pixmap(sna, pixmap, priv); return TRUE; } void sna_pixmap_destroy(PixmapPtr pixmap) { assert(pixmap->refcnt == 1); assert(sna_pixmap(pixmap) == NULL || sna_pixmap(pixmap)->header == true); sna_destroy_pixmap(pixmap); } static inline bool has_coherent_map(struct sna *sna, struct kgem_bo *bo, unsigned flags) { assert(bo); if (kgem_bo_mapped(&sna->kgem, bo)) return true; if (bo->tiling == I915_TILING_Y) return false; return kgem_bo_can_map__cpu(&sna->kgem, bo, flags & MOVE_WRITE); } static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { if (priv == NULL) return true; if (flags & MOVE_ASYNC_HINT) { /* Not referencing the pointer itself, so do not care */ return true; } if (!priv->mapped) { if (!priv->cpu_bo) return true; assert(!priv->cpu_bo->needs_flush || (flags & MOVE_WRITE) == 0); assert(priv->pixmap->devKind == priv->cpu_bo->pitch); return priv->pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu); } assert(!priv->move_to_gpu || (flags & MOVE_WRITE) == 0); assert_pixmap_map(priv->pixmap, priv); assert(priv->pixmap->devKind == priv->gpu_bo->pitch); if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)) { assert(priv->mapped == MAPPED_CPU); if (priv->gpu_bo->tiling != I915_TILING_NONE) return false; return flags & MOVE_READ || kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE); } if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__gtt)) { assert(priv->mapped == MAPPED_GTT); if (priv->gpu_bo->tiling == I915_TILING_Y && sna->kgem.gen == 0x21) return false; return true; } if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__wc)) { assert(priv->mapped == MAPPED_GTT); return true; } return false; } static inline bool pixmap_inplace(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, unsigned flags) { if (FORCE_INPLACE) return FORCE_INPLACE > 0; if (wedged(sna) && !priv->pinned) { DBG(("%s: no, wedged and unpinned; pull pixmap back to CPU\n", __FUNCTION__)); return false; } if (priv->move_to_gpu && flags & MOVE_WRITE) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) { if (priv->clear) { DBG(("%s: no, clear GPU bo is busy\n", __FUNCTION__)); return false; } if (flags & MOVE_ASYNC_HINT) { DBG(("%s: no, async hint and GPU bo is busy\n", __FUNCTION__)); return false; } if ((flags & (MOVE_WRITE | MOVE_READ)) == (MOVE_WRITE | MOVE_READ)) { DBG(("%s: no, GPU bo is busy\n", __FUNCTION__)); return false; } if ((flags & MOVE_READ) == 0) { DBG(("%s: %s, GPU bo is busy, but not reading\n", __FUNCTION__, priv->pinned ? "no" : "yes")); return !priv->pinned; } } if (priv->mapped) { DBG(("%s: %s, already mapped\n", __FUNCTION__, has_coherent_map(sna, priv->gpu_bo, flags) ? "yes" : "no")); return has_coherent_map(sna, priv->gpu_bo, flags); } if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: yes, has CPU bo and is active on CPU\n", __FUNCTION__)); return true; } if (priv->cpu_bo && priv->cpu) { DBG(("%s: no, has CPU bo and was last active on CPU, presume future CPU activity\n", __FUNCTION__)); return false; } if (flags & MOVE_READ && (priv->cpu || priv->cpu_damage || priv->gpu_damage == NULL)) { DBG(("%s:, no, reading and has CPU damage\n", __FUNCTION__)); return false; } return (priv->stride * pixmap->drawable.height >> 12) > sna->kgem.half_cpu_cache_pages; } static bool sna_pixmap_alloc_gpu(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, unsigned flags) { uint32_t tiling; /* Use tiling by default, but disable per user request */ if (pixmap->usage_hint == SNA_CREATE_FB && (sna->flags & SNA_LINEAR_FB) == 0) { flags |= CREATE_SCANOUT; tiling = kgem_choose_tiling(&sna->kgem, -DEFAULT_SCANOUT_TILING, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel); } else tiling = sna_pixmap_default_tiling(sna, pixmap); DBG(("%s: pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); priv->gpu_bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, tiling, flags); return priv->gpu_bo != NULL; } static bool sna_pixmap_create_mappable_gpu(PixmapPtr pixmap, bool can_replace) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); if (wedged(sna)) goto out; if ((priv->create & KGEM_CAN_CREATE_GTT) == 0) goto out; assert_pixmap_damage(pixmap); if (can_replace && priv->gpu_bo && (!kgem_bo_can_map(&sna->kgem, priv->gpu_bo) || __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) { if (priv->pinned) return false; DBG(("%s: discard busy GPU bo\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); } if (priv->gpu_bo == NULL) { assert_pixmap_damage(pixmap); assert(priv->gpu_damage == NULL); sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_GTT_MAP | CREATE_INACTIVE); } out: if (priv->gpu_bo == NULL) return false; return (kgem_bo_can_map(&sna->kgem, priv->gpu_bo) && !kgem_bo_is_busy(priv->gpu_bo)); } static inline bool gpu_bo_download(struct sna *sna, struct sna_pixmap *priv, int n, const BoxRec *box, bool idle) { char *src; if (!USE_INPLACE) return false; switch (priv->gpu_bo->tiling) { case I915_TILING_Y: return false; case I915_TILING_X: if (!sna->kgem.memcpy_from_tiled_x) return false; default: break; } if (!kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC)) return false; if (idle) { if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) return false; if (priv->cpu_bo && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) return false; } src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo); if (src == NULL) return false; kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC); if (priv->cpu_bo) kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); assert(has_coherent_ptr(sna, priv, MOVE_WRITE)); if (sigtrap_get()) return false; if (priv->gpu_bo->tiling) { int bpp = priv->pixmap->drawable.bitsPerPixel; void *dst = priv->pixmap->devPrivate.ptr; int dst_pitch = priv->pixmap->devKind; DBG(("%s: download through a tiled CPU map\n", __FUNCTION__)); do { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); memcpy_from_tiled_x(&sna->kgem, src, dst, bpp, priv->gpu_bo->pitch, dst_pitch, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { int bpp = priv->pixmap->drawable.bitsPerPixel; void *dst = priv->pixmap->devPrivate.ptr; int dst_pitch = priv->pixmap->devKind; DBG(("%s: download through a linear CPU map\n", __FUNCTION__)); do { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); memcpy_blt(src, dst, bpp, priv->gpu_bo->pitch, dst_pitch, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } sigtrap_put(); return true; } static inline bool cpu_bo_download(struct sna *sna, struct sna_pixmap *priv, int n, const BoxRec *box) { if (DBG_NO_CPU_DOWNLOAD) return false; if (wedged(sna)) return false; if (priv->cpu_bo == NULL || !sna->kgem.can_blt_cpu) return false; if (!kgem_bo_is_busy(priv->gpu_bo) && !kgem_bo_is_busy(priv->cpu_bo)) { /* Is it worth detiling? */ assert(box[0].y1 < box[n-1].y2); if (kgem_bo_can_map(&sna->kgem, priv->gpu_bo) && (box[n-1].y2 - box[0].y1 - 1) * priv->gpu_bo->pitch < 4096) { DBG(("%s: no, tiny transfer (height=%d, pitch=%d) expect to read inplace\n", __FUNCTION__, box[n-1].y2-box[0].y1, priv->gpu_bo->pitch)); return false; } } DBG(("%s: using GPU write to CPU bo for download from GPU\n", __FUNCTION__)); return sna->render.copy_boxes(sna, GXcopy, &priv->pixmap->drawable, priv->gpu_bo, 0, 0, &priv->pixmap->drawable, priv->cpu_bo, 0, 0, box, n, COPY_LAST); } static void download_boxes(struct sna *sna, struct sna_pixmap *priv, int n, const BoxRec *box) { bool ok; DBG(("%s: nbox=%d\n", __FUNCTION__, n)); ok = gpu_bo_download(sna, priv, n, box, true); if (!ok) ok = cpu_bo_download(sna, priv, n, box); if (!ok) ok = gpu_bo_download(sna, priv, n, box, false); if (!ok) { if (priv->cpu_bo) kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); assert(priv->mapped == MAPPED_NONE); assert(has_coherent_ptr(sna, priv, MOVE_WRITE)); sna_read_boxes(sna, priv->pixmap, priv->gpu_bo, box, n); } } static inline bool use_cpu_bo_for_upload(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { if (DBG_NO_CPU_UPLOAD) return false; if (wedged(sna)) return false; if (priv->cpu_bo == NULL) return false; DBG(("%s? flags=%x, gpu busy?=%d, cpu busy?=%d\n", __FUNCTION__, flags, kgem_bo_is_busy(priv->gpu_bo), kgem_bo_is_busy(priv->cpu_bo))); if (!priv->cpu) return true; if (flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) return true; if (priv->gpu_bo->tiling) return true; return kgem_bo_is_busy(priv->gpu_bo) || kgem_bo_is_busy(priv->cpu_bo); } bool sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { struct sna_cow *cow = COW(priv->cow); DBG(("%s: pixmap=%ld, handle=%d [refcnt=%d], cow refcnt=%d, flags=%x\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, priv->gpu_bo->handle, priv->gpu_bo->refcnt, cow->refcnt, flags)); assert(priv->gpu_bo == cow->bo); assert(cow->refcnt); if (flags && /* flags == 0 => force decouple */ (flags & MOVE_WRITE) == 0 && (((flags & __MOVE_FORCE) == 0) || IS_COW_OWNER(priv->cow))) return true; if (!IS_COW_OWNER(priv->cow)) list_del(&priv->cow_list); if (!--cow->refcnt) { DBG(("%s: freeing cow\n", __FUNCTION__)); assert(list_is_empty(&cow->list)); free(cow); } else if (IS_COW_OWNER(priv->cow) && priv->pinned) { PixmapPtr pixmap = priv->pixmap; struct kgem_bo *bo; BoxRec box; DBG(("%s: copying the Holy cow\n", __FUNCTION__)); box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; bo = kgem_create_2d(&sna->kgem, box.x2, box.y2, pixmap->drawable.bitsPerPixel, sna_pixmap_default_tiling(sna, pixmap), 0); if (bo == NULL) { cow->refcnt++; DBG(("%s: allocation failed\n", __FUNCTION__)); return false; } if (!sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); cow->refcnt++; return false; } assert(!list_is_empty(&cow->list)); while (!list_is_empty(&cow->list)) { struct sna_pixmap *clone; clone = list_first_entry(&cow->list, struct sna_pixmap, cow_list); list_del(&clone->cow_list); assert(clone->gpu_bo == cow->bo); sna_pixmap_unmap(clone->pixmap, clone); kgem_bo_destroy(&sna->kgem, clone->gpu_bo); clone->gpu_bo = kgem_bo_reference(bo); } cow->bo = bo; kgem_bo_destroy(&sna->kgem, bo); } else { struct kgem_bo *bo = NULL; if (flags & MOVE_READ) { PixmapPtr pixmap = priv->pixmap; unsigned create, tiling; BoxRec box; DBG(("%s: copying cow\n", __FUNCTION__)); box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (flags & __MOVE_PRIME) { create = CREATE_GTT_MAP | CREATE_SCANOUT | CREATE_PRIME | CREATE_EXACT; tiling = I915_TILING_NONE; } else { create = 0; tiling = sna_pixmap_default_tiling(sna, pixmap); } bo = kgem_create_2d(&sna->kgem, box.x2, box.y2, pixmap->drawable.bitsPerPixel, tiling, create); if (bo == NULL) { cow->refcnt++; DBG(("%s: allocation failed\n", __FUNCTION__)); return false; } if (!sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); cow->refcnt++; return false; } } assert(priv->gpu_bo); sna_pixmap_unmap(priv->pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; } priv->cow = NULL; return true; } static bool sna_pixmap_make_cow(struct sna *sna, struct sna_pixmap *src_priv, struct sna_pixmap *dst_priv) { struct sna_cow *cow; assert(src_priv->gpu_bo); if (!USE_COW) return false; if (src_priv->gpu_bo->proxy) return false; DBG(("%s: make cow src=%ld, dst=%ld, handle=%d (already cow? src=%d, dst=%d)\n", __FUNCTION__, src_priv->pixmap->drawable.serialNumber, dst_priv->pixmap->drawable.serialNumber, src_priv->gpu_bo->handle, src_priv->cow ? IS_COW_OWNER(src_priv->cow) ? 1 : -1 : 0, dst_priv->cow ? IS_COW_OWNER(dst_priv->cow) ? 1 : -1 : 0)); if (dst_priv->pinned) { DBG(("%s: can't cow, dst_pinned=%x\n", __FUNCTION__, dst_priv->pinned)); return false; } assert(dst_priv->move_to_gpu == NULL); assert(!dst_priv->flush); assert(list_is_empty(&dst_priv->cow_list)); cow = COW(src_priv->cow); if (cow == NULL) { cow = malloc(sizeof(*cow)); if (cow == NULL) return false; list_init(&cow->list); cow->bo = src_priv->gpu_bo; cow->refcnt = 1; DBG(("%s: moo! attaching source cow to pixmap=%ld, handle=%d\n", __FUNCTION__, src_priv->pixmap->drawable.serialNumber, cow->bo->handle)); src_priv->cow = MAKE_COW_OWNER(cow); if (src_priv->flush & FLUSH_WRITE) { assert(!src_priv->shm); sna_add_flush_pixmap(sna, src_priv, src_priv->gpu_bo); } } if (cow == COW(dst_priv->cow)) { assert(dst_priv->gpu_bo == cow->bo); return true; } if (dst_priv->cow) sna_pixmap_undo_cow(sna, dst_priv, 0); if (dst_priv->gpu_bo) { sna_pixmap_unmap(dst_priv->pixmap, dst_priv); kgem_bo_destroy(&sna->kgem, dst_priv->gpu_bo); } assert(!dst_priv->mapped); dst_priv->gpu_bo = kgem_bo_reference(cow->bo); dst_priv->cow = cow; list_add(&dst_priv->cow_list, &cow->list); cow->refcnt++; DBG(("%s: moo! attaching clone to pixmap=%ld (source=%ld, handle=%d)\n", __FUNCTION__, dst_priv->pixmap->drawable.serialNumber, src_priv->pixmap->drawable.serialNumber, cow->bo->handle)); return true; } static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags) { if (!USE_INPLACE) return false; if ((flags & MOVE_INPLACE_HINT) == 0) { DBG(("%s: no, inplace operation not suitable\n", __FUNCTION__)); return false; } assert((flags & MOVE_ASYNC_HINT) == 0 || (priv->create & KGEM_CAN_CREATE_LARGE)); if (priv->move_to_gpu && flags & MOVE_WRITE) { DBG(("%s: no, has pending move-to-gpu\n", __FUNCTION__)); return false; } if (priv->cow && flags & MOVE_WRITE) { DBG(("%s: no, has COW\n", __FUNCTION__)); return false; } if ((priv->create & KGEM_CAN_CREATE_GTT) == 0) { DBG(("%s: no, not accessible via GTT\n", __FUNCTION__)); return false; } if ((priv->gpu_damage == NULL || priv->cpu_damage) && flags & MOVE_READ) { DBG(("%s: no, has CPU damage and requires readback\n", __FUNCTION__)); return false; } if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: yes, CPU is busy\n", __FUNCTION__)); return true; } if (priv->create & KGEM_CAN_CREATE_LARGE) { DBG(("%s: large object, has GPU? %d\n", __FUNCTION__, priv->gpu_bo ? priv->gpu_bo->handle : 0)); return priv->gpu_bo != NULL; } if (flags & MOVE_WRITE && priv->gpu_bo&&kgem_bo_is_busy(priv->gpu_bo)) { DBG(("%s: no, GPU is busy, so stage write\n", __FUNCTION__)); return false; } return true; } bool _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; DBG(("%s(pixmap=%ld, %dx%d, flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, flags)); assert(flags & (MOVE_READ | MOVE_WRITE)); assert_pixmap_damage(pixmap); priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: not attached\n", __FUNCTION__)); return true; } DBG(("%s: gpu_bo=%d, gpu_damage=%p, cpu_damage=%p, is-clear?=%d\n", __FUNCTION__, priv->gpu_bo ? priv->gpu_bo->handle : 0, priv->gpu_damage, priv->cpu_damage, priv->clear)); assert(priv->gpu_damage == NULL || priv->gpu_bo); if ((flags & MOVE_READ) == 0 && UNDO) { kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (priv->move_to_gpu) sna_pixmap_discard_shadow_damage(priv, NULL); } if (kgem_bo_discard_cache(priv->gpu_bo, flags & MOVE_WRITE)) { assert(DAMAGE_IS_ALL(priv->cpu_damage)); if (DAMAGE_IS_ALL(priv->gpu_damage)) { DBG(("%s: using magical upload buffer\n", __FUNCTION__)); goto skip; } DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); assert(priv->gpu_damage == NULL); assert(!priv->pinned); assert(!priv->mapped); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } if (DAMAGE_IS_ALL(priv->cpu_damage)) { DBG(("%s: CPU all-damaged\n", __FUNCTION__)); assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); assert(priv->gpu_damage == NULL || (flags & MOVE_WRITE) == 0); goto done; } if (USE_INPLACE && (flags & MOVE_READ) == 0 && !(priv->cow || priv->move_to_gpu)) { assert(flags & MOVE_WRITE); DBG(("%s: no readback, discarding gpu damage [%d], pending clear[%d]\n", __FUNCTION__, priv->gpu_damage != NULL, priv->clear)); if ((priv->gpu_bo || priv->create & KGEM_CAN_CREATE_GPU) && pixmap_inplace(sna, pixmap, priv, flags) && sna_pixmap_create_mappable_gpu(pixmap, true)) { void *ptr; DBG(("%s: write inplace\n", __FUNCTION__)); assert(!priv->shm); assert(priv->cow == NULL); assert(priv->move_to_gpu == NULL); assert(priv->gpu_bo->exec == NULL); assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL); ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo); if (ptr == NULL) goto skip_inplace_map; pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = ptr == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; assert(has_coherent_ptr(sna, priv, flags)); assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_destroy(&priv->cpu_damage); priv->clear = false; list_del(&priv->flush_list); assert(!priv->shm); assert(priv->cpu_bo == NULL || !priv->cpu_bo->flush); sna_pixmap_free_cpu(sna, priv, priv->cpu); priv->cpu &= priv->mapped == MAPPED_CPU; assert_pixmap_damage(pixmap); return true; } skip_inplace_map: sna_damage_destroy(&priv->gpu_damage); priv->clear = false; if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo && !priv->cpu_bo->flush && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { DBG(("%s: discarding busy CPU bo\n", __FUNCTION__)); assert(!priv->shm); assert(priv->gpu_bo == NULL || priv->gpu_damage == NULL); sna_damage_destroy(&priv->cpu_damage); sna_pixmap_free_cpu(sna, priv, false); assert(priv->mapped == MAPPED_NONE); if (!sna_pixmap_alloc_cpu(sna, pixmap, priv, 0)) return false; assert(priv->mapped == MAPPED_NONE); assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); goto mark_damage; } } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); if (operate_inplace(priv, flags) && pixmap_inplace(sna, pixmap, priv, flags) && sna_pixmap_create_mappable_gpu(pixmap, (flags & MOVE_READ) == 0)) { void *ptr; DBG(("%s: try to operate inplace (GTT)\n", __FUNCTION__)); assert(priv->gpu_bo); assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0); assert(!priv->move_to_gpu); assert(priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL); /* XXX only sync for writes? */ kgem_bo_submit(&sna->kgem, priv->gpu_bo); assert(priv->gpu_bo->exec == NULL); ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo); if (ptr != NULL) { pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = ptr == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; assert(has_coherent_ptr(sna, priv, flags)); if (flags & MOVE_WRITE) { assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_destroy(&priv->cpu_damage); sna_pixmap_free_cpu(sna, priv, priv->cpu); list_del(&priv->flush_list); priv->clear = false; } priv->cpu &= priv->mapped == MAPPED_CPU; assert_pixmap_damage(pixmap); DBG(("%s: operate inplace (GTT)\n", __FUNCTION__)); return true; } } sna_pixmap_unmap(pixmap, priv); if (USE_INPLACE && (flags & MOVE_WRITE ? (void *)priv->gpu_bo : (void *)priv->gpu_damage) && priv->cpu_damage == NULL && priv->gpu_bo->tiling == I915_TILING_NONE && (flags & MOVE_READ || kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE)) && (!priv->clear || !kgem_bo_is_busy(priv->gpu_bo)) && ((flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == 0 || (!priv->cow && !priv->move_to_gpu && !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)))) { void *ptr; DBG(("%s: try to operate inplace (CPU)\n", __FUNCTION__)); assert(priv->gpu_bo); assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0); assert(priv->move_to_gpu == NULL || (flags & MOVE_WRITE) == 0); assert(priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); assert(!priv->mapped); assert(priv->gpu_bo->tiling == I915_TILING_NONE); ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo); if (ptr != NULL) { pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = MAPPED_CPU; assert(has_coherent_ptr(sna, priv, flags)); if (flags & MOVE_WRITE) { assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_destroy(&priv->cpu_damage); sna_pixmap_free_cpu(sna, priv, priv->cpu); list_del(&priv->flush_list); priv->clear = false; priv->cpu = true; } assert(pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)); kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC || flags & MOVE_WRITE); assert((flags & MOVE_WRITE) == 0 || !kgem_bo_is_busy(priv->gpu_bo)); assert_pixmap_damage(pixmap); assert(has_coherent_ptr(sna, priv, flags)); DBG(("%s: operate inplace (CPU)\n", __FUNCTION__)); return true; } } assert(priv->mapped == MAPPED_NONE); if (((flags & MOVE_READ) == 0 || priv->clear) && priv->cpu_bo && !priv->cpu_bo->flush && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { assert(!priv->shm); sna_pixmap_free_cpu(sna, priv, false); } assert(priv->mapped == MAPPED_NONE); if (pixmap->devPrivate.ptr == NULL && !sna_pixmap_alloc_cpu(sna, pixmap, priv, flags)) return false; assert(priv->mapped == MAPPED_NONE); assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); if (flags & MOVE_READ) { if (priv->clear) { DBG(("%s: applying clear [%08x] size=%dx%d, stride=%d (total=%d)\n", __FUNCTION__, priv->clear_color, pixmap->drawable.width, pixmap->drawable.height, pixmap->devKind, pixmap->devKind * pixmap->drawable.height)); if (priv->cpu_bo) { kgem_bo_undo(&sna->kgem, priv->cpu_bo); if ((flags & MOVE_ASYNC_HINT || priv->cpu_bo->exec) && sna->kgem.can_blt_cpu && sna->render.fill_one(sna, pixmap, priv->cpu_bo, priv->clear_color, 0, 0, pixmap->drawable.width, pixmap->drawable.height, GXcopy)) goto clear_done; DBG(("%s: syncing CPU bo\n", __FUNCTION__)); kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu)); } if (sigtrap_get() == 0) { assert(pixmap->devKind); sigtrap_assert_active(); if (priv->clear_color == 0 || pixmap->drawable.bitsPerPixel == 8 || priv->clear_color == (1 << pixmap->drawable.depth) - 1) { memset(pixmap->devPrivate.ptr, priv->clear_color, (size_t)pixmap->devKind * pixmap->drawable.height); } else { pixman_fill(pixmap->devPrivate.ptr, pixmap->devKind/sizeof(uint32_t), pixmap->drawable.bitsPerPixel, 0, 0, pixmap->drawable.width, pixmap->drawable.height, priv->clear_color); } sigtrap_put(); } else return false; clear_done: sna_damage_all(&priv->cpu_damage, pixmap); sna_pixmap_free_gpu(sna, priv); assert(priv->gpu_damage == NULL); assert(priv->clear == false); } if (priv->gpu_damage) { const BoxRec *box; int n; DBG(("%s: flushing GPU damage\n", __FUNCTION__)); assert(priv->gpu_bo); n = sna_damage_get_boxes(priv->gpu_damage, &box); if (n) { if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ)) { DBG(("%s: move-to-gpu override failed\n", __FUNCTION__)); return false; } download_boxes(sna, priv, n, box); } __sna_damage_destroy(DAMAGE_PTR(priv->gpu_damage)); priv->gpu_damage = NULL; } } if (flags & MOVE_WRITE || priv->create & KGEM_CAN_CREATE_LARGE) { mark_damage: DBG(("%s: marking as damaged\n", __FUNCTION__)); sna_damage_all(&priv->cpu_damage, pixmap); sna_pixmap_free_gpu(sna, priv); assert(priv->gpu_damage == NULL); assert(priv->clear == false); if (priv->flush) { assert(!priv->shm); sna_add_flush_pixmap(sna, priv, priv->gpu_bo); } } done: if (flags & MOVE_WRITE) { assert(DAMAGE_IS_ALL(priv->cpu_damage)); assert(priv->gpu_damage == NULL); assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); if (priv->cow) sna_pixmap_undo_cow(sna, priv, 0); if (priv->gpu_bo && priv->gpu_bo->rq == NULL) { DBG(("%s: discarding idle GPU bo\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); } priv->source_count = SOURCE_BIAS; } if (priv->cpu_bo) { if ((flags & MOVE_ASYNC_HINT) == 0) { DBG(("%s: syncing CPU bo\n", __FUNCTION__)); assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu)); kgem_bo_sync__cpu_full(&sna->kgem, priv->cpu_bo, FORCE_FULL_SYNC || flags & MOVE_WRITE); assert((flags & MOVE_WRITE) == 0 || !kgem_bo_is_busy(priv->cpu_bo)); } } skip: priv->cpu |= (flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == MOVE_WRITE; assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); assert(pixmap->devKind); assert_pixmap_damage(pixmap); assert(has_coherent_ptr(sna, sna_pixmap(pixmap), flags)); return true; } static bool region_overlaps_damage(const RegionRec *region, struct sna_damage *damage, int dx, int dy) { const BoxRec *re, *de; DBG(("%s?\n", __FUNCTION__)); if (damage == NULL) return false; if (DAMAGE_IS_ALL(damage)) return true; re = ®ion->extents; de = &DAMAGE_PTR(damage)->extents; DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n", __FUNCTION__, re->x1, re->y1, re->x2, re->y2, de->x1, de->y1, de->x2, de->y2)); return (re->x1 + dx < de->x2 && re->x2 + dx > de->x1 && re->y1 + dy < de->y2 && re->y2 + dy > de->y1); } static inline bool region_inplace(struct sna *sna, PixmapPtr pixmap, RegionPtr region, struct sna_pixmap *priv, unsigned flags) { assert_pixmap_damage(pixmap); if (FORCE_INPLACE) return FORCE_INPLACE > 0; if (wedged(sna) && !priv->pinned) return false; if (priv->gpu_damage && (priv->clear || (flags & MOVE_READ) == 0) && kgem_bo_is_busy(priv->gpu_bo)) return false; if (flags & MOVE_READ && (priv->cpu || priv->gpu_damage == NULL || region_overlaps_damage(region, priv->cpu_damage, 0, 0))) { DBG(("%s: no, uncovered CPU damage pending\n", __FUNCTION__)); return false; } if (priv->mapped) { DBG(("%s: %s, already mapped, continuing\n", __FUNCTION__, has_coherent_map(sna, priv->gpu_bo, flags) ? "yes" : "no")); return has_coherent_map(sna, priv->gpu_bo, flags); } if (priv->flush) { DBG(("%s: yes, exported via dri, will flush\n", __FUNCTION__)); return true; } if (DAMAGE_IS_ALL(priv->gpu_damage)) { DBG(("%s: yes, already wholly damaged on the GPU\n", __FUNCTION__)); assert(priv->gpu_bo); return true; } if (priv->cpu_bo && priv->cpu) { DBG(("%s: no, has CPU bo and was last active on CPU, presume future CPU activity\n", __FUNCTION__)); return false; } DBG(("%s: (%dx%d), inplace? %d\n", __FUNCTION__, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1, ((int)(region->extents.x2 - region->extents.x1) * (int)(region->extents.y2 - region->extents.y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages)); return ((int)(region->extents.x2 - region->extents.x1) * (int)(region->extents.y2 - region->extents.y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; } static bool cpu_clear_boxes(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, const BoxRec *box, int n) { struct sna_fill_op fill; if (!sna->kgem.can_blt_cpu) return false; if (!sna_fill_init_blt(&fill, sna, pixmap, priv->cpu_bo, GXcopy, priv->clear_color, FILL_BOXES)) { DBG(("%s: unsupported fill\n", __FUNCTION__)); return false; } fill.boxes(sna, &fill, box, n); fill.done(sna, &fill); return true; } bool sna_drawable_move_region_to_cpu(DrawablePtr drawable, RegionPtr region, unsigned flags) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; int16_t dx, dy; DBG(("%s(pixmap=%ld (%dx%d), [(%d, %d), (%d, %d)], flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, RegionExtents(region)->x1, RegionExtents(region)->y1, RegionExtents(region)->x2, RegionExtents(region)->y2, flags)); assert_pixmap_damage(pixmap); if (flags & MOVE_WRITE) { assert_drawable_contains_box(drawable, ®ion->extents); } assert(flags & (MOVE_WRITE | MOVE_READ)); if (box_empty(®ion->extents)) return true; if (MIGRATE_ALL || DBG_NO_PARTIAL_MOVE_TO_CPU) { if (!region_subsumes_pixmap(region, pixmap)) flags |= MOVE_READ; return _sna_pixmap_move_to_cpu(pixmap, flags); } priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: not attached to pixmap %ld (depth %d)\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.depth)); return true; } assert(priv->gpu_damage == NULL || priv->gpu_bo); if (kgem_bo_discard_cache(priv->gpu_bo, flags & MOVE_WRITE)) { assert(DAMAGE_IS_ALL(priv->cpu_damage)); if (DAMAGE_IS_ALL(priv->gpu_damage)) { DBG(("%s: using magical upload buffer\n", __FUNCTION__)); goto skip; } DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); assert(priv->gpu_damage == NULL); assert(!priv->pinned); assert(!priv->mapped); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } if (sna_damage_is_all(&priv->cpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { bool discard_gpu = priv->cpu; DBG(("%s: pixmap=%ld all damaged on CPU\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(!priv->clear); sna_damage_destroy(&priv->gpu_damage); if ((flags & (MOVE_READ | MOVE_ASYNC_HINT)) == 0 && priv->cpu_bo && !priv->cpu_bo->flush && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { DBG(("%s: active CPU bo replacing\n", __FUNCTION__)); assert(!priv->shm); assert(!IS_STATIC_PTR(priv->ptr)); if (!region_subsumes_pixmap(region, pixmap)) { DBG(("%s: partial replacement\n", __FUNCTION__)); if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) RegionTranslate(region, dx, dy); if (sna->kgem.has_llc && !priv->pinned && sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE) { #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs--; sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo); #endif DBG(("%s: promoting CPU bo to GPU bo\n", __FUNCTION__)); if (priv->gpu_bo) sna_pixmap_free_gpu(sna, priv); priv->gpu_bo = priv->cpu_bo; priv->cpu_bo = NULL; priv->ptr = NULL; pixmap->devPrivate.ptr = NULL; priv->gpu_damage = priv->cpu_damage; priv->cpu_damage = NULL; sna_damage_subtract(&priv->gpu_damage, region); discard_gpu = false; } else { DBG(("%s: pushing surrounding damage to GPU bo\n", __FUNCTION__)); sna_damage_subtract(&priv->cpu_damage, region); assert(priv->cpu_damage); if (sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT)) { sna_pixmap_free_cpu(sna, priv, false); if (priv->flush) sna_add_flush_pixmap(sna, priv, priv->gpu_bo); assert(priv->cpu_damage == NULL); sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_subtract(&priv->gpu_damage, region); discard_gpu = false; } } sna_damage_add_to_pixmap(&priv->cpu_damage, region, pixmap); if (dx | dy) RegionTranslate(region, -dx, -dy); } else sna_pixmap_free_cpu(sna, priv, false); } if (flags & MOVE_WRITE && discard_gpu) sna_pixmap_free_gpu(sna, priv); sna_pixmap_unmap(pixmap, priv); assert(priv->mapped == MAPPED_NONE); if (pixmap->devPrivate.ptr == NULL && !sna_pixmap_alloc_cpu(sna, pixmap, priv, flags)) return false; assert(priv->mapped == MAPPED_NONE); assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); goto out; } if (USE_INPLACE && (priv->create & KGEM_CAN_CREATE_LARGE || ((flags & (MOVE_READ | MOVE_ASYNC_HINT)) == 0 && (priv->flush || (flags & MOVE_WHOLE_HINT && whole_pixmap_inplace(pixmap)) || box_inplace(pixmap, ®ion->extents))))) { DBG(("%s: marking for inplace hint (%d, %d)\n", __FUNCTION__, priv->flush, box_inplace(pixmap, ®ion->extents))); flags |= MOVE_INPLACE_HINT; } if (region_subsumes_pixmap(region, pixmap)) { DBG(("%s: region (%d, %d), (%d, %d) + (%d, %d) subsumes pixmap (%dx%d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, get_drawable_dx(drawable), get_drawable_dy(drawable), pixmap->drawable.width, pixmap->drawable.height)); return _sna_pixmap_move_to_cpu(pixmap, flags); } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy)); RegionTranslate(region, dx, dy); } if (priv->move_to_gpu) { DBG(("%s: applying move-to-gpu override\n", __FUNCTION__)); if ((flags & MOVE_READ) == 0) sna_pixmap_discard_shadow_damage(priv, region); if (!priv->move_to_gpu(sna, priv, MOVE_READ)) { DBG(("%s: move-to-gpu override failed\n", __FUNCTION__)); return NULL; } } if (operate_inplace(priv, flags) && region_inplace(sna, pixmap, region, priv, flags) && sna_pixmap_create_mappable_gpu(pixmap, false)) { void *ptr; DBG(("%s: try to operate inplace\n", __FUNCTION__)); assert(priv->gpu_bo); assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0); assert(priv->move_to_gpu == NULL || (flags & MOVE_WRITE) == 0); assert(priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); /* XXX only sync for writes? */ kgem_bo_submit(&sna->kgem, priv->gpu_bo); assert(priv->gpu_bo->exec == NULL); ptr = kgem_bo_map(&sna->kgem, priv->gpu_bo); if (ptr != NULL) { pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = ptr == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; assert(has_coherent_ptr(sna, priv, flags)); if (flags & MOVE_WRITE) { if (!DAMAGE_IS_ALL(priv->gpu_damage)) { assert(!priv->clear); sna_damage_add_to_pixmap(&priv->gpu_damage, region, pixmap); if (sna_damage_is_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: replaced entire pixmap, destroying CPU shadow\n", __FUNCTION__)); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } else sna_damage_subtract(&priv->cpu_damage, region); } priv->clear = false; } priv->cpu &= priv->mapped == MAPPED_CPU; assert_pixmap_damage(pixmap); if (dx | dy) RegionTranslate(region, -dx, -dy); DBG(("%s: operate inplace\n", __FUNCTION__)); return true; } } if (priv->clear && flags & MOVE_WRITE) { DBG(("%s: pending clear, moving whole pixmap for partial write\n", __FUNCTION__)); demote_to_cpu: if (dx | dy) RegionTranslate(region, -dx, -dy); return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ); } if (flags & MOVE_WHOLE_HINT) { DBG(("%s: region (%d, %d), (%d, %d) marked with WHOLE hint, pixmap %dx%d\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, pixmap->drawable.width, pixmap->drawable.height)); move_to_cpu: if ((flags & MOVE_READ) == 0) sna_damage_subtract(&priv->gpu_damage, region); goto demote_to_cpu; } sna_pixmap_unmap(pixmap, priv); if (USE_INPLACE && priv->gpu_damage && priv->gpu_bo->tiling == I915_TILING_NONE && ((priv->cow == NULL && priv->move_to_gpu == NULL) || (flags & MOVE_WRITE) == 0) && (DAMAGE_IS_ALL(priv->gpu_damage) || sna_damage_contains_box__no_reduce(priv->gpu_damage, ®ion->extents)) && kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE) && ((flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == 0 || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) { void *ptr; DBG(("%s: try to operate inplace (CPU), read? %d, write? %d\n", __FUNCTION__, !!(flags & MOVE_READ), !!(flags & MOVE_WRITE))); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL || (flags & MOVE_WRITE) == 0); assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT); ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo); if (ptr != NULL) { pixmap->devPrivate.ptr = ptr; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = MAPPED_CPU; assert(has_coherent_ptr(sna, priv, flags)); if (flags & MOVE_WRITE) { if (!DAMAGE_IS_ALL(priv->gpu_damage)) { assert(!priv->clear); sna_damage_add_to_pixmap(&priv->gpu_damage, region, pixmap); if (sna_damage_is_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: replaced entire pixmap, destroying CPU shadow\n", __FUNCTION__)); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } else sna_damage_subtract(&priv->cpu_damage, region); } priv->clear = false; } assert_pixmap_damage(pixmap); kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC || flags & MOVE_WRITE); priv->cpu = true; assert_pixmap_map(pixmap, priv); assert((flags & MOVE_WRITE) == 0 || !kgem_bo_is_busy(priv->gpu_bo)); if (dx | dy) RegionTranslate(region, -dx, -dy); DBG(("%s: operate inplace (CPU)\n", __FUNCTION__)); return true; } } if ((priv->clear || (flags & MOVE_READ) == 0) && priv->cpu_bo && !priv->cpu_bo->flush && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { sna_damage_subtract(&priv->cpu_damage, region); if (sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT)) { assert(priv->gpu_bo); sna_damage_all(&priv->gpu_damage, pixmap); sna_pixmap_free_cpu(sna, priv, false); } } assert(priv->mapped == MAPPED_NONE); if (pixmap->devPrivate.ptr == NULL && !sna_pixmap_alloc_cpu(sna, pixmap, priv, flags)) { DBG(("%s: CPU bo allocation failed, trying full move-to-cpu\n", __FUNCTION__)); goto move_to_cpu; } assert(priv->mapped == MAPPED_NONE); assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); if (priv->gpu_bo == NULL) { assert(priv->gpu_damage == NULL); goto done; } assert(priv->gpu_bo->proxy == NULL); if ((flags & MOVE_READ) == 0) { assert(flags & MOVE_WRITE); sna_damage_subtract(&priv->gpu_damage, region); priv->clear = false; goto done; } if (priv->clear) { int n = region_num_rects(region); const BoxRec *box = region_rects(region); assert(DAMAGE_IS_ALL(priv->gpu_damage)); assert(priv->cpu_damage == NULL); DBG(("%s: pending clear, doing partial fill\n", __FUNCTION__)); if (priv->cpu_bo) { if ((flags & MOVE_ASYNC_HINT || priv->cpu_bo->exec) && cpu_clear_boxes(sna, pixmap, priv, box, n)) goto clear_done; DBG(("%s: syncing CPU bo\n", __FUNCTION__)); kgem_bo_sync__cpu(&sna->kgem, priv->cpu_bo); assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu)); } if (sigtrap_get() == 0) { assert(pixmap->devKind); sigtrap_assert_active(); do { pixman_fill(pixmap->devPrivate.ptr, pixmap->devKind/sizeof(uint32_t), pixmap->drawable.bitsPerPixel, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, priv->clear_color); box++; } while (--n); sigtrap_put(); } else return false; clear_done: if (flags & MOVE_WRITE || region->extents.x2 - region->extents.x1 > 1 || region->extents.y2 - region->extents.y1 > 1) { sna_damage_subtract(&priv->gpu_damage, region); priv->clear = false; } goto done; } if (priv->gpu_damage && (DAMAGE_IS_ALL(priv->gpu_damage) || sna_damage_overlaps_box(priv->gpu_damage, ®ion->extents))) { DBG(("%s: region (%dx%d) overlaps gpu damage\n", __FUNCTION__, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1)); assert(priv->gpu_bo); if (priv->cpu_damage == NULL) { if ((flags & MOVE_WRITE) == 0 && region->extents.x2 - region->extents.x1 == 1 && region->extents.y2 - region->extents.y1 == 1) { /* Often associated with synchronisation, KISS */ DBG(("%s: single pixel read\n", __FUNCTION__)); sna_read_boxes(sna, pixmap, priv->gpu_bo, ®ion->extents, 1); goto done; } } else { if (DAMAGE_IS_ALL(priv->cpu_damage) || sna_damage_contains_box__no_reduce(priv->cpu_damage, ®ion->extents)) { assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_OUT); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_IN); DBG(("%s: region already in CPU damage\n", __FUNCTION__)); goto already_damaged; } } if (sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) != PIXMAN_REGION_OUT) { RegionRec want, *r = region; DBG(("%s: region (%dx%d) intersects gpu damage\n", __FUNCTION__, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1)); if ((flags & MOVE_WRITE) == 0 && region->extents.x2 - region->extents.x1 == 1 && region->extents.y2 - region->extents.y1 == 1) { sna_read_boxes(sna, pixmap, priv->gpu_bo, ®ion->extents, 1); goto done; } /* Expand the region to move 32x32 pixel blocks at a * time, as we assume that we will continue writing * afterwards and so aim to coallesce subsequent * reads. */ if (flags & MOVE_WRITE) { int n = region_num_rects(region), i; const BoxRec *boxes = region_rects(region); BoxPtr blocks; blocks = NULL; if (priv->cpu_damage == NULL) blocks = malloc(sizeof(BoxRec) * n); if (blocks) { for (i = 0; i < n; i++) { blocks[i].x1 = boxes[i].x1 & ~31; if (blocks[i].x1 < 0) blocks[i].x1 = 0; blocks[i].x2 = (boxes[i].x2 + 31) & ~31; if (blocks[i].x2 > pixmap->drawable.width) blocks[i].x2 = pixmap->drawable.width; blocks[i].y1 = boxes[i].y1 & ~31; if (blocks[i].y1 < 0) blocks[i].y1 = 0; blocks[i].y2 = (boxes[i].y2 + 31) & ~31; if (blocks[i].y2 > pixmap->drawable.height) blocks[i].y2 = pixmap->drawable.height; } if (pixman_region_init_rects(&want, blocks, i)) r = &want; free(blocks); } } if (region_subsumes_damage(r, priv->gpu_damage)) { const BoxRec *box; int n; DBG(("%s: region wholly contains damage\n", __FUNCTION__)); n = sna_damage_get_boxes(priv->gpu_damage, &box); if (n) download_boxes(sna, priv, n, box); sna_damage_destroy(&priv->gpu_damage); } else if (DAMAGE_IS_ALL(priv->gpu_damage) || sna_damage_contains_box__no_reduce(priv->gpu_damage, &r->extents)) { DBG(("%s: region wholly inside damage\n", __FUNCTION__)); assert(sna_damage_contains_box(&priv->gpu_damage, &r->extents) == PIXMAN_REGION_IN); assert(sna_damage_contains_box(&priv->cpu_damage, &r->extents) == PIXMAN_REGION_OUT); download_boxes(sna, priv, region_num_rects(r), region_rects(r)); sna_damage_subtract(&priv->gpu_damage, r); } else { RegionRec need; pixman_region_init(&need); if (sna_damage_intersect(priv->gpu_damage, r, &need)) { DBG(("%s: region intersects damage\n", __FUNCTION__)); download_boxes(sna, priv, region_num_rects(&need), region_rects(&need)); sna_damage_subtract(&priv->gpu_damage, r); RegionUninit(&need); } } if (r == &want) pixman_region_fini(&want); } } done: if ((flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == MOVE_WRITE) { DBG(("%s: applying cpu damage\n", __FUNCTION__)); assert(!DAMAGE_IS_ALL(priv->cpu_damage)); assert_pixmap_contains_box(pixmap, RegionExtents(region)); sna_damage_add_to_pixmap(&priv->cpu_damage, region, pixmap); sna_damage_reduce_all(&priv->cpu_damage, pixmap); if (DAMAGE_IS_ALL(priv->cpu_damage)) { DBG(("%s: replaced entire pixmap\n", __FUNCTION__)); sna_pixmap_free_gpu(sna, priv); } if (priv->flush) { assert(!priv->shm); sna_add_flush_pixmap(sna, priv, priv->gpu_bo); } } already_damaged: if (dx | dy) RegionTranslate(region, -dx, -dy); out: if (flags & MOVE_WRITE) { assert(!DAMAGE_IS_ALL(priv->gpu_damage)); priv->source_count = SOURCE_BIAS; assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); assert(priv->gpu_bo || priv->gpu_damage == NULL); assert(!priv->flush || !list_is_empty(&priv->flush_list)); assert(!priv->clear); } if ((flags & MOVE_ASYNC_HINT) == 0 && priv->cpu_bo) { DBG(("%s: syncing cpu bo\n", __FUNCTION__)); assert(pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu)); kgem_bo_sync__cpu_full(&sna->kgem, priv->cpu_bo, FORCE_FULL_SYNC || flags & MOVE_WRITE); assert((flags & MOVE_WRITE) == 0 || !kgem_bo_is_busy(priv->cpu_bo)); } skip: priv->cpu |= (flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == MOVE_WRITE; assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); assert(pixmap->devKind); assert_pixmap_damage(pixmap); assert(has_coherent_ptr(sna, priv, flags)); return true; } bool sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags) { RegionRec region; PixmapPtr pixmap; int16_t dx, dy; if (drawable->type == DRAWABLE_PIXMAP) return sna_pixmap_move_to_cpu((PixmapPtr)drawable, flags); pixmap = get_window_pixmap((WindowPtr)drawable); get_drawable_deltas(drawable, pixmap, &dx, &dy); DBG(("%s: (%d, %d)x(%d, %d) + (%d, %d), flags=%x\n", __FUNCTION__, drawable->x, drawable->y, drawable->width, drawable->height, dx, dy, flags)); region.extents.x1 = drawable->x + dx; region.extents.y1 = drawable->y + dy; region.extents.x2 = region.extents.x1 + drawable->width; region.extents.y2 = region.extents.y1 + drawable->height; region.data = NULL; if (region.extents.x1 < 0) region.extents.x1 = 0; if (region.extents.y1 < 0) region.extents.y1 = 0; if (region.extents.x2 > pixmap->drawable.width) region.extents.x2 = pixmap->drawable.width; if (region.extents.y2 > pixmap->drawable.height) region.extents.y2 = pixmap->drawable.height; if (box_empty(®ion.extents)) return true; return sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, flags); } pure static bool alu_overwrites(uint8_t alu) { switch (alu) { case GXclear: case GXcopy: case GXcopyInverted: case GXset: return true; default: return false; } } inline static bool drawable_gc_inplace_hint(DrawablePtr draw, GCPtr gc) { if (!alu_overwrites(gc->alu)) return false; if (!PM_IS_SOLID(draw, gc->planemask)) return false; if (gc->fillStyle == FillStippled) return false; return true; } inline static unsigned drawable_gc_flags(DrawablePtr draw, GCPtr gc, bool partial) { assert(sna_gc(gc)->changes == 0); if (gc->fillStyle == FillStippled) { DBG(("%s: read due to fill %d\n", __FUNCTION__, gc->fillStyle)); return MOVE_READ | MOVE_WRITE; } if (fb_gc(gc)->and | fb_gc(gc)->bgand) { DBG(("%s: read due to rrop %d:%x\n", __FUNCTION__, gc->alu, (unsigned)fb_gc(gc)->and)); return MOVE_READ | MOVE_WRITE; } DBG(("%s: try operating on drawable inplace [hint? %d]\n", __FUNCTION__, drawable_gc_inplace_hint(draw, gc))); return (partial ? MOVE_READ : 0) | MOVE_WRITE | MOVE_INPLACE_HINT; } static inline struct sna_pixmap * sna_pixmap_mark_active(struct sna *sna, struct sna_pixmap *priv) { assert(priv->gpu_bo); DBG(("%s: pixmap=%ld, handle=%u\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, priv->gpu_bo->handle)); return priv; } inline static struct sna_pixmap * __sna_pixmap_for_gpu(struct sna *sna, PixmapPtr pixmap, unsigned flags) { struct sna_pixmap *priv; assert(flags & (MOVE_READ | MOVE_WRITE | __MOVE_FORCE)); if ((flags & __MOVE_FORCE) == 0 && wedged(sna)) return NULL; priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: not attached\n", __FUNCTION__)); if ((flags & (__MOVE_DRI | __MOVE_SCANOUT)) == 0) return NULL; if (pixmap->usage_hint == -1) { DBG(("%s: not promoting SHM Pixmap for DRI\n", __FUNCTION__)); return NULL; } DBG(("%s: forcing the creation on the GPU\n", __FUNCTION__)); priv = sna_pixmap_attach(pixmap); if (priv == NULL) return NULL; sna_damage_all(&priv->cpu_damage, pixmap); assert(priv->gpu_bo == NULL); assert(priv->gpu_damage == NULL); } return priv; } inline static void sna_pixmap_unclean(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { struct drm_i915_gem_busy busy; assert(DAMAGE_IS_ALL(priv->gpu_damage)); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); assert_pixmap_map(priv->pixmap, priv); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); if (flags & (__MOVE_DRI | __MOVE_SCANOUT)) return; if (!priv->flush || priv->gpu_bo->exec) return; busy.handle = priv->gpu_bo->handle; busy.busy = 0; ioctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy); DBG(("%s(pixmap=%ld): cleaning foreign bo handle=%u, busy=%x [ring=%d]\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, busy.handle, busy.busy, !!(busy.busy & (0xfffe << 16)))); if (busy.busy) { unsigned mode = KGEM_RENDER; if (busy.busy & (0xfffe << 16)) mode = KGEM_BLT; kgem_bo_mark_busy(&sna->kgem, priv->gpu_bo, mode); } else __kgem_bo_clear_busy(priv->gpu_bo); } struct sna_pixmap * sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; RegionRec i, r; DBG(("%s: pixmap=%ld box=(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, pixmap->drawable.serialNumber, box->x1, box->y1, box->x2, box->y2, flags)); priv = __sna_pixmap_for_gpu(sna, pixmap, flags); if (priv == NULL) return NULL; assert(box->x2 > box->x1 && box->y2 > box->y1); assert_pixmap_damage(pixmap); assert_pixmap_contains_box(pixmap, box); assert(priv->gpu_damage == NULL || priv->gpu_bo); if ((flags & MOVE_READ) == 0) sna_damage_subtract_box(&priv->cpu_damage, box); if (priv->move_to_gpu) { unsigned int hint; DBG(("%s: applying move-to-gpu override\n", __FUNCTION__)); hint = flags | MOVE_READ; if ((flags & MOVE_READ) == 0) { RegionRec region; region.extents = *box; region.data = NULL; sna_pixmap_discard_shadow_damage(priv, ®ion); if (region_subsumes_pixmap(®ion, pixmap)) hint &= ~MOVE_READ; } else { if (priv->cpu_damage) hint |= MOVE_WRITE; } if (!priv->move_to_gpu(sna, priv, hint)) { DBG(("%s: move-to-gpu override failed\n", __FUNCTION__)); return NULL; } } if (priv->cow) { unsigned cow = flags & (MOVE_READ | MOVE_WRITE | __MOVE_FORCE); assert(cow); if ((flags & MOVE_READ) == 0) { if (priv->gpu_damage) { r.extents = *box; r.data = NULL; if (!region_subsumes_damage(&r, priv->gpu_damage)) cow |= MOVE_READ | __MOVE_FORCE; } } else { if (priv->cpu_damage) { r.extents = *box; r.data = NULL; if (region_overlaps_damage(&r, priv->cpu_damage, 0, 0)) cow |= MOVE_WRITE; } } if (!sna_pixmap_undo_cow(sna, priv, cow)) return NULL; if (priv->gpu_bo == NULL) sna_damage_destroy(&priv->gpu_damage); } if (sna_damage_is_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: already all-damaged\n", __FUNCTION__)); sna_pixmap_unclean(sna, priv, flags); goto done; } if (kgem_bo_discard_cache(priv->gpu_bo, flags & (MOVE_WRITE | __MOVE_FORCE))) { DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); assert(DAMAGE_IS_ALL(priv->cpu_damage)); assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); /* magical upload buffer */ assert(!priv->pinned); assert(!priv->mapped); sna_damage_destroy(&priv->gpu_damage); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } sna_damage_reduce(&priv->cpu_damage); assert_pixmap_damage(pixmap); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); return sna_pixmap_move_to_gpu(pixmap, MOVE_READ | flags); } if (priv->gpu_bo == NULL) { assert(priv->gpu_damage == NULL); if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_INACTIVE); if (priv->gpu_bo == NULL) return NULL; DBG(("%s: created gpu bo\n", __FUNCTION__)); } if (priv->gpu_bo->proxy) { DBG(("%s: reusing cached upload\n", __FUNCTION__)); assert((flags & MOVE_WRITE) == 0); assert(priv->gpu_damage == NULL); return priv; } if (priv->shm) { assert(!priv->flush); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); } assert(priv->cpu_damage); region_set(&r, box); if (MIGRATE_ALL || region_subsumes_damage(&r, priv->cpu_damage)) { bool ok = false; int n; n = sna_damage_get_boxes(priv->cpu_damage, &box); assert(n); if (use_cpu_bo_for_upload(sna, priv, 0)) { DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__)); ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->cpu_bo, 0, 0, &pixmap->drawable, priv->gpu_bo, 0, 0, box, n, 0); } if (!ok) { sna_pixmap_unmap(pixmap, priv); if (pixmap->devPrivate.ptr == NULL) return NULL; assert(pixmap->devKind); if (n == 1 && !priv->pinned && box->x1 <= 0 && box->y1 <= 0 && box->x2 >= pixmap->drawable.width && box->y2 >= pixmap->drawable.height) { ok = sna_replace(sna, pixmap, pixmap->devPrivate.ptr, pixmap->devKind); } else { ok = sna_write_boxes(sna, pixmap, priv->gpu_bo, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind, 0, 0, box, n); } if (!ok) return NULL; } sna_damage_destroy(&priv->cpu_damage); } else if (DAMAGE_IS_ALL(priv->cpu_damage) || sna_damage_contains_box__no_reduce(priv->cpu_damage, box)) { bool ok = false; assert(sna_damage_contains_box(&priv->gpu_damage, box) == PIXMAN_REGION_OUT); assert(sna_damage_contains_box(&priv->cpu_damage, box) == PIXMAN_REGION_IN); if (use_cpu_bo_for_upload(sna, priv, 0)) { DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__)); ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->cpu_bo, 0, 0, &pixmap->drawable, priv->gpu_bo, 0, 0, box, 1, 0); } if (!ok) { sna_pixmap_unmap(pixmap, priv); if (pixmap->devPrivate.ptr != NULL) { assert(pixmap->devKind); ok = sna_write_boxes(sna, pixmap, priv->gpu_bo, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind, 0, 0, box, 1); } } if (!ok) return NULL; sna_damage_subtract(&priv->cpu_damage, &r); } else if (sna_damage_intersect(priv->cpu_damage, &r, &i)) { int n = region_num_rects(&i); bool ok; box = region_rects(&i); ok = false; if (use_cpu_bo_for_upload(sna, priv, 0)) { DBG(("%s: using CPU bo for upload to GPU, %d boxes\n", __FUNCTION__, n)); ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->cpu_bo, 0, 0, &pixmap->drawable, priv->gpu_bo, 0, 0, box, n, 0); } if (!ok) { sna_pixmap_unmap(pixmap, priv); if (pixmap->devPrivate.ptr != NULL) { assert(pixmap->devKind); ok = sna_write_boxes(sna, pixmap, priv->gpu_bo, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind, 0, 0, box, n); } } if (!ok) return NULL; sna_damage_subtract(&priv->cpu_damage, &r); RegionUninit(&i); } done: if (priv->cpu_damage == NULL && priv->flush) list_del(&priv->flush_list); if (flags & MOVE_WRITE) { priv->clear = false; if (!DAMAGE_IS_ALL(priv->gpu_damage) && priv->cpu_damage == NULL && (box_covers_pixmap(pixmap, &r.extents) || box_inplace(pixmap, &r.extents))) { DBG(("%s: large operation on undamaged, discarding CPU shadow\n", __FUNCTION__)); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); if (sna_pixmap_free_cpu(sna, priv, priv->cpu)) { DBG(("%s: large operation on undamaged, promoting to full GPU\n", __FUNCTION__)); sna_damage_all(&priv->gpu_damage, pixmap); } } if (DAMAGE_IS_ALL(priv->gpu_damage)) { sna_pixmap_free_cpu(sna, priv, priv->cpu); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } priv->cpu = false; } assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0); return sna_pixmap_mark_active(sna, priv); } struct kgem_bo * sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, struct sna_damage ***damage) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna *sna; RegionRec region; int16_t dx, dy; int ret; DBG(("%s pixmap=%ld, box=((%d, %d), (%d, %d)), flags=%x...\n", __FUNCTION__, pixmap->drawable.serialNumber, box->x1, box->y1, box->x2, box->y2, flags)); assert(box->x2 > box->x1 && box->y2 > box->y1); assert(pixmap->refcnt); assert_pixmap_damage(pixmap); assert_drawable_contains_box(drawable, box); if (priv == NULL) { DBG(("%s: not attached\n", __FUNCTION__)); return NULL; } if (priv->cow) { unsigned cow = MOVE_WRITE | MOVE_READ | __MOVE_FORCE; assert(cow); if (flags & IGNORE_DAMAGE) { if (priv->gpu_damage) { region.extents = *box; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } region.data = NULL; if (region_subsumes_damage(®ion, priv->gpu_damage)) cow &= ~MOVE_READ; } else cow &= ~MOVE_READ; } if (!sna_pixmap_undo_cow(to_sna_from_pixmap(pixmap), priv, cow)) return NULL; if (priv->gpu_bo == NULL) sna_damage_destroy(&priv->gpu_damage); } if (kgem_bo_discard_cache(priv->gpu_bo, true)) { DBG(("%s: cached upload proxy, discard and revert to GPU\n", __FUNCTION__)); assert(DAMAGE_IS_ALL(priv->cpu_damage)); assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); /* magical upload buffer */ assert(!priv->pinned); assert(!priv->mapped); sna_damage_destroy(&priv->gpu_damage); kgem_bo_destroy(&to_sna_from_pixmap(pixmap)->kgem, priv->gpu_bo); priv->gpu_bo = NULL; goto use_cpu_bo; } if (priv->flush) { DBG(("%s: exported target, set PREFER_GPU\n", __FUNCTION__)); flags |= PREFER_GPU; } if (priv->shm) { DBG(("%s: shm target, discard PREFER_GPU\n", __FUNCTION__)); flags &= ~PREFER_GPU; } if (priv->pinned) { DBG(("%s: pinned, never REPLACES\n", __FUNCTION__)); flags &= ~REPLACES; } if (priv->cpu && (flags & (FORCE_GPU | IGNORE_DAMAGE)) == 0) { DBG(("%s: last on cpu and needs damage, discard PREFER_GPU\n", __FUNCTION__)); flags &= ~PREFER_GPU; } if ((flags & (PREFER_GPU | IGNORE_DAMAGE)) == IGNORE_DAMAGE) { if (priv->gpu_bo && (box_covers_pixmap(pixmap, box) || box_inplace(pixmap, box))) { DBG(("%s: not reading damage and large, set PREFER_GPU\n", __FUNCTION__)); flags |= PREFER_GPU; } } DBG(("%s: flush=%d, shm=%d, cpu=%d => flags=%x\n", __FUNCTION__, priv->flush, priv->shm, priv->cpu, flags)); if ((flags & PREFER_GPU) == 0 && (flags & (REPLACES | IGNORE_DAMAGE) || !priv->gpu_damage || !kgem_bo_is_busy(priv->gpu_bo))) { DBG(("%s: try cpu as GPU bo is idle\n", __FUNCTION__)); goto use_cpu_bo; } if (DAMAGE_IS_ALL(priv->gpu_damage)) { DBG(("%s: use GPU fast path (all-damaged)\n", __FUNCTION__)); assert(priv->cpu_damage == NULL); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); goto use_gpu_bo; } if (DAMAGE_IS_ALL(priv->cpu_damage)) { assert(priv->gpu_damage == NULL); if ((flags & FORCE_GPU) == 0 || priv->cpu_bo) { DBG(("%s: use CPU fast path (all-damaged), and not forced-gpu\n", __FUNCTION__)); goto use_cpu_bo; } } DBG(("%s: gpu? %d, damaged? %d; cpu? %d, damaged? %d\n", __FUNCTION__, priv->gpu_bo ? priv->gpu_bo->handle : 0, priv->gpu_damage != NULL, priv->cpu_bo ? priv->cpu_bo->handle : 0, priv->cpu_damage != NULL)); if (priv->gpu_bo == NULL) { unsigned int move; if ((flags & FORCE_GPU) == 0 && (priv->create & KGEM_CAN_CREATE_GPU) == 0) { DBG(("%s: untiled, will not force allocation\n", __FUNCTION__)); goto use_cpu_bo; } if ((flags & IGNORE_DAMAGE) == 0) { if (priv->cpu_bo) { if (to_sna_from_pixmap(pixmap)->kgem.can_blt_cpu) { if (kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: already using CPU bo, will not force allocation\n", __FUNCTION__)); goto use_cpu_bo; } if ((flags & RENDER_GPU) == 0) { DBG(("%s: prefer cpu", __FUNCTION__)); goto use_cpu_bo; } } else { if (kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s: CPU bo active, must force allocation\n", __FUNCTION__)); goto create_gpu_bo; } } } if ((flags & FORCE_GPU) == 0 && priv->cpu_damage) { if ((flags & PREFER_GPU) == 0) { DBG(("%s: already damaged and prefer cpu", __FUNCTION__)); goto use_cpu_bo; } if (!box_inplace(pixmap, box)) { DBG(("%s: damaged with a small operation, will not force allocation\n", __FUNCTION__)); goto use_cpu_bo; } } } else if (priv->cpu_damage) { region.extents = *box; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } region.data = NULL; sna_damage_subtract(&priv->cpu_damage, ®ion); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); priv->cpu = false; } } create_gpu_bo: move = MOVE_WRITE | MOVE_READ | MOVE_ASYNC_HINT; if (flags & FORCE_GPU) move |= __MOVE_FORCE; if (!sna_pixmap_move_to_gpu(pixmap, move)) goto use_cpu_bo; DBG(("%s: allocated GPU bo for operation\n", __FUNCTION__)); goto done; } region.extents = *box; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } region.data = NULL; DBG(("%s extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (priv->gpu_damage) { assert(priv->gpu_bo); if (!priv->cpu_damage || flags & IGNORE_DAMAGE) { if (flags & REPLACES || box_covers_pixmap(pixmap, ®ion.extents)) { unsigned int move; if (flags & IGNORE_DAMAGE) move = MOVE_WRITE; else move = MOVE_WRITE | MOVE_READ | MOVE_ASYNC_HINT; if (sna_pixmap_move_to_gpu(pixmap, move)) { sna_damage_all(&priv->gpu_damage, pixmap); goto use_gpu_bo; } } if (DAMAGE_IS_ALL(priv->gpu_damage) || sna_damage_contains_box__no_reduce(priv->gpu_damage, ®ion.extents)) { DBG(("%s: region wholly contained within GPU damage\n", __FUNCTION__)); assert(sna_damage_contains_box(&priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_IN); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_OUT); goto use_gpu_bo; } else { DBG(("%s: partial GPU damage with no CPU damage, continuing to use GPU\n", __FUNCTION__)); goto move_to_gpu; } } ret = sna_damage_contains_box(&priv->gpu_damage, ®ion.extents); if (ret == PIXMAN_REGION_IN) { DBG(("%s: region wholly contained within GPU damage\n", __FUNCTION__)); goto use_gpu_bo; } if (ret != PIXMAN_REGION_OUT) { DBG(("%s: region partially contained within GPU damage\n", __FUNCTION__)); goto move_to_gpu; } } if ((flags & IGNORE_DAMAGE) == 0 && priv->cpu_damage) { ret = sna_damage_contains_box(&priv->cpu_damage, ®ion.extents); if (ret == PIXMAN_REGION_IN) { DBG(("%s: region wholly contained within CPU damage\n", __FUNCTION__)); goto use_cpu_bo; } if (box_inplace(pixmap, box)) { DBG(("%s: forcing inplace\n", __FUNCTION__)); goto move_to_gpu; } if (ret != PIXMAN_REGION_OUT) { DBG(("%s: region partially contained within CPU damage\n", __FUNCTION__)); goto use_cpu_bo; } } move_to_gpu: if (!sna_pixmap_move_area_to_gpu(pixmap, ®ion.extents, flags & IGNORE_DAMAGE ? MOVE_WRITE : MOVE_READ | MOVE_WRITE)) { DBG(("%s: failed to move-to-gpu, fallback\n", __FUNCTION__)); assert(priv->gpu_bo == NULL); goto use_cpu_bo; } done: assert(priv->move_to_gpu == NULL); assert(priv->gpu_bo != NULL); assert(priv->gpu_bo->refcnt); if (sna_damage_is_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); *damage = NULL; } else *damage = &priv->gpu_damage; DBG(("%s: using GPU bo with damage? %d\n", __FUNCTION__, *damage != NULL)); assert(*damage == NULL || !DAMAGE_IS_ALL(*damage)); assert(priv->gpu_bo->proxy == NULL); assert(priv->clear == false); assert(priv->cpu == false); assert(!priv->shm); return priv->gpu_bo; use_gpu_bo: if (priv->move_to_gpu) { unsigned hint = MOVE_READ | MOVE_WRITE; sna = to_sna_from_pixmap(pixmap); DBG(("%s: applying move-to-gpu override\n", __FUNCTION__)); if (flags & IGNORE_DAMAGE) { region.extents = *box; region.data = NULL; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } sna_pixmap_discard_shadow_damage(priv, ®ion); if (region_subsumes_pixmap(®ion, pixmap)) { DBG(("%s: discarding move-to-gpu READ for subsumed pixmap\n", __FUNCTION__)); hint = MOVE_WRITE; } } if (!priv->move_to_gpu(sna, priv, hint)) { DBG(("%s: move-to-gpu override failed\n", __FUNCTION__)); goto use_cpu_bo; } } if (priv->shm) { assert(!priv->flush); list_move(&priv->flush_list, &sna->flush_pixmaps); } DBG(("%s: using whole GPU bo\n", __FUNCTION__)); assert(priv->gpu_bo != NULL); assert(priv->gpu_bo->refcnt); assert(priv->gpu_bo->proxy == NULL); assert(priv->gpu_damage); priv->cpu = false; priv->clear = false; *damage = NULL; return priv->gpu_bo; use_cpu_bo: if (!USE_CPU_BO || priv->cpu_bo == NULL) { if ((flags & FORCE_GPU) == 0) { DBG(("%s: no CPU bo, and GPU not forced\n", __FUNCTION__)); return NULL; } flags &= ~FORCE_GPU; region.extents = *box; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } region.data = NULL; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, (flags & IGNORE_DAMAGE ? 0 : MOVE_READ) | MOVE_WRITE | MOVE_ASYNC_HINT) || priv->cpu_bo == NULL) { DBG(("%s: did not create CPU bo\n", __FUNCTION__)); cpu_fail: if (priv->gpu_bo) goto move_to_gpu; return NULL; } } assert(priv->cpu_bo->refcnt); sna = to_sna_from_pixmap(pixmap); if ((flags & FORCE_GPU) == 0 && !__kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { DBG(("%s: has CPU bo, but is idle and acceleration not forced\n", __FUNCTION__)); return NULL; } region.extents = *box; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { region.extents.x1 += dx; region.extents.x2 += dx; region.extents.y1 += dy; region.extents.y2 += dy; } region.data = NULL; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) { DBG(("%s: both CPU and GPU are busy, prefer to use the GPU\n", __FUNCTION__)); goto move_to_gpu; } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); if (flags & RENDER_GPU) { flags &= ~RENDER_GPU; if ((flags & IGNORE_DAMAGE) == 0 && priv->gpu_damage) { DBG(("%s: prefer to use GPU bo for rendering whilst reading from GPU damage\n", __FUNCTION__)); prefer_gpu_bo: if (priv->gpu_bo == NULL) { if ((flags & FORCE_GPU) == 0) { DBG(("%s: untiled, will not force allocation\n", __FUNCTION__)); return NULL; } if (flags & IGNORE_DAMAGE) { sna_damage_subtract(&priv->cpu_damage, ®ion); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); priv->cpu = false; } } if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ | MOVE_ASYNC_HINT | __MOVE_FORCE)) return NULL; sna_damage_all(&priv->gpu_damage, pixmap); DBG(("%s: allocated GPU bo for operation\n", __FUNCTION__)); goto done; } goto move_to_gpu; } if ((priv->cpu_damage == NULL || flags & IGNORE_DAMAGE)) { if (priv->gpu_bo && priv->gpu_bo->tiling) { DBG(("%s: prefer to use GPU bo for rendering large pixmaps\n", __FUNCTION__)); goto prefer_gpu_bo; } if (priv->cpu_bo->pitch >= 4096) { DBG(("%s: prefer to use GPU bo for rendering wide pixmaps\n", __FUNCTION__)); goto prefer_gpu_bo; } } if ((flags & IGNORE_DAMAGE) == 0 && priv->cpu_bo->snoop) { DBG(("%s: prefer to use GPU bo for reading from snooped target bo\n", __FUNCTION__)); goto prefer_gpu_bo; } if (!sna->kgem.can_blt_cpu) { DBG(("%s: can't render to CPU bo, try to use GPU bo\n", __FUNCTION__)); goto prefer_gpu_bo; } } if (!sna->kgem.can_blt_cpu) goto cpu_fail; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, (flags & IGNORE_DAMAGE ? 0 : MOVE_READ) | MOVE_WRITE | MOVE_ASYNC_HINT)) { DBG(("%s: failed to move-to-cpu, fallback\n", __FUNCTION__)); goto cpu_fail; } if (priv->shm) { assert(!priv->flush); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); /* As we may have flushed and retired,, recheck for busy bo */ if ((flags & FORCE_GPU) == 0 && !kgem_bo_is_busy(priv->cpu_bo)) return NULL; } if (priv->flush) { assert(!priv->shm); sna_add_flush_pixmap(sna, priv, priv->gpu_bo); } if (sna_damage_is_all(&priv->cpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { sna_damage_destroy(&priv->gpu_damage); *damage = NULL; } else { assert(!DAMAGE_IS_ALL(priv->cpu_damage)); if (priv->cpu_damage && sna_damage_contains_box__no_reduce(priv->cpu_damage, ®ion.extents)) { assert(sna_damage_contains_box(&priv->gpu_damage, ®ion.extents) == PIXMAN_REGION_OUT); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion.extents) == PIXMAN_REGION_IN); *damage = NULL; } else *damage = &priv->cpu_damage; } DBG(("%s: using CPU bo with damage? %d\n", __FUNCTION__, *damage != NULL)); assert(damage == NULL || !DAMAGE_IS_ALL(*damage)); assert(priv->clear == false); priv->cpu = false; return priv->cpu_bo; } PixmapPtr sna_pixmap_create_upload(ScreenPtr screen, int width, int height, int depth, unsigned flags) { struct sna *sna = to_sna_from_screen(screen); PixmapPtr pixmap; struct sna_pixmap *priv; void *ptr; DBG(("%s(%d, %d, %d, flags=%x)\n", __FUNCTION__, width, height, depth, flags)); assert(width); assert(height); if (depth < 8) return create_pixmap(sna, screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH); pixmap = create_pixmap_hdr(sna, screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH, &priv); if (!pixmap) return NullPixmap; priv->gpu_bo = kgem_create_buffer_2d(&sna->kgem, width, height, pixmap->drawable.bitsPerPixel, flags, &ptr); if (!priv->gpu_bo) { free(priv); FreePixmap(pixmap); return NullPixmap; } /* Marking both the shadow and the GPU bo is a little dubious, * but will work so long as we always check before doing the * transfer. */ sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_all(&priv->cpu_damage, pixmap); pixmap->devKind = priv->gpu_bo->pitch; pixmap->devPrivate.ptr = ptr; priv->ptr = MAKE_STATIC_PTR(ptr); priv->stride = priv->gpu_bo->pitch; priv->create = 0; pixmap->usage_hint = 0; if (!kgem_buffer_is_inplace(priv->gpu_bo)) pixmap->usage_hint = 1; DBG(("%s: serial=%ld, %dx%d, usage=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, pixmap->usage_hint)); return pixmap; } static bool can_convert_to_gpu(struct sna_pixmap *priv, unsigned flags) { assert(priv->gpu_bo == NULL); if (priv->cpu_bo == NULL) return false; if (priv->shm) return false; /* Linear scanout have a restriction that their pitch must be * 64 byte aligned. Force the creation of a proper GPU bo if * this CPU bo is not suitable for scanout. */ if (priv->pixmap->usage_hint == SNA_CREATE_FB || flags & __MOVE_SCANOUT) if (priv->cpu_bo->pitch & 63) return false; if (flags & __MOVE_PRIME) if (priv->cpu_bo->pitch & 255) return false; return true; } struct sna_pixmap * sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; const BoxRec *box; int n; DBG(("%s(pixmap=%ld, usage=%d), flags=%x\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint, flags)); priv = __sna_pixmap_for_gpu(sna, pixmap, flags); if (priv == NULL) return NULL; assert_pixmap_damage(pixmap); if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, flags | ((priv->cpu_damage && (flags & MOVE_READ)) ? MOVE_WRITE : 0))) { DBG(("%s: move-to-gpu override failed\n", __FUNCTION__)); return NULL; } if ((flags & MOVE_READ) == 0 && UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (priv->cow) { unsigned cow = flags & (MOVE_READ | MOVE_WRITE | __MOVE_FORCE); assert(cow); if (flags & MOVE_READ && priv->cpu_damage) cow |= MOVE_WRITE; if (!sna_pixmap_undo_cow(sna, priv, cow)) return NULL; if (priv->gpu_bo == NULL) sna_damage_destroy(&priv->gpu_damage); } if (sna_damage_is_all(&priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: already all-damaged\n", __FUNCTION__)); sna_pixmap_unclean(sna, priv, flags); goto active; } if ((flags & MOVE_READ) == 0) sna_damage_destroy(&priv->cpu_damage); sna_damage_reduce(&priv->cpu_damage); assert_pixmap_damage(pixmap); DBG(("%s: CPU damage? %d\n", __FUNCTION__, priv->cpu_damage != NULL)); if (priv->gpu_bo == NULL || kgem_bo_discard_cache(priv->gpu_bo, flags & (MOVE_WRITE | __MOVE_FORCE))) { struct kgem_bo *proxy; proxy = priv->gpu_bo; priv->gpu_bo = NULL; DBG(("%s: creating GPU bo (%dx%d@%d), create=%x\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, priv->create)); assert(!priv->mapped); assert(list_is_empty(&priv->flush_list)); if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) { bool is_linear; assert(pixmap->drawable.width > 0); assert(pixmap->drawable.height > 0); assert(pixmap->drawable.bitsPerPixel >= 8); if (flags & __MOVE_PRIME) { assert((flags & __MOVE_TILED) == 0); is_linear = true; } else { is_linear = sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE; if (is_linear && flags & __MOVE_TILED) { DBG(("%s: not creating linear GPU bo\n", __FUNCTION__)); return NULL; } } if (is_linear && can_convert_to_gpu(priv, flags) && kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) { assert(!priv->mapped); assert(!IS_STATIC_PTR(priv->ptr)); #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs--; sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo); #endif priv->gpu_bo = priv->cpu_bo; priv->cpu_bo = NULL; priv->ptr = NULL; pixmap->devPrivate.ptr = NULL; sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_destroy(&priv->cpu_damage); } else { unsigned create = 0; if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL)) create = CREATE_GTT_MAP | CREATE_INACTIVE; if (flags & __MOVE_PRIME) create |= CREATE_GTT_MAP | CREATE_SCANOUT | CREATE_PRIME | CREATE_EXACT; sna_pixmap_alloc_gpu(sna, pixmap, priv, create); } } if (priv->gpu_bo == NULL) { DBG(("%s: not creating GPU bo\n", __FUNCTION__)); assert(priv->gpu_damage == NULL); priv->gpu_bo = proxy; if (proxy) sna_damage_all(&priv->cpu_damage, pixmap); return NULL; } if (proxy) { DBG(("%s: promoting upload proxy handle=%d to GPU\n", __FUNCTION__, proxy->handle)); if (priv->cpu_damage && sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, proxy, 0, 0, &pixmap->drawable, priv->gpu_bo, 0, 0, region_rects(DAMAGE_REGION(priv->cpu_damage)), region_num_rects(DAMAGE_REGION(priv->cpu_damage)), 0)) sna_damage_destroy(&priv->cpu_damage); kgem_bo_destroy(&sna->kgem, proxy); } if (flags & MOVE_WRITE && priv->cpu_damage == NULL) { /* Presume that we will only ever write to the GPU * bo. Readbacks are expensive but fairly constant * in cost for all sizes i.e. it is the act of * synchronisation that takes the most time. This is * mitigated by avoiding fallbacks in the first place. */ assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); DBG(("%s: marking as all-damaged for GPU\n", __FUNCTION__)); goto active; } } if (priv->gpu_bo->proxy) { DBG(("%s: reusing cached upload\n", __FUNCTION__)); assert((flags & MOVE_WRITE) == 0); assert(priv->gpu_damage == NULL); return priv; } if (priv->cpu_damage == NULL) goto done; if (DAMAGE_IS_ALL(priv->cpu_damage) && priv->cpu_bo && !priv->pinned && !priv->shm && priv->gpu_bo->tiling == I915_TILING_NONE && kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) { assert(!priv->mapped); assert(!IS_STATIC_PTR(priv->ptr)); #ifdef DEBUG_MEMORY sna->debug_memory.cpu_bo_allocs--; sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo); #endif sna_pixmap_free_gpu(sna, priv); priv->gpu_bo = priv->cpu_bo; priv->cpu_bo = NULL; priv->ptr = NULL; pixmap->devPrivate.ptr = NULL; sna_damage_all(&priv->gpu_damage, pixmap); sna_damage_destroy(&priv->cpu_damage); goto done; } if (priv->shm) { assert(!priv->flush); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); } n = sna_damage_get_boxes(priv->cpu_damage, &box); assert(n); if (n) { bool ok; assert_pixmap_contains_damage(pixmap, priv->cpu_damage); DBG(("%s: uploading %d damage boxes\n", __FUNCTION__, n)); ok = false; if (use_cpu_bo_for_upload(sna, priv, flags)) { DBG(("%s: using CPU bo for upload to GPU\n", __FUNCTION__)); ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->cpu_bo, 0, 0, &pixmap->drawable, priv->gpu_bo, 0, 0, box, n, 0); } if (!ok) { sna_pixmap_unmap(pixmap, priv); if (pixmap->devPrivate.ptr == NULL) return NULL; assert(pixmap->devKind); if (n == 1 && !priv->pinned && (box->x2 - box->x1) >= pixmap->drawable.width && (box->y2 - box->y1) >= pixmap->drawable.height) { ok = sna_replace(sna, pixmap, pixmap->devPrivate.ptr, pixmap->devKind); } else { ok = sna_write_boxes(sna, pixmap, priv->gpu_bo, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind, 0, 0, box, n); } if (!ok) return NULL; } } __sna_damage_destroy(DAMAGE_PTR(priv->cpu_damage)); priv->cpu_damage = NULL; /* For large bo, try to keep only a single copy around */ if (priv->create & KGEM_CAN_CREATE_LARGE || flags & MOVE_SOURCE_HINT) { DBG(("%s: disposing of system copy for large/source\n", __FUNCTION__)); assert(!priv->shm); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); sna_pixmap_free_cpu(sna, priv, (priv->create & KGEM_CAN_CREATE_LARGE) ? false : priv->cpu); } done: list_del(&priv->flush_list); sna_damage_reduce_all(&priv->gpu_damage, pixmap); if (DAMAGE_IS_ALL(priv->gpu_damage)) sna_pixmap_free_cpu(sna, priv, priv->cpu); active: if (flags & MOVE_WRITE) { priv->clear = false; priv->cpu = false; } assert(!priv->gpu_bo->proxy || (flags & MOVE_WRITE) == 0); return sna_pixmap_mark_active(sna, priv); } static bool must_check sna_validate_pixmap(DrawablePtr draw, PixmapPtr pixmap) { DBG(("%s: target bpp=%d, source bpp=%d\n", __FUNCTION__, draw->bitsPerPixel, pixmap->drawable.bitsPerPixel)); if (draw->bitsPerPixel == pixmap->drawable.bitsPerPixel && FbEvenTile(pixmap->drawable.width * pixmap->drawable.bitsPerPixel)) { DBG(("%s: flushing pixmap\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return false; fbPadPixmap(pixmap); } return true; } static bool must_check sna_gc_move_to_cpu(GCPtr gc, DrawablePtr drawable, RegionPtr region) { struct sna_gc *sgc = sna_gc(gc); long changes = sgc->changes; DBG(("%s(%p) changes=%lx\n", __FUNCTION__, gc, changes)); assert(drawable); assert(region); assert(gc->ops == (GCOps *)&sna_gc_ops); gc->ops = (GCOps *)&sna_gc_ops__cpu; assert(gc->funcs); sgc->old_funcs = gc->funcs; gc->funcs = (GCFuncs *)&sna_gc_funcs__cpu; assert(gc->pCompositeClip); sgc->priv = gc->pCompositeClip; gc->pCompositeClip = region; #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) if (gc->clientClipType == CT_PIXMAP) { PixmapPtr clip = gc->clientClip; gc->clientClip = region_from_bitmap(gc->pScreen, clip); gc->pScreen->DestroyPixmap(clip); gc->clientClipType = gc->clientClip ? CT_REGION : CT_NONE; changes |= GCClipMask; } else changes &= ~GCClipMask; #else changes &= ~GCClipMask; #endif if (changes || drawable->serialNumber != (sgc->serial & DRAWABLE_SERIAL_BITS)) { long tmp = gc->serialNumber; gc->serialNumber = sgc->serial; if (fb_gc(gc)->bpp != drawable->bitsPerPixel) { changes |= GCStipple | GCForeground | GCBackground | GCPlaneMask; fb_gc(gc)->bpp = drawable->bitsPerPixel; } if (changes & GCTile && !gc->tileIsPixel) { DBG(("%s: flushing tile pixmap\n", __FUNCTION__)); if (!sna_validate_pixmap(drawable, gc->tile.pixmap)) return false; } if (changes & GCStipple && gc->stipple) { DBG(("%s: flushing stipple pixmap\n", __FUNCTION__)); if (!sna_validate_pixmap(drawable, gc->stipple)) return false; } fbValidateGC(gc, changes, drawable); gc->serialNumber = tmp; } sgc->changes = 0; switch (gc->fillStyle) { case FillTiled: DBG(("%s: moving tile to cpu\n", __FUNCTION__)); return sna_drawable_move_to_cpu(&gc->tile.pixmap->drawable, MOVE_READ); case FillStippled: case FillOpaqueStippled: DBG(("%s: moving stipple to cpu\n", __FUNCTION__)); return sna_drawable_move_to_cpu(&gc->stipple->drawable, MOVE_READ); default: return true; } } static void sna_gc_move_to_gpu(GCPtr gc) { DBG(("%s(%p)\n", __FUNCTION__, gc)); assert(gc->ops == (GCOps *)&sna_gc_ops__cpu); assert(gc->funcs == (GCFuncs *)&sna_gc_funcs__cpu); gc->ops = (GCOps *)&sna_gc_ops; gc->funcs = (GCFuncs *)sna_gc(gc)->old_funcs; assert(gc->funcs); gc->pCompositeClip = sna_gc(gc)->priv; assert(gc->pCompositeClip); } static inline bool clip_box(BoxPtr box, GCPtr gc) { const BoxRec *clip; bool clipped; assert(gc->pCompositeClip); clip = &gc->pCompositeClip->extents; clipped = !region_is_singular(gc->pCompositeClip); if (box->x1 < clip->x1) box->x1 = clip->x1, clipped = true; if (box->x2 > clip->x2) box->x2 = clip->x2, clipped = true; if (box->y1 < clip->y1) box->y1 = clip->y1, clipped = true; if (box->y2 > clip->y2) box->y2 = clip->y2, clipped = true; return clipped; } static inline void translate_box(BoxPtr box, DrawablePtr d) { box->x1 += d->x; box->x2 += d->x; box->y1 += d->y; box->y2 += d->y; } static inline bool trim_and_translate_box(BoxPtr box, DrawablePtr d, GCPtr gc) { translate_box(box, d); return clip_box(box, gc); } static inline bool box32_clip(Box32Rec *box, GCPtr gc) { bool clipped = !region_is_singular(gc->pCompositeClip); const BoxRec *clip = &gc->pCompositeClip->extents; if (box->x1 < clip->x1) box->x1 = clip->x1, clipped = true; if (box->x2 > clip->x2) box->x2 = clip->x2, clipped = true; if (box->y1 < clip->y1) box->y1 = clip->y1, clipped = true; if (box->y2 > clip->y2) box->y2 = clip->y2, clipped = true; return clipped; } static inline void box32_translate(Box32Rec *box, DrawablePtr d) { box->x1 += d->x; box->x2 += d->x; box->y1 += d->y; box->y2 += d->y; } static inline bool box32_trim_and_translate(Box32Rec *box, DrawablePtr d, GCPtr gc) { box32_translate(box, d); return box32_clip(box, gc); } static inline void box_add_xy(BoxPtr box, int16_t x, int16_t y) { if (box->x1 > x) box->x1 = x; else if (box->x2 < x) box->x2 = x; if (box->y1 > y) box->y1 = y; else if (box->y2 < y) box->y2 = y; } static inline void box_add_pt(BoxPtr box, const DDXPointRec *pt) { box_add_xy(box, pt->x, pt->y); } static inline bool box32_to_box16(const Box32Rec *b32, BoxRec *b16) { b16->x1 = b32->x1; b16->y1 = b32->y1; b16->x2 = b32->x2; b16->y2 = b32->y2; return b16->x2 > b16->x1 && b16->y2 > b16->y1; } static inline void box32_add_rect(Box32Rec *box, const xRectangle *r) { int32_t v; v = r->x; if (box->x1 > v) box->x1 = v; v += r->width; if (box->x2 < v) box->x2 = v; v = r->y; if (box->y1 > v) box->y1 = v; v += r->height; if (box->y2 < v) box->y2 = v; } static bool can_create_upload_tiled_x(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, bool replaces) { if (priv->shm || (priv->cpu && !replaces)) return false; if ((priv->create & KGEM_CAN_CREATE_GPU) == 0) return false; if (sna->kgem.has_llc) return true; if (!sna->kgem.has_wc_mmap && sna_pixmap_default_tiling(sna, pixmap)) return false; return true; } static bool create_upload_tiled_x(struct sna *sna, PixmapPtr pixmap, struct sna_pixmap *priv, bool replaces) { unsigned create; if (!can_create_upload_tiled_x(sna, pixmap, priv, replaces)) return false; assert(priv->gpu_bo == NULL); assert(priv->gpu_damage == NULL); if (sna->kgem.has_llc) create = CREATE_CPU_MAP | CREATE_INACTIVE; else if (sna->kgem.has_wc_mmap) create = CREATE_GTT_MAP | CREATE_INACTIVE; else create = CREATE_CPU_MAP | CREATE_INACTIVE | CREATE_CACHED; return sna_pixmap_alloc_gpu(sna, pixmap, priv, create); } static bool can_upload__tiled_x(struct kgem *kgem, struct kgem_bo *bo) { return kgem_bo_can_map__cpu(kgem, bo, true) || kgem->has_wc_mmap; } static bool try_upload__tiled_x(PixmapPtr pixmap, RegionRec *region, int x, int y, int w, int h, char *bits, int stride) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); const BoxRec *box; uint8_t *dst; int n; if (!can_upload__tiled_x(&sna->kgem, priv->gpu_bo)) { DBG(("%s: no, cannot map through the CPU\n", __FUNCTION__)); return false; } if (!sna_pixmap_move_area_to_gpu(pixmap, ®ion->extents, MOVE_WRITE | (region->data ? MOVE_READ : 0))) return false; if ((priv->create & KGEM_CAN_CREATE_LARGE) == 0 && __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) return false; if (kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)) { dst = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo); if (dst == NULL) return false; kgem_bo_sync__cpu(&sna->kgem, priv->gpu_bo); } else { dst = kgem_bo_map__wc(&sna->kgem, priv->gpu_bo); if (dst == NULL) return false; kgem_bo_sync__gtt(&sna->kgem, priv->gpu_bo); } box = region_rects(region); n = region_num_rects(region); DBG(("%s: upload(%d, %d, %d, %d) x %d\n", __FUNCTION__, x, y, w, h, n)); if (sigtrap_get()) return false; if (priv->gpu_bo->tiling) { do { DBG(("%s: copy tiled box (%d, %d)->(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); assert(box->x1 - x >= 0); assert(box->y1 - y >= 0); assert(box->x2 - x <= w); assert(box->y2 - y <= h); memcpy_to_tiled_x(&sna->kgem, bits, dst, pixmap->drawable.bitsPerPixel, stride, priv->gpu_bo->pitch, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { do { DBG(("%s: copy lined box (%d, %d)->(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); assert(box->x1 - x >= 0); assert(box->y1 - y >= 0); assert(box->x2 - x <= w); assert(box->y2 - y <= h); memcpy_blt(bits, dst, pixmap->drawable.bitsPerPixel, stride, priv->gpu_bo->pitch, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); if (!priv->shm) { pixmap->devPrivate.ptr = dst; pixmap->devKind = priv->gpu_bo->pitch; if (dst == MAP(priv->gpu_bo->map__cpu)) { priv->mapped = MAPPED_CPU; priv->cpu = true; } else priv->mapped = MAPPED_GTT; assert_pixmap_map(pixmap, priv); } } sigtrap_put(); return true; } static bool try_upload__inplace(PixmapPtr pixmap, RegionRec *region, int x, int y, int w, int h, char *bits, int stride) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); bool ignore_cpu = false; bool replaces; const BoxRec *box; uint8_t *dst; int n; if (!USE_INPLACE) return false; assert(priv); if (priv->shm && priv->gpu_damage == NULL) return false; replaces = region_subsumes_pixmap(region, pixmap); DBG(("%s: bo? %d, can map? %d, replaces? %d\n", __FUNCTION__, priv->gpu_bo != NULL, priv->gpu_bo ? kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true) : 0, replaces)); if (kgem_bo_discard_cache(priv->gpu_bo, true)) { DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); assert(DAMAGE_IS_ALL(priv->cpu_damage)); assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); /* magical upload buffer */ assert(!priv->pinned); assert(!priv->mapped); sna_damage_destroy(&priv->gpu_damage); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } if (priv->gpu_bo && replaces) { if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (can_create_upload_tiled_x(sna, pixmap, priv, true) && (priv->cow || __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { DBG(("%s: discarding unusable target bo (busy? %d, mappable? %d)\n", __FUNCTION__, kgem_bo_is_busy(priv->gpu_bo), kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); ignore_cpu = true; } } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); if (priv->cow || (priv->move_to_gpu && !sna_pixmap_discard_shadow_damage(priv, replaces ? NULL : region))) { DBG(("%s: no, has pending COW? %d or move-to-gpu? %d\n", __FUNCTION__, priv->cow != NULL, priv->move_to_gpu != NULL)); return false; } if (priv->gpu_damage && region_subsumes_damage(region, priv->gpu_damage)) { if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo); if (can_create_upload_tiled_x(sna, pixmap, priv, priv->cpu_damage == NULL) && (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) { DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__, kgem_bo_is_busy(priv->gpu_bo), kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); ignore_cpu = priv->cpu_damage == NULL; if (priv->ptr) sna_damage_all(&priv->cpu_damage, pixmap); } } if (priv->gpu_bo == NULL && !create_upload_tiled_x(sna, pixmap, priv, ignore_cpu)) return false; DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling)); switch (priv->gpu_bo->tiling) { case I915_TILING_Y: break; case I915_TILING_X: if (!sna->kgem.memcpy_to_tiled_x) break; default: if (try_upload__tiled_x(pixmap, region, x, y, w, h, bits, stride)) goto done; break; } if (priv->gpu_damage == NULL && !box_inplace(pixmap, ®ion->extents)) { DBG(("%s: no, too small to bother with using the GTT\n", __FUNCTION__)); return false; } if (!kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) { DBG(("%s: no, cannot map through the CPU\n", __FUNCTION__)); return false; } if (!sna_pixmap_move_area_to_gpu(pixmap, ®ion->extents, MOVE_WRITE | (region->data ? MOVE_READ : 0))) return false; if ((priv->create & KGEM_CAN_CREATE_LARGE) == 0 && __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) return false; dst = kgem_bo_map(&sna->kgem, priv->gpu_bo); if (dst == NULL) return false; pixmap->devPrivate.ptr = dst; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = dst == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; priv->cpu &= priv->mapped == MAPPED_CPU; assert(has_coherent_ptr(sna, priv, MOVE_WRITE)); box = region_rects(region); n = region_num_rects(region); DBG(("%s: upload(%d, %d, %d, %d) x %d\n", __FUNCTION__, x, y, w, h, n)); if (sigtrap_get()) return false; do { DBG(("%s: copy lined box (%d, %d)->(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); assert(box->x1 - x >= 0); assert(box->y1 - y >= 0); assert(box->x2 - x <= w); assert(box->y2 - y <= h); memcpy_blt(bits, dst, pixmap->drawable.bitsPerPixel, stride, priv->gpu_bo->pitch, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); done: if (!DAMAGE_IS_ALL(priv->gpu_damage)) { if (replaces) { sna_damage_all(&priv->gpu_damage, pixmap); } else { sna_damage_add_to_pixmap(&priv->gpu_damage, region, pixmap); sna_damage_reduce_all(&priv->gpu_damage, pixmap); } if (DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_destroy(&priv->cpu_damage); else sna_damage_subtract(&priv->cpu_damage, region); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); sna_damage_all(&priv->gpu_damage, pixmap); } if (priv->shm) sna_add_flush_pixmap(sna, priv, priv->cpu_bo); } assert(!priv->clear); return true; } static bool try_upload__blt(PixmapPtr pixmap, RegionRec *region, int x, int y, int w, int h, char *bits, int stride) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; struct kgem_bo *src_bo; bool ok; if (!sna->kgem.has_userptr || !USE_USERPTR_UPLOADS) return false; priv = sna_pixmap(pixmap); assert(priv); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); if (priv->cpu_damage && (DAMAGE_IS_ALL(priv->cpu_damage) || sna_damage_contains_box__no_reduce(priv->cpu_damage, ®ion->extents)) && !box_inplace(pixmap, ®ion->extents)) { DBG(("%s: no, damage on CPU and too small\n", __FUNCTION__)); return false; } src_bo = kgem_create_map(&sna->kgem, bits, stride * h, true); if (src_bo == NULL) return false; src_bo->pitch = stride; kgem_bo_mark_unreusable(src_bo); if (!sna_pixmap_move_area_to_gpu(pixmap, ®ion->extents, MOVE_WRITE | MOVE_ASYNC_HINT | (region->data ? MOVE_READ : 0))) { kgem_bo_destroy(&sna->kgem, src_bo); return false; } DBG(("%s: upload(%d, %d, %d, %d) x %d through a temporary map\n", __FUNCTION__, x, y, w, h, region_num_rects(region))); if (sigtrap_get() == 0) { ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, src_bo, -x, -y, &pixmap->drawable, priv->gpu_bo, 0, 0, region_rects(region), region_num_rects(region), COPY_LAST); sigtrap_put(); } else ok = false; kgem_bo_sync__cpu(&sna->kgem, src_bo); assert(src_bo->rq == NULL); kgem_bo_destroy(&sna->kgem, src_bo); if (!ok) { DBG(("%s: copy failed!\n", __FUNCTION__)); return false; } if (!DAMAGE_IS_ALL(priv->gpu_damage)) { assert(!priv->clear); if (region_subsumes_drawable(region, &pixmap->drawable)) { sna_damage_all(&priv->gpu_damage, pixmap); } else { sna_damage_add_to_pixmap(&priv->gpu_damage, region, pixmap); sna_damage_reduce_all(&priv->gpu_damage, pixmap); } if (DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_destroy(&priv->cpu_damage); else sna_damage_subtract(&priv->cpu_damage, region); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); if (sna_pixmap_free_cpu(sna, priv, priv->cpu)) sna_damage_all(&priv->gpu_damage, pixmap); } } priv->cpu = false; priv->clear = false; return true; } static bool ignore_cpu_damage(struct sna *sna, struct sna_pixmap *priv, const RegionRec *region) { if (region_subsumes_pixmap(region, priv->pixmap)) return true; if (priv->cpu_damage != NULL) { if (DAMAGE_IS_ALL(priv->cpu_damage)) return false; if (!box_inplace(priv->pixmap, ®ion->extents)) return false; if (sna_damage_contains_box__no_reduce(priv->cpu_damage, ®ion->extents)) return false; } return priv->gpu_bo == NULL || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo); } static bool try_upload__fast(PixmapPtr pixmap, RegionRec *region, int x, int y, int w, int h, char *bits, int stride) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; if (wedged(sna)) return false; priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (ignore_cpu_damage(sna, priv, region)) { DBG(("%s: ignore existing cpu damage (if any)\n", __FUNCTION__)); if (try_upload__inplace(pixmap, region, x, y, w, h, bits, stride)) return true; } if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL || priv->cpu) { DBG(("%s: no, no gpu damage\n", __FUNCTION__)); return false; } assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); if (try_upload__blt(pixmap, region, x, y, w, h, bits, stride)) return true; if (try_upload__inplace(pixmap, region, x, y, w, h, bits, stride)) return true; return false; } static bool sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, int x, int y, int w, int h, char *bits, int stride) { PixmapPtr pixmap = get_drawable_pixmap(drawable); unsigned int hint; const BoxRec *box; int16_t dx, dy; int n; assert_pixmap_contains_box(pixmap, RegionExtents(region)); if (gc->alu != GXcopy) return false; if (drawable->depth < 8) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); x += dx + drawable->x; y += dy + drawable->y; assert(region->extents.x1 >= x); assert(region->extents.y1 >= y); assert(region->extents.x2 <= x + w); assert(region->extents.y2 <= y + h); if (try_upload__fast(pixmap, region, x, y, w, h, bits, stride)) return true; hint = MOVE_WRITE; if (region_is_unclipped(region, pixmap->drawable.width, h) && (h+1)*stride > 65536) { DBG(("%s: segmented, unclipped large upload (%d bytes), marking WHOLE_HINT\n", __FUNCTION__, h*stride)); hint |= MOVE_WHOLE_HINT; } if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, region, hint)) return false; if (sigtrap_get()) return false; /* Region is pre-clipped and translated into pixmap space */ box = region_rects(region); n = region_num_rects(region); DBG(("%s: upload(%d, %d, %d, %d) x %d boxes\n", __FUNCTION__, x, y, w, h, n)); do { DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); assert(box->x1 - x >= 0); assert(box->y1 - y >= 0); assert(box->x2 - x <= w); assert(box->y2 - y <= h); assert(has_coherent_ptr(to_sna_from_pixmap(pixmap), sna_pixmap(pixmap), MOVE_WRITE)); assert(pixmap->devKind); memcpy_blt(bits, pixmap->devPrivate.ptr, pixmap->drawable.bitsPerPixel, stride, pixmap->devKind, box->x1 - x, box->y1 - y, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); assert_pixmap_damage(pixmap); return true; } static inline uint8_t byte_reverse(uint8_t b) { return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; } static inline uint8_t blt_depth(int depth) { switch (depth) { case 8: return 0; case 15: return 0x2; case 16: return 0x1; default: return 0x3; } } inline static void blt_done(struct sna *sna) { sna->blt_state.fill_bo = 0; if (sna->kgem.nbatch && __kgem_ring_empty(&sna->kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(&sna->kgem); } } static bool sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, int x, int y, int w, int h, char *bits) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; const BoxRec *box; int16_t dx, dy; int n; uint8_t rop = copy_ROP[gc->alu]; bo = sna_drawable_use_bo(&pixmap->drawable, PREFER_GPU, ®ion->extents, &damage); if (bo == NULL) return false; if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&sna->kgem, bo)) return false; assert_pixmap_contains_box(pixmap, RegionExtents(region)); if (damage) sna_damage_add_to_pixmap(damage, region, pixmap); assert_pixmap_damage(pixmap); DBG(("%s: upload(%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h)); get_drawable_deltas(drawable, pixmap, &dx, &dy); x += dx + drawable->x; y += dy + drawable->y; kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); /* Region is pre-clipped and translated into pixmap space */ box = region_rects(region); n = region_num_rects(region); do { int bx1 = (box->x1 - x) & ~7; int bx2 = (box->x2 - x + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = box->y2 - box->y1; int bstride = ALIGN(bw, 2); struct kgem_bo *upload; void *ptr; if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { int src_stride = BitmapBytePad(w); uint8_t *dst = ptr; uint8_t *src = (uint8_t*)bits + (box->y1 - y) * src_stride + bx1/8; uint32_t *b; bstride -= bw; src_stride -= bw; do { int i = bw; assert(src >= (uint8_t *)bits); do { *dst++ = byte_reverse(*src++); } while (--i); assert(src <= (uint8_t *)bits + BitmapBytePad(w) * h); assert(dst <= (uint8_t *)ptr + kgem_bo_size(upload)); dst += bstride; src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); if (sna->kgem.gen >= 0100) { b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_MONO_SRC_COPY | 3 << 20 | 8; b[0] |= ((box->x1 - x) & 7) << 17; b[1] = bo->pitch; if (bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= blt_depth(drawable->depth) << 24; b[1] |= rop << 16; b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_MONO_SRC_COPY | 3 << 20 | 6; b[0] |= ((box->x1 - x) & 7) << 17; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= blt_depth(drawable->depth) << 24; b[1] |= rop << 16; b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); box++; } while (--n); blt_done(sna); return true; } static bool sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region, int x, int y, int w, int h, int left,char *bits) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; int16_t dx, dy; unsigned i, skip; if (gc->alu != GXcopy) return false; bo = sna_drawable_use_bo(&pixmap->drawable, PREFER_GPU, ®ion->extents, &damage); if (bo == NULL) return false; if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&sna->kgem, bo)) return false; assert_pixmap_contains_box(pixmap, RegionExtents(region)); if (damage) sna_damage_add_to_pixmap(damage, region, pixmap); assert_pixmap_damage(pixmap); DBG(("%s: upload(%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h)); get_drawable_deltas(drawable, pixmap, &dx, &dy); x += dx + drawable->x; y += dy + drawable->y; kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); skip = h * BitmapBytePad(w + left); for (i = 1 << (gc->depth-1); i; i >>= 1, bits += skip) { const BoxRec *box = region_rects(region); int n = region_num_rects(region); if ((gc->planemask & i) == 0) continue; /* Region is pre-clipped and translated into pixmap space */ do { int bx1 = (box->x1 - x) & ~7; int bx2 = (box->x2 - x + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = box->y2 - box->y1; int bstride = ALIGN(bw, 2); struct kgem_bo *upload; void *ptr; if (!kgem_check_batch(&sna->kgem, 14) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { int src_stride = BitmapBytePad(w); uint8_t *src = (uint8_t*)bits + (box->y1 - y) * src_stride + bx1/8; uint8_t *dst = ptr; uint32_t *b; bstride -= bw; src_stride -= bw; do { int j = bw; assert(src >= (uint8_t *)bits); do { *dst++ = byte_reverse(*src++); } while (--j); assert(src <= (uint8_t *)bits + BitmapBytePad(w) * h); assert(dst <= (uint8_t *)ptr + kgem_bo_size(upload)); dst += bstride; src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); if (sna->kgem.gen >= 0100) { assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_FULL_MONO_PATTERN_MONO_SRC_BLT | 3 << 20 | 12; b[0] |= ((box->x1 - x) & 7) << 17; b[1] = bo->pitch; if (bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 31; /* solid pattern */ b[1] |= blt_depth(drawable->depth) << 24; b[1] |= 0xce << 16; /* S or (D and !P) */ b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = 0; b[9] = i; b[10] = i; b[11] = i; b[12] = -1; b[13] = -1; sna->kgem.nbatch += 14; } else { b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_FULL_MONO_PATTERN_MONO_SRC_BLT | 3 << 20 | 10; b[0] |= ((box->x1 - x) & 7) << 17; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 31; /* solid pattern */ b[1] |= blt_depth(drawable->depth) << 24; b[1] |= 0xce << 16; /* S or (D and !P) */ b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = 0; b[7] = i; b[8] = i; b[9] = i; b[10] = -1; b[11] = -1; sna->kgem.nbatch += 12; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); box++; } while (--n); } blt_done(sna); return true; } static void sna_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int left, int format, char *bits) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); RegionRec region; int16_t dx, dy; DBG(("%s((%d, %d)x(%d, %d), depth=%d, format=%d)\n", __FUNCTION__, x, y, w, h, depth, format)); if (w == 0 || h == 0) return; region.extents.x1 = x + drawable->x; region.extents.y1 = y + drawable->y; region.extents.x2 = region.extents.x1 + w; region.extents.y2 = region.extents.y1 + h; region.data = NULL; if (!region_is_singular(gc->pCompositeClip) || gc->pCompositeClip->extents.x1 > region.extents.x1 || gc->pCompositeClip->extents.y1 > region.extents.y1 || gc->pCompositeClip->extents.x2 < region.extents.x2 || gc->pCompositeClip->extents.y2 < region.extents.y2) { if (!RegionIntersect(®ion, ®ion, gc->pCompositeClip) || box_empty(®ion.extents)) return; } if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) RegionTranslate(®ion, dx, dy); if (priv == NULL) { DBG(("%s: fallback -- unattached(%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h)); goto fallback; } if (FORCE_FALLBACK) goto fallback; if (wedged(sna)) goto fallback; if (!ACCEL_PUT_IMAGE) goto fallback; switch (format) { case ZPixmap: if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (sna_put_zpixmap_blt(drawable, gc, ®ion, x, y, w, h, bits, PixmapBytePad(w, depth))) return; break; case XYBitmap: if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (sna_put_xybitmap_blt(drawable, gc, ®ion, x, y, w, h, bits)) return; break; case XYPixmap: if (sna_put_xypixmap_blt(drawable, gc, ®ion, x, y, w, h, left, bits)) return; break; default: return; } fallback: DBG(("%s: fallback\n", __FUNCTION__)); RegionTranslate(®ion, -dx, -dy); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, format == XYPixmap ? MOVE_READ | MOVE_WRITE : drawable_gc_flags(drawable, gc, false))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbPutImage(%d, %d, %d, %d)\n", __FUNCTION__, x, y, w, h)); fbPutImage(drawable, gc, depth, x, y, w, h, left, format, bits); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static bool source_contains_region(struct sna_damage *damage, const RegionRec *region, int16_t dx, int16_t dy) { BoxRec box; if (DAMAGE_IS_ALL(damage)) return true; if (damage == NULL) return false; box = region->extents; box.x1 += dx; box.x2 += dx; box.y1 += dy; box.y2 += dy; return sna_damage_contains_box__no_reduce(damage, &box); } static bool move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv, RegionRec *region, int16_t dx, int16_t dy, uint8_t alu, bool dst_is_gpu) { int w = region->extents.x2 - region->extents.x1; int h = region->extents.y2 - region->extents.y1; int count; assert_pixmap_map(pixmap, priv); if (DAMAGE_IS_ALL(priv->gpu_damage)) { assert(priv->gpu_bo); return true; } if (dst_is_gpu && priv->cpu_bo && priv->cpu_damage) { DBG(("%s: can use CPU bo? cpu_damage=%d, gpu_damage=%d, cpu hint=%d\n", __FUNCTION__, priv->cpu_damage ? DAMAGE_IS_ALL(priv->cpu_damage) ? -1 : 1 : 0, priv->gpu_damage ? DAMAGE_IS_ALL(priv->gpu_damage) ? -1 : 1 : 0, priv->cpu)); if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL) return false; if (priv->cpu && source_contains_region(priv->cpu_damage, region, dx, dy)) return false; } if (priv->gpu_bo) { DBG(("%s: has gpu bo (cpu damage?=%d, cpu=%d, gpu tiling=%d)\n", __FUNCTION__, priv->cpu_damage ? DAMAGE_IS_ALL(priv->cpu_damage) ? -1 : 1 : 0, priv->cpu, priv->gpu_bo->tiling)); if (priv->cpu_damage == NULL) return true; if (alu != GXcopy) return true; if (!priv->cpu) return true; if (priv->gpu_bo->tiling) return true; RegionTranslate(region, dx, dy); count = region_subsumes_damage(region, priv->cpu_damage); RegionTranslate(region, -dx, -dy); if (count) return true; } else { if ((priv->create & KGEM_CAN_CREATE_GPU) == 0) return false; if (priv->shm) return false; } count = priv->source_count++; if (priv->cpu_bo) { if (priv->cpu_bo->flush && count > SOURCE_BIAS) return true; if (sna_pixmap_default_tiling(to_sna_from_pixmap(pixmap), pixmap) == I915_TILING_NONE) return false; if (priv->cpu) return false; return count > SOURCE_BIAS; } else { if (w == pixmap->drawable.width && h == pixmap->drawable.height) return count > SOURCE_BIAS; return count * w*h >= (SOURCE_BIAS+2) * (int)pixmap->drawable.width * pixmap->drawable.height; } } static const BoxRec * reorder_boxes(const BoxRec *box, int n, int dx, int dy) { const BoxRec *next, *base; BoxRec *new; DBG(("%s x %d dx=%d, dy=%d\n", __FUNCTION__, n, dx, dy)); if (dy <= 0 && dx <= 0) { BoxRec *tmp; new = malloc(sizeof(BoxRec) * n); if (new == NULL) return NULL; tmp = new; next = box + n; do { *tmp++ = *--next; } while (next != box); } else if (dy < 0) { new = malloc(sizeof(BoxRec) * n); if (new == NULL) return NULL; base = next = box + n - 1; while (base >= box) { const BoxRec *tmp; while (next >= box && base->y1 == next->y1) next--; tmp = next + 1; while (tmp <= base) *new++ = *tmp++; base = next; } new -= n; } else { new = malloc(sizeof(BoxRec) * n); if (!new) return NULL; base = next = box; while (base < box + n) { const BoxRec *tmp; while (next < box + n && next->y1 == base->y1) next++; tmp = next; while (tmp != base) *new++ = *--tmp; base = next; } new -= n; } return new; } static void sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region,int dx, int dy, Pixel bitplane, void *closure) { PixmapPtr pixmap = get_drawable_pixmap(src); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); const BoxRec *box = region_rects(region); int n = region_num_rects(region); int alu = gc ? gc->alu : GXcopy; int16_t tx, ty, sx, sy; assert(pixmap == get_drawable_pixmap(dst)); assert(region_num_rects(region)); if (((dx | dy) == 0 && alu == GXcopy)) return; if (n > 1 && (dx | dy) < 0) { box = reorder_boxes(box, n, dx, dy); if (box == NULL) return; } DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src=+(%d, %d), alu=%d, pix.size=%dx%d)\n", __FUNCTION__, n, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, dx, dy, alu, pixmap->drawable.width, pixmap->drawable.height)); get_drawable_deltas(dst, pixmap, &tx, &ty); get_drawable_deltas(src, pixmap, &sx, &sy); sx += dx; sy += dy; if (priv == NULL || DAMAGE_IS_ALL(priv->cpu_damage)) { DBG(("%s: unattached, or all damaged on CPU\n", __FUNCTION__)); goto fallback; } if (priv->gpu_damage || (priv->cpu_damage == NULL && priv->gpu_bo)) { assert(priv->gpu_bo); if (alu == GXcopy && priv->clear) goto free_boxes; assert(priv->gpu_bo->proxy == NULL); if (!sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE | MOVE_READ | MOVE_ASYNC_HINT)) { DBG(("%s: fallback - not a pure copy and failed to move dst to GPU\n", __FUNCTION__)); goto fallback; } assert(priv->cpu_damage == NULL); if (!sna->render.copy_boxes(sna, alu, &pixmap->drawable, priv->gpu_bo, sx, sy, &pixmap->drawable, priv->gpu_bo, tx, ty, box, n, small_copy(region))) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; } if (!DAMAGE_IS_ALL(priv->gpu_damage)) { assert(!priv->clear); if (sna_pixmap_free_cpu(sna, priv, false)) { sna_damage_all(&priv->gpu_damage, pixmap); } else { RegionTranslate(region, tx, ty); sna_damage_add_to_pixmap(&priv->gpu_damage, region, pixmap); } } assert_pixmap_damage(pixmap); } else { fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE)) goto free_boxes; if (alu == GXcopy && pixmap->drawable.bitsPerPixel >= 8) { assert(pixmap->devKind); if (sigtrap_get() == 0) { FbBits *dst_bits, *src_bits; int stride = pixmap->devKind; int bpp = pixmap->drawable.bitsPerPixel; int i; dst_bits = (FbBits *) ((char *)pixmap->devPrivate.ptr + ty * stride + tx * bpp / 8); src_bits = (FbBits *) ((char *)pixmap->devPrivate.ptr + sy * stride + sx * bpp / 8); for (i = 0; i < n; i++) memmove_box(src_bits, dst_bits, bpp, stride, box+i, dx, dy); sigtrap_put(); } } else { if (gc && !sna_gc_move_to_cpu(gc, dst, region)) goto out; if (sigtrap_get() == 0) { miCopyRegion(src, dst, gc, region, dx, dy, fbCopyNtoN, 0, NULL); sigtrap_put(); } if (gc) out: sna_gc_move_to_gpu(gc); } } free_boxes: if (box != region_rects(region)) free((void *)box); } static inline bool sna_pixmap_is_gpu(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL || priv->clear) return false; if (DAMAGE_IS_ALL(priv->gpu_damage) || (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo) && !priv->gpu_bo->proxy)) return true; return priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo); } static int copy_prefer_gpu(struct sna *sna, struct sna_pixmap *dst_priv, struct sna_pixmap *src_priv, RegionRec *region, int16_t dx, int16_t dy) { assert(dst_priv); if (wedged(sna) && !dst_priv->pinned) return 0; if (src_priv == NULL) { DBG(("%s: source unattached, use cpu\n", __FUNCTION__)); return 0; } if (src_priv->clear) { DBG(("%s: source is clear, don't force use of GPU\n", __FUNCTION__)); return 0; } if (src_priv->gpu_damage && !source_contains_region(src_priv->cpu_damage, region, dx, dy)) { DBG(("%s: source has gpu damage, force gpu? %d\n", __FUNCTION__, src_priv->cpu_damage == NULL)); assert(src_priv->gpu_bo); return src_priv->cpu_damage ? PREFER_GPU : PREFER_GPU | FORCE_GPU; } if (src_priv->cpu_bo && kgem_bo_is_busy(src_priv->cpu_bo)) { DBG(("%s: source has busy CPU bo, force gpu\n", __FUNCTION__)); return PREFER_GPU | FORCE_GPU; } if (source_contains_region(src_priv->cpu_damage, region, dx, dy)) return src_priv->cpu_bo && kgem_is_idle(&sna->kgem); DBG(("%s: source has GPU bo? %d\n", __FUNCTION__, src_priv->gpu_bo != NULL)); return src_priv->gpu_bo != NULL; } static bool use_shm_bo(struct sna *sna, struct kgem_bo *bo, struct sna_pixmap *priv, int alu, bool replaces) { if (priv == NULL || priv->cpu_bo == NULL) { DBG(("%s: no, not attached\n", __FUNCTION__)); return false; } if (!priv->shm && !priv->cpu) { DBG(("%s: yes, ordinary CPU bo\n", __FUNCTION__)); return true; } if (alu != GXcopy) { DBG(("%s: yes, complex alu=%d\n", __FUNCTION__, alu)); return true; } if (!replaces && __kgem_bo_is_busy(&sna->kgem, bo)) { DBG(("%s: yes, dst is busy\n", __FUNCTION__)); return true; } if (priv->cpu_bo->needs_flush && __kgem_bo_is_busy(&sna->kgem, priv->cpu_bo)) { DBG(("%s: yes, src is busy\n", __FUNCTION__)); return true; } return false; } static bool sna_damage_contains_box__no_reduce__offset(struct sna_damage *damage, const BoxRec *extents, int16_t dx, int16_t dy) { BoxRec _extents; if (dx | dy) { _extents.x1 = extents->x1 + dx; _extents.x2 = extents->x2 + dx; _extents.y1 = extents->y1 + dy; _extents.y2 = extents->y2 + dy; extents = &_extents; } return sna_damage_contains_box__no_reduce(damage, extents); } static bool sna_copy_boxes__inplace(struct sna *sna, RegionPtr region, int alu, PixmapPtr src_pixmap, struct sna_pixmap *src_priv, int dx, int dy, PixmapPtr dst_pixmap, struct sna_pixmap *dst_priv, bool replaces) { const BoxRec *box; char *ptr; int n; assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel); if (alu != GXcopy) { DBG(("%s - no, complex alu [%d]\n", __FUNCTION__, alu)); return false; } if (!USE_INPLACE) { DBG(("%s - no, compile time disabled\n", __FUNCTION__)); return false; } if (dst_priv == src_priv) { DBG(("%s - no, dst == src\n", __FUNCTION__)); return false; } if (src_priv == NULL || src_priv->gpu_bo == NULL) { if (dst_priv && dst_priv->gpu_bo) goto upload_inplace; DBG(("%s - no, no src or dst GPU bo\n", __FUNCTION__)); return false; } switch (src_priv->gpu_bo->tiling) { case I915_TILING_Y: DBG(("%s - no, bad src tiling [Y]\n", __FUNCTION__)); return false; case I915_TILING_X: if (!sna->kgem.memcpy_from_tiled_x) { DBG(("%s - no, bad src tiling [X]\n", __FUNCTION__)); return false; } default: break; } if (src_priv->move_to_gpu && !src_priv->move_to_gpu(sna, src_priv, MOVE_READ)) { DBG(("%s - no, pending src move-to-gpu failed\n", __FUNCTION__)); return false; } if (!kgem_bo_can_map__cpu(&sna->kgem, src_priv->gpu_bo, FORCE_FULL_SYNC)) { DBG(("%s - no, cannot map src for reads into the CPU\n", __FUNCTION__)); return false; } if (src_priv->gpu_damage == NULL || !(DAMAGE_IS_ALL(src_priv->gpu_damage) || sna_damage_contains_box__no_reduce__offset(src_priv->gpu_damage, ®ion->extents, dx, dy))) { DBG(("%s - no, src is not damaged on the GPU\n", __FUNCTION__)); return false; } assert(sna_damage_contains_box__offset(&src_priv->gpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_IN); assert(sna_damage_contains_box__offset(&src_priv->cpu_damage, ®ion->extents, dx, dy) == PIXMAN_REGION_OUT); ptr = kgem_bo_map__cpu(&sna->kgem, src_priv->gpu_bo); if (ptr == NULL) { DBG(("%s - no, map failed\n", __FUNCTION__)); return false; } if (dst_priv && !sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, region, MOVE_WRITE | MOVE_INPLACE_HINT)) { DBG(("%s - no, dst sync failed\n", __FUNCTION__)); return false; } kgem_bo_sync__cpu_full(&sna->kgem, src_priv->gpu_bo, FORCE_FULL_SYNC); if (sigtrap_get()) return false; box = region_rects(region); n = region_num_rects(region); if (src_priv->gpu_bo->tiling) { DBG(("%s: copy from a tiled CPU map\n", __FUNCTION__)); assert(dst_pixmap->devKind); do { memcpy_from_tiled_x(&sna->kgem, ptr, dst_pixmap->devPrivate.ptr, src_pixmap->drawable.bitsPerPixel, src_priv->gpu_bo->pitch, dst_pixmap->devKind, box->x1 + dx, box->y1 + dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { DBG(("%s: copy from a linear CPU map\n", __FUNCTION__)); assert(dst_pixmap->devKind); do { memcpy_blt(ptr, dst_pixmap->devPrivate.ptr, src_pixmap->drawable.bitsPerPixel, src_priv->gpu_bo->pitch, dst_pixmap->devKind, box->x1 + dx, box->y1 + dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); if (!src_priv->shm) { assert(ptr == MAP(src_priv->gpu_bo->map__cpu)); src_pixmap->devPrivate.ptr = ptr; src_pixmap->devKind = src_priv->gpu_bo->pitch; src_priv->mapped = MAPPED_CPU; assert_pixmap_map(src_pixmap, src_priv); src_priv->cpu = true; } } sigtrap_put(); return true; upload_inplace: switch (dst_priv->gpu_bo->tiling) { case I915_TILING_Y: DBG(("%s - no, bad dst tiling [Y]\n", __FUNCTION__)); return false; case I915_TILING_X: if (!sna->kgem.memcpy_to_tiled_x) { DBG(("%s - no, bad dst tiling [X]\n", __FUNCTION__)); return false; } default: break; } if (dst_priv->move_to_gpu) { DBG(("%s - no, pending dst move-to-gpu\n", __FUNCTION__)); return false; } if (!can_upload__tiled_x(&sna->kgem, dst_priv->gpu_bo) || __kgem_bo_is_busy(&sna->kgem, dst_priv->gpu_bo)) { if (replaces && !dst_priv->pinned) { unsigned create; struct kgem_bo *bo; create = CREATE_CPU_MAP | CREATE_INACTIVE; if (dst_priv->gpu_bo->scanout) create |= CREATE_SCANOUT; bo = kgem_create_2d(&sna->kgem, dst_pixmap->drawable.width, dst_pixmap->drawable.height, dst_pixmap->drawable.bitsPerPixel, dst_priv->gpu_bo->tiling, create); if (bo == NULL) return false; sna_pixmap_unmap(dst_pixmap, dst_priv); kgem_bo_destroy(&sna->kgem, dst_priv->gpu_bo); dst_priv->gpu_bo = bo; } else { DBG(("%s - no, dst is busy\n", __FUNCTION__)); return false; } if (!can_upload__tiled_x(&sna->kgem, dst_priv->gpu_bo)) { DBG(("%s - no, cannot map dst for reads into the CPU\n", __FUNCTION__)); return false; } } if (src_priv && !sna_drawable_move_region_to_cpu(&src_pixmap->drawable, region, MOVE_READ)) { DBG(("%s - no, src sync failed\n", __FUNCTION__)); return false; } if (kgem_bo_can_map__cpu(&sna->kgem, dst_priv->gpu_bo, true)) { ptr = kgem_bo_map__cpu(&sna->kgem, dst_priv->gpu_bo); if (ptr == NULL) { DBG(("%s - no, map failed\n", __FUNCTION__)); return false; } kgem_bo_sync__cpu(&sna->kgem, dst_priv->gpu_bo); } else { ptr = kgem_bo_map__wc(&sna->kgem, dst_priv->gpu_bo); if (ptr == NULL) { DBG(("%s - no, map failed\n", __FUNCTION__)); return false; } kgem_bo_sync__gtt(&sna->kgem, dst_priv->gpu_bo); } if (!DAMAGE_IS_ALL(dst_priv->gpu_damage)) { assert(!dst_priv->clear); sna_damage_add_to_pixmap(&dst_priv->gpu_damage, region, dst_pixmap); if (sna_damage_is_all(&dst_priv->gpu_damage, dst_pixmap->drawable.width, dst_pixmap->drawable.height)) { DBG(("%s: replaced entire pixmap, destroying CPU shadow\n", __FUNCTION__)); sna_damage_destroy(&dst_priv->cpu_damage); list_del(&dst_priv->flush_list); } else sna_damage_subtract(&dst_priv->cpu_damage, region); } dst_priv->clear = false; assert(has_coherent_ptr(sna, src_priv, MOVE_READ)); if (sigtrap_get()) return false; box = region_rects(region); n = region_num_rects(region); if (dst_priv->gpu_bo->tiling) { DBG(("%s: copy to a tiled CPU map\n", __FUNCTION__)); assert(dst_priv->gpu_bo->tiling == I915_TILING_X); assert(src_pixmap->devKind); do { memcpy_to_tiled_x(&sna->kgem, src_pixmap->devPrivate.ptr, ptr, src_pixmap->drawable.bitsPerPixel, src_pixmap->devKind, dst_priv->gpu_bo->pitch, box->x1 + dx, box->y1 + dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { DBG(("%s: copy to a linear CPU map\n", __FUNCTION__)); assert(src_pixmap->devKind); do { memcpy_blt(src_pixmap->devPrivate.ptr, ptr, src_pixmap->drawable.bitsPerPixel, src_pixmap->devKind, dst_priv->gpu_bo->pitch, box->x1 + dx, box->y1 + dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); if (!dst_priv->shm) { dst_pixmap->devPrivate.ptr = ptr; dst_pixmap->devKind = dst_priv->gpu_bo->pitch; if (ptr == MAP(dst_priv->gpu_bo->map__cpu)) { dst_priv->mapped = MAPPED_CPU; dst_priv->cpu = true; } else dst_priv->mapped = MAPPED_GTT; assert_pixmap_map(dst_pixmap, dst_priv); } } sigtrap_put(); return true; } static void discard_cpu_damage(struct sna *sna, struct sna_pixmap *priv) { if (priv->cpu_damage == NULL && !priv->shm) return; DBG(("%s: discarding existing CPU damage\n", __FUNCTION__)); if (kgem_bo_discard_cache(priv->gpu_bo, true)) { DBG(("%s: discarding cached upload buffer\n", __FUNCTION__)); assert(DAMAGE_IS_ALL(priv->cpu_damage)); assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage)); /* magical upload buffer */ assert(!priv->pinned); assert(!priv->mapped); sna_damage_destroy(&priv->gpu_damage); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); if (priv->gpu_bo && sna_pixmap_free_cpu(sna, priv, priv->cpu)) sna_damage_all(&priv->gpu_damage, priv->pixmap); priv->cpu = false; } static void sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region, int dx, int dy, Pixel bitplane, void *closure) { PixmapPtr src_pixmap = get_drawable_pixmap(src); struct sna_pixmap *src_priv = sna_pixmap(src_pixmap); PixmapPtr dst_pixmap = get_drawable_pixmap(dst); struct sna_pixmap *dst_priv = sna_pixmap(dst_pixmap); struct sna *sna = to_sna_from_pixmap(src_pixmap); struct sna_damage **damage; struct kgem_bo *bo; int16_t src_dx, src_dy; int16_t dst_dx, dst_dy; const BoxRec *box = region_rects(region); int n = region_num_rects(region); int alu = gc->alu; int stride, bpp; char *bits; bool replaces; assert(region_num_rects(region)); if (src_priv && src_priv->gpu_bo == NULL && src_priv->cpu_bo == NULL && src_priv->ptr == NULL) { /* Rare but still happens, nothing to copy */ DBG(("%s: src pixmap=%ld is empty\n", __FUNCTION__, src_pixmap->drawable.serialNumber)); return; } if (src_pixmap == dst_pixmap) return sna_self_copy_boxes(src, dst, gc, region, dx, dy, bitplane, closure); DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src pixmap=%ld+(%d, %d), dst pixmap=%ld+(%d, %d), alu=%d, src.size=%dx%d, dst.size=%dx%d)\n", __FUNCTION__, n, box[0].x1, box[0].y1, box[0].x2, box[0].y2, src_pixmap->drawable.serialNumber, dx, dy, dst_pixmap->drawable.serialNumber, get_drawable_dx(dst), get_drawable_dy(dst), alu, src_pixmap->drawable.width, src_pixmap->drawable.height, dst_pixmap->drawable.width, dst_pixmap->drawable.height)); assert_pixmap_damage(dst_pixmap); assert_pixmap_damage(src_pixmap); bpp = dst_pixmap->drawable.bitsPerPixel; if (get_drawable_deltas(dst, dst_pixmap, &dst_dx, &dst_dy)) RegionTranslate(region, dst_dx, dst_dy); get_drawable_deltas(src, src_pixmap, &src_dx, &src_dy); src_dx += dx - dst_dx; src_dy += dy - dst_dy; assert_pixmap_contains_box(dst_pixmap, RegionExtents(region)); assert_pixmap_contains_box_with_offset(src_pixmap, RegionExtents(region), src_dx, src_dy); replaces = n == 1 && alu_overwrites(alu) && box->x1 <= 0 && box->y1 <= 0 && box->x2 >= dst_pixmap->drawable.width && box->y2 >= dst_pixmap->drawable.height; DBG(("%s: dst=(priv=%p, gpu_bo=%d, cpu_bo=%d), src=(priv=%p, gpu_bo=%d, cpu_bo=%d), replaces=%d\n", __FUNCTION__, dst_priv, dst_priv && dst_priv->gpu_bo ? dst_priv->gpu_bo->handle : 0, dst_priv && dst_priv->cpu_bo ? dst_priv->cpu_bo->handle : 0, src_priv, src_priv && src_priv->gpu_bo ? src_priv->gpu_bo->handle : 0, src_priv && src_priv->cpu_bo ? src_priv->cpu_bo->handle : 0, replaces)); if (dst_priv == NULL) { DBG(("%s: unattached dst failed, fallback\n", __FUNCTION__)); goto fallback; } if (alu == GXcopy && src_priv && src_priv->cow && COW(src_priv->cow) == COW(dst_priv->cow)) { if ((dx | dy) == 0) { DBG(("%s: ignoring cow for no op\n", __FUNCTION__)); return; } else if (IS_COW_OWNER(dst_priv->cow)) { /* XXX hack for firefox -- subsequent uses of src will be corrupt! */ DBG(("%s: ignoring cow reference for cousin copy\n", __FUNCTION__)); assert(src_priv->cpu_damage == NULL); assert(dst_priv->move_to_gpu == NULL); bo = dst_priv->gpu_bo; damage = NULL; } else goto discard_cow; } else { unsigned hint; discard_cow: hint = copy_prefer_gpu(sna, dst_priv, src_priv, region, src_dx, src_dy); if (replaces) { discard_cpu_damage(sna, dst_priv); hint |= REPLACES | IGNORE_DAMAGE; } else if (alu_overwrites(alu)) { if (region->data == NULL) hint |= IGNORE_DAMAGE; if (dst_priv->cpu_damage && region_subsumes_damage(region, dst_priv->cpu_damage)) discard_cpu_damage(sna, dst_priv); } bo = sna_drawable_use_bo(&dst_pixmap->drawable, hint, ®ion->extents, &damage); } if (bo) { if (alu == GXset || alu == GXclear || (src_priv && src_priv->clear)) { uint32_t color; if (alu == GXset) color = (1 << dst_pixmap->drawable.depth) - 1; else if (alu == GXclear) color = 0; else color = src_priv->clear_color; DBG(("%s: applying src clear [%08x] to dst\n", __FUNCTION__, src_priv->clear_color)); if (n == 1) { if (replaces && UNDO) kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo); if (!sna->render.fill_one(sna, dst_pixmap, bo, color, box->x1, box->y1, box->x2, box->y2, alu)) { DBG(("%s: unsupported fill\n", __FUNCTION__)); goto fallback; } if (replaces && bo == dst_priv->gpu_bo) { DBG(("%s: marking dst handle=%d as all clear [%08x]\n", __FUNCTION__, dst_priv->gpu_bo->handle, src_priv->clear_color)); dst_priv->clear = true; dst_priv->clear_color = color; sna_damage_all(&dst_priv->gpu_damage, dst_pixmap); sna_damage_destroy(&dst_priv->cpu_damage); list_del(&dst_priv->flush_list); return; } } else { struct sna_fill_op fill; if (!sna_fill_init_blt(&fill, sna, dst_pixmap, bo, alu, color, FILL_BOXES)) { DBG(("%s: unsupported fill\n", __FUNCTION__)); goto fallback; } fill.boxes(sna, &fill, box, n); fill.done(sna, &fill); } if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } if (src_priv && move_to_gpu(src_pixmap, src_priv, region, src_dx, src_dy, alu, bo == dst_priv->gpu_bo) && sna_pixmap_move_to_gpu(src_pixmap, MOVE_READ | MOVE_ASYNC_HINT)) { DBG(("%s: move whole src_pixmap to GPU and copy\n", __FUNCTION__)); if (replaces && UNDO) kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo); if (replaces && src_pixmap->drawable.width == dst_pixmap->drawable.width && src_pixmap->drawable.height == dst_pixmap->drawable.height) { assert(src_pixmap->drawable.depth == dst_pixmap->drawable.depth); assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel); if (sna_pixmap_make_cow(sna, src_priv, dst_priv)) { assert(dst_priv->gpu_bo == src_priv->gpu_bo); sna_damage_all(&dst_priv->gpu_damage, dst_pixmap); sna_damage_destroy(&dst_priv->cpu_damage); list_del(&dst_priv->flush_list); if (dst_priv->shm) sna_add_flush_pixmap(sna, dst_priv, dst_priv->cpu_bo); return; } } if (!sna->render.copy_boxes(sna, alu, &src_pixmap->drawable, src_priv->gpu_bo, src_dx, src_dy, &dst_pixmap->drawable, bo, 0, 0, box, n, small_copy(region))) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; } if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } if (src_priv && region_overlaps_damage(region, src_priv->gpu_damage, src_dx, src_dy)) { BoxRec area; DBG(("%s: region overlaps GPU damage, upload and copy\n", __FUNCTION__)); area = region->extents; area.x1 += src_dx; area.x2 += src_dx; area.y1 += src_dy; area.y2 += src_dy; if (!sna_pixmap_move_area_to_gpu(src_pixmap, &area, MOVE_READ | MOVE_ASYNC_HINT)) { DBG(("%s: move-to-gpu(src) failed, fallback\n", __FUNCTION__)); goto fallback; } if (replaces && UNDO) kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo); if (!sna->render.copy_boxes(sna, alu, &src_pixmap->drawable, src_priv->gpu_bo, src_dx, src_dy, &dst_pixmap->drawable, bo, 0, 0, box, n, small_copy(region))) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; } if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } if (bo != dst_priv->gpu_bo) goto fallback; if (use_shm_bo(sna, bo, src_priv, alu, replaces && !dst_priv->pinned)) { bool ret; DBG(("%s: region overlaps CPU damage, copy from CPU bo (shm? %d)\n", __FUNCTION__, src_priv->shm)); assert(bo != dst_priv->cpu_bo); RegionTranslate(region, src_dx, src_dy); ret = sna_drawable_move_region_to_cpu(&src_pixmap->drawable, region, MOVE_READ | MOVE_ASYNC_HINT); RegionTranslate(region, -src_dx, -src_dy); if (!ret) { DBG(("%s: move-to-cpu(src) failed, fallback\n", __FUNCTION__)); goto fallback; } if (replaces && UNDO) kgem_bo_pair_undo(&sna->kgem, dst_priv->gpu_bo, dst_priv->cpu_bo); if (src_priv->shm) { assert(!src_priv->flush); sna_add_flush_pixmap(sna, src_priv, src_priv->cpu_bo); } if (!sna->render.copy_boxes(sna, alu, &src_pixmap->drawable, src_priv->cpu_bo, src_dx, src_dy, &dst_pixmap->drawable, bo, 0, 0, box, n, small_copy(region) | (src_priv->shm ? COPY_LAST : 0))) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); goto fallback; } if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } if (src_priv) { bool ret; RegionTranslate(region, src_dx, src_dy); ret = sna_drawable_move_region_to_cpu(&src_pixmap->drawable, region, MOVE_READ); RegionTranslate(region, -src_dx, -src_dy); if (!ret) { DBG(("%s: move-to-cpu(src) failed, fallback\n", __FUNCTION__)); goto fallback; } assert(!src_priv->mapped); if (src_pixmap->devPrivate.ptr == NULL) /* uninitialised!*/ return; } if (USE_USERPTR_UPLOADS && sna->kgem.has_userptr && (alu != GXcopy || (box_inplace(src_pixmap, ®ion->extents) && __kgem_bo_is_busy(&sna->kgem, bo)))) { struct kgem_bo *src_bo; bool ok = false; DBG(("%s: upload through a temporary map\n", __FUNCTION__)); assert(src_pixmap->devKind); src_bo = kgem_create_map(&sna->kgem, src_pixmap->devPrivate.ptr, src_pixmap->devKind * src_pixmap->drawable.height, true); if (src_bo) { src_bo->pitch = src_pixmap->devKind; kgem_bo_mark_unreusable(src_bo); ok = sna->render.copy_boxes(sna, alu, &src_pixmap->drawable, src_bo, src_dx, src_dy, &dst_pixmap->drawable, bo, 0, 0, box, n, small_copy(region) | COPY_LAST); kgem_bo_sync__cpu(&sna->kgem, src_bo); assert(src_bo->rq == NULL); kgem_bo_destroy(&sna->kgem, src_bo); } if (ok) { if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } } if (alu != GXcopy) { PixmapPtr tmp; struct kgem_bo *src_bo; int i; assert(src_pixmap->drawable.depth != 1); DBG(("%s: creating temporary source upload for non-copy alu [%d]\n", __FUNCTION__, alu)); tmp = sna_pixmap_create_upload(src->pScreen, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1, src->depth, KGEM_BUFFER_WRITE_INPLACE); if (tmp == NullPixmap) return; src_bo = __sna_pixmap_get_bo(tmp); assert(src_bo != NULL); dx = -region->extents.x1; dy = -region->extents.y1; for (i = 0; i < n; i++) { assert(box[i].x1 + src_dx >= 0); assert(box[i].y1 + src_dy >= 0); assert(box[i].x2 + src_dx <= src_pixmap->drawable.width); assert(box[i].y2 + src_dy <= src_pixmap->drawable.height); assert(box[i].x1 + dx >= 0); assert(box[i].y1 + dy >= 0); assert(box[i].x2 + dx <= tmp->drawable.width); assert(box[i].y2 + dy <= tmp->drawable.height); assert(has_coherent_ptr(sna, sna_pixmap(src_pixmap), MOVE_READ)); assert(has_coherent_ptr(sna, sna_pixmap(tmp), MOVE_WRITE)); assert(src_pixmap->devKind); assert(tmp->devKind); memcpy_blt(src_pixmap->devPrivate.ptr, tmp->devPrivate.ptr, src_pixmap->drawable.bitsPerPixel, src_pixmap->devKind, tmp->devKind, box[i].x1 + src_dx, box[i].y1 + src_dy, box[i].x1 + dx, box[i].y1 + dy, box[i].x2 - box[i].x1, box[i].y2 - box[i].y1); } if (n == 1 && tmp->drawable.width == src_pixmap->drawable.width && tmp->drawable.height == src_pixmap->drawable.height) { DBG(("%s: caching upload for src bo\n", __FUNCTION__)); assert(src_priv->gpu_damage == NULL); assert(src_priv->gpu_bo == NULL); kgem_proxy_bo_attach(src_bo, &src_priv->gpu_bo); } if (!sna->render.copy_boxes(sna, alu, &tmp->drawable, src_bo, dx, dy, &dst_pixmap->drawable, bo, 0, 0, box, n, 0)) { DBG(("%s: fallback - accelerated copy boxes failed\n", __FUNCTION__)); tmp->drawable.pScreen->DestroyPixmap(tmp); goto fallback; } tmp->drawable.pScreen->DestroyPixmap(tmp); if (damage) sna_damage_add_to_pixmap(damage, region, dst_pixmap); return; } else { DBG(("%s: dst is on the GPU, src is on the CPU, uploading into dst\n", __FUNCTION__)); assert(src_pixmap->devKind); if (!dst_priv->pinned && replaces) { stride = src_pixmap->devKind; bits = src_pixmap->devPrivate.ptr; bits += (src_dy + box->y1) * stride + (src_dx + box->x1) * bpp / 8; if (!sna_replace(sna, dst_pixmap, bits, stride)) { DBG(("%s: replace failed, fallback\n", __FUNCTION__)); goto fallback; } } else { assert(!DAMAGE_IS_ALL(dst_priv->cpu_damage)); if (!sna_write_boxes(sna, dst_pixmap, dst_priv->gpu_bo, 0, 0, src_pixmap->devPrivate.ptr, src_pixmap->devKind, src_dx, src_dy, box, n)) { DBG(("%s: write failed, fallback\n", __FUNCTION__)); goto fallback; } } assert(dst_priv->clear == false); dst_priv->cpu = false; if (damage) { assert(!dst_priv->clear); assert(dst_priv->gpu_bo); assert(dst_priv->gpu_bo->proxy == NULL); assert(*damage == dst_priv->gpu_damage); if (replaces) { sna_damage_destroy(&dst_priv->cpu_damage); sna_damage_all(&dst_priv->gpu_damage, dst_pixmap); list_del(&dst_priv->flush_list); } else sna_damage_add(&dst_priv->gpu_damage, region); assert_pixmap_damage(dst_pixmap); } } return; } fallback: if (alu == GXcopy && src_priv && src_priv->clear) { DBG(("%s: copying clear [%08x]\n", __FUNCTION__, src_priv->clear_color)); if (dst_priv) { if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, region, MOVE_WRITE | MOVE_INPLACE_HINT)) return; } if (sigtrap_get() == 0) { assert(dst_pixmap->devPrivate.ptr); assert(dst_pixmap->devKind); sigtrap_assert_active(); do { pixman_fill(dst_pixmap->devPrivate.ptr, dst_pixmap->devKind/sizeof(uint32_t), dst_pixmap->drawable.bitsPerPixel, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, src_priv->clear_color); box++; } while (--n); sigtrap_put(); } } else if (!sna_copy_boxes__inplace(sna, region, alu, src_pixmap, src_priv, src_dx, src_dy, dst_pixmap, dst_priv, replaces)) { FbBits *dst_bits, *src_bits; int dst_stride, src_stride; DBG(("%s: fallback -- src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy)); if (src_priv) { unsigned mode; RegionTranslate(region, src_dx, src_dy); assert_pixmap_contains_box(src_pixmap, RegionExtents(region)); mode = MOVE_READ; if (!sna->kgem.can_blt_cpu || (src_priv->cpu_bo == NULL && (src_priv->create & KGEM_CAN_CREATE_CPU) == 0)) mode |= MOVE_INPLACE_HINT; if (!sna_drawable_move_region_to_cpu(&src_pixmap->drawable, region, mode)) return; RegionTranslate(region, -src_dx, -src_dy); } assert(src_priv == sna_pixmap(src_pixmap)); if (dst_priv) { unsigned mode; if (alu_overwrites(alu)) mode = MOVE_WRITE | MOVE_INPLACE_HINT; else mode = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_region_to_cpu(&dst_pixmap->drawable, region, mode)) return; } assert(dst_priv == sna_pixmap(dst_pixmap)); assert(dst_pixmap->devKind); assert(src_pixmap->devKind); dst_stride = dst_pixmap->devKind; src_stride = src_pixmap->devKind; if (alu == GXcopy && bpp >= 8) { dst_bits = (FbBits *)dst_pixmap->devPrivate.ptr; src_bits = (FbBits *) ((char *)src_pixmap->devPrivate.ptr + src_dy * src_stride + src_dx * bpp / 8); if (sigtrap_get() == 0) { do { DBG(("%s: memcpy_blt(box=(%d, %d), (%d, %d), src=(%d, %d), pitches=(%d, %d))\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, src_dx, src_dy, src_stride, dst_stride)); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= dst_pixmap->drawable.width); assert(box->y2 <= dst_pixmap->drawable.height); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x2 + src_dx <= src_pixmap->drawable.width); assert(box->y2 + src_dy <= src_pixmap->drawable.height); assert(has_coherent_ptr(sna, src_priv, MOVE_READ)); assert(has_coherent_ptr(sna, dst_priv, MOVE_WRITE)); assert(src_stride); assert(dst_stride); memcpy_blt(src_bits, dst_bits, bpp, src_stride, dst_stride, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); } } else { DBG(("%s: fallback -- miCopyRegion\n", __FUNCTION__)); RegionTranslate(region, -dst_dx, -dst_dy); if (sna_gc_move_to_cpu(gc, dst, region) && sigtrap_get() == 0) { miCopyRegion(src, dst, gc, region, dx, dy, fbCopyNtoN, 0, NULL); sigtrap_put(); } sna_gc_move_to_gpu(gc); } } } typedef void (*sna_copy_func)(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region, int dx, int dy, Pixel bitPlane, void *closure); static inline bool box_equal(const BoxRec *a, const BoxRec *b) { return *(const uint64_t *)a == *(const uint64_t *)b; } static inline bool has_clip(GCPtr gc) { #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0) return gc->clientClipType != CT_NONE; #else return gc->clientClip != NULL; #endif } static RegionPtr sna_do_copy(DrawablePtr src, DrawablePtr dst, GCPtr gc, int sx, int sy, int width, int height, int dx, int dy, sna_copy_func copy, Pixel bitPlane, void *closure) { RegionPtr clip; RegionRec region; BoxRec src_extents; bool expose; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%dx%d)\n", __FUNCTION__, sx, sy, dx, dy, width, height)); /* Short cut for unmapped windows */ if (dst->type == DRAWABLE_WINDOW && !((WindowPtr)dst)->realized) { DBG(("%s: unmapped/unrealized dst (pixmap=%ld)\n", __FUNCTION__, get_window_pixmap((WindowPtr)dst))); return NULL; } SourceValidate(src, sx, sy, width, height, gc->subWindowMode); sx += src->x; sy += src->y; dx += dst->x; dy += dst->y; DBG(("%s: after drawable: src=(%d, %d), dst=(%d, %d), size=(%dx%d)\n", __FUNCTION__, sx, sy, dx, dy, width, height)); region.extents.x1 = dx; region.extents.y1 = dy; region.extents.x2 = bound(dx, width); region.extents.y2 = bound(dy, height); region.data = NULL; DBG(("%s: dst extents (%d, %d), (%d, %d), dst clip extents (%d, %d), (%d, %d), dst size=%dx%d\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, gc->pCompositeClip->extents.x1, gc->pCompositeClip->extents.y1, gc->pCompositeClip->extents.x2, gc->pCompositeClip->extents.y2, dst->width, dst->height)); if (!box_intersect(®ion.extents, &gc->pCompositeClip->extents)) { DBG(("%s: dst clipped out\n", __FUNCTION__)); return NULL; } DBG(("%s: clipped dst extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); assert_drawable_contains_box(dst, ®ion.extents); region.extents.x1 = clamp(region.extents.x1, sx - dx); region.extents.x2 = clamp(region.extents.x2, sx - dx); region.extents.y1 = clamp(region.extents.y1, sy - dy); region.extents.y2 = clamp(region.extents.y2, sy - dy); src_extents = region.extents; expose = true; DBG(("%s: unclipped src extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (region.extents.x1 < src->x) region.extents.x1 = src->x; if (region.extents.y1 < src->y) region.extents.y1 = src->y; if (region.extents.x2 > src->x + (int) src->width) region.extents.x2 = src->x + (int) src->width; if (region.extents.y2 > src->y + (int) src->height) region.extents.y2 = src->y + (int) src->height; DBG(("%s: clipped src extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (box_empty(®ion.extents)) { DBG(("%s: src clipped out\n", __FUNCTION__)); return NULL; } /* Compute source clip region */ if (src->type == DRAWABLE_PIXMAP) { if (src == dst && !has_clip(gc)) { DBG(("%s: pixmap -- using gc clip\n", __FUNCTION__)); clip = gc->pCompositeClip; } else { DBG(("%s: pixmap -- no source clipping\n", __FUNCTION__)); expose = false; clip = NULL; } } else { WindowPtr w = (WindowPtr)src; if (gc->subWindowMode == IncludeInferiors) { DBG(("%s: window -- include inferiors\n", __FUNCTION__)); if (w->winSize.data) RegionIntersect(®ion, ®ion, &w->winSize); else box_intersect(®ion.extents, &w->winSize.extents); clip = &w->borderClip; } else { DBG(("%s: window -- clip by children\n", __FUNCTION__)); clip = &w->clipList; } } if (clip != NULL) { if (clip->data == NULL) { box_intersect(®ion.extents, &clip->extents); if (box_equal(&src_extents, ®ion.extents)) expose = false; } else RegionIntersect(®ion, ®ion, clip); } DBG(("%s: src extents (%d, %d), (%d, %d) x %d\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, region_num_rects(®ion))); RegionTranslate(®ion, dx-sx, dy-sy); if (gc->pCompositeClip->data) RegionIntersect(®ion, ®ion, gc->pCompositeClip); DBG(("%s: copy region (%d, %d), (%d, %d) x %d + (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, region_num_rects(®ion), sx-dx, sy-dy)); if (!box_empty(®ion.extents)) copy(src, dst, gc, ®ion, sx-dx, sy-dy, bitPlane, closure); assert(gc->pCompositeClip != ®ion); RegionUninit(®ion); /* Pixmap sources generate a NoExposed (we return NULL to do this) */ clip = NULL; if (expose && gc->fExpose) clip = miHandleExposures(src, dst, gc, sx - src->x, sy - src->y, width, height, dx - dst->x, dy - dst->y, (unsigned long) bitPlane); return clip; } static void sna_fallback_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc, RegionPtr region, int dx, int dy, Pixel bitplane, void *closure) { DBG(("%s (boxes=%dx[(%d, %d), (%d, %d)...], src=+(%d, %d), alu=%d\n", __FUNCTION__, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, dx, dy, gc->alu)); if (!sna_gc_move_to_cpu(gc, dst, region)) goto out; RegionTranslate(region, dx, dy); if (!sna_drawable_move_region_to_cpu(src, region, MOVE_READ)) goto out; RegionTranslate(region, -dx, -dy); if (src == dst || get_drawable_pixmap(src) == get_drawable_pixmap(dst)) { DBG(("%s: self-copy\n", __FUNCTION__)); if (!sna_drawable_move_to_cpu(dst, MOVE_WRITE | MOVE_READ)) goto out; } else { if (!sna_drawable_move_region_to_cpu(dst, region, drawable_gc_flags(dst, gc, false))) goto out; } if (sigtrap_get() == 0) { miCopyRegion(src, dst, gc, region, dx, dy, fbCopyNtoN, 0, NULL); FALLBACK_FLUSH(dst); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); } static RegionPtr sna_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int src_x, int src_y, int width, int height, int dst_x, int dst_y) { struct sna *sna = to_sna_from_drawable(dst); sna_copy_func copy; if (gc->planemask == 0) return NULL; if (sna->ignore_copy_area) return NULL; DBG(("%s: src=pixmap=%ld:(%d, %d)x(%d, %d)+(%d, %d) -> dst=pixmap=%ld:(%d, %d)+(%d, %d); alu=%d, pm=%lx, depth=%d\n", __FUNCTION__, get_drawable_pixmap(src)->drawable.serialNumber, src_x, src_y, width, height, src->x, src->y, get_drawable_pixmap(dst)->drawable.serialNumber, dst_x, dst_y, dst->x, dst->y, gc->alu, gc->planemask, gc->depth)); if (FORCE_FALLBACK || !ACCEL_COPY_AREA || wedged(sna) || !PM_IS_SOLID(dst, gc->planemask) || gc->depth < 8) { DBG(("%s: fallback copy\n", __FUNCTION__)); copy = sna_fallback_copy_boxes; } else if (src == dst) { DBG(("%s: self copy\n", __FUNCTION__)); copy = sna_self_copy_boxes; } else { DBG(("%s: normal copy\n", __FUNCTION__)); copy = sna_copy_boxes; } return sna_do_copy(src, dst, gc, src_x, src_y, width, height, dst_x, dst_y, copy, 0, NULL); } const BoxRec * __find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y) { assert(end - begin > 1); do { const BoxRec *mid = begin + (end - begin) / 2; if (mid->y2 > y) end = mid; else begin = mid; } while (end > begin + 1); if (begin->y2 > y) return begin; else return end; } struct sna_fill_spans { struct sna *sna; PixmapPtr pixmap; RegionRec region; unsigned flags; uint32_t phase; struct kgem_bo *bo; struct sna_damage **damage; int16_t dx, dy; void *op; }; static void sna_poly_point__cpu(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { fbPolyPoint(drawable, gc, mode, n, pt, -1); } static void sna_poly_point__fill(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; BoxRec box[512]; DDXPointRec last; DBG(("%s: count=%d\n", __FUNCTION__, n)); if (n == 0) return; last.x = drawable->x + data->dx; last.y = drawable->y + data->dy; if (op->points && mode != CoordModePrevious) { op->points(data->sna, op, last.x, last.y, pt, n); } else do { BoxRec *b = box; unsigned nbox = n; if (nbox > ARRAY_SIZE(box)) nbox = ARRAY_SIZE(box); n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x1 += last.x; b->y1 += last.y; if (mode == CoordModePrevious) last = *(DDXPointRec *)b; b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; b++; } while (--nbox); op->boxes(data->sna, op, box, b - box); } while (n); } static void sna_poly_point__gpu(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op fill; BoxRec box[512]; DDXPointRec last; if (!sna_fill_init_blt(&fill, data->sna, data->pixmap, data->bo, gc->alu, gc->fgPixel, FILL_POINTS)) return; DBG(("%s: count=%d\n", __FUNCTION__, n)); last.x = drawable->x; last.y = drawable->y; while (n) { BoxRec *b = box; unsigned nbox = n; if (nbox > ARRAY_SIZE(box)) nbox = ARRAY_SIZE(box); n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x1 += last.x; b->y1 += last.y; if (mode == CoordModePrevious) last = *(DDXPointRec *)b; if (RegionContainsPoint(&data->region, b->x1, b->y1, NULL)) { b->x1 += data->dx; b->y1 += data->dy; b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; b++; } } while (--nbox); if (b != box) fill.boxes(data->sna, &fill, box, b - box); } fill.done(data->sna, &fill); } static void sna_poly_point__fill_clip_extents(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; const BoxRec *extents = &data->region.extents; BoxRec box[512], *b = box; const BoxRec *const last_box = b + ARRAY_SIZE(box); DDXPointRec last; DBG(("%s: count=%d\n", __FUNCTION__, n)); last.x = drawable->x + data->dx; last.y = drawable->y + data->dy; while (n--) { *(DDXPointRec *)b = *pt++; b->x1 += last.x; b->y1 += last.y; if (mode == CoordModePrevious) last = *(DDXPointRec *)b; if (b->x1 >= extents->x1 && b->x1 < extents->x2 && b->y1 >= extents->y1 && b->y1 < extents->y2) { b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; if (++b == last_box) { op->boxes(data->sna, op, box, last_box - box); b = box; } } } if (b != box) op->boxes(data->sna, op, box, b - box); } static void sna_poly_point__fill_clip_boxes(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; RegionRec *clip = &data->region; BoxRec box[512], *b = box; const BoxRec *const last_box = b + ARRAY_SIZE(box); DDXPointRec last; DBG(("%s: count=%d\n", __FUNCTION__, n)); last.x = drawable->x + data->dx; last.y = drawable->y + data->dy; while (n--) { *(DDXPointRec *)b = *pt++; b->x1 += last.x; b->y1 += last.y; if (mode == CoordModePrevious) last = *(DDXPointRec *)b; if (RegionContainsPoint(clip, b->x1, b->y1, NULL)) { b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; if (++b == last_box) { op->boxes(data->sna, op, box, last_box - box); b = box; } } } if (b != box) op->boxes(data->sna, op, box, b - box); } static void sna_poly_point__dash(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_poly_point__fill(drawable, gc, mode, n, pt); } static void sna_poly_point__dash_clip_extents(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_poly_point__fill_clip_extents(drawable, gc, mode, n, pt); } static void sna_poly_point__dash_clip_boxes(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_poly_point__fill_clip_boxes(drawable, gc, mode, n, pt); } static void sna_fill_spans__fill(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; BoxRec box[512]; DBG(("%s: alu=%d, fg=%08lx, count=%d\n", __FUNCTION__, gc->alu, gc->fgPixel, n)); while (n) { BoxRec *b = box; int nbox = n; if (nbox > ARRAY_SIZE(box)) nbox = ARRAY_SIZE(box); n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; DBG(("%s: (%d, %d), (%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2, b->y2)); assert(b->x1 >= drawable->x); assert(b->x2 <= drawable->x + drawable->width); assert(b->y1 >= drawable->y); assert(b->y2 <= drawable->y + drawable->height); if (b->x2 > b->x1) { if (b != box && b->y1 == b[-1].y2 && b->x1 == b[-1].x1 && b->x2 == b[-1].x2) b[-1].y2 = b->y2; else b++; } } while (--nbox); if (b != box) op->boxes(data->sna, op, box, b - box); } } static void sna_fill_spans__dash(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_fill_spans__fill(drawable, gc, n, pt, width, sorted); } static void sna_fill_spans__fill_offset(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; BoxRec box[512]; DBG(("%s: alu=%d, fg=%08lx\n", __FUNCTION__, gc->alu, gc->fgPixel)); while (n) { BoxRec *b = box; int nbox = n; if (nbox > ARRAY_SIZE(box)) nbox = ARRAY_SIZE(box); n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x1 += data->dx; b->y1 += data->dy; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; if (b->x2 > b->x1) b++; } while (--nbox); if (b != box) op->boxes(data->sna, op, box, b - box); } } static void sna_fill_spans__dash_offset(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_fill_spans__fill_offset(drawable, gc, n, pt, width, sorted); } static void sna_fill_spans__fill_clip_extents(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; const BoxRec *extents = &data->region.extents; BoxRec box[512], *b = box, *const last_box = box + ARRAY_SIZE(box); DBG(("%s: alu=%d, fg=%08lx, count=%d, extents=(%d, %d), (%d, %d)\n", __FUNCTION__, gc->alu, gc->fgPixel, n, extents->x1, extents->y1, extents->x2, extents->y2)); while (n--) { DBG(("%s: [%d] pt=(%d, %d), width=%d\n", __FUNCTION__, n, pt->x, pt->y, *width)); *(DDXPointRec *)b = *pt++; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; if (box_intersect(b, extents)) { DBG(("%s: [%d] clipped=(%d, %d), (%d, %d)\n", __FUNCTION__, n, b->x1, b->y1, b->x2, b->y2)); if (data->dx|data->dy) { b->x1 += data->dx; b->x2 += data->dx; b->y1 += data->dy; b->y2 += data->dy; } if (b != box && b->y1 == b[-1].y2 && b->x1 == b[-1].x1 && b->x2 == b[-1].x2) { b[-1].y2 = b->y2; } else if (++b == last_box) { op->boxes(data->sna, op, box, last_box - box); b = box; } } } if (b != box) op->boxes(data->sna, op, box, b - box); } static void sna_fill_spans__dash_clip_extents(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_fill_spans__fill_clip_extents(drawable, gc, n, pt, width, sorted); } static void sna_fill_spans__fill_clip_boxes(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; struct sna_fill_op *op = data->op; BoxRec box[512], *b = box, *const last_box = box + ARRAY_SIZE(box); const BoxRec * const clip_start = RegionBoxptr(&data->region); const BoxRec * const clip_end = clip_start + data->region.data->numRects; DBG(("%s: alu=%d, fg=%08lx, count=%d, extents=(%d, %d), (%d, %d)\n", __FUNCTION__, gc->alu, gc->fgPixel, n, data->region.extents.x1, data->region.extents.y1, data->region.extents.x2, data->region.extents.y2)); while (n--) { int16_t X1 = pt->x; int16_t y = pt->y; int16_t X2 = X1 + (int)*width; const BoxRec *c; pt++; width++; if (y < data->region.extents.y1 || data->region.extents.y2 <= y) continue; if (X1 < data->region.extents.x1) X1 = data->region.extents.x1; if (X2 > data->region.extents.x2) X2 = data->region.extents.x2; if (X1 >= X2) continue; c = find_clip_box_for_y(clip_start, clip_end, y); while (c != clip_end) { if (y + 1 <= c->y1 || X2 <= c->x1) break; if (X1 >= c->x2) { c++; continue; } b->x1 = c->x1; b->x2 = c->x2; c++; if (b->x1 < X1) b->x1 = X1; if (b->x2 > X2) b->x2 = X2; if (b->x2 <= b->x1) continue; b->x1 += data->dx; b->x2 += data->dx; b->y1 = y + data->dy; b->y2 = b->y1 + 1; if (++b == last_box) { op->boxes(data->sna, op, box, last_box - box); b = box; } } } if (b != box) op->boxes(data->sna, op, box, b - box); } static void sna_fill_spans__dash_clip_boxes(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; if (data->phase == gc->fgPixel) sna_fill_spans__fill_clip_boxes(drawable, gc, n, pt, width, sorted); } static bool sna_fill_spans_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, uint32_t pixel, int n, DDXPointPtr pt, int *width, int sorted, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); int16_t dx, dy; struct sna_fill_op fill; BoxRec box[512], *b = box, *const last_box = box + ARRAY_SIZE(box); static void * const jump[] = { &&no_damage, &&damage, &&no_damage_clipped, &&damage_clipped, }; unsigned v; DBG(("%s: alu=%d, fg=%08lx, damge=%p, clipped?=%d\n", __FUNCTION__, gc->alu, gc->fgPixel, damage, clipped)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, pixel, FILL_SPANS)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); v = (damage != NULL) | clipped; goto *jump[v]; no_damage: if (dx|dy) { do { int nbox = n; if (nbox > last_box - box) nbox = last_box - box; n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x1 += dx; b->y1 += dy; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; b++; } while (--nbox); fill.boxes(sna, &fill, box, b - box); b = box; } while (n); } else { do { int nbox = n; if (nbox > last_box - box) nbox = last_box - box; n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; b++; } while (--nbox); fill.boxes(sna, &fill, box, b - box); b = box; } while (n); } goto done; damage: do { *(DDXPointRec *)b = *pt++; b->x1 += dx; b->y1 += dy; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, box, last_box-box, 0, 0); fill.boxes(sna, &fill, box, last_box - box); sna_damage_add_boxes(damage, box, last_box - box, 0, 0); b = box; } } while (--n); if (b != box) { assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, b - box); sna_damage_add_boxes(damage, box, b - box, 0, 0); } goto done; no_damage_clipped: { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; assert(dx + clip.extents.x1 >= 0); assert(dy + clip.extents.y1 >= 0); assert(dx + clip.extents.x2 <= pixmap->drawable.width); assert(dy + clip.extents.y2 <= pixmap->drawable.height); DBG(("%s: clip %d x [(%d, %d), (%d, %d)] x %d [(%d, %d)...]\n", __FUNCTION__, region_num_rects(&clip), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, n, pt->x, pt->y)); if (clip.data == NULL) { do { *(DDXPointRec *)b = *pt++; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; if (box_intersect(b, &clip.extents)) { if (dx|dy) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; } if (++b == last_box) { fill.boxes(sna, &fill, box, last_box - box); b = box; } } } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; do { int16_t X1 = pt->x; int16_t y = pt->y; int16_t X2 = X1 + (int)*width; const BoxRec *c; pt++; width++; if (y < extents->y1 || extents->y2 <= y) continue; if (X1 < extents->x1) X1 = extents->x1; if (X2 > extents->x2) X2 = extents->x2; if (X1 >= X2) continue; c = find_clip_box_for_y(clip_start, clip_end, y); while (c != clip_end) { if (y + 1 <= c->y1 || X2 <= c->x1) break; if (X1 >= c->x2) { c++; continue; } b->x1 = c->x1; b->x2 = c->x2; c++; if (b->x1 < X1) b->x1 = X1; if (b->x2 > X2) b->x2 = X2; if (b->x2 <= b->x1) continue; b->x1 += dx; b->x2 += dx; b->y1 = y + dy; b->y2 = b->y1 + 1; if (++b == last_box) { fill.boxes(sna, &fill, box, last_box - box); b = box; } } } while (--n); RegionUninit(&clip); } if (b != box) fill.boxes(sna, &fill, box, b - box); goto done; } damage_clipped: { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; assert(dx + clip.extents.x1 >= 0); assert(dy + clip.extents.y1 >= 0); assert(dx + clip.extents.x2 <= pixmap->drawable.width); assert(dy + clip.extents.y2 <= pixmap->drawable.height); DBG(("%s: clip %d x [(%d, %d), (%d, %d)] x %d [(%d, %d)...]\n", __FUNCTION__, region_num_rects(&clip), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, n, pt->x, pt->y)); if (clip.data == NULL) { do { *(DDXPointRec *)b = *pt++; b->x2 = b->x1 + (int)*width++; b->y2 = b->y1 + 1; if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, last_box - box); sna_damage_add_boxes(damage, box, b - box, 0, 0); b = box; } } } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; do { int16_t X1 = pt->x; int16_t y = pt->y; int16_t X2 = X1 + (int)*width; const BoxRec *c; pt++; width++; if (y < extents->y1 || extents->y2 <= y) continue; if (X1 < extents->x1) X1 = extents->x1; if (X2 > extents->x2) X2 = extents->x2; if (X1 >= X2) continue; c = find_clip_box_for_y(clip_start, clip_end, y); while (c != clip_end) { if (y + 1 <= c->y1 || X2 <= c->x1) break; if (X1 >= c->x2) { c++; continue; } b->x1 = c->x1; b->x2 = c->x2; c++; if (b->x1 < X1) b->x1 = X1; if (b->x2 > X2) b->x2 = X2; if (b->x2 <= b->x1) continue; b->x1 += dx; b->x2 += dx; b->y1 = y + dy; b->y2 = b->y1 + 1; if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, box, last_box-box, 0, 0); fill.boxes(sna, &fill, box, last_box - box); sna_damage_add_boxes(damage, box, last_box - box, 0, 0); b = box; } } } while (--n); RegionUninit(&clip); } if (b != box) { assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, b - box); sna_damage_add_boxes(damage, box, b - box, 0, 0); } goto done; } done: fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static bool sna_poly_fill_rect_tiled_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *rect, const BoxRec *extents, unsigned clipped); static bool sna_poly_fill_rect_stippled_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *rect, const BoxRec *extents, unsigned clipped); static inline bool gc_is_solid(GCPtr gc, uint32_t *color) { assert(FbFullMask(gc->depth) == (FbFullMask(gc->depth) & gc->planemask)); if (gc->alu == GXclear) { *color = 0; return true; } if (gc->alu == GXset) { *color = (1 << gc->depth) - 1; return true; } if (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel) || (gc->fillStyle == FillOpaqueStippled && gc->bgPixel == gc->fgPixel)) { *color = gc->fillStyle == FillTiled ? gc->tile.pixel : gc->fgPixel; return true; } return false; } static void sna_fill_spans__gpu(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { struct sna_fill_spans *data = sna_gc(gc)->priv; uint32_t color; DBG(("%s(n=%d, pt[0]=(%d, %d)+%d, sorted=%d\n", __FUNCTION__, n, pt[0].x, pt[0].y, width[0], sorted)); assert(PM_IS_SOLID(drawable, gc->planemask)); if (n == 0) return; /* The mi routines do not attempt to keep the spans it generates * within the clip, so we must run them through the clipper. */ if (gc_is_solid(gc, &color)) { sna_fill_spans_blt(drawable, data->bo, NULL, gc, color, n, pt, width, sorted, &data->region.extents, 2); } else { /* Try converting these to a set of rectangles instead */ xRectangle *rect; int i; DBG(("%s: converting to rectagnles\n", __FUNCTION__)); rect = malloc (n * sizeof (xRectangle)); if (rect == NULL) return; for (i = 0; i < n; i++) { rect[i].x = pt[i].x - drawable->x; rect[i].width = width[i]; rect[i].y = pt[i].y - drawable->y; rect[i].height = 1; } if (gc->fillStyle == FillTiled) { (void)sna_poly_fill_rect_tiled_blt(drawable, data->bo, NULL, gc, n, rect, &data->region.extents, 2); } else { (void)sna_poly_fill_rect_stippled_blt(drawable, data->bo, NULL, gc, n, rect, &data->region.extents, 2); } free (rect); } } static unsigned sna_spans_extents(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, BoxPtr out) { BoxRec box; bool clipped = false; if (n == 0) return 0; box.x1 = pt->x; box.x2 = box.x1 + *width; box.y2 = box.y1 = pt->y; while (--n) { pt++; width++; if (box.x1 > pt->x) box.x1 = pt->x; if (box.x2 < pt->x + *width) box.x2 = pt->x + *width; if (box.y1 > pt->y) box.y1 = pt->y; else if (box.y2 < pt->y) box.y2 = pt->y; } box.y2++; if (gc) clipped = clip_box(&box, gc); if (box_empty(&box)) return 0; *out = box; return 1 | clipped << 1; } static void sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n, DDXPointPtr pt, int *width, int sorted) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; RegionRec region; unsigned flags; uint32_t color; DBG(("%s(n=%d, pt[0]=(%d, %d)+%d, sorted=%d\n", __FUNCTION__, n, pt[0].x, pt[0].y, width[0], sorted)); flags = sna_spans_extents(drawable, gc, n, pt, width, ®ion.extents); if (flags == 0) return; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_FILL_SPANS) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } DBG(("%s: fillStyle=%x [%d], mask=%lx [%d]\n", __FUNCTION__, gc->fillStyle, gc->fillStyle == FillSolid, gc->planemask, PM_IS_SOLID(drawable, gc->planemask))); if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; bo = sna_drawable_use_bo(drawable, PREFER_GPU, ®ion.extents, &damage); if (bo) { if (gc_is_solid(gc, &color)) { DBG(("%s: trying solid fill [alu=%d, pixel=%08lx] blt paths\n", __FUNCTION__, gc->alu, gc->fgPixel)); sna_fill_spans_blt(drawable, bo, damage, gc, color, n, pt, width, sorted, ®ion.extents, flags & IS_CLIPPED); } else { /* Try converting these to a set of rectangles instead */ xRectangle *rect; int i; DBG(("%s: converting to rectagnles\n", __FUNCTION__)); rect = malloc (n * sizeof (xRectangle)); if (rect == NULL) return; for (i = 0; i < n; i++) { rect[i].x = pt[i].x - drawable->x; rect[i].width = width[i]; rect[i].y = pt[i].y - drawable->y; rect[i].height = 1; } if (gc->fillStyle == FillTiled) { i = sna_poly_fill_rect_tiled_blt(drawable, bo, damage, gc, n, rect, ®ion.extents, flags & IS_CLIPPED); } else { i = sna_poly_fill_rect_stippled_blt(drawable, bo, damage, gc, n, rect, ®ion.extents, flags & IS_CLIPPED); } free (rect); if (i) return; } } fallback: DBG(("%s: fallback\n", __FUNCTION__)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, drawable_gc_flags(drawable, gc, n > 1))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbFillSpans\n", __FUNCTION__)); fbFillSpans(drawable, gc, n, pt, width, sorted); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static void sna_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr pt, int *width, int n, int sorted) { RegionRec region; if (sna_spans_extents(drawable, gc, n, pt, width, ®ion.extents) == 0) return; DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_SET_SPANS) goto fallback; fallback: region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, drawable_gc_flags(drawable, gc, n > 1))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbSetSpans\n", __FUNCTION__)); fbSetSpans(drawable, gc, src, pt, width, n, sorted); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } struct sna_copy_plane { struct sna_damage **damage; struct kgem_bo *bo; }; static void sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc, RegionRec *region, int sx, int sy, Pixel bitplane, void *closure) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_copy_plane *arg = closure; PixmapPtr bitmap = (PixmapPtr)_bitmap; uint32_t br00, br13; int16_t dx, dy; const BoxRec *box; int n; DBG(("%s: plane=%x (%d,%d),(%d,%d)xld\n", __FUNCTION__, (unsigned)bitplane, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region))); box = region_rects(region); n = region_num_rects(region); assert(n); get_drawable_deltas(drawable, pixmap, &dx, &dy); assert_pixmap_contains_boxes(pixmap, box, n, dx, dy); br00 = 3 << 20; br13 = arg->bo->pitch; if (sna->kgem.gen >= 040 && arg->bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; DBG(("%s: target-depth=%d, alu=%d, bg=%08x, fg=%08x\n", __FUNCTION__, drawable->depth, gc->alu, gc->bgPixel, gc->fgPixel)); kgem_set_mode(&sna->kgem, KGEM_BLT, arg->bo); assert(kgem_bo_can_blt(&sna->kgem, arg->bo)); do { int bx1 = (box->x1 + sx) & ~7; int bx2 = (box->x2 + sx + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = box->y2 - box->y1; int bstride = ALIGN(bw, 2); int src_stride; uint8_t *dst, *src; uint32_t *b; DBG(("%s: box(%d, %d), (%d, %d), sx=(%d,%d) bx=[%d, %d]\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, sx, sy, bx1, bx2)); src_stride = bstride*bh; assert(src_stride > 0); if (src_stride <= 128) { src_stride = ALIGN(src_stride, 8) / 4; assert(src_stride <= 32); if (!kgem_check_batch(&sna->kgem, 8+src_stride) || !kgem_check_bo_fenced(&sna->kgem, arg->bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, arg->bo)) return; /* XXX fallback? */ _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo); assert(sna->kgem.mode == KGEM_BLT); if (sna->kgem.gen >= 0100) { b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_MONO_SRC_COPY_IMM | (6 + src_stride) | br00; b[0] |= ((box->x1 + sx) & 7) << 17; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + src_stride; } else { b = sna->kgem.batch + sna->kgem.nbatch; b[0] = XY_MONO_SRC_COPY_IMM | (5 + src_stride) | br00; b[0] |= ((box->x1 + sx) & 7) << 17; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + src_stride; } assert(bitmap->devKind); src_stride = bitmap->devKind; src = bitmap->devPrivate.ptr; src += (box->y1 + sy) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; assert(src >= (uint8_t *)bitmap->devPrivate.ptr); do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); assert(src <= (uint8_t *)bitmap->devPrivate.ptr + bitmap->devKind * bitmap->drawable.height); src += src_stride; } while (--bh); } else { struct kgem_bo *upload; void *ptr; if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, arg->bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, arg->bo)) return; /* XXX fallback? */ _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY | br00 | 8; b[0] |= ((box->x1 + sx) & 7) << 17; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_SRC_COPY | br00 | 6; b[0] |= ((box->x1 + sx) & 7) << 17; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } dst = ptr; assert(bitmap->devKind); src_stride = bitmap->devKind; src = bitmap->devPrivate.ptr; src += (box->y1 + sy) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; assert(src >= (uint8_t *)bitmap->devPrivate.ptr); do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); assert(src <= (uint8_t *)bitmap->devPrivate.ptr + bitmap->devKind * bitmap->drawable.height); assert(dst <= (uint8_t *)ptr + kgem_bo_size(upload)); src += src_stride; } while (--bh); sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); } box++; } while (--n); if (arg->damage) { RegionTranslate(region, dx, dy); sna_damage_add_to_pixmap(arg->damage, region, pixmap); } assert_pixmap_damage(pixmap); blt_done(sna); } static void sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc, RegionPtr region, int sx, int sy, Pixel bitplane, void *closure) { PixmapPtr dst_pixmap = get_drawable_pixmap(drawable); PixmapPtr src_pixmap = get_drawable_pixmap(source); struct sna *sna = to_sna_from_pixmap(dst_pixmap); struct sna_copy_plane *arg = closure; int16_t dx, dy; int bit = ffs(bitplane) - 1; uint32_t br00, br13; const BoxRec *box = region_rects(region); int n = region_num_rects(region); DBG(("%s: plane=%x [%d] x%d\n", __FUNCTION__, (unsigned)bitplane, bit, n)); if (n == 0) return; if (get_drawable_deltas(source, src_pixmap, &dx, &dy)) sx += dx, sy += dy; get_drawable_deltas(drawable, dst_pixmap, &dx, &dy); assert_pixmap_contains_boxes(dst_pixmap, box, n, dx, dy); br00 = XY_MONO_SRC_COPY | 3 << 20; br13 = arg->bo->pitch; if (sna->kgem.gen >= 040 && arg->bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; kgem_set_mode(&sna->kgem, KGEM_BLT, arg->bo); assert(kgem_bo_can_blt(&sna->kgem, arg->bo)); do { int bx1 = (box->x1 + sx) & ~7; int bx2 = (box->x2 + sx + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = box->y2 - box->y1; int bstride = ALIGN(bw, 2); struct kgem_bo *upload; void *ptr; DBG(("%s: box(%d, %d), (%d, %d), sx=(%d,%d) bx=[%d, %d]\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, sx, sy, bx1, bx2)); if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, arg->bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, arg->bo)) return; /* XXX fallback? */ _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { uint32_t *b; assert(src_pixmap->devKind); switch (source->bitsPerPixel) { case 32: { uint32_t *src = src_pixmap->devPrivate.ptr; int src_stride = src_pixmap->devKind/sizeof(uint32_t); uint8_t *dst = ptr; src += (box->y1 + sy) * src_stride; src += bx1; src_stride -= bw * 8; bstride -= bw; do { int i = bw; do { uint8_t v = 0; v |= ((*src++ >> bit) & 1) << 7; v |= ((*src++ >> bit) & 1) << 6; v |= ((*src++ >> bit) & 1) << 5; v |= ((*src++ >> bit) & 1) << 4; v |= ((*src++ >> bit) & 1) << 3; v |= ((*src++ >> bit) & 1) << 2; v |= ((*src++ >> bit) & 1) << 1; v |= ((*src++ >> bit) & 1) << 0; *dst++ = v; } while (--i); dst += bstride; src += src_stride; } while (--bh); break; } case 16: { uint16_t *src = src_pixmap->devPrivate.ptr; int src_stride = src_pixmap->devKind/sizeof(uint16_t); uint8_t *dst = ptr; src += (box->y1 + sy) * src_stride; src += bx1; src_stride -= bw * 8; bstride -= bw; do { int i = bw; do { uint8_t v = 0; v |= ((*src++ >> bit) & 1) << 7; v |= ((*src++ >> bit) & 1) << 6; v |= ((*src++ >> bit) & 1) << 5; v |= ((*src++ >> bit) & 1) << 4; v |= ((*src++ >> bit) & 1) << 3; v |= ((*src++ >> bit) & 1) << 2; v |= ((*src++ >> bit) & 1) << 1; v |= ((*src++ >> bit) & 1) << 0; *dst++ = v; } while (--i); dst += bstride; src += src_stride; } while (--bh); break; } default: assert(0); case 8: { uint8_t *src = src_pixmap->devPrivate.ptr; int src_stride = src_pixmap->devKind/sizeof(uint8_t); uint8_t *dst = ptr; src += (box->y1 + sy) * src_stride; src += bx1; src_stride -= bw * 8; bstride -= bw; do { int i = bw; do { uint8_t v = 0; v |= ((*src++ >> bit) & 1) << 7; v |= ((*src++ >> bit) & 1) << 6; v |= ((*src++ >> bit) & 1) << 5; v |= ((*src++ >> bit) & 1) << 4; v |= ((*src++ >> bit) & 1) << 3; v |= ((*src++ >> bit) & 1) << 2; v |= ((*src++ >> bit) & 1) << 1; v |= ((*src++ >> bit) & 1) << 0; *dst++ = v; } while (--i); dst += bstride; src += src_stride; } while (--bh); break; } } kgem_bcs_set_tiling(&sna->kgem, upload, arg->bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = br00 | ((box->x1 + sx) & 7) << 17 | 8; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = br00 | ((box->x1 + sx) & 7) << 17 | 6; b[1] = br13; b[2] = (box->y1 + dy) << 16 | (box->x1 + dx); b[3] = (box->y2 + dy) << 16 | (box->x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, arg->bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); box++; } while (--n); if (arg->damage) { RegionTranslate(region, dx, dy); sna_damage_add_to_pixmap(arg->damage, region, dst_pixmap); } assert_pixmap_damage(dst_pixmap); blt_done(sna); } static RegionPtr sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc, int src_x, int src_y, int w, int h, int dst_x, int dst_y, unsigned long bit) { PixmapPtr pixmap = get_drawable_pixmap(dst); struct sna *sna = to_sna_from_pixmap(pixmap); RegionRec region, *ret = NULL; struct sna_copy_plane arg; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=%dx%d\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, w, h)); if (gc->planemask == 0) goto empty; if (src->bitsPerPixel == 1 && (bit&1) == 0) goto empty; region.extents.x1 = dst_x + dst->x; region.extents.y1 = dst_y + dst->y; region.extents.x2 = region.extents.x1 + w; region.extents.y2 = region.extents.y1 + h; region.data = NULL; RegionIntersect(®ion, ®ion, gc->pCompositeClip); DBG(("%s: dst extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); { RegionRec clip; clip.extents.x1 = src->x - (src->x + src_x) + (dst->x + dst_x); clip.extents.y1 = src->y - (src->y + src_y) + (dst->y + dst_y); clip.extents.x2 = clip.extents.x1 + src->width; clip.extents.y2 = clip.extents.y1 + src->height; clip.data = NULL; DBG(("%s: src extents (%d, %d), (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); RegionIntersect(®ion, ®ion, &clip); } DBG(("%s: dst^src extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (box_empty(®ion.extents)) goto empty; RegionTranslate(®ion, src_x - dst_x - dst->x + src->x, src_y - dst_y - dst->y + src->y); if (!sna_drawable_move_region_to_cpu(src, ®ion, MOVE_READ)) goto out; RegionTranslate(®ion, -(src_x - dst_x - dst->x + src->x), -(src_y - dst_y - dst->y + src->y)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_COPY_PLANE) goto fallback; if (wedged(sna)) goto fallback; if (!PM_IS_SOLID(dst, gc->planemask)) goto fallback; arg.bo = sna_drawable_use_bo(dst, PREFER_GPU, ®ion.extents, &arg.damage); if (arg.bo) { if (arg.bo->tiling == I915_TILING_Y) { assert(arg.bo == __sna_pixmap_get_bo(pixmap)); arg.bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (arg.bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); goto fallback; } } if (!kgem_bo_can_blt(&sna->kgem, arg.bo)) return false; RegionUninit(®ion); return sna_do_copy(src, dst, gc, src_x, src_y, w, h, dst_x, dst_y, src->depth == 1 ? sna_copy_bitmap_blt : sna_copy_plane_blt, (Pixel)bit, &arg); } fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!sna_gc_move_to_cpu(gc, dst, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(dst, ®ion, drawable_gc_flags(dst, gc, false))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbCopyPlane(%d, %d, %d, %d, %d,%d) %x\n", __FUNCTION__, src_x, src_y, w, h, dst_x, dst_y, (unsigned)bit)); ret = miDoCopy(src, dst, gc, src_x, src_y, w, h, dst_x, dst_y, src->bitsPerPixel > 1 ? fbCopyNto1 : fbCopy1toN, bit, 0); FALLBACK_FLUSH(dst); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); return ret; empty: return miHandleExposures(src, dst, gc, src_x, src_y, w, h, dst_x, dst_y, bit); } static bool sna_poly_point_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int mode, int n, DDXPointPtr pt, bool clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); BoxRec box[512], *b = box, * const last_box = box + ARRAY_SIZE(box); struct sna_fill_op fill; DDXPointRec last; int16_t dx, dy; DBG(("%s: alu=%d, pixel=%08lx, clipped?=%d\n", __FUNCTION__, gc->alu, gc->fgPixel, clipped)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, gc->fgPixel, FILL_POINTS)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); last.x = drawable->x; last.y = drawable->y; if (!clipped) { last.x += dx; last.y += dy; assert_pixmap_contains_points(pixmap, pt, n, last.x, last.y); sna_damage_add_points(damage, pt, n, last.x, last.y); if (fill.points && mode != CoordModePrevious) { fill.points(sna, &fill, last.x, last.y, pt, n); } else { do { unsigned nbox = n; if (nbox > ARRAY_SIZE(box)) nbox = ARRAY_SIZE(box); n -= nbox; do { *(DDXPointRec *)b = *pt++; b->x1 += last.x; b->y1 += last.y; if (mode == CoordModePrevious) last = *(DDXPointRec *)b; b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; b++; } while (--nbox); fill.boxes(sna, &fill, box, b - box); b = box; } while (n); } } else { RegionPtr clip = gc->pCompositeClip; while (n--) { int x, y; x = pt->x; y = pt->y; pt++; if (mode == CoordModePrevious) { x += last.x; y += last.y; last.x = x; last.y = y; } else { x += drawable->x; y += drawable->y; } if (RegionContainsPoint(clip, x, y, NULL)) { b->x1 = x + dx; b->y1 = y + dy; b->x2 = b->x1 + 1; b->y2 = b->y1 + 1; if (++b == last_box){ assert_pixmap_contains_boxes(pixmap, box, last_box-box, 0, 0); fill.boxes(sna, &fill, box, last_box - box); if (damage) sna_damage_add_boxes(damage, box, last_box-box, 0, 0); b = box; } } } if (b != box){ assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, b - box); if (damage) sna_damage_add_boxes(damage, box, b-box, 0, 0); } } fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static unsigned sna_poly_point_extents(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt, BoxPtr out) { BoxRec box; bool clipped; if (n == 0) return 0; box.x2 = box.x1 = pt->x; box.y2 = box.y1 = pt->y; if (mode == CoordModePrevious) { DDXPointRec last = *pt++; while (--n) { last.x += pt->x; last.y += pt->y; pt++; box_add_xy(&box, last.x, last.y); } } else { while (--n) box_add_pt(&box, ++pt); } box.x2++; box.y2++; clipped = trim_and_translate_box(&box, drawable, gc); if (box_empty(&box)) return 0; *out = box; return 1 | clipped << 1; } static void sna_poly_point(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); RegionRec region; unsigned flags; DBG(("%s(mode=%d, n=%d, pt[0]=(%d, %d)\n", __FUNCTION__, mode, n, pt[0].x, pt[0].y)); flags = sna_poly_point_extents(drawable, gc, mode, n, pt, ®ion.extents); if (flags == 0) return; DBG(("%s: extents (%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, flags)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_POINT) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (PM_IS_SOLID(drawable, gc->planemask)) { struct sna_damage **damage; struct kgem_bo *bo; DBG(("%s: trying solid fill [%08lx] blt paths\n", __FUNCTION__, gc->fgPixel)); if ((bo = sna_drawable_use_bo(drawable, PREFER_GPU, ®ion.extents, &damage)) && sna_poly_point_blt(drawable, bo, damage, gc, mode, n, pt, flags & IS_CLIPPED)) return; } fallback: DBG(("%s: fallback\n", __FUNCTION__)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_READ | MOVE_WRITE)) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbPolyPoint\n", __FUNCTION__)); fbPolyPoint(drawable, gc, mode, n, pt, flags); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static bool sna_poly_zero_line_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int mode, const int _n, const DDXPointRec * const _pt, const BoxRec *extents, unsigned clipped) { static void * const _jump[] = { &&no_damage, &&damage, &&no_damage_offset, &&damage_offset, }; PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); int x2, y2, xstart, ystart, oc2; unsigned int bias = miGetZeroLineBias(drawable->pScreen); bool degenerate = true; struct sna_fill_op fill; RegionRec clip; BoxRec box[512], *b, * const last_box = box + ARRAY_SIZE(box); const BoxRec *last_extents; int16_t dx, dy; void *jump, *ret; DBG(("%s: alu=%d, pixel=%lx, n=%d, clipped=%d, damage=%p\n", __FUNCTION__, gc->alu, gc->fgPixel, _n, clipped, damage)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, gc->fgPixel, FILL_SPANS)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); region_set(&clip, extents); if (clipped) { if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; } jump = _jump[(damage != NULL) | !!(dx|dy) << 1]; DBG(("%s: [clipped=%x] extents=(%d, %d), (%d, %d), delta=(%d, %d), damage=%p\n", __FUNCTION__, clipped, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, dx, dy, damage)); extents = region_rects(&clip); last_extents = extents + region_num_rects(&clip); b = box; do { int n = _n; const DDXPointRec *pt = _pt; xstart = pt->x + drawable->x; ystart = pt->y + drawable->y; x2 = xstart; y2 = ystart; oc2 = 0; OUTCODES(oc2, x2, y2, extents); while (--n) { int16_t sdx, sdy; int adx, ady, length; int e, e1, e2, e3; int x1 = x2, x; int y1 = y2, y; int oc1 = oc2; int octant; ++pt; x2 = pt->x; y2 = pt->y; if (mode == CoordModePrevious) { x2 += x1; y2 += y1; } else { x2 += drawable->x; y2 += drawable->y; } DBG(("%s: segment (%d, %d) to (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 == x1 && y2 == y1) continue; degenerate = false; oc2 = 0; OUTCODES(oc2, x2, y2, extents); if (oc1 & oc2) continue; CalcLineDeltas(x1, y1, x2, y2, adx, ady, sdx, sdy, 1, 1, octant); DBG(("%s: adx=(%d, %d), sdx=(%d, %d), oc1=%x, oc2=%x\n", __FUNCTION__, adx, ady, sdx, sdy, oc1, oc2)); if (adx == 0 || ady == 0) { if (x1 <= x2) { b->x1 = x1; b->x2 = x2; } else { b->x1 = x2; b->x2 = x1; } if (y1 <= y2) { b->y1 = y1; b->y2 = y2; } else { b->y1 = y2; b->y2 = y1; } b->x2++; b->y2++; if (oc1 | oc2) { bool intersects; intersects = box_intersect(b, extents); assert(intersects); } if (++b == last_box) { ret = &&rectangle_continue; goto *jump; rectangle_continue: b = box; } } else if (adx >= ady) { int x2_clipped = x2, y2_clipped = y2; bool dirty; /* X-major segment */ e1 = ady << 1; e2 = e1 - (adx << 1); e = e1 - adx; length = adx; FIXUP_ERROR(e, octant, bias); x = x1; y = y1; if (oc1 | oc2) { int pt1_clipped, pt2_clipped; if (miZeroClipLine(extents->x1, extents->y1, extents->x2-1, extents->y2-1, &x, &y, &x2_clipped, &y2_clipped, adx, ady, &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2) == -1) continue; length = abs(x2_clipped - x); if (length == 0) continue; if (pt1_clipped) { int clipdx = abs(x - x1); int clipdy = abs(y - y1); e += clipdy * e2 + (clipdx - clipdy) * e1; } } e3 = e2 - e1; e = e - e1; b->x1 = x; b->y1 = y; dirty = false; while (length--) { e += e1; dirty = true; if (e >= 0) { e += e3; if (sdx < 0) { b->x2 = b->x1 + 1; b->x1 = x; } else b->x2 = x + 1; b->y2 = b->y1 + 1; if (++b == last_box) { ret = &&X_continue; goto *jump; X_continue: b = box; } b->x1 = x + sdx; b->y1 = y += sdy; dirty = false; } x += sdx; } if (dirty) { x -= sdx; if (sdx < 0) { b->x2 = b->x1 + 1; b->x1 = x; } else b->x2 = x + 1; b->y2 = b->y1 + 1; if (++b == last_box) { ret = &&X2_continue; goto *jump; X2_continue: b = box; } } } else { int x2_clipped = x2, y2_clipped = y2; bool dirty; /* Y-major segment */ e1 = adx << 1; e2 = e1 - (ady << 1); e = e1 - ady; length = ady; SetYMajorOctant(octant); FIXUP_ERROR(e, octant, bias); x = x1; y = y1; if (oc1 | oc2) { int pt1_clipped, pt2_clipped; if (miZeroClipLine(extents->x1, extents->y1, extents->x2-1, extents->y2-1, &x, &y, &x2_clipped, &y2_clipped, adx, ady, &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2) == -1) continue; length = abs(y2_clipped - y); if (length == 0) continue; if (pt1_clipped) { int clipdx = abs(x - x1); int clipdy = abs(y - y1); e += clipdx * e2 + (clipdy - clipdx) * e1; } } e3 = e2 - e1; e = e - e1; b->x1 = x; b->y1 = y; dirty = false; while (length--) { e += e1; dirty = true; if (e >= 0) { e += e3; if (sdy < 0) { b->y2 = b->y1 + 1; b->y1 = y; } else b->y2 = y + 1; b->x2 = x + 1; if (++b == last_box) { ret = &&Y_continue; goto *jump; Y_continue: b = box; } b->x1 = x += sdx; b->y1 = y + sdy; dirty = false; } y += sdy; } if (dirty) { y -= sdy; if (sdy < 0) { b->y2 = b->y1 + 1; b->y1 = y; } else b->y2 = y + 1; b->x2 = x + 1; if (++b == last_box) { ret = &&Y2_continue; goto *jump; Y2_continue: b = box; } } } } #if 0 /* Only do the CapNotLast check on the last segment * and only if the endpoint wasn't clipped. And then, if the last * point is the same as the first point, do not draw it, unless the * line is degenerate */ if (!pt2_clipped && gc->capStyle != CapNotLast && !(xstart == x2 && ystart == y2 && !degenerate)) { b->x2 = x2; b->y2 = y2; if (b->x2 < b->x1) { int16_t t = b->x1; b->x1 = b->x2; b->x2 = t; } if (b->y2 < b->y1) { int16_t t = b->y1; b->y1 = b->y2; b->y2 = t; } b->x2++; b->y2++; b++; } #endif } while (++extents != last_extents); if (b != box) { ret = &&done; goto *jump; } done: fill.done(sna, &fill); assert_pixmap_damage(pixmap); RegionUninit(&clip); return true; damage: assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); sna_damage_add_boxes(damage, box, b-box, 0, 0); no_damage: fill.boxes(sna, &fill, box, b-box); goto *ret; no_damage_offset: { BoxRec *bb = box; do { bb->x1 += dx; bb->x2 += dx; bb->y1 += dy; bb->y2 += dy; } while (++bb != b); assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, b - box); } goto *ret; damage_offset: { BoxRec *bb = box; do { bb->x1 += dx; bb->x2 += dx; bb->y1 += dy; bb->y2 += dy; } while (++bb != b); assert_pixmap_contains_boxes(pixmap, box, b-box, 0, 0); fill.boxes(sna, &fill, box, b - box); sna_damage_add_boxes(damage, box, b - box, 0, 0); } goto *ret; } static bool sna_poly_line_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, uint32_t pixel, int mode, int n, DDXPointPtr pt, const BoxRec *extents, bool clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); BoxRec boxes[512], *b = boxes, * const last_box = boxes + ARRAY_SIZE(boxes); struct sna_fill_op fill; DDXPointRec last; int16_t dx, dy; DBG(("%s: alu=%d, fg=%08x, clipped=%d\n", __FUNCTION__, gc->alu, (unsigned)pixel, clipped)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, pixel, FILL_BOXES)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); if (!clipped) { dx += drawable->x; dy += drawable->y; last.x = pt->x + dx; last.y = pt->y + dy; pt++; while (--n) { DDXPointRec p; p = *pt++; if (mode == CoordModePrevious) { p.x += last.x; p.y += last.y; } else { p.x += dx; p.y += dy; } DBG(("%s: line (%d, %d) -> (%d, %d)\n", __FUNCTION__, last.x, last.y, p.x, p.y)); if (last.x == p.x) { b->x1 = last.x; b->x2 = last.x + 1; } else if (last.x < p.x) { b->x1 = last.x; b->x2 = p.x; } else { b->x1 = p.x; b->x2 = last.x; } if (last.y == p.y) { b->y1 = last.y; b->y2 = last.y + 1; } else if (last.y < p.y) { b->y1 = last.y; b->y2 = p.y; } else { b->y1 = p.y; b->y2 = last.y; } b->y2 += last.x == p.x && last.y != p.y; b->x2 += last.y == p.y && last.x != p.x; DBG(("%s: blt (%d, %d), (%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2, b->y2)); if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, boxes, last_box-boxes, 0, 0); fill.boxes(sna, &fill, boxes, last_box - boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box - boxes, 0, 0); b = boxes; } last = p; } } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; last.x = pt->x + drawable->x; last.y = pt->y + drawable->y; pt++; if (clip.data == NULL) { while (--n) { DDXPointRec p; p = *pt++; if (mode == CoordModePrevious) { p.x += last.x; p.y += last.y; } else { p.x += drawable->x; p.y += drawable->y; } if (last.x == p.x) { b->x1 = last.x; b->x2 = last.x + 1; } else if (last.x < p.x) { b->x1 = last.x; b->x2 = p.x; } else { b->x1 = p.x; b->x2 = last.x; } if (last.y == p.y) { b->y1 = last.y; b->y2 = last.y + 1; } else if (last.y < p.y) { b->y1 = last.y; b->y2 = p.y; } else { b->y1 = p.y; b->y2 = last.y; } b->y2 += last.x == p.x && last.y != p.y; b->x2 += last.y == p.y && last.x != p.x; DBG(("%s: blt (%d, %d), (%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2, b->y2)); if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, boxes, last_box-boxes, 0, 0); fill.boxes(sna, &fill, boxes, last_box - boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box - boxes, 0, 0); b = boxes; } } last = p; } } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; while (--n) { DDXPointRec p; BoxRec box; p = *pt++; if (mode == CoordModePrevious) { p.x += last.x; p.y += last.y; } else { p.x += drawable->x; p.y += drawable->y; } if (last.x == p.x) { box.x1 = last.x; box.x2 = last.x + 1; } else if (last.x < p.x) { box.x1 = last.x; box.x2 = p.x; } else { box.x1 = p.x; box.x2 = last.x; } if (last.y == p.y) { box.y1 = last.y; box.y2 = last.y + 1; } else if (last.y < p.y) { box.y1 = last.y; box.y2 = p.y; } else { box.y1 = p.y; box.y2 = last.y; } b->y2 += last.x == p.x && last.y != p.y; b->x2 += last.y == p.y && last.x != p.x; DBG(("%s: blt (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); c = find_clip_box_for_y(clip_start, clip_end, box.y1); while (c != clip_end) { if (box.y2 <= c->y1) break; *b = box; if (box_intersect(b, c++)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { assert_pixmap_contains_boxes(pixmap, boxes, last_box-boxes, 0, 0); fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } last = p; } } RegionUninit(&clip); } if (b != boxes) { assert_pixmap_contains_boxes(pixmap, boxes, b-boxes, 0, 0); fill.boxes(sna, &fill, boxes, b - boxes); if (damage) sna_damage_add_boxes(damage, boxes, b - boxes, 0, 0); } fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static unsigned sna_poly_line_extents(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt, BoxPtr out) { BoxRec box; bool clip, blt = true; if (n == 0) return 0; box.x2 = box.x1 = pt->x; box.y2 = box.y1 = pt->y; if (mode == CoordModePrevious) { int x = box.x1; int y = box.y1; while (--n) { pt++; x += pt->x; y += pt->y; if (blt) blt &= pt->x == 0 || pt->y == 0; box_add_xy(&box, x, y); } } else { int x = box.x1; int y = box.y1; while (--n) { pt++; if (blt) { blt &= pt->x == x || pt->y == y; x = pt->x; y = pt->y; } box_add_pt(&box, pt); } } box.x2++; box.y2++; if (gc->lineWidth) { int extra = gc->lineWidth >> 1; if (n > 1) { if (gc->joinStyle == JoinMiter) extra = 6 * gc->lineWidth; else if (gc->capStyle == CapProjecting) extra = gc->lineWidth; } if (extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } } clip = trim_and_translate_box(&box, drawable, gc); if (box_empty(&box)) return 0; *out = box; return 1 | blt << 2 | clip << 1; } inline static int _use_line_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents, unsigned flags) { uint32_t ignored; if (USE_SPANS) return USE_SPANS > 0; if (flags & RECTILINEAR) return PREFER_GPU; if (gc->lineStyle != LineSolid && gc->lineWidth == 0) return 0; if (gc_is_solid(gc, &ignored)) return PREFER_GPU; return !drawable_gc_inplace_hint(drawable, gc); } inline static int use_line_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents, unsigned flags) { int ret = _use_line_spans(drawable, gc, extents, flags); DBG(("%s? %d\n", __FUNCTION__, ret)); return ret; } static void sna_poly_line(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt) { struct sna_pixmap *priv; struct sna_fill_spans data; uint32_t color; DBG(("%s(mode=%d, n=%d, pt[0]=(%d, %d), lineWidth=%d\n", __FUNCTION__, mode, n, pt[0].x, pt[0].y, gc->lineWidth)); data.flags = sna_poly_line_extents(drawable, gc, mode, n, pt, &data.region.extents); if (data.flags == 0) return; DBG(("%s: extents (%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2, data.flags)); data.region.data = NULL; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_LINE) goto fallback; data.pixmap = get_drawable_pixmap(drawable); data.sna = to_sna_from_pixmap(data.pixmap); if (wedged(data.sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } DBG(("%s: fill=%d [%d], line=%d [%d], width=%d, mask=%lx [%d], rectlinear=%d\n", __FUNCTION__, gc->fillStyle, gc->fillStyle == FillSolid, gc->lineStyle, gc->lineStyle == LineSolid, gc->lineWidth, gc->planemask, PM_IS_SOLID(drawable, gc->planemask), data.flags & RECTILINEAR)); if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; priv = sna_pixmap(data.pixmap); if (!priv) { DBG(("%s: not attached to pixmap %ld\n", __FUNCTION__, data.pixmap->drawable.serialNumber)); goto fallback; } if (gc->lineStyle != LineSolid) { DBG(("%s: lineStyle, %d, is not solid\n", __FUNCTION__, gc->lineStyle)); goto spans_fallback; } if (!(gc->lineWidth == 0 || (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy)))) { DBG(("%s: non-zero lineWidth %d\n", __FUNCTION__, gc->lineWidth)); goto spans_fallback; } data.bo = sna_drawable_use_bo(drawable, PREFER_GPU, &data.region.extents, &data.damage); if (data.bo == NULL) goto fallback; if (gc_is_solid(gc, &color)) { DBG(("%s: trying solid fill [%08x]\n", __FUNCTION__, (unsigned)color)); if (data.flags & RECTILINEAR) { if (sna_poly_line_blt(drawable, data.bo, data.damage, gc, color, mode, n, pt, &data.region.extents, data.flags & IS_CLIPPED)) return; } else { /* !rectilinear */ if (sna_poly_zero_line_blt(drawable, data.bo, data.damage, gc, mode, n, pt, &data.region.extents, data.flags & IS_CLIPPED)) return; } } else if (data.flags & RECTILINEAR) { /* Try converting these to a set of rectangles instead */ DDXPointRec p1, p2; xRectangle *rect; int i; DBG(("%s: converting to rectagnles\n", __FUNCTION__)); rect = malloc (n * sizeof (xRectangle)); if (rect == NULL) return; p1 = pt[0]; for (i = 1; i < n; i++) { if (mode == CoordModePrevious) { p2.x = p1.x + pt[i].x; p2.y = p1.y + pt[i].y; } else p2 = pt[i]; if (p1.x < p2.x) { rect[i].x = p1.x; rect[i].width = p2.x - p1.x + 1; } else if (p1.x > p2.x) { rect[i].x = p2.x; rect[i].width = p1.x - p2.x + 1; } else { rect[i].x = p1.x; rect[i].width = 1; } if (p1.y < p2.y) { rect[i].y = p1.y; rect[i].height = p2.y - p1.y + 1; } else if (p1.y > p2.y) { rect[i].y = p2.y; rect[i].height = p1.y - p2.y + 1; } else { rect[i].y = p1.y; rect[i].height = 1; } /* don't paint last pixel */ if (gc->capStyle == CapNotLast) { if (p1.x == p2.x) rect[i].height--; else rect[i].width--; } p1 = p2; } if (gc->fillStyle == FillTiled) { i = sna_poly_fill_rect_tiled_blt(drawable, data.bo, data.damage, gc, n - 1, rect + 1, &data.region.extents, data.flags & IS_CLIPPED); } else { i = sna_poly_fill_rect_stippled_blt(drawable, data.bo, data.damage, gc, n - 1, rect + 1, &data.region.extents, data.flags & IS_CLIPPED); } free (rect); if (i) return; } spans_fallback: if ((data.bo = sna_drawable_use_bo(drawable, use_line_spans(drawable, gc, &data.region.extents, data.flags), &data.region.extents, &data.damage))) { DBG(("%s: converting line into spans\n", __FUNCTION__)); get_drawable_deltas(drawable, data.pixmap, &data.dx, &data.dy); sna_gc(gc)->priv = &data; if (gc->lineWidth == 0 && gc_is_solid(gc, &color)) { struct sna_fill_op fill; if (gc->lineStyle == LineSolid) { if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_POINTS | FILL_SPANS)) goto fallback; data.op = &fill; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_extents; } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_boxes; } } assert(gc->miTranslate); gc->ops = &sna_gc_ops__tmp; DBG(("%s: miZeroLine (solid fill)\n", __FUNCTION__)); miZeroLine(drawable, gc, mode, n, pt); fill.done(data.sna, &fill); } else { data.op = &fill; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__dash_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__dash; sna_gc_ops__tmp.PolyPoint = sna_poly_point__dash; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) { sna_gc_ops__tmp.FillSpans = sna_fill_spans__dash_clip_extents; sna_gc_ops__tmp.PolyPoint = sna_poly_point__dash_clip_extents; } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__dash_clip_boxes; sna_gc_ops__tmp.PolyPoint = sna_poly_point__dash_clip_boxes; } } assert(gc->miTranslate); DBG(("%s: miZeroLine (solid dash, clipped? %d (complex? %d)), fg pass [%08x]\n", __FUNCTION__, !!(data.flags & IS_CLIPPED), data.flags & IS_CLIPPED && !region_is_singular(&data.region), gc->fgPixel)); if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_POINTS | FILL_SPANS)) goto fallback; gc->ops = &sna_gc_ops__tmp; data.phase = gc->fgPixel; miZeroDashLine(drawable, gc, mode, n, pt); fill.done(data.sna, &fill); DBG(("%s: miZeroLine (solid dash, clipped? %d (complex? %d)), bg pass [%08x]\n", __FUNCTION__, !!(data.flags & IS_CLIPPED), data.flags & IS_CLIPPED && !region_is_singular(&data.region), gc->bgPixel)); if (sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, gc->bgPixel, FILL_POINTS | FILL_SPANS)) { data.phase = gc->bgPixel; miZeroDashLine(drawable, gc, mode, n, pt); fill.done(data.sna, &fill); } } } else { /* Note that the WideDash functions alternate * between filling using fgPixel and bgPixel * so we need to reset state between FillSpans and * cannot use the fill fast paths. */ sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; sna_gc_ops__tmp.PolyFillRect = sna_poly_fill_rect__gpu; sna_gc_ops__tmp.PolyPoint = sna_poly_point__gpu; gc->ops = &sna_gc_ops__tmp; switch (gc->lineStyle) { default: assert(0); case LineSolid: if (gc->lineWidth == 0) { DBG(("%s: miZeroLine\n", __FUNCTION__)); miZeroLine(drawable, gc, mode, n, pt); } else { DBG(("%s: miWideLine\n", __FUNCTION__)); miWideLine(drawable, gc, mode, n, pt); } break; case LineOnOffDash: case LineDoubleDash: if (gc->lineWidth == 0) { DBG(("%s: miZeroDashLine\n", __FUNCTION__)); miZeroDashLine(drawable, gc, mode, n, pt); } else { DBG(("%s: miWideDash\n", __FUNCTION__)); miWideDash(drawable, gc, mode, n, pt); } break; } } gc->ops = (GCOps *)&sna_gc_ops; if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); assert_pixmap_contains_box(data.pixmap, &data.region.extents); sna_damage_add_to_pixmap(data.damage, &data.region, data.pixmap); assert_pixmap_damage(data.pixmap); } RegionUninit(&data.region); return; } fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, &data.region)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, &data.region, drawable_gc_flags(drawable, gc, !(data.flags & RECTILINEAR && n == 2)))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbPolyLine\n", __FUNCTION__)); fbPolyLine(drawable, gc, mode, n, pt); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(&data.region); } static inline void box_from_seg(BoxPtr b, const xSegment *seg, GCPtr gc) { if (seg->x1 == seg->x2) { if (seg->y1 > seg->y2) { b->y2 = seg->y1 + 1; b->y1 = seg->y2 + 1; if (gc->capStyle != CapNotLast) b->y1--; } else { b->y1 = seg->y1; b->y2 = seg->y2; if (gc->capStyle != CapNotLast) b->y2++; } b->x1 = seg->x1; b->x2 = seg->x1 + 1; } else { if (seg->x1 > seg->x2) { b->x2 = seg->x1 + 1; b->x1 = seg->x2 + 1; if (gc->capStyle != CapNotLast) b->x1--; } else { b->x1 = seg->x1; b->x2 = seg->x2; if (gc->capStyle != CapNotLast) b->x2++; } b->y1 = seg->y1; b->y2 = seg->y1 + 1; } DBG(("%s: seg=(%d,%d),(%d,%d); box=(%d,%d),(%d,%d)\n", __FUNCTION__, seg->x1, seg->y1, seg->x2, seg->y2, b->x1, b->y1, b->x2, b->y2)); } static bool sna_poly_segment_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, uint32_t pixel, int n, xSegment *seg, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); BoxRec boxes[512], *b = boxes, * const last_box = boxes + ARRAY_SIZE(boxes); struct sna_fill_op fill; int16_t dx, dy; DBG(("%s: n=%d, alu=%d, fg=%08lx, clipped=%d\n", __FUNCTION__, n, gc->alu, gc->fgPixel, clipped)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, pixel, FILL_SPANS)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); if (!clipped) { dx += drawable->x; dy += drawable->y; if (dx|dy) { do { unsigned nbox = n; if (nbox > ARRAY_SIZE(boxes)) nbox = ARRAY_SIZE(boxes); n -= nbox; do { box_from_seg(b, seg++, gc); if (b->y2 > b->y1 && b->x2 > b->x1) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; b++; } } while (--nbox); if (b != boxes) { fill.boxes(sna, &fill, boxes, b-boxes); if (damage) sna_damage_add_boxes(damage, boxes, b-boxes, 0, 0); b = boxes; } } while (n); } else { do { unsigned nbox = n; if (nbox > ARRAY_SIZE(boxes)) nbox = ARRAY_SIZE(boxes); n -= nbox; do { box_from_seg(b++, seg++, gc); } while (--nbox); if (b != boxes) { fill.boxes(sna, &fill, boxes, b-boxes); if (damage) sna_damage_add_boxes(damage, boxes, b-boxes, 0, 0); b = boxes; } } while (n); } } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; if (clip.data) { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { BoxRec box; box_from_seg(&box, seg++, gc); box.x1 += drawable->x; box.x2 += drawable->x; box.y1 += drawable->y; box.y2 += drawable->y; c = find_clip_box_for_y(clip_start, clip_end, box.y1); while (c != clip_end) { if (box.y2 <= c->y1) break; *b = box; if (box_intersect(b, c++)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } while (--n); } else { do { box_from_seg(b, seg++, gc); b->x1 += drawable->x; b->x2 += drawable->x; b->y1 += drawable->y; b->y2 += drawable->y; if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } while (--n); } RegionUninit(&clip); } if (b != boxes) { fill.boxes(sna, &fill, boxes, b - boxes); if (damage) sna_damage_add_boxes(damage, boxes, b - boxes, 0, 0); } done: fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static bool sna_poly_zero_segment_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, const int _n, const xSegment *_s, const BoxRec *extents, unsigned clipped) { static void * const _jump[] = { &&no_damage, &&damage, &&no_damage_offset, &&damage_offset, }; PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); unsigned int bias = miGetZeroLineBias(drawable->pScreen); struct sna_fill_op fill; RegionRec clip; const BoxRec *last_extents; BoxRec box[512], *b; BoxRec *const last_box = box + ARRAY_SIZE(box); int16_t dx, dy; void *jump, *ret; DBG(("%s: alu=%d, pixel=%lx, n=%d, clipped=%d, damage=%p\n", __FUNCTION__, gc->alu, gc->fgPixel, _n, clipped, damage)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, gc->fgPixel, FILL_BOXES)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); region_set(&clip, extents); if (clipped) { if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; } DBG(("%s: [clipped] extents=(%d, %d), (%d, %d), delta=(%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, dx, dy)); jump = _jump[(damage != NULL) | !!(dx|dy) << 1]; b = box; extents = region_rects(&clip); last_extents = extents + region_num_rects(&clip); do { int n = _n; const xSegment *s = _s; do { int16_t sdx, sdy; int adx, ady, length; int e, e1, e2, e3; int x1, x2; int y1, y2; int oc1, oc2; int octant; x1 = s->x1 + drawable->x; y1 = s->y1 + drawable->y; x2 = s->x2 + drawable->x; y2 = s->y2 + drawable->y; s++; DBG(("%s: segment (%d, %d) to (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 == x1 && y2 == y1) continue; oc1 = 0; OUTCODES(oc1, x1, y1, extents); oc2 = 0; OUTCODES(oc2, x2, y2, extents); if (oc1 & oc2) continue; CalcLineDeltas(x1, y1, x2, y2, adx, ady, sdx, sdy, 1, 1, octant); DBG(("%s: adx=(%d, %d), sdx=(%d, %d)\n", __FUNCTION__, adx, ady, sdx, sdy)); if (adx == 0 || ady == 0) { if (x1 <= x2) { b->x1 = x1; b->x2 = x2; } else { b->x1 = x2; b->x2 = x1; } if (y1 <= y2) { b->y1 = y1; b->y2 = y2; } else { b->y1 = y2; b->y2 = y1; } b->x2++; b->y2++; if (oc1 | oc2) box_intersect(b, extents); if (++b == last_box) { ret = &&rectangle_continue; goto *jump; rectangle_continue: b = box; } } else if (adx >= ady) { bool dirty; /* X-major segment */ e1 = ady << 1; e2 = e1 - (adx << 1); e = e1 - adx; length = adx; /* don't draw endpoint in main loop */ FIXUP_ERROR(e, octant, bias); if (oc1 | oc2) { int pt1_clipped, pt2_clipped; int x = x1, y = y1; if (miZeroClipLine(extents->x1, extents->y1, extents->x2-1, extents->y2-1, &x1, &y1, &x2, &y2, adx, ady, &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2) == -1) continue; length = abs(x2 - x1); if (length == 0) continue; if (pt1_clipped) { int clipdx = abs(x1 - x); int clipdy = abs(y1 - y); e += clipdy * e2 + (clipdx - clipdy) * e1; } } e3 = e2 - e1; e = e - e1; b->x1 = x1; b->y1 = y1; dirty = false; while (length--) { dirty = true; e += e1; if (e >= 0) { e += e3; if (sdx < 0) { b->x2 = b->x1 + 1; b->x1 = x1; } else b->x2 = x1 + 1; b->y2 = b->y1 + 1; DBG(("%s: horizontal step: (%d, %d), box: (%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, b->x1, b->y1, b->x2, b->y2)); if (++b == last_box) { ret = &&X_continue; goto *jump; X_continue: b = box; } b->x1 = x1 + sdx; b->y1 = y1 += sdy; dirty = false; } x1 += sdx; } if (dirty) { x1 -= sdx; DBG(("%s: horizontal tail: (%d, %d)\n", __FUNCTION__, x1, y1)); if (sdx < 0) { b->x2 = b->x1 + 1; b->x1 = x1; } else b->x2 = x1 + 1; b->y2 = b->y1 + 1; if (++b == last_box) { ret = &&X2_continue; goto *jump; X2_continue: b = box; } } } else { bool dirty; /* Y-major segment */ e1 = adx << 1; e2 = e1 - (ady << 1); e = e1 - ady; length = ady; /* don't draw endpoint in main loop */ SetYMajorOctant(octant); FIXUP_ERROR(e, octant, bias); if (oc1 | oc2) { int pt1_clipped, pt2_clipped; int x = x1, y = y1; if (miZeroClipLine(extents->x1, extents->y1, extents->x2-1, extents->y2-1, &x1, &y1, &x2, &y2, adx, ady, &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2) == -1) continue; length = abs(y2 - y1); if (length == 0) continue; if (pt1_clipped) { int clipdx = abs(x1 - x); int clipdy = abs(y1 - y); e += clipdx * e2 + (clipdy - clipdx) * e1; } } e3 = e2 - e1; e = e - e1; b->x1 = x1; b->y1 = y1; dirty = false; while (length--) { e += e1; dirty = true; if (e >= 0) { e += e3; if (sdy < 0) { b->y2 = b->y1 + 1; b->y1 = y1; } else b->y2 = y1 + 1; b->x2 = x1 + 1; if (++b == last_box) { ret = &&Y_continue; goto *jump; Y_continue: b = box; } b->x1 = x1 += sdx; b->y1 = y1 + sdy; dirty = false; } y1 += sdy; } if (dirty) { y1 -= sdy; if (sdy < 0) { b->y2 = b->y1 + 1; b->y1 = y1; } else b->y2 = y1 + 1; b->x2 = x1 + 1; if (++b == last_box) { ret = &&Y2_continue; goto *jump; Y2_continue: b = box; } } } } while (--n); } while (++extents != last_extents); if (b != box) { ret = &&done; goto *jump; } done: fill.done(sna, &fill); assert_pixmap_damage(pixmap); RegionUninit(&clip); return true; damage: sna_damage_add_boxes(damage, box, b-box, 0, 0); no_damage: fill.boxes(sna, &fill, box, b-box); goto *ret; no_damage_offset: { BoxRec *bb = box; do { bb->x1 += dx; bb->x2 += dx; bb->y1 += dy; bb->y2 += dy; } while (++bb != b); fill.boxes(sna, &fill, box, b - box); } goto *ret; damage_offset: { BoxRec *bb = box; do { bb->x1 += dx; bb->x2 += dx; bb->y1 += dy; bb->y2 += dy; } while (++bb != b); fill.boxes(sna, &fill, box, b - box); sna_damage_add_boxes(damage, box, b - box, 0, 0); } goto *ret; } static unsigned sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg, BoxPtr out) { BoxRec box; bool clipped, can_blit; if (n == 0) return 0; if (seg->x2 >= seg->x1) { box.x1 = seg->x1; box.x2 = seg->x2; } else { box.x2 = seg->x1; box.x1 = seg->x2; } if (seg->y2 >= seg->y1) { box.y1 = seg->y1; box.y2 = seg->y2; } else { box.y2 = seg->y1; box.y1 = seg->y2; } can_blit = seg->x1 == seg->x2 || seg->y1 == seg->y2; while (--n) { seg++; if (seg->x2 > seg->x1) { if (seg->x1 < box.x1) box.x1 = seg->x1; if (seg->x2 > box.x2) box.x2 = seg->x2; } else { if (seg->x2 < box.x1) box.x1 = seg->x2; if (seg->x1 > box.x2) box.x2 = seg->x1; } if (seg->y2 > seg->y1) { if (seg->y1 < box.y1) box.y1 = seg->y1; if (seg->y2 > box.y2) box.y2 = seg->y2; } else { if (seg->y2 < box.y1) box.y1 = seg->y2; if (seg->y1 > box.y2) box.y2 = seg->y1; } if (can_blit && !(seg->x1 == seg->x2 || seg->y1 == seg->y2)) can_blit = false; } box.x2++; box.y2++; if (gc->lineWidth) { int extra = gc->lineWidth; if (gc->capStyle != CapProjecting) extra >>= 1; if (extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; } } DBG(("%s: unclipped, untranslated extents (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); clipped = trim_and_translate_box(&box, drawable, gc); if (box_empty(&box)) return 0; *out = box; return 1 | clipped << 1 | can_blit << 2; } static void sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg) { struct sna_pixmap *priv; struct sna_fill_spans data; uint32_t color; DBG(("%s(n=%d, first=((%d, %d), (%d, %d)), lineWidth=%d\n", __FUNCTION__, n, seg->x1, seg->y1, seg->x2, seg->y2, gc->lineWidth)); data.flags = sna_poly_segment_extents(drawable, gc, n, seg, &data.region.extents); if (data.flags == 0) return; DBG(("%s: extents=(%d, %d), (%d, %d)\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2)); data.region.data = NULL; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_SEGMENT) goto fallback; data.pixmap = get_drawable_pixmap(drawable); data.sna = to_sna_from_pixmap(data.pixmap); priv = sna_pixmap(data.pixmap); if (priv == NULL) { DBG(("%s: fallback -- unattached\n", __FUNCTION__)); goto fallback; } if (wedged(data.sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } DBG(("%s: fill=%d [%d], line=%d [%d], width=%d, mask=%lu [%d], rectlinear=%d\n", __FUNCTION__, gc->fillStyle, gc->fillStyle == FillSolid, gc->lineStyle, gc->lineStyle == LineSolid, gc->lineWidth, gc->planemask, PM_IS_SOLID(drawable, gc->planemask), data.flags & RECTILINEAR)); if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (gc->lineStyle != LineSolid || gc->lineWidth > 1) goto spans_fallback; data.bo = sna_drawable_use_bo(drawable, PREFER_GPU, &data.region.extents, &data.damage); if (data.bo == NULL) goto fallback; if (gc_is_solid(gc, &color)) { DBG(("%s: trying blt solid fill [%08x, flags=%x] paths\n", __FUNCTION__, (unsigned)color, data.flags)); if (data.flags & RECTILINEAR) { if (sna_poly_segment_blt(drawable, data.bo, data.damage, gc, color, n, seg, &data.region.extents, data.flags & IS_CLIPPED)) return; } else { if (sna_poly_zero_segment_blt(drawable, data.bo, data.damage, gc, n, seg, &data.region.extents, data.flags & IS_CLIPPED)) return; } } else if (data.flags & RECTILINEAR) { /* Try converting these to a set of rectangles instead */ xRectangle *rect; int i; DBG(("%s: converting to rectangles\n", __FUNCTION__)); rect = malloc (n * sizeof (xRectangle)); if (rect == NULL) return; for (i = 0; i < n; i++) { if (seg[i].x1 < seg[i].x2) { rect[i].x = seg[i].x1; rect[i].width = seg[i].x2 - seg[i].x1 + 1; } else if (seg[i].x1 > seg[i].x2) { rect[i].x = seg[i].x2; rect[i].width = seg[i].x1 - seg[i].x2 + 1; } else { rect[i].x = seg[i].x1; rect[i].width = 1; } if (seg[i].y1 < seg[i].y2) { rect[i].y = seg[i].y1; rect[i].height = seg[i].y2 - seg[i].y1 + 1; } else if (seg[i].y1 > seg[i].y2) { rect[i].y = seg[i].y2; rect[i].height = seg[i].y1 - seg[i].y2 + 1; } else { rect[i].y = seg[i].y1; rect[i].height = 1; } /* don't paint last pixel */ if (gc->capStyle == CapNotLast) { if (seg[i].x1 == seg[i].x2) rect[i].height--; else rect[i].width--; } } if (gc->fillStyle == FillTiled) { i = sna_poly_fill_rect_tiled_blt(drawable, data.bo, data.damage, gc, n, rect, &data.region.extents, data.flags); } else { i = sna_poly_fill_rect_stippled_blt(drawable, data.bo, data.damage, gc, n, rect, &data.region.extents, data.flags); } free (rect); if (i) return; } spans_fallback: if ((data.bo = sna_drawable_use_bo(drawable, use_line_spans(drawable, gc, &data.region.extents, data.flags), &data.region.extents, &data.damage))) { void (*line)(DrawablePtr, GCPtr, int, int, DDXPointPtr); int i; DBG(("%s: converting segments into spans\n", __FUNCTION__)); switch (gc->lineStyle) { default: case LineSolid: if (gc->lineWidth == 0) line = miZeroLine; else line = miWideLine; break; case LineOnOffDash: case LineDoubleDash: if (gc->lineWidth == 0) line = miZeroDashLine; else line = miWideDash; break; } get_drawable_deltas(drawable, data.pixmap, &data.dx, &data.dy); sna_gc(gc)->priv = &data; if (gc->lineWidth == 0 && gc->lineStyle == LineSolid && gc_is_solid(gc, &color)) { struct sna_fill_op fill; if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_POINTS | FILL_SPANS)) goto fallback; data.op = &fill; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_extents; } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_boxes; } } assert(gc->miTranslate); gc->ops = &sna_gc_ops__tmp; for (i = 0; i < n; i++) line(drawable, gc, CoordModeOrigin, 2, (DDXPointPtr)&seg[i]); fill.done(data.sna, &fill); } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; sna_gc_ops__tmp.PolyFillRect = sna_poly_fill_rect__gpu; sna_gc_ops__tmp.PolyPoint = sna_poly_point__gpu; gc->ops = &sna_gc_ops__tmp; for (i = 0; i < n; i++) line(drawable, gc, CoordModeOrigin, 2, (DDXPointPtr)&seg[i]); } gc->ops = (GCOps *)&sna_gc_ops; if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); assert_pixmap_contains_box(data.pixmap, &data.region.extents); sna_damage_add_to_pixmap(data.damage, &data.region, data.pixmap); } assert_pixmap_damage(data.pixmap); RegionUninit(&data.region); return; } fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, &data.region)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, &data.region, drawable_gc_flags(drawable, gc, !(data.flags & RECTILINEAR && n == 1)))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fbPolySegment\n", __FUNCTION__)); fbPolySegment(drawable, gc, n, seg); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(&data.region); } static unsigned sna_poly_rectangle_extents(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r, BoxPtr out) { Box32Rec box; int extra = gc->lineWidth >> 1; bool clipped; bool zero = false; if (n == 0) return 0; box.x1 = r->x; box.y1 = r->y; box.x2 = box.x1 + r->width; box.y2 = box.y1 + r->height; zero |= (r->width | r->height) == 0; while (--n) { r++; zero |= (r->width | r->height) == 0; box32_add_rect(&box, r); } box.x2++; box.y2++; if (extra) { box.x1 -= extra; box.x2 += extra; box.y1 -= extra; box.y2 += extra; zero = !zero; } else zero = true; DBG(("%s: unclipped original extents: (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); clipped = box32_trim_and_translate(&box, drawable, gc); if (!box32_to_box16(&box, out)) return 0; DBG(("%s: extents: (%d, %d), (%d, %d), clipped? %d\n", __FUNCTION__, out->x1, out->y1, out->x2, out->y2, clipped)); return 1 | clipped << 1 | zero << 2; } static bool sna_poly_rectangle_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_fill_op fill; BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes); int16_t dx, dy; static void * const jump[] = { &&wide, &&zero, &&wide_clipped, &&zero_clipped, }; DBG(("%s: n=%d, alu=%d, width=%d, fg=%08lx, damge=%p, clipped?=%d\n", __FUNCTION__, n, gc->alu, gc->lineWidth, gc->fgPixel, damage, clipped)); if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, gc->fgPixel, FILL_BOXES)) return false; get_drawable_deltas(drawable, pixmap, &dx, &dy); goto *jump[(gc->lineWidth <= 1) | clipped]; zero: dx += drawable->x; dy += drawable->y; do { xRectangle rr = *r++; if ((rr.width | rr.height) == 0) continue; /* XXX -> PolyLine */ DBG(("%s - zero : r[%d] = (%d, %d) x (%d, %d)\n", __FUNCTION__, n, rr.x, rr.y, rr.width, rr.height)); rr.x += dx; rr.y += dy; if (b+4 > last_box) { fill.boxes(sna, &fill, boxes, b-boxes); if (damage) sna_damage_add_boxes(damage, boxes, b-boxes, 0, 0); b = boxes; } if (rr.width <= 1 || rr.height <= 1) { b->x1 = rr.x; b->y1 = rr.y; b->x2 = rr.x + rr.width + (rr.height != 0); b->y2 = rr.y + rr.height + (rr.width != 0); DBG(("%s: blt (%d, %d), (%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2,b->y2)); b++; } else { b[0].x1 = rr.x; b[0].y1 = rr.y; b[0].x2 = rr.x + rr.width + 1; b[0].y2 = rr.y + 1; b[1] = b[0]; b[1].y1 += rr.height; b[1].y2 += rr.height; b[2].y1 = rr.y + 1; b[2].y2 = rr.y + rr.height; b[2].x1 = rr.x; b[2].x2 = rr.x + 1; b[3] = b[2]; b[3].x1 += rr.width; b[3].x2 += rr.width; b += 4; } } while (--n); goto done; zero_clipped: { RegionRec clip; BoxRec box[4]; int count; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; if (clip.data) { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { xRectangle rr = *r++; DBG(("%s - zero, clipped complex: r[%d] = (%d, %d) x (%d, %d)\n", __FUNCTION__, n, rr.x, rr.y, rr.width, rr.height)); if ((rr.width | rr.height) == 0) continue; /* XXX -> PolyLine */ rr.x += drawable->x; rr.y += drawable->y; if (rr.width <= 1 || rr.height <= 1) { box[0].x1 = rr.x; box[0].y1 = rr.y; box[0].x2 = rr.x + rr.width + (rr.height != 0); box[0].y2 = rr.y + rr.height + (rr.width != 0); count = 1; } else { box[0].x1 = rr.x; box[0].y1 = rr.y; box[0].x2 = rr.x + rr.width + 1; box[0].y2 = rr.y + 1; box[1] = box[0]; box[1].y1 += rr.height; box[1].y2 += rr.height; box[2].y1 = rr.y + 1; box[2].y2 = rr.y + rr.height; box[2].x1 = rr.x; box[2].x2 = rr.x + 1; box[3] = box[2]; box[3].x1 += rr.width; box[3].x2 += rr.width; count = 4; } while (count--) { c = find_clip_box_for_y(clip_start, clip_end, box[count].y1); while (c != clip_end) { if (box[count].y2 <= c->y1) break; *b = box[count]; if (box_intersect(b, c++)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } } while (--n); } else { do { xRectangle rr = *r++; DBG(("%s - zero, clip: r[%d] = (%d, %d) x (%d, %d)\n", __FUNCTION__, n, rr.x, rr.y, rr.width, rr.height)); if ((rr.width | rr.height) == 0) continue; /* XXX -> PolyLine */ rr.x += drawable->x; rr.y += drawable->y; if (rr.width <= 1 || rr.height <= 1) { box[0].x1 = rr.x; box[0].y1 = rr.y; box[0].x2 = rr.x + rr.width + (rr.height != 0); box[0].y2 = rr.y + rr.height + (rr.width != 0); count = 1; } else { box[0].x1 = rr.x; box[0].y1 = rr.y; box[0].x2 = rr.x + rr.width + 1; box[0].y2 = rr.y + 1; box[1] = box[0]; box[1].y1 += rr.height; box[1].y2 += rr.height; box[2].y1 = rr.y + 1; box[2].y2 = rr.y + rr.height; box[2].x1 = rr.x; box[2].x2 = rr.x + 1; box[3] = box[2]; box[3].x1 += rr.width; box[3].x2 += rr.width; count = 4; } while (count--) { *b = box[count]; if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } while (--n); } RegionUninit(&clip); } goto done; wide_clipped: { RegionRec clip; BoxRec box[4]; int16_t offset2 = gc->lineWidth; int16_t offset1 = offset2 >> 1; int16_t offset3 = offset2 - offset1; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; DBG(("%s: wide clipped: extents=((%d, %d), (%d, %d))\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); if (clip.data) { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { xRectangle rr = *r++; int count; if ((rr.width | rr.height) == 0) continue; /* XXX -> PolyLine */ rr.x += drawable->x; rr.y += drawable->y; if (rr.height <= offset2 || rr.width <= offset2) { if (rr.height == 0) { box[0].x1 = rr.x; box[0].x2 = rr.x + rr.width; } else { box[0].x1 = rr.x - offset1; box[0].x2 = rr.x + rr.width + offset3; } if (rr.width == 0) { box[0].y1 = rr.y; box[0].y2 = rr.y + rr.height; } else { box[0].y1 = rr.y - offset1; box[0].y2 = rr.y + rr.height + offset3; } count = 1; } else { box[0].x1 = rr.x - offset1; box[0].x2 = box[0].x1 + rr.width + offset2; box[0].y1 = rr.y - offset1; box[0].y2 = box[0].y1 + offset2; box[1].x1 = rr.x - offset1; box[1].x2 = box[1].x1 + offset2; box[1].y1 = rr.y + offset3; box[1].y2 = rr.y + rr.height - offset1; box[2] = box[1]; box[2].x1 += rr.width; box[2].x2 += rr.width; box[3] = box[0]; box[3].y1 += rr.height; box[3].y2 += rr.height; count = 4; } while (count--) { c = find_clip_box_for_y(clip_start, clip_end, box[count].y1); while (c != clip_end) { if (box[count].y2 <= c->y1) break; *b = box[count]; if (box_intersect(b, c++)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } } while (--n); } else { DBG(("%s: singular clip offset1=%d, offset2=%d, offset3=%d\n", __FUNCTION__, offset1, offset2, offset3)); do { xRectangle rr = *r++; int count; rr.x += drawable->x; rr.y += drawable->y; DBG(("%s: r=(%d, %d)x(%d, %d)\n", __FUNCTION__, rr.x, rr.y, rr.width, rr.height)); if (rr.height <= offset2 || rr.width <= offset2) { if (rr.height == 0) { box[0].x1 = rr.x; box[0].x2 = rr.x + rr.width; } else { box[0].x1 = rr.x - offset1; box[0].x2 = box[0].x1 + rr.width + offset2; } if (rr.width == 0) { box[0].y1 = rr.y; box[0].y2 = rr.y + rr.height; } else { box[0].y1 = rr.y - offset1; box[0].y2 = box[0].y1 + rr.height + offset2; } count = 1; } else { box[0].x1 = rr.x - offset1; box[0].x2 = box[0].x1 + rr.width + offset2; box[0].y1 = rr.y - offset1; box[0].y2 = box[0].y1 + offset2; DBG(("%s: box[0]=(%d, %d), (%d, %d)\n", __FUNCTION__, box[0].x1, box[0].y1, box[0].x2, box[0].y2)); box[1].x1 = rr.x - offset1; box[1].x2 = box[1].x1 + offset2; box[1].y1 = rr.y + offset3; box[1].y2 = rr.y + rr.height - offset1; DBG(("%s: box[1]=(%d, %d), (%d, %d)\n", __FUNCTION__, box[1].x1, box[1].y1, box[1].x2, box[1].y2)); box[2] = box[1]; box[2].x1 += rr.width; box[2].x2 += rr.width; DBG(("%s: box[2]=(%d, %d), (%d, %d)\n", __FUNCTION__, box[2].x1, box[2].y1, box[2].x2, box[2].y2)); box[3] = box[0]; box[3].y1 += rr.height; box[3].y2 += rr.height; DBG(("%s: box[3]=(%d, %d), (%d, %d)\n", __FUNCTION__, box[3].x1, box[3].y1, box[3].x2, box[3].y2)); count = 4; } while (count--) { *b = box[count]; if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } while (--n); } RegionUninit(&clip); } goto done; wide: { int offset2 = gc->lineWidth; int offset1 = offset2 >> 1; int offset3 = offset2 - offset1; dx += drawable->x; dy += drawable->y; do { xRectangle rr = *r++; if ((rr.width | rr.height) == 0) continue; /* XXX -> PolyLine */ rr.x += dx; rr.y += dy; if (b+4 > last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } if (rr.height <= offset2 || rr.width <= offset2) { if (rr.height == 0) { b->x1 = rr.x; b->x2 = rr.x + rr.width; } else { b->x1 = rr.x - offset1; b->x2 = rr.x + rr.width + offset3; } if (rr.width == 0) { b->y1 = rr.y; b->y2 = rr.y + rr.height; } else { b->y1 = rr.y - offset1; b->y2 = rr.y + rr.height + offset3; } b++; } else { b[0].x1 = rr.x - offset1; b[0].x2 = b[0].x1 + rr.width + offset2; b[0].y1 = rr.y - offset1; b[0].y2 = b[0].y1 + offset2; b[1].x1 = rr.x - offset1; b[1].x2 = b[1].x1 + offset2; b[1].y1 = rr.y + offset3; b[1].y2 = rr.y + rr.height - offset1; b[2] = b[1]; b[2].x1 += rr.width; b[2].x2 += rr.width; b[3] = b[0]; b[3].y1 += rr.height; b[3].y2 += rr.height; b += 4; } } while (--n); } goto done; done: if (b != boxes) { fill.boxes(sna, &fill, boxes, b-boxes); if (damage) sna_damage_add_boxes(damage, boxes, b-boxes, 0, 0); } fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static void sna_poly_rectangle(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; RegionRec region; unsigned flags; DBG(("%s(n=%d, first=((%d, %d)x(%d, %d)), lineWidth=%d\n", __FUNCTION__, n, r->x, r->y, r->width, r->height, gc->lineWidth)); flags = sna_poly_rectangle_extents(drawable, gc, n, r, ®ion.extents); if (flags == 0) return; DBG(("%s: extents=(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, flags)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_RECTANGLE) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } DBG(("%s: fill=%d [%d], line=%d [%d], join=%d [%d], mask=%lu [%d]\n", __FUNCTION__, gc->fillStyle, gc->fillStyle == FillSolid, gc->lineStyle, gc->lineStyle == LineSolid, gc->joinStyle, gc->joinStyle == JoinMiter, gc->planemask, PM_IS_SOLID(drawable, gc->planemask))); if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (flags & RECTILINEAR && gc->fillStyle == FillSolid && gc->lineStyle == LineSolid && gc->joinStyle == JoinMiter) { DBG(("%s: trying blt solid fill [%08lx] paths\n", __FUNCTION__, gc->fgPixel)); if ((bo = sna_drawable_use_bo(drawable, PREFER_GPU, ®ion.extents, &damage)) && sna_poly_rectangle_blt(drawable, bo, damage, gc, n, r, ®ion.extents, flags&2)) return; } else { /* Not a trivial outline, but we still maybe able to break it * down into simpler operations that we can accelerate. */ if (sna_drawable_use_bo(drawable, PREFER_GPU, ®ion.extents, &damage)) { miPolyRectangle(drawable, gc, n, r); return; } } fallback: DBG(("%s: fallback, clip=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, region_num_rects(gc->pCompositeClip), gc->pCompositeClip->extents.x1, gc->pCompositeClip->extents.y1, gc->pCompositeClip->extents.x2, gc->pCompositeClip->extents.y2)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; DBG(("%s: CPU region=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, region_num_rects(®ion), region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, drawable_gc_flags(drawable, gc, true))) goto out; if (sigtrap_get() == 0) { DBG(("%s: miPolyRectangle\n", __FUNCTION__)); miPolyRectangle(drawable, gc, n, r); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static unsigned sna_poly_arc_extents(DrawablePtr drawable, GCPtr gc, int n, xArc *arc, BoxPtr out) { BoxRec box; bool clipped; int v; if (n == 0) return 0; box.x1 = arc->x; box.x2 = bound(box.x1, arc->width); box.y1 = arc->y; box.y2 = bound(box.y1, arc->height); while (--n) { arc++; if (box.x1 > arc->x) box.x1 = arc->x; v = bound(arc->x, arc->width); if (box.x2 < v) box.x2 = v; if (box.y1 > arc->y) box.y1 = arc->y; v = bound(arc->y, arc->height); if (box.y2 < v) box.y2 = v; } v = gc->lineWidth >> 1; if (v) { box.x1 -= v; box.x2 += v; box.y1 -= v; box.y2 += v; } box.x2++; box.y2++; clipped = trim_and_translate_box(&box, drawable, gc); if (box_empty(&box)) return 0; *out = box; return 1 | clipped << 1; } static void sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc) { struct sna_fill_spans data; struct sna_pixmap *priv; DBG(("%s(n=%d, lineWidth=%d\n", __FUNCTION__, n, gc->lineWidth)); data.flags = sna_poly_arc_extents(drawable, gc, n, arc, &data.region.extents); if (data.flags == 0) return; DBG(("%s: extents=(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2, data.flags)); data.region.data = NULL; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_ARC) goto fallback; data.pixmap = get_drawable_pixmap(drawable); data.sna = to_sna_from_pixmap(data.pixmap); priv = sna_pixmap(data.pixmap); if (priv == NULL) { DBG(("%s: fallback -- unattached\n", __FUNCTION__)); goto fallback; } if (wedged(data.sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if ((data.bo = sna_drawable_use_bo(drawable, PREFER_GPU, &data.region.extents, &data.damage))) { uint32_t color; DBG(("%s: converting arcs into spans\n", __FUNCTION__)); get_drawable_deltas(drawable, data.pixmap, &data.dx, &data.dy); if (gc_is_solid(gc, &color)) { sna_gc(gc)->priv = &data; assert(gc->miTranslate); if (gc->lineStyle == LineSolid) { struct sna_fill_op fill; if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_POINTS | FILL_SPANS)) goto fallback; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_extents; } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; sna_gc_ops__tmp.PolyPoint = sna_poly_point__fill_clip_boxes; } } data.op = &fill; gc->ops = &sna_gc_ops__tmp; if (gc->lineWidth == 0) miZeroPolyArc(drawable, gc, n, arc); else miPolyArc(drawable, gc, n, arc); gc->ops = (GCOps *)&sna_gc_ops; fill.done(data.sna, &fill); } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; sna_gc_ops__tmp.PolyPoint = sna_poly_point__gpu; gc->ops = &sna_gc_ops__tmp; if (gc->lineWidth == 0) miZeroPolyArc(drawable, gc, n, arc); else miPolyArc(drawable, gc, n, arc); gc->ops = (GCOps *)&sna_gc_ops; } if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); assert_pixmap_contains_box(data.pixmap, &data.region.extents); sna_damage_add_to_pixmap(data.damage, &data.region, data.pixmap); } assert_pixmap_damage(data.pixmap); RegionUninit(&data.region); return; } /* XXX still around 10x slower for x11perf -ellipse */ if (gc->lineWidth == 0) miZeroPolyArc(drawable, gc, n, arc); else miPolyArc(drawable, gc, n, arc); return; } fallback: DBG(("%s -- fallback\n", __FUNCTION__)); if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (!sna_gc_move_to_cpu(gc, drawable, &data.region)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, &data.region, drawable_gc_flags(drawable, gc, true))) goto out; if (sigtrap_get() == 0) { DBG(("%s -- fbPolyArc\n", __FUNCTION__)); fbPolyArc(drawable, gc, n, arc); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(&data.region); } static bool sna_poly_fill_rect_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, uint32_t pixel, int n, const xRectangle *rect, const BoxRec *extents, unsigned flags) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_fill_op fill; BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes); int16_t dx, dy; DBG(("%s pixmap=%ld x %d [(%d, %d)x(%d, %d)...]+(%d,%d), clipped?=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, n, rect->x, rect->y, rect->width, rect->height, drawable->x, drawable->y, flags&2)); if (n == 1 && region_is_singular(gc->pCompositeClip)) { BoxRec r; bool success = true; r.x1 = rect->x + drawable->x; r.y1 = rect->y + drawable->y; r.x2 = bound(r.x1, rect->width); r.y2 = bound(r.y1, rect->height); if (box_intersect(&r, &gc->pCompositeClip->extents)) { if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) { r.x1 += dx; r.y1 += dy; r.x2 += dx; r.y2 += dy; } DBG(("%s: using fill_one() fast path: (%d, %d), (%d, %d). alu=%d, pixel=%08x, damage?=%d\n", __FUNCTION__, r.x1, r.y1, r.x2, r.y2, gc->alu, pixel, damage != NULL)); assert_pixmap_contains_box(pixmap, &r); if (sna->render.fill_one(sna, pixmap, bo, pixel, r.x1, r.y1, r.x2, r.y2, gc->alu)) { if (r.x2 - r.x1 == pixmap->drawable.width && r.y2 - r.y1 == pixmap->drawable.height) { if (damage) { sna_damage_all(damage, pixmap); damage = NULL; } if (flags & OVERWRITES) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (bo == priv->gpu_bo) { assert(damage == NULL || damage == &priv->gpu_damage); assert(priv->gpu_bo->proxy == NULL); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); priv->clear = true; priv->clear_color = gc->alu == GXcopyInverted ? ~pixel & ((1 << gc->depth) - 1) : pixel; DBG(("%s: pixmap=%ld, marking clear [%08x]\n", __FUNCTION__, pixmap->drawable.serialNumber, priv->clear_color)); } } } if (damage) sna_damage_add_box(damage, &r); assert_pixmap_damage(pixmap); } else success = false; } return success; } if (!sna_fill_init_blt(&fill, sna, pixmap, bo, gc->alu, pixel, FILL_BOXES)) { DBG(("%s: unsupported blt\n", __FUNCTION__)); return false; } get_drawable_deltas(drawable, pixmap, &dx, &dy); if ((flags & IS_CLIPPED) == 0) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, rect, n, dx, dy); if (dx|dy) { do { unsigned nbox = n; if (nbox > ARRAY_SIZE(boxes)) nbox = ARRAY_SIZE(boxes); n -= nbox; while (nbox >= 2) { b[0].x1 = rect[0].x + dx; b[0].y1 = rect[0].y + dy; b[0].x2 = b[0].x1 + rect[0].width; b[0].y2 = b[0].y1 + rect[0].height; b[1].x1 = rect[1].x + dx; b[1].y1 = rect[1].y + dy; b[1].x2 = b[1].x1 + rect[1].width; b[1].y2 = b[1].y1 + rect[1].height; b += 2; rect += 2; nbox -= 2; } if (nbox) { b->x1 = rect->x + dx; b->y1 = rect->y + dy; b->x2 = b->x1 + rect->width; b->y2 = b->y1 + rect->height; b++; rect++; } fill.boxes(sna, &fill, boxes, b-boxes); b = boxes; } while (n); } else { do { unsigned nbox = n; if (nbox > ARRAY_SIZE(boxes)) nbox = ARRAY_SIZE(boxes); n -= nbox; while (nbox >= 2) { b[0].x1 = rect[0].x; b[0].y1 = rect[0].y; b[0].x2 = b[0].x1 + rect[0].width; b[0].y2 = b[0].y1 + rect[0].height; b[1].x1 = rect[1].x; b[1].y1 = rect[1].y; b[1].x2 = b[1].x1 + rect[1].width; b[1].y2 = b[1].y1 + rect[1].height; b += 2; rect += 2; nbox -= 2; } if (nbox) { b->x1 = rect->x; b->y1 = rect->y; b->x2 = b->x1 + rect->width; b->y2 = b->y1 + rect->height; b++; rect++; } fill.boxes(sna, &fill, boxes, b-boxes); b = boxes; } while (n); } } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; if (clip.data == NULL) { do { b->x1 = rect->x + drawable->x; b->y1 = rect->y + drawable->y; b->x2 = bound(b->x1, rect->width); b->y2 = bound(b->y1, rect->height); rect++; if (box_intersect(b, &clip.extents)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { BoxRec box; box.x1 = rect->x + drawable->x; box.y1 = rect->y + drawable->y; box.x2 = bound(box.x1, rect->width); box.y2 = bound(box.y1, rect->height); rect++; c = find_clip_box_for_y(clip_start, clip_end, box.y1); while (c != clip_end) { if (box.y2 <= c->y1) break; *b = box; if (box_intersect(b, c++)) { b->x1 += dx; b->x2 += dx; b->y1 += dy; b->y2 += dy; if (++b == last_box) { fill.boxes(sna, &fill, boxes, last_box-boxes); if (damage) sna_damage_add_boxes(damage, boxes, last_box-boxes, 0, 0); b = boxes; } } } } while (--n); } RegionUninit(&clip); if (b != boxes) { fill.boxes(sna, &fill, boxes, b-boxes); if (damage) sna_damage_add_boxes(damage, boxes, b-boxes, 0, 0); } } done: fill.done(sna, &fill); assert_pixmap_damage(pixmap); return true; } static uint32_t get_pixel(PixmapPtr pixmap) { DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return 0; switch (pixmap->drawable.bitsPerPixel) { case 32: return *(uint32_t *)pixmap->devPrivate.ptr; case 16: return *(uint16_t *)pixmap->devPrivate.ptr; default: return *(uint8_t *)pixmap->devPrivate.ptr; } } inline static int _use_fill_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents, unsigned flags) { if (USE_SPANS) return USE_SPANS > 0; if (gc->fillStyle == FillTiled && !gc->tileIsPixel && sna_pixmap_is_gpu(gc->tile.pixmap)) { DBG(("%s: source is already on the gpu\n", __FUNCTION__)); return PREFER_GPU | FORCE_GPU; } return PREFER_GPU; } static int use_fill_spans(DrawablePtr drawable, GCPtr gc, const BoxRec *extents, unsigned flags) { int ret = _use_fill_spans(drawable, gc, extents, flags); DBG(("%s? %d\n", __FUNCTION__, ret)); return ret; } static void sna_poly_fill_polygon(DrawablePtr draw, GCPtr gc, int shape, int mode, int n, DDXPointPtr pt) { struct sna_fill_spans data; struct sna_pixmap *priv; DBG(("%s(n=%d, PlaneMask: %lx (solid %d), solid fill: %d [style=%d, tileIsPixel=%d], alu=%d)\n", __FUNCTION__, n, gc->planemask, !!PM_IS_SOLID(draw, gc->planemask), (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel)), gc->fillStyle, gc->tileIsPixel, gc->alu)); DBG(("%s: draw=%ld, offset=(%d, %d), size=%dx%d\n", __FUNCTION__, draw->serialNumber, draw->x, draw->y, draw->width, draw->height)); data.flags = sna_poly_point_extents(draw, gc, mode, n, pt, &data.region.extents); if (data.flags == 0) { DBG(("%s, nothing to do\n", __FUNCTION__)); return; } DBG(("%s: extents(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2, data.flags)); data.region.data = NULL; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_FILL_POLYGON) goto fallback; data.pixmap = get_drawable_pixmap(draw); data.sna = to_sna_from_pixmap(data.pixmap); priv = sna_pixmap(data.pixmap); if (priv == NULL) { DBG(("%s: fallback -- unattached\n", __FUNCTION__)); goto fallback; } if (wedged(data.sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(draw, gc->planemask)) goto fallback; if ((data.bo = sna_drawable_use_bo(draw, use_fill_spans(draw, gc, &data.region.extents, data.flags), &data.region.extents, &data.damage))) { uint32_t color; sna_gc(gc)->priv = &data; get_drawable_deltas(draw, data.pixmap, &data.dx, &data.dy); if (gc_is_solid(gc, &color)) { struct sna_fill_op fill; if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_SPANS)) goto fallback; data.op = &fill; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; } assert(gc->miTranslate); gc->ops = &sna_gc_ops__tmp; miFillPolygon(draw, gc, shape, mode, n, pt); fill.done(data.sna, &fill); } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; gc->ops = &sna_gc_ops__tmp; miFillPolygon(draw, gc, shape, mode, n, pt); } gc->ops = (GCOps *)&sna_gc_ops; if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); assert_pixmap_contains_box(data.pixmap, &data.region.extents); sna_damage_add_to_pixmap(data.damage, &data.region, data.pixmap); } assert_pixmap_damage(data.pixmap); RegionUninit(&data.region); return; } fallback: DBG(("%s: fallback (%d, %d), (%d, %d)\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2)); if (!region_maybe_clip(&data.region, gc->pCompositeClip)) { DBG(("%s: nothing to do, all clipped\n", __FUNCTION__)); return; } if (!sna_gc_move_to_cpu(gc, draw, &data.region)) goto out; if (!sna_drawable_move_region_to_cpu(draw, &data.region, drawable_gc_flags(draw, gc, true))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- miFillPolygon -> sna_fill_spans__cpu\n", __FUNCTION__)); miFillPolygon(draw, gc, shape, mode, n, pt); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(&data.region); } static struct kgem_bo * sna_pixmap_get_source_bo(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); unsigned flags; BoxRec box; box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; DBG(("%s(pixmap=%ld, size=%dx%d)\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height)); if (priv == NULL) { DBG(("%s: unattached, uploading data into temporary\n", __FUNCTION__)); return kgem_upload_source_image(&to_sna_from_pixmap(pixmap)->kgem, pixmap->devPrivate.ptr, &box, pixmap->devKind, pixmap->drawable.bitsPerPixel); } if (priv->gpu_damage) { if (sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT)) return kgem_bo_reference(priv->gpu_bo); } else if (priv->cpu_damage) { if (priv->cpu_bo) return kgem_bo_reference(priv->cpu_bo); } else { if (priv->gpu_bo) return kgem_bo_reference(priv->gpu_bo); if (priv->cpu_bo) return kgem_bo_reference(priv->cpu_bo); } flags = MOVE_READ | MOVE_ASYNC_HINT; if (priv->gpu_bo && priv->gpu_bo->proxy) { struct kgem_bo *bo = priv->gpu_bo; if (bo->rq == NULL && (bo->snoop || bo->pitch >= 4096)) flags |= __MOVE_FORCE; } if (priv->gpu_bo == NULL) { if (++priv->source_count > SOURCE_BIAS) flags |= __MOVE_FORCE; } if (!sna_pixmap_move_to_gpu(pixmap, flags)) { struct kgem_bo *upload; if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return NULL; upload = kgem_upload_source_image(&to_sna_from_pixmap(pixmap)->kgem, pixmap->devPrivate.ptr, &box, pixmap->devKind, pixmap->drawable.bitsPerPixel); if (upload == NULL) return NULL; if (priv->gpu_bo == NULL) { DBG(("%s: adding upload cache to pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(upload->proxy != NULL); kgem_proxy_bo_attach(upload, &priv->gpu_bo); } return upload; } return kgem_bo_reference(priv->gpu_bo); } /* static bool tile(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, PixmapPtr tile, const DDXPointRec * const origin, int alu, int n, xRectangle *rect, const BoxRec *extents, unsigned clipped) */ static bool sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, struct kgem_bo *tile_bo, GCPtr gc, int n, const xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); const DDXPointRec * const origin = &gc->patOrg; uint32_t br00, br13; int tx, ty; int16_t dx, dy; uint32_t *b; if (NO_TILE_8x8) return false; DBG(("%s x %d [(%d, %d)x(%d, %d)...], clipped=%x, origin=(%d, %d)\n", __FUNCTION__, n, r->x, r->y, r->width, r->height, clipped, origin->x, origin->y)); DBG(("%s: tile_bo tiling=%d, pitch=%d\n", __FUNCTION__, tile_bo->tiling, tile_bo->pitch)); if (tile_bo->tiling) return false; if (!kgem_bo_can_blt(&sna->kgem, bo) || !kgem_bo_can_blt(&sna->kgem, tile_bo)) return false; assert(tile_bo->pitch == 8 * drawable->bitsPerPixel >> 3); kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!kgem_check_batch(&sna->kgem, 10+2*3) || !kgem_check_reloc(&sna->kgem, 2) || !kgem_check_many_bo_fenced(&sna->kgem, bo, tile_bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_many_bo_fenced(&sna->kgem, bo, tile_bo, NULL)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo); get_drawable_deltas(drawable, pixmap, &dx, &dy); assert(extents->x1 + dx >= 0); assert(extents->y1 + dy >= 0); assert(extents->x2 + dx <= pixmap->drawable.width); assert(extents->y2 + dy <= pixmap->drawable.height); br00 = XY_SCANLINE_BLT; tx = (-drawable->x - dx - origin->x) % 8; if (tx < 0) tx += 8; ty = (-drawable->y - dy - origin->y) % 8; if (ty < 0) ty += 8; br00 |= tx << 12 | ty << 8; br13 = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= blt_depth(drawable->depth) << 24; br13 |= fill_ROP[gc->alu] << 16; if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, r, n, dx, dy); if (n == 1) { DBG(("%s: rect=(%d, %d)x(%d, %d) + (%d, %d), tile=(%d, %d)\n", __FUNCTION__, r->x, r->y, r->width, r->height, dx, dy, tx, ty)); assert(r->x + dx >= 0); assert(r->y + dy >= 0); assert(r->x + dx + r->width <= pixmap->drawable.width); assert(r->y + dy + r->height <= pixmap->drawable.height); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_PAT_BLT | 3 << 20 | (br00 & 0x7f00) | 6; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 8; } else { b[0] = XY_PAT_BLT | 3 << 20 | (br00 & 0x7f00) | 4; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 6; } } else do { int n_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; *(uint64_t *)(b+8) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 8, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 6; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 7, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 8; } n_this_time = n; rem = kgem_batch_space(&sna->kgem); if (3*n_this_time > rem) n_this_time = rem / 3; assert(n_this_time); n -= n_this_time; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3*n_this_time; do { assert(r->x + dx >= 0); assert(r->y + dy >= 0); assert(r->x + dx + r->width <= pixmap->drawable.width); assert(r->y + dy + r->height <= pixmap->drawable.height); b[0] = br00; b[1] = (r->y + dy) << 16 | (r->x + dx); b[2] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b += 3; r++; } while (--n_this_time); if (!n) break; _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo); } while (1); } else { RegionRec clip; uint16_t unwind_batch, unwind_reloc; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; *(uint64_t *)(b+8) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 8, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 6; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 7, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 8; } if (clip.data == NULL) { const BoxRec *c = &clip.extents; DBG(("%s: simple clip, %d boxes\n", __FUNCTION__, n)); while (n--) { BoxRec box; box.x1 = r->x + drawable->x; box.y1 = r->y + drawable->y; box.x2 = bound(box.x1, r->width); box.y2 = bound(box.y1, r->height); r++; if (box_intersect(&box, c)) { if (!kgem_check_batch(&sna->kgem, 3)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; *(uint64_t *)(b+8) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 8, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 6; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 7, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 8; } } assert(box.x1 + dx >= 0); assert(box.y1 + dy >= 0); assert(box.x2 + dx <= pixmap->drawable.width); assert(box.y2 + dy <= pixmap->drawable.height); DBG(("%s: box=(%d, %d),(%d, %d) + (%d, %d), tile=(%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, dx, dy, tx, ty)); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; b[0] = br00; b[1] = (box.y1 + dy) << 16 | (box.x1 + dx); b[2] = (box.y2 + dy) << 16 | (box.x2 + dx); sna->kgem.nbatch += 3; } } } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; DBG(("%s: complex clip (%ld cliprects), %d boxes\n", __FUNCTION__, (long)clip.data->numRects, n)); do { BoxRec box; box.x1 = r->x + drawable->x; box.y1 = r->y + drawable->y; box.x2 = bound(box.x1, r->width); box.y2 = bound(box.y1, r->height); DBG(("%s: rect=(%d, %d), (%d, %d), box=(%d, %d), (%d, %d)\n", __FUNCTION__, r->x, r->y, r->width, r->height, box.x1, box.y1, box.x2, box.y2)); r++; c = find_clip_box_for_y(clip_start, clip_end, box.y1); while (c != clip_end) { BoxRec bb; DBG(("%s: clip=(%d, %d), (%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2)); if (box.y2 <= c->y1) break; bb = box; if (box_intersect(&bb, c++)) { if (!kgem_check_batch(&sna->kgem, 3)) { DBG(("%s: emitting split batch\n", __FUNCTION__)); _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; *(uint64_t *)(b+8) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 8, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 6; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 7, tile_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); sna->kgem.nbatch += 8; } } assert(bb.x1 + dx >= 0); assert(bb.y1 + dy >= 0); assert(bb.x2 + dx <= pixmap->drawable.width); assert(bb.y2 + dy <= pixmap->drawable.height); DBG(("%s: emit box=(%d, %d),(%d, %d) + (%d, %d), tile=(%d, %d) [relative to drawable: (%d, %d)]\n", __FUNCTION__, bb.x1, bb.y1, bb.x2, bb.y2, dx, dy, tx, ty, bb.x1 - drawable->x, bb.y1 - drawable->y)); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; b[0] = br00; b[1] = (bb.y1 + dy) << 16 | (bb.x1 + dx); b[2] = (bb.y2 + dy) << 16 | (bb.x2 + dx); sna->kgem.nbatch += 3; } } } while (--n); } if (sna->kgem.nbatch == unwind_batch + (sna->kgem.gen >= 0100 ? 10 : 8)) { sna->kgem.nbatch = unwind_batch; sna->kgem.nreloc = unwind_reloc; if (sna->kgem.nbatch == 0) kgem_bo_pair_undo(&sna->kgem, bo, tile_bo); } } done: assert_pixmap_damage(pixmap); blt_done(sna); return true; } static bool tile8(int x) { switch(x) { case 1: case 2: case 4: case 8: return true; default: return false; } } static int next8(int x, int max) { if (x > 2 && x <= 4) x = 4; else if (x < 8) x = 8; return MIN(x, max); } static bool sna_poly_fill_rect_tiled_nxm_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, const xRectangle *rect, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); PixmapPtr tile = gc->tile.pixmap; int w, h, tx, ty, tw, th, bpp = tile->drawable.bitsPerPixel; const DDXPointRec origin = gc->patOrg; struct kgem_bo *upload; bool ret = false; uint8_t *src; void *ptr; tx = 0, tw = tile->drawable.width; if (!tile8(tw) && tw > extents->x2 - extents->x1) { tx = (extents->x1 - gc->patOrg.x - drawable->x) % tw; if (tx < 0) tx += tw; tw = next8(extents->x2 - extents->x1, tw); gc->patOrg.x = extents->x1 - drawable->x; } ty = 0, th = tile->drawable.height; if (!tile8(th) && th > extents->y2 - extents->y1) { ty = (extents->y1 - gc->patOrg.y - drawable->y) % th; if (ty < 0) ty += th; th = next8(extents->y2 - extents->y1, th); gc->patOrg.y = extents->y1 - drawable->y; } DBG(("%s: %dx%d+%d+%d (full tile size %dx%d)\n", __FUNCTION__, tw, th, tx, ty, tile->drawable.width, tile->drawable.height)); assert(tx < tile->drawable.width && tx >= 0); assert(ty < tile->drawable.height && ty >= 0); assert(tw && tw <= 8 && tw <= tile->drawable.width); assert(is_power_of_two(tw)); assert(th && th <= 8 && th <= tile->drawable.height); assert(is_power_of_two(th)); if (!sna_pixmap_move_to_cpu(tile, MOVE_READ)) goto out_gc; assert(tile->devKind); assert(has_coherent_ptr(sna, sna_pixmap(tile), MOVE_READ)); src = tile->devPrivate.ptr; src += tile->devKind * ty; src += tx * bpp/8; if ((tw | th) == 1) { uint32_t pixel; switch (bpp) { case 32: pixel = *(uint32_t *)src; break; case 16: pixel = *(uint16_t *)src; break; default: pixel = *(uint8_t *)src; break; } return sna_poly_fill_rect_blt(drawable, bo, damage, gc, pixel, n, rect, extents, clipped); } upload = kgem_create_buffer(&sna->kgem, 8*bpp, KGEM_BUFFER_WRITE, &ptr); if (upload == NULL) goto out_gc; upload->pitch = bpp; /* for sanity checks */ if (sigtrap_get() == 0) { uint8_t *dst = ptr; if (tx + tw > tile->drawable.width || ty + th > tile->drawable.height) { int sy = ty; src = tile->devPrivate.ptr; for (h = 0; h < th; h++) { int sx = tx; for (w = 0; w < tw; w++) { memcpy(dst + w*bpp/8, src + sy * tile->devKind + sx*bpp/8, bpp/8); if (++sx == tile->drawable.width) sx = 0; } w *= bpp/8; while (w < bpp) { memcpy(dst+w, dst, w); w *= 2; } if (++sy == tile->drawable.height) sy = 0; dst += bpp; } while (h < 8) { memcpy(dst, ptr, bpp*h); dst += bpp * h; h *= 2; } } else { for (h = 0; h < th; h++) { w = tw*bpp/8; memcpy(dst, src, w); while (w < bpp) { memcpy(dst+w, dst, w); w *= 2; } assert(w == bpp); src += tile->devKind; dst += bpp; } while (h < 8) { memcpy(dst, ptr, bpp*h); dst += bpp * h; h *= 2; } assert(h == 8); } ret = sna_poly_fill_rect_tiled_8x8_blt(drawable, bo, damage, upload, gc, n, rect, extents, clipped); sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); out_gc: gc->patOrg = origin; return ret; } inline static bool tile_is_solid(GCPtr gc, uint32_t *pixel) { PixmapPtr tile = gc->tile.pixmap; struct sna_pixmap *priv; if ((tile->drawable.width | tile->drawable.height) == 1) { DBG(("%s: single pixel tile pixmap, converting to solid fill\n", __FUNCTION__)); *pixel = get_pixel(tile); return true; } priv = sna_pixmap(tile); if (priv == NULL || !priv->clear) return false; DBG(("%s: tile is clear, converting to solid fill\n", __FUNCTION__)); *pixel = priv->clear_color; return true; } static bool sna_poly_fill_rect_tiled_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *rect, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); PixmapPtr tile = gc->tile.pixmap; struct kgem_bo *tile_bo; const DDXPointRec * const origin = &gc->patOrg; struct sna_copy_op copy; CARD32 alu = gc->alu; int tile_width, tile_height; int16_t dx, dy; uint32_t pixel; DBG(("%s pixmap=%ld, x %d [(%d, %d)x(%d, %d)...], clipped? %d\n", __FUNCTION__, pixmap->drawable.serialNumber, n, rect->x, rect->y, rect->width, rect->height, clipped)); assert(tile->drawable.depth == drawable->depth); assert(bo); if (tile_is_solid(gc, &pixel)) return sna_poly_fill_rect_blt(drawable, bo, damage, gc, pixel, n, rect, extents, clipped); /* XXX [248]x[238] tiling can be reduced to a pattern fill. * Also we can do the lg2 reduction for BLT and use repeat modes for * RENDER. */ tile_width = tile->drawable.width; tile_height = tile->drawable.height; if ((tile_width | tile_height) == 8) { bool ret; DBG(("%s: have 8x8 tile, using BLT fast path\n", __FUNCTION__)); tile_bo = sna_pixmap_get_source_bo(tile); if (tile_bo == NULL) { DBG(("%s: unable to move tile go GPU, fallback\n", __FUNCTION__)); return false; } ret = sna_poly_fill_rect_tiled_8x8_blt(drawable, bo, damage, tile_bo, gc, n, rect, extents, clipped); if (ret) { kgem_bo_destroy(&sna->kgem, tile_bo); return true; } } else { int w = tile_width, h = tile_height; struct sna_pixmap *priv = sna_pixmap(tile); if (priv == NULL || priv->gpu_damage == NULL) { w = next8(extents->x2 - extents->x1, w); h = next8(extents->y2 - extents->y1, h); } DBG(("%s: not 8x8, triming size for tile: %dx%d from %dx%d (area %dx%d)\n", __FUNCTION__, w, h, tile_width, tile_height, extents->x2-extents->x1, extents->y2-extents->y1)); if ((w|h) < 0x10 && is_power_of_two(w) && is_power_of_two(h) && sna_poly_fill_rect_tiled_nxm_blt(drawable, bo, damage, gc, n, rect, extents, clipped)) return true; tile_bo = sna_pixmap_get_source_bo(tile); if (tile_bo == NULL) { DBG(("%s: unable to move tile go GPU, fallback\n", __FUNCTION__)); return false; } } if (!sna_copy_init_blt(©, sna, tile, tile_bo, pixmap, bo, alu)) { DBG(("%s: unsupported blt\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, tile_bo); return false; } get_drawable_deltas(drawable, pixmap, &dx, &dy); DBG(("%s: drawable offset into pixmap(%ld) = (%d, %d)\n", __FUNCTION__, pixmap->drawable.serialNumber, dx, dy)); if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, rect, n, dx, dy); do { xRectangle r = *rect++; int16_t tile_y = (r.y - origin->y) % tile_height; if (tile_y < 0) tile_y += tile_height; assert(r.x + dx >= 0); assert(r.y + dy >= 0); assert(r.x + dx + r.width <= pixmap->drawable.width); assert(r.y + dy + r.height <= pixmap->drawable.height); r.y += dy; do { int16_t width = r.width; int16_t x = r.x + dx, tile_x; int16_t h = tile_height - tile_y; if (h > r.height) h = r.height; r.height -= h; tile_x = (r.x - origin->x) % tile_width; if (tile_x < 0) tile_x += tile_width; do { int16_t w = tile_width - tile_x; if (w > width) w = width; width -= w; copy.blt(sna, ©, tile_x, tile_y, w, h, x, r.y); x += w; tile_x = 0; } while (width); r.y += h; tile_y = 0; } while (r.height); } while (--n); } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) goto done; if (clip.data == NULL) { const BoxRec *box = &clip.extents; DBG(("%s: single clip box [(%d, %d), (%d, %d)]\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); while (n--) { BoxRec r; r.x1 = rect->x + drawable->x; r.y1 = rect->y + drawable->y; r.x2 = bound(r.x1, rect->width); r.y2 = bound(r.y1, rect->height); rect++; DBG(("%s: rectangle [(%d, %d), (%d, %d)]\n", __FUNCTION__, r.x1, r.y1, r.x2, r.y2)); if (box_intersect(&r, box)) { int height = r.y2 - r.y1; int dst_y = r.y1; int tile_y = (r.y1 - drawable->y - origin->y) % tile_height; if (tile_y < 0) tile_y += tile_height; assert(r.x1 + dx >= 0); assert(r.y1 + dy >= 0); assert(r.x2 + dx <= pixmap->drawable.width); assert(r.y2 + dy <= pixmap->drawable.height); while (height) { int width = r.x2 - r.x1; int dst_x = r.x1, tile_x; int h = tile_height - tile_y; if (h > height) h = height; height -= h; tile_x = (r.x1 - drawable->x - origin->x) % tile_width; if (tile_x < 0) tile_x += tile_width; while (width > 0) { int w = tile_width - tile_x; if (w > width) w = width; width -= w; copy.blt(sna, ©, tile_x, tile_y, w, h, dst_x + dx, dst_y + dy); if (damage) { BoxRec b; b.x1 = dst_x + dx; b.y1 = dst_y + dy; b.x2 = b.x1 + w; b.y2 = b.y1 + h; assert_pixmap_contains_box(pixmap, &b); sna_damage_add_box(damage, &b); } dst_x += w; tile_x = 0; } dst_y += h; tile_y = 0; } } } } else { while (n--) { RegionRec region; const BoxRec *box; int nbox; region.extents.x1 = rect->x + drawable->x; region.extents.y1 = rect->y + drawable->y; region.extents.x2 = bound(region.extents.x1, rect->width); region.extents.y2 = bound(region.extents.y1, rect->height); rect++; DBG(("%s: rectangle [(%d, %d), (%d, %d)]\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; RegionIntersect(®ion, ®ion, &clip); assert(region.extents.x1 + dx >= 0); assert(region.extents.y1 + dy >= 0); assert(region.extents.x2 + dx <= pixmap->drawable.width); assert(region.extents.y2 + dy <= pixmap->drawable.height); nbox = region_num_rects(®ion); box = region_rects(®ion); DBG(("%s: split into %d boxes after clipping\n", __FUNCTION__, nbox)); while (nbox--) { int height = box->y2 - box->y1; int dst_y = box->y1; int tile_y = (box->y1 - drawable->y - origin->y) % tile_height; if (tile_y < 0) tile_y += tile_height; while (height) { int width = box->x2 - box->x1; int dst_x = box->x1, tile_x; int h = tile_height - tile_y; if (h > height) h = height; height -= h; tile_x = (box->x1 - drawable->x - origin->x) % tile_width; if (tile_x < 0) tile_x += tile_width; while (width > 0) { int w = tile_width - tile_x; if (w > width) w = width; width -= w; copy.blt(sna, ©, tile_x, tile_y, w, h, dst_x + dx, dst_y + dy); if (damage) { BoxRec b; b.x1 = dst_x + dx; b.y1 = dst_y + dy; b.x2 = b.x1 + w; b.y2 = b.y1 + h; assert_pixmap_contains_box(pixmap, &b); sna_damage_add_box(damage, &b); } dst_x += w; tile_x = 0; } dst_y += h; tile_y = 0; } box++; } RegionUninit(®ion); } } RegionUninit(&clip); } done: copy.done(sna, ©); assert_pixmap_damage(pixmap); kgem_bo_destroy(&sna->kgem, tile_bo); return true; } static bool sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); uint32_t pat[2] = {0, 0}, br00, br13; int16_t dx, dy; uint32_t *b; if (NO_STIPPLE_8x8) return false; DBG(("%s: alu=%d, upload (%d, %d), (%d, %d), origin (%d, %d)\n", __FUNCTION__, gc->alu, extents->x1, extents->y1, extents->x2, extents->y2, gc->patOrg.x, gc->patOrg.y)); get_drawable_deltas(drawable, pixmap, &dx, &dy); { int px, py; px = (0 - gc->patOrg.x - drawable->x - dx) % 8; if (px < 0) px += 8; py = (0 - gc->patOrg.y - drawable->y - dy) % 8; if (py < 0) py += 8; DBG(("%s: pat offset (%d, %d)\n", __FUNCTION__ ,px, py)); br00 = XY_SCANLINE_BLT | px << 12 | py << 8 | 3 << 20; br13 = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= (gc->fillStyle == FillStippled) << 28; br13 |= blt_depth(drawable->depth) << 24; br13 |= fill_ROP[gc->alu] << 16; } assert(gc->stipple->devKind); { uint8_t *dst = (uint8_t *)pat; const uint8_t *src = gc->stipple->devPrivate.ptr; int stride = gc->stipple->devKind; int j = gc->stipple->drawable.height; do { *dst++ = byte_reverse(*src); src += stride; } while (--j); } kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!kgem_check_batch(&sna->kgem, 10 + 2*3) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, r, n, dx, dy); if (n == 1) { DBG(("%s: single unclipped rect (%d, %d)x(%d, %d)\n", __FUNCTION__, r->x + dx, r->y + dy, r->width, r->height)); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_PAT | (br00 & 0x7f00) | 3<<20 | 8; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; b[8] = pat[0]; b[9] = pat[1]; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_PAT | (br00 & 0x7f00) | 3<<20 | 7; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = pat[0]; b[8] = pat[1]; sna->kgem.nbatch += 9; } } else do { int n_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; b[8] = pat[0]; b[9] = pat[1]; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 7; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = pat[0]; b[8] = pat[1]; sna->kgem.nbatch += 9; } n_this_time = n; rem = kgem_batch_space(&sna->kgem); if (3*n_this_time > rem) n_this_time = rem / 3; assert(n_this_time); n -= n_this_time; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3 * n_this_time; do { DBG(("%s: rect (%d, %d)x(%d, %d)\n", __FUNCTION__, r->x + dx, r->y + dy, r->width, r->height)); assert(r->x + dx >= 0); assert(r->y + dy >= 0); assert(r->x + dx + r->width <= pixmap->drawable.width); assert(r->y + dy + r->height <= pixmap->drawable.height); b[0] = br00; b[1] = (r->y + dy) << 16 | (r->x + dx); b[2] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b += 3; r++; } while(--n_this_time); if (!n) break; _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); } while (1); } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; b[8] = pat[0]; b[9] = pat[1]; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 7; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = pat[0]; b[8] = pat[1]; sna->kgem.nbatch += 9; } if (clip.data == NULL) { do { BoxRec box; box.x1 = r->x + drawable->x; box.y1 = r->y + drawable->y; box.x2 = bound(box.x1, r->width); box.y2 = bound(box.y1, r->height); r++; if (box_intersect(&box, &clip.extents)) { if (!kgem_check_batch(&sna->kgem, 3)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; b[8] = pat[0]; b[9] = pat[1]; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 7; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = pat[0]; b[8] = pat[1]; sna->kgem.nbatch += 9; } } assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3; b[0] = br00; b[1] = (box.y1 + dy) << 16 | (box.x1 + dx); b[2] = (box.y2 + dy) << 16 | (box.x2 + dx); } } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { BoxRec box; box.x1 = r->x + drawable->x; box.y1 = r->y + drawable->y; box.x2 = bound(box.x1, r->width); box.y2 = bound(box.y1, r->height); r++; c = find_clip_box_for_y(clip_start, clip_end, box.y1); while (c != clip_end) { BoxRec bb; if (box.y2 <= c->y1) break; bb = box; if (box_intersect(&bb, c++)) { if (!kgem_check_batch(&sna->kgem, 3)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 8; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; b[8] = pat[0]; b[9] = pat[1]; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 3 << 20 | (br00 & BLT_DST_TILED) | 7; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; b[7] = pat[0]; b[8] = pat[1]; sna->kgem.nbatch += 9; } } assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3; b[0] = br00; b[1] = (bb.y1 + dy) << 16 | (bb.x1 + dx); b[2] = (bb.y2 + dy) << 16 | (bb.x2 + dx); } } } while (--n); } } assert_pixmap_damage(pixmap); blt_done(sna); return true; } static bool sna_poly_fill_rect_stippled_nxm_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr scratch, stipple; uint8_t bytes[8], *dst = bytes; const uint8_t *src, *end; int j, stride; bool ret; DBG(("%s: expanding %dx%d stipple to 8x8\n", __FUNCTION__, gc->stipple->drawable.width, gc->stipple->drawable.height)); scratch = GetScratchPixmapHeader(drawable->pScreen, 8, 8, 1, 1, 1, bytes); if (scratch == NullPixmap) return false; stipple = gc->stipple; gc->stipple = scratch; assert(stipple->devKind); stride = stipple->devKind; src = stipple->devPrivate.ptr; end = src + stride * stipple->drawable.height; for(j = 0; j < 8; j++) { switch (stipple->drawable.width) { case 1: *dst = (*src & 1) * 0xff; break; case 2: *dst = (*src & 3) * 0x55; break; case 4: *dst = (*src & 15) * 0x11; break; case 8: *dst = *src; break; default: assert(0); break; } dst++; src += stride; if (src == end) src = stipple->devPrivate.ptr; } ret = sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage, gc, n, r, extents, clipped); gc->stipple = stipple; FreeScratchPixmapHeader(scratch); return ret; } static bool sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); PixmapPtr stipple = gc->stipple; const DDXPointRec *origin = &gc->patOrg; int16_t dx, dy; uint32_t br00, br13; DBG(("%s: upload (%d, %d), (%d, %d), origin (%d, %d), clipped=%x\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2, origin->x, origin->y, clipped)); get_drawable_deltas(drawable, pixmap, &dx, &dy); kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); br00 = 3 << 20; br13 = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= (gc->fillStyle == FillStippled) << 29; br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, r, n, dx, dy); do { int bx1 = (r->x - origin->x) & ~7; int bx2 = (r->x + r->width - origin->x + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = r->height; int bstride = ALIGN(bw, 2); int src_stride; uint8_t *dst, *src; uint32_t *b; DBG(("%s: rect (%d, %d)x(%d, %d) stipple [%d,%d]\n", __FUNCTION__, r->x, r->y, r->width, r->height, bx1, bx2)); src_stride = bstride*bh; assert(src_stride > 0); if (src_stride <= 128) { src_stride = ALIGN(src_stride, 8) / 4; assert(src_stride <= 32); if (!kgem_check_batch(&sna->kgem, 8+src_stride) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY_IMM | (6 + src_stride) | br00; b[0] |= ((r->x - origin->x) & 7) << 17; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + src_stride; } else { b[0] = XY_MONO_SRC_COPY_IMM | (5 + src_stride) | br00; b[0] |= ((r->x - origin->x) & 7) << 17; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + src_stride; } assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (r->y - origin->y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); } else { struct kgem_bo *upload; void *ptr; if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { dst = ptr; assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (r->y - origin->y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY | br00 | 8; b[0] |= ((r->x - origin->x) & 7) << 17; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_SRC_COPY | br00 | 6; b[0] |= ((r->x - origin->x) & 7) << 17; b[1] = br13; b[2] = (r->y + dy) << 16 | (r->x + dx); b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); } r++; } while (--n); } else { RegionRec clip; DDXPointRec pat; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) return true; pat.x = origin->x + drawable->x; pat.y = origin->y + drawable->y; if (clip.data == NULL) { do { BoxRec box; int bx1, bx2, bw, bh, bstride; int src_stride; uint8_t *dst, *src; uint32_t *b; struct kgem_bo *upload; void *ptr; box.x1 = r->x + drawable->x; box.x2 = bound(box.x1, r->width); box.y1 = r->y + drawable->y; box.y2 = bound(box.y1, r->height); r++; if (!box_intersect(&box, &clip.extents)) continue; bx1 = (box.x1 - pat.x) & ~7; bx2 = (box.x2 - pat.x + 7) & ~7; bw = (bx2 - bx1)/8; bh = box.y2 - box.y1; bstride = ALIGN(bw, 2); DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d], pitch=%d, stride=%d\n", __FUNCTION__, r->x, r->y, r->width, r->height, box.x1, box.y1, box.x2, box.y2, bx1, bx2, bw, bstride)); src_stride = bstride*bh; assert(src_stride > 0); if (src_stride <= 128) { src_stride = ALIGN(src_stride, 8) / 4; assert(src_stride <= 32); if (!kgem_check_batch(&sna->kgem, 8+src_stride) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY_IMM | (6 + src_stride) | br00; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + src_stride; } else { b[0] = XY_MONO_SRC_COPY_IMM | (5 + src_stride) | br00; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + src_stride; } assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (box.y1 - pat.y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); } else { if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { dst = ptr; assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (box.y1 - pat.y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY | br00 | 8; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+5) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_SRC_COPY | br00 | 6; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); } } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; do { BoxRec unclipped; int bx1, bx2, bw, bh, bstride; int src_stride; uint8_t *dst, *src; uint32_t *b; struct kgem_bo *upload; void *ptr; unclipped.x1 = r->x + drawable->x; unclipped.x2 = bound(unclipped.x1, r->width); unclipped.y1 = r->y + drawable->y; unclipped.y2 = bound(unclipped.y1, r->height); r++; c = find_clip_box_for_y(clip_start, clip_end, unclipped.y1); while (c != clip_end) { BoxRec box; if (unclipped.y2 <= c->y1) break; box = unclipped; if (!box_intersect(&box, c++)) continue; bx1 = (box.x1 - pat.x) & ~7; bx2 = (box.x2 - pat.x + 7) & ~7; bw = (bx2 - bx1)/8; bh = box.y2 - box.y1; bstride = ALIGN(bw, 2); DBG(("%s: rect (%d, %d)x(%d, %d), box (%d,%d),(%d,%d) stipple [%d,%d]\n", __FUNCTION__, r->x, r->y, r->width, r->height, box.x1, box.y1, box.x2, box.y2, bx1, bx2)); src_stride = bstride*bh; assert(src_stride > 0); if (src_stride <= 128) { src_stride = ALIGN(src_stride, 8) / 4; assert(src_stride <= 32); if (!kgem_check_batch(&sna->kgem, 8+src_stride) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY_IMM | (6 + src_stride) | br00; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + src_stride; } else { b[0] = XY_MONO_SRC_COPY_IMM | (5 + src_stride) | br00; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + src_stride; } assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (box.y1 - pat.y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); } else { if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { dst = ptr; assert(stipple->devKind); src_stride = stipple->devKind; src = stipple->devPrivate.ptr; src += (box.y1 - pat.y) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY | br00 | 8; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_SRC_COPY | br00 | 6; b[0] |= ((box.x1 - pat.x) & 7) << 17; b[1] = br13; b[2] = (box.y1 + dy) << 16 | (box.x1 + dx); b[3] = (box.y2 + dy) << 16 | (box.x2 + dx); b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); } } } while (--n); } } blt_done(sna); return true; } static void sna_poly_fill_rect_stippled_n_box__imm(struct sna *sna, struct kgem_bo *bo, uint32_t br00, uint32_t br13, const GC *gc, const BoxRec *box, const DDXPointRec *origin) { int x1, x2, y1, y2; uint32_t *b; for (y1 = box->y1; y1 < box->y2; y1 = y2) { int oy = (y1 - origin->y) % gc->stipple->drawable.height; if (oy < 0) oy += gc->stipple->drawable.height; y2 = box->y2; if (y2 - y1 > gc->stipple->drawable.height - oy) y2 = y1 + gc->stipple->drawable.height - oy; for (x1 = box->x1; x1 < box->x2; x1 = x2) { int bx1, bx2, bw, bh, len, ox; uint8_t *dst, *src; x2 = box->x2; ox = (x1 - origin->x) % gc->stipple->drawable.width; if (ox < 0) ox += gc->stipple->drawable.width; bx1 = ox & ~7; bx2 = ox + (x2 - x1); if (bx2 > gc->stipple->drawable.width) { bx2 = gc->stipple->drawable.width; x2 = x1 + bx2-ox; } bw = (bx2 - bx1 + 7)/8; bw = ALIGN(bw, 2); bh = y2 - y1; DBG(("%s: box((%d, %d)x(%d, %d)) origin=(%d, %d), pat=(%d, %d), up=(%d, %d), stipple=%dx%d\n", __FUNCTION__, x1, y1, x2-x1, y2-y1, origin->x, origin->y, ox, oy, bx1, bx2, gc->stipple->drawable.width, gc->stipple->drawable.height)); len = bw*bh; len = ALIGN(len, 8) / 4; assert(len > 0); assert(len <= 32); if (!kgem_check_batch(&sna->kgem, 8+len) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return; /* XXX fallback? */ _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = br00 | (6 + len) | (ox & 7) << 17; b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + len; } else { b[0] = br00 | (5 + len) | (ox & 7) << 17; b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + len; } assert(gc->stipple->devKind); len = gc->stipple->devKind; src = gc->stipple->devPrivate.ptr; src += oy*len + ox/8; len -= bw; do { int i = bw; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += len; } while (--bh); } } } static void sna_poly_fill_rect_stippled_n_box(struct sna *sna, struct kgem_bo *bo, struct kgem_bo **tile, uint32_t br00, uint32_t br13, const GC *gc, const BoxRec *box, const DDXPointRec *origin) { int x1, x2, y1, y2; int w = gc->stipple->drawable.width; int h = gc->stipple->drawable.height; int stride = gc->stipple->devKind; uint32_t *b; assert(stride); if ((((box->y2-box->y1) | (box->x2-box->x1)) & ~31) == 0) { br00 = XY_MONO_SRC_COPY_IMM |(br00 & (BLT_DST_TILED | 3 << 20)); sna_poly_fill_rect_stippled_n_box__imm(sna, bo, br00, br13, gc, box, origin); return; } for (y1 = box->y1; y1 < box->y2; y1 = y2) { int row, oy = (y1 - origin->y) % gc->stipple->drawable.height; if (oy < 0) oy += h; y2 = box->y2; if (y2 - y1 > h - oy) y2 = y1 + h - oy; row = oy * stride; for (x1 = box->x1; x1 < box->x2; x1 = x2) { int bx1, bx2, bw, bh, len, ox; bool use_tile; x2 = box->x2; ox = (x1 - origin->x) % w; if (ox < 0) ox += w; bx1 = ox & ~7; bx2 = ox + (x2 - x1); if (bx2 > w) { bx2 = w; x2 = x1 + bx2-ox; } use_tile = y2-y1 == h && x2-x1 == w; DBG(("%s: box((%d, %d)x(%d, %d)) origin=(%d, %d), pat=(%d, %d), up=(%d, %d), stipple=%dx%d, full tile?=%d\n", __FUNCTION__, x1, y1, x2-x1, y2-y1, origin->x, origin->y, ox, oy, bx1, bx2, w, h, use_tile)); bw = (bx2 - bx1 + 7)/8; bw = ALIGN(bw, 2); bh = y2 - y1; len = bw*bh; len = ALIGN(len, 8) / 4; assert(len > 0); if (!kgem_check_batch(&sna->kgem, 8+len) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return; /* XXX fallback? */ _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (!use_tile && len <= 32) { uint8_t *dst, *src; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY_IMM; b[0] |= (br00 & (BLT_DST_TILED | 3 << 20)); b[0] |= (ox & 7) << 17; b[0] |= (6 + len); b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; dst = (uint8_t *)&b[8]; sna->kgem.nbatch += 8 + len; } else { b[0] = XY_MONO_SRC_COPY_IMM; b[0] |= (br00 & (BLT_DST_TILED | 3 << 20)); b[0] |= (ox & 7) << 17; b[0] |= (5 + len); b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = gc->bgPixel; b[6] = gc->fgPixel; dst = (uint8_t *)&b[7]; sna->kgem.nbatch += 7 + len; } assert(gc->stipple->devKind); len = gc->stipple->devKind; src = gc->stipple->devPrivate.ptr; src += oy*len + ox/8; len -= bw; do { int i = bw; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += len; } while (--bh); } else { bool has_tile = use_tile && *tile; struct kgem_bo *upload; uint8_t *dst, *src; void *ptr; if (has_tile) { upload = kgem_bo_reference(*tile); } else { upload = kgem_create_buffer(&sna->kgem, bw*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) return; } assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = br00 | (ox & 7) << 17 | 8; b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = br00 | (ox & 7) << 17 | 6; b[1] = br13; b[2] = y1 << 16 | x1; b[3] = y2 << 16 | x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } if (!has_tile) { dst = ptr; len = stride; src = gc->stipple->devPrivate.ptr; src += row + (ox >> 3); len -= bw; do { int i = bw; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += len; } while (--bh); if (use_tile) *tile = kgem_bo_reference(upload); } kgem_bo_destroy(&sna->kgem, upload); } } } } static bool sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); DDXPointRec origin = gc->patOrg; int16_t dx, dy; uint32_t br00, br13; DBG(("%s: upload (%d, %d), (%d, %d), origin (%d, %d), clipped=%d, alu=%d, opaque=%d\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2, origin.x, origin.y, clipped, gc->alu, gc->fillStyle == FillOpaqueStippled)); get_drawable_deltas(drawable, pixmap, &dx, &dy); kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); br00 = XY_MONO_SRC_COPY_IMM | 3 << 20; br13 = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= (gc->fillStyle == FillStippled) << 29; br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; origin.x += dx + drawable->x; origin.y += dy + drawable->y; if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, r, n, dx, dy); do { BoxRec box; box.x1 = r->x + dx; box.y1 = r->y + dy; box.x2 = box.x1 + r->width; box.y2 = box.y1 + r->height; sna_poly_fill_rect_stippled_n_box__imm(sna, bo, br00, br13, gc, &box, &origin); r++; } while (--n); } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) { DBG(("%s: all clipped\n", __FUNCTION__)); return true; } if (clip.data == NULL) { DBG(("%s: clipped to extents ((%d, %d), (%d, %d))\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); do { BoxRec box; box.x1 = r->x + drawable->x; box.x2 = bound(box.x1, r->width); box.y1 = r->y + drawable->y; box.y2 = bound(box.y1, r->height); r++; DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); if (!box_intersect(&box, &clip.extents)) continue; box.x1 += dx; box.x2 += dx; box.y1 += dy; box.y2 += dy; sna_poly_fill_rect_stippled_n_box__imm(sna, bo, br00, br13, gc, &box, &origin); } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; DBG(("%s: clipped to boxes: start((%d, %d), (%d, %d)); end=((%d, %d), (%d, %d))\n", __FUNCTION__, clip_start->x1, clip_start->y1, clip_start->x2, clip_start->y2, clip_end->x1, clip_end->y1, clip_end->x2, clip_end->y2)); do { BoxRec unclipped; unclipped.x1 = r->x + drawable->x; unclipped.x2 = bound(unclipped.x1, r->width); unclipped.y1 = r->y + drawable->y; unclipped.y2 = bound(unclipped.y1, r->height); r++; c = find_clip_box_for_y(clip_start, clip_end, unclipped.y1); while (c != clip_end) { BoxRec box; if (unclipped.y2 <= c->y1) break; box = unclipped; if (!box_intersect(&box, c++)) continue; box.x1 += dx; box.x2 += dx; box.y1 += dy; box.y2 += dy; sna_poly_fill_rect_stippled_n_box__imm(sna, bo, br00, br13, gc, &box, &origin); } } while (--n); } } assert_pixmap_damage(pixmap); blt_done(sna); return true; } static bool sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *r, const BoxRec *extents, unsigned clipped) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); DDXPointRec origin = gc->patOrg; struct kgem_bo *tile = NULL; int16_t dx, dy; uint32_t br00, br13; DBG(("%s: upload (%d, %d), (%d, %d), origin (%d, %d), clipped=%d, alu=%d, opaque=%d\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2, origin.x, origin.y, clipped, gc->alu, gc->fillStyle == FillOpaqueStippled)); if (((gc->stipple->drawable.width | gc->stipple->drawable.height) & ~31) == 0) return sna_poly_fill_rect_stippled_n_blt__imm(drawable, bo, damage, gc, n, r, extents, clipped); get_drawable_deltas(drawable, pixmap, &dx, &dy); kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); br00 = XY_MONO_SRC_COPY | 3 << 20; br13 = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { br00 |= BLT_DST_TILED; br13 >>= 2; } br13 |= (gc->fillStyle == FillStippled) << 29; br13 |= blt_depth(drawable->depth) << 24; br13 |= copy_ROP[gc->alu] << 16; origin.x += dx + drawable->x; origin.y += dy + drawable->y; if (!clipped) { dx += drawable->x; dy += drawable->y; sna_damage_add_rectangles(damage, r, n, dx, dy); do { BoxRec box; box.x1 = r->x + dx; box.y1 = r->y + dy; box.x2 = box.x1 + r->width; box.y2 = box.y1 + r->height; sna_poly_fill_rect_stippled_n_box(sna, bo, &tile, br00, br13, gc, &box, &origin); r++; } while (--n); } else { RegionRec clip; region_set(&clip, extents); if (!region_maybe_clip(&clip, gc->pCompositeClip)) { DBG(("%s: all clipped\n", __FUNCTION__)); return true; } if (clip.data == NULL) { DBG(("%s: clipped to extents ((%d, %d), (%d, %d))\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); do { BoxRec box; box.x1 = r->x + drawable->x; box.x2 = bound(box.x1, r->width); box.y1 = r->y + drawable->y; box.y2 = bound(box.y1, r->height); r++; DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); if (!box_intersect(&box, &clip.extents)) continue; box.x1 += dx; box.x2 += dx; box.y1 += dy; box.y2 += dy; sna_poly_fill_rect_stippled_n_box(sna, bo, &tile, br00, br13, gc, &box, &origin); } while (--n); } else { const BoxRec * const clip_start = RegionBoxptr(&clip); const BoxRec * const clip_end = clip_start + clip.data->numRects; const BoxRec *c; DBG(("%s: clipped to boxes: start((%d, %d), (%d, %d)); end=((%d, %d), (%d, %d))\n", __FUNCTION__, clip_start->x1, clip_start->y1, clip_start->x2, clip_start->y2, clip_end->x1, clip_end->y1, clip_end->x2, clip_end->y2)); do { BoxRec unclipped; unclipped.x1 = r->x + drawable->x; unclipped.x2 = bound(unclipped.x1, r->width); unclipped.y1 = r->y + drawable->y; unclipped.y2 = bound(unclipped.y1, r->height); r++; c = find_clip_box_for_y(clip_start, clip_end, unclipped.y1); while (c != clip_end) { BoxRec box; if (unclipped.y2 <= c->y1) break; box = unclipped; if (!box_intersect(&box, c++)) continue; box.x1 += dx; box.x2 += dx; box.y1 += dy; box.y2 += dy; sna_poly_fill_rect_stippled_n_box(sna, bo, &tile, br00, br13, gc, &box, &origin); } } while (--n); } } assert_pixmap_damage(pixmap); if (tile) kgem_bo_destroy(&sna->kgem, tile); blt_done(sna); return true; } static bool sna_poly_fill_rect_stippled_blt(DrawablePtr drawable, struct kgem_bo *bo, struct sna_damage **damage, GCPtr gc, int n, xRectangle *rect, const BoxRec *extents, unsigned clipped) { PixmapPtr stipple = gc->stipple; PixmapPtr pixmap = get_drawable_pixmap(drawable); if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); /* This is cheating, but only the gpu_bo can be tiled */ assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&to_sna_from_pixmap(pixmap)->kgem, bo)) return false; if (!sna_drawable_move_to_cpu(&stipple->drawable, MOVE_READ)) return false; DBG(("%s: origin (%d, %d), extents (stipple): (%d, %d), stipple size %dx%d\n", __FUNCTION__, gc->patOrg.x, gc->patOrg.y, extents->x2 - gc->patOrg.x - drawable->x, extents->y2 - gc->patOrg.y - drawable->y, stipple->drawable.width, stipple->drawable.height)); if ((stipple->drawable.width | stipple->drawable.height) == 8) return sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage, gc, n, rect, extents, clipped); if ((stipple->drawable.width | stipple->drawable.height) <= 0xc && is_power_of_two(stipple->drawable.width) && is_power_of_two(stipple->drawable.height)) return sna_poly_fill_rect_stippled_nxm_blt(drawable, bo, damage, gc, n, rect, extents, clipped); if (extents->x1 - gc->patOrg.x - drawable->x >= 0 && extents->x2 - gc->patOrg.x - drawable->x <= stipple->drawable.width && extents->y1 - gc->patOrg.y - drawable->y >= 0 && extents->y2 - gc->patOrg.y - drawable->y <= stipple->drawable.height) { if (stipple->drawable.width <= 8 && stipple->drawable.height <= 8) return sna_poly_fill_rect_stippled_8x8_blt(drawable, bo, damage, gc, n, rect, extents, clipped); else return sna_poly_fill_rect_stippled_1_blt(drawable, bo, damage, gc, n, rect, extents, clipped); } else { return sna_poly_fill_rect_stippled_n_blt(drawable, bo, damage, gc, n, rect, extents, clipped); } } static unsigned sna_poly_fill_rect_extents(DrawablePtr drawable, GCPtr gc, int *_n, xRectangle **_r, BoxPtr out) { int n; xRectangle *r; Box32Rec box; bool clipped; if (*_n == 0) return 0; DBG(("%s: [0] = (%d, %d)x(%d, %d)\n", __FUNCTION__, (*_r)->x, (*_r)->y, (*_r)->width, (*_r)->height)); /* Remove any zero-size rectangles from the array */ while (*_n && ((*_r)->width == 0 || (*_r)->height == 0)) --*_n, ++*_r; if (*_n == 0) return 0; n = *_n; r = *_r; box.x1 = r->x; box.x2 = box.x1 + r->width; box.y1 = r->y; box.y2 = box.y1 + r->height; r++; while (--n) { if (r->width == 0 || r->height == 0) goto slow; box32_add_rect(&box, r++); } goto done; slow: { xRectangle *rr = r; do { do { --*_n, r++; } while (--n && (r->width == 0 || r->height == 0)); while (n && r->width && r->height) { box32_add_rect(&box, r); *rr++ = *r++; n--; } } while (n); } done: clipped = box32_trim_and_translate(&box, drawable, gc); if (!box32_to_box16(&box, out)) return 0; return 1 | clipped << 1; } static void sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect) { PixmapPtr pixmap = get_drawable_pixmap(draw); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; RegionRec region; unsigned flags, hint; uint32_t color; DBG(("%s(n=%d, PlaneMask: %lx (solid %d), solid fill: %d [style=%d, tileIsPixel=%d], alu=%d)\n", __FUNCTION__, n, gc->planemask, !!PM_IS_SOLID(draw, gc->planemask), (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel)), gc->fillStyle, gc->tileIsPixel, gc->alu)); flags = sna_poly_fill_rect_extents(draw, gc, &n, &rect, ®ion.extents); if (flags == 0) { DBG(("%s, nothing to do\n", __FUNCTION__)); return; } DBG(("%s: extents(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, flags)); if (FORCE_FALLBACK || !ACCEL_POLY_FILL_RECT) { DBG(("%s: fallback forced\n", __FUNCTION__)); goto fallback; } if (priv == NULL) { DBG(("%s: fallback -- unattached\n", __FUNCTION__)); goto fallback; } if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(draw, gc->planemask)) { DBG(("%s: fallback -- planemask=0x%lx (not-solid)\n", __FUNCTION__, gc->planemask)); goto fallback; } if (alu_overwrites(gc->alu)) flags |= OVERWRITES; /* Clear the cpu damage so that we refresh the GPU status of the * pixmap upon a redraw after a period of inactivity. */ hint = PREFER_GPU; if (n == 1 && gc->fillStyle != FillStippled && flags & OVERWRITES) { int16_t dx, dy; region.data = NULL; if (get_drawable_deltas(draw, pixmap, &dx, &dy)) { DBG(("%s: delta=(%d, %d)\n", __FUNCTION__, dx, dy)); RegionTranslate(®ion, dx, dy); } if ((flags & IS_CLIPPED) == 0) { hint |= IGNORE_DAMAGE; if (region_subsumes_drawable(®ion, &pixmap->drawable)) { discard_cpu_damage(sna, priv); hint |= REPLACES; } else { if (priv->cpu_damage && region_subsumes_damage(®ion, priv->cpu_damage)) discard_cpu_damage(sna, priv); } } if (priv->cpu_damage == NULL) { if (priv->gpu_bo && (hint & REPLACES || box_covers_pixmap(pixmap, ®ion.extents) || box_inplace(pixmap, ®ion.extents))) { DBG(("%s: promoting to full GPU\n", __FUNCTION__)); assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); } DBG(("%s: dropping last-cpu hint\n", __FUNCTION__)); priv->cpu = false; } if (dx | dy) RegionTranslate(®ion, -dx, -dy); } /* If the source is already on the GPU, keep the operation on the GPU */ if (gc->fillStyle == FillTiled && !gc->tileIsPixel && sna_pixmap_is_gpu(gc->tile.pixmap)) { DBG(("%s: source is already on the gpu\n", __FUNCTION__)); hint |= FORCE_GPU; } bo = sna_drawable_use_bo(draw, hint, ®ion.extents, &damage); if (bo == NULL) { DBG(("%s: not using GPU, hint=%x\n", __FUNCTION__, hint)); goto fallback; } if (hint & REPLACES && UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (gc_is_solid(gc, &color)) { DBG(("%s: solid fill [%08x], testing for blt\n", __FUNCTION__, color)); if (sna_poly_fill_rect_blt(draw, bo, damage, gc, color, n, rect, ®ion.extents, flags)) return; } else if (gc->fillStyle == FillTiled) { DBG(("%s: tiled fill, testing for blt\n", __FUNCTION__)); if (sna_poly_fill_rect_tiled_blt(draw, bo, damage, gc, n, rect, ®ion.extents, flags)) return; } else { DBG(("%s: stippled fill, testing for blt\n", __FUNCTION__)); if (sna_poly_fill_rect_stippled_blt(draw, bo, damage, gc, n, rect, ®ion.extents, flags)) return; } fallback: DBG(("%s: fallback (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) { DBG(("%s: nothing to do, all clipped\n", __FUNCTION__)); return; } if (!sna_gc_move_to_cpu(gc, draw, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(draw, ®ion, drawable_gc_flags(draw, gc, n > 1))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__)); fbPolyFillRect(draw, gc, n, rect); FALLBACK_FLUSH(draw); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static void sna_poly_fill_rect__gpu(DrawablePtr draw, GCPtr gc, int n, xRectangle *r) { struct sna_fill_spans *data = sna_gc(gc)->priv; uint32_t color; DBG(("%s(n=%d, PlaneMask: %lx (solid %d), solid fill: %d [style=%d, tileIsPixel=%d], alu=%d)\n", __FUNCTION__, n, gc->planemask, !!PM_IS_SOLID(draw, gc->planemask), (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel)), gc->fillStyle, gc->tileIsPixel, gc->alu)); assert(PM_IS_SOLID(draw, gc->planemask)); if (n == 0) return; /* The mi routines do not attempt to keep the spans it generates * within the clip, so we must run them through the clipper. */ if (gc_is_solid(gc, &color)) { (void)sna_poly_fill_rect_blt(draw, data->bo, NULL, gc, color, n, r, &data->region.extents, IS_CLIPPED); } else if (gc->fillStyle == FillTiled) { (void)sna_poly_fill_rect_tiled_blt(draw, data->bo, NULL, gc, n, r, &data->region.extents, IS_CLIPPED); } else { (void)sna_poly_fill_rect_stippled_blt(draw, data->bo, NULL, gc, n, r, &data->region.extents, IS_CLIPPED); } } static void sna_poly_fill_arc(DrawablePtr draw, GCPtr gc, int n, xArc *arc) { struct sna_fill_spans data; struct sna_pixmap *priv; DBG(("%s(n=%d, PlaneMask: %lx (solid %d), solid fill: %d [style=%d, tileIsPixel=%d], alu=%d)\n", __FUNCTION__, n, gc->planemask, !!PM_IS_SOLID(draw, gc->planemask), (gc->fillStyle == FillSolid || (gc->fillStyle == FillTiled && gc->tileIsPixel)), gc->fillStyle, gc->tileIsPixel, gc->alu)); data.flags = sna_poly_arc_extents(draw, gc, n, arc, &data.region.extents); if (data.flags == 0) return; DBG(("%s: extents(%d, %d), (%d, %d), flags=%x\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2, data.flags)); data.region.data = NULL; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_FILL_ARC) goto fallback; data.pixmap = get_drawable_pixmap(draw); data.sna = to_sna_from_pixmap(data.pixmap); priv = sna_pixmap(data.pixmap); if (priv == NULL) { DBG(("%s: fallback -- unattached\n", __FUNCTION__)); goto fallback; } if (wedged(data.sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(draw, gc->planemask)) goto fallback; if ((data.bo = sna_drawable_use_bo(draw, use_fill_spans(draw, gc, &data.region.extents, data.flags), &data.region.extents, &data.damage))) { uint32_t color; get_drawable_deltas(draw, data.pixmap, &data.dx, &data.dy); sna_gc(gc)->priv = &data; if (gc_is_solid(gc, &color)) { struct sna_fill_op fill; if (!sna_fill_init_blt(&fill, data.sna, data.pixmap, data.bo, gc->alu, color, FILL_SPANS)) goto fallback; data.op = &fill; if ((data.flags & IS_CLIPPED) == 0) { if (data.dx | data.dy) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_offset; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill; } else { if (!region_maybe_clip(&data.region, gc->pCompositeClip)) return; if (region_is_singular(&data.region)) sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_extents; else sna_gc_ops__tmp.FillSpans = sna_fill_spans__fill_clip_boxes; } assert(gc->miTranslate); gc->ops = &sna_gc_ops__tmp; miPolyFillArc(draw, gc, n, arc); fill.done(data.sna, &fill); } else { sna_gc_ops__tmp.FillSpans = sna_fill_spans__gpu; gc->ops = &sna_gc_ops__tmp; miPolyFillArc(draw, gc, n, arc); } gc->ops = (GCOps *)&sna_gc_ops; if (data.damage) { if (data.dx | data.dy) pixman_region_translate(&data.region, data.dx, data.dy); assert_pixmap_contains_box(data.pixmap, &data.region.extents); sna_damage_add_to_pixmap(data.damage, &data.region, data.pixmap); } assert_pixmap_damage(data.pixmap); RegionUninit(&data.region); return; } fallback: DBG(("%s: fallback (%d, %d), (%d, %d)\n", __FUNCTION__, data.region.extents.x1, data.region.extents.y1, data.region.extents.x2, data.region.extents.y2)); if (!region_maybe_clip(&data.region, gc->pCompositeClip)) { DBG(("%s: nothing to do, all clipped\n", __FUNCTION__)); return; } if (!sna_gc_move_to_cpu(gc, draw, &data.region)) goto out; if (!sna_drawable_move_region_to_cpu(draw, &data.region, drawable_gc_flags(draw, gc, true))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- miPolyFillArc -> sna_fill_spans__cpu\n", __FUNCTION__)); miPolyFillArc(draw, gc, n, arc); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(&data.region); } struct sna_font { CharInfoRec glyphs8[256]; CharInfoRec *glyphs16[256]; }; #define GLYPH_INVALID (void *)1 #define GLYPH_EMPTY (void *)2 static Bool sna_realize_font(ScreenPtr screen, FontPtr font) { struct sna_font *priv; DBG(("%s (key=%d)\n", __FUNCTION__, sna_font_key)); priv = calloc(1, sizeof(struct sna_font)); if (priv == NULL) return FALSE; if (!FontSetPrivate(font, sna_font_key, priv)) { free(priv); return FALSE; } return TRUE; } static Bool sna_unrealize_font(ScreenPtr screen, FontPtr font) { struct sna_font *priv = FontGetPrivate(font, sna_font_key); int i, j; DBG(("%s (key=%d)\n", __FUNCTION__, sna_font_key)); if (priv == NULL) return TRUE; for (i = 0; i < 256; i++) { if ((uintptr_t)priv->glyphs8[i].bits & ~3) free(priv->glyphs8[i].bits); } for (j = 0; j < 256; j++) { if (priv->glyphs16[j] == NULL) continue; for (i = 0; i < 256; i++) { if ((uintptr_t)priv->glyphs16[j][i].bits & ~3) free(priv->glyphs16[j][i].bits); } free(priv->glyphs16[j]); } free(priv); FontSetPrivate(font, sna_font_key, NULL); return TRUE; } static bool sna_glyph_blt(DrawablePtr drawable, GCPtr gc, int _x, int _y, unsigned int _n, CharInfoPtr *_info, RegionRec *clip, uint32_t fg, uint32_t bg, bool transparent) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct kgem_bo *bo; struct sna_damage **damage; const BoxRec *extents, *last_extents; uint32_t *b; int16_t dx, dy; uint32_t br00; uint16_t unwind_batch, unwind_reloc; unsigned hint; uint8_t rop = transparent ? copy_ROP[gc->alu] : ROP_S; DBG(("%s (%d, %d) x %d, fg=%08x, bg=%08x alu=%02x\n", __FUNCTION__, _x, _y, _n, fg, bg, rop)); if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); return false; } if (!transparent && clip->data == NULL) hint = PREFER_GPU | IGNORE_DAMAGE; else hint = PREFER_GPU; bo = sna_drawable_use_bo(drawable, hint, &clip->extents, &damage); if (bo == NULL) return false; if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&sna->kgem, bo)) return false; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) RegionTranslate(clip, dx, dy); _x += drawable->x + dx; _y += drawable->y + dy; extents = region_rects(clip); last_extents = extents + region_num_rects(clip); if (!transparent) { /* emulate miImageGlyphBlt */ if (!sna_blt_fill_boxes(sna, GXcopy, bo, drawable->bitsPerPixel, bg, extents, last_extents - extents)) { RegionTranslate(clip, -dx, -dy); return false; } } kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!kgem_check_batch(&sna->kgem, 20) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) { RegionTranslate(clip, -dx, -dy); return false; } _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | 8; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = bg; b[7] = fg; b[8] = 0; b[9] = 0; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | 6; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = bg; b[6] = fg; b[7] = 0; sna->kgem.nbatch += 8; } br00 = XY_TEXT_IMMEDIATE_BLT; if (bo->tiling && sna->kgem.gen >= 040) br00 |= BLT_DST_TILED; do { CharInfoPtr *info = _info; int x = _x, y = _y, n = _n; do { CharInfoPtr c = *info++; int w = GLYPHWIDTHPIXELS(c); int h = GLYPHHEIGHTPIXELS(c); int w8 = (w + 7) >> 3; int x1, y1, len; if (c->bits == GLYPH_EMPTY) goto skip; len = (w8 * h + 7) >> 3 << 1; x1 = x + c->metrics.leftSideBearing; y1 = y - c->metrics.ascent; DBG(("%s glyph: (%d, %d) -> (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__, x,y, x1, y1, w, w8, h, len)); if (x1 >= extents->x2 || y1 >= extents->y2) goto skip; if (x1 + w <= extents->x1 || y1 + h <= extents->y1) goto skip; assert(len > 0); if (!kgem_check_batch(&sna->kgem, 3+len)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 3 << 20 | 8; b[1] = bo->pitch; if (bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = bg; b[7] = fg; b[8] = 0; b[9] = 0; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 3 << 20 | 6; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = bg; b[6] = fg; b[7] = 0; sna->kgem.nbatch += 8; } } assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3 + len; b[0] = br00 | (1 + len); b[1] = (uint16_t)y1 << 16 | (uint16_t)x1; b[2] = (uint16_t)(y1+h) << 16 | (uint16_t)(x1+w); { uint64_t *src = (uint64_t *)c->bits; uint64_t *dst = (uint64_t *)(b + 3); do { *dst++ = *src++; len -= 2; } while (len); } if (damage) { BoxRec r; r.x1 = x1; r.y1 = y1; r.x2 = x1 + w; r.y2 = y1 + h; if (box_intersect(&r, extents)) sna_damage_add_box(damage, &r); } skip: x += c->metrics.characterWidth; } while (--n); if (++extents == last_extents) break; if (kgem_check_batch(&sna->kgem, 3)) { assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3; DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); b[0] = XY_SETUP_CLIP; b[1] = extents->y1 << 16 | extents->x1; b[2] = extents->y2 << 16 | extents->x2; } } while (1); if (sna->kgem.nbatch == unwind_batch + (sna->kgem.gen >= 0100 ? 10 : 8)) { sna->kgem.nbatch = unwind_batch; sna->kgem.nreloc = unwind_reloc; if (sna->kgem.nbatch == 0) kgem_bo_undo(&sna->kgem, bo); } assert_pixmap_damage(pixmap); blt_done(sna); return true; } static void sna_glyph_extents(FontPtr font, CharInfoPtr *info, unsigned long count, ExtentInfoRec *extents) { extents->drawDirection = font->info.drawDirection; extents->fontAscent = font->info.fontAscent; extents->fontDescent = font->info.fontDescent; extents->overallAscent = info[0]->metrics.ascent; extents->overallDescent = info[0]->metrics.descent; extents->overallLeft = info[0]->metrics.leftSideBearing; extents->overallRight = info[0]->metrics.rightSideBearing; extents->overallWidth = info[0]->metrics.characterWidth; while (--count) { CharInfoPtr p =*++info; int v; if (p->metrics.ascent > extents->overallAscent) extents->overallAscent = p->metrics.ascent; if (p->metrics.descent > extents->overallDescent) extents->overallDescent = p->metrics.descent; v = extents->overallWidth + p->metrics.leftSideBearing; if (v < extents->overallLeft) extents->overallLeft = v; v = extents->overallWidth + p->metrics.rightSideBearing; if (v > extents->overallRight) extents->overallRight = v; extents->overallWidth += p->metrics.characterWidth; } } static bool sna_set_glyph(CharInfoPtr in, CharInfoPtr out) { int w = GLYPHWIDTHPIXELS(in); int h = GLYPHHEIGHTPIXELS(in); int stride = GLYPHWIDTHBYTESPADDED(in); uint8_t *dst, *src; int clear = 1; out->metrics = in->metrics; /* Skip empty glyphs */ if (w == 0 || h == 0 || ((w|h) == 1 && (in->bits[0] & 1) == 0)) { out->bits = GLYPH_EMPTY; return true; } w = (w + 7) >> 3; out->bits = malloc((w*h + 7) & ~7); if (out->bits == NULL) return false; VG(memset(out->bits, 0, (w*h + 7) & ~7)); src = (uint8_t *)in->bits; dst = (uint8_t *)out->bits; stride -= w; do { int i = w; do { clear &= *src == 0; *dst++ = byte_reverse(*src++); } while (--i); src += stride; } while (--h); if (clear) { free(out->bits); out->bits = GLYPH_EMPTY; } return true; } inline static bool sna_get_glyph8(FontPtr font, struct sna_font *priv, uint8_t g, CharInfoPtr *out) { unsigned long n; CharInfoPtr p, ret; p = &priv->glyphs8[g]; if (p->bits) { *out = p; return p->bits != GLYPH_INVALID; } font->get_glyphs(font, 1, &g, Linear8Bit, &n, &ret); if (n == 0) { p->bits = GLYPH_INVALID; return false; } return sna_set_glyph(ret, *out = p); } inline static bool sna_get_glyph16(FontPtr font, struct sna_font *priv, uint16_t g, CharInfoPtr *out) { unsigned long n; CharInfoPtr page, p, ret; page = priv->glyphs16[g>>8]; if (page == NULL) page = priv->glyphs16[g>>8] = calloc(256, sizeof(CharInfoRec)); p = &page[g&0xff]; if (p->bits) { *out = p; return p->bits != GLYPH_INVALID; } font->get_glyphs(font, 1, (unsigned char *)&g, FONTLASTROW(font) ? TwoD16Bit : Linear16Bit, &n, &ret); if (n == 0) { p->bits = GLYPH_INVALID; return false; } return sna_set_glyph(ret, *out = p); } static inline bool sna_font_too_large(FontPtr font) { int top = max(FONTMAXBOUNDS(font, ascent), FONTASCENT(font)); int bot = max(FONTMAXBOUNDS(font, descent), FONTDESCENT(font)); int width = max(FONTMAXBOUNDS(font, characterWidth), -FONTMINBOUNDS(font, characterWidth)); DBG(("%s? (%d + %d) x %d: %d > 124\n", __FUNCTION__, top, bot, width, (top + bot) * (width + 7)/8)); return (top + bot) * (width + 7)/8 > 124; } static int sna_poly_text8(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars) { struct sna_font *priv = gc->font->devPrivates[sna_font_key]; CharInfoPtr info[255]; ExtentInfoRec extents; RegionRec region; long unsigned i, n; uint32_t fg; for (i = n = 0; i < count; i++) { if (sna_get_glyph8(gc->font, priv, chars[i], &info[n])) n++; } if (n == 0) return x; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + extents.overallLeft; region.extents.y1 = y - extents.overallAscent; region.extents.x2 = x + extents.overallRight; region.extents.y2 = y + extents.overallDescent; translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return x + extents.overallRight; region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return x + extents.overallRight; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_TEXT8) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (!gc_is_solid(gc, &fg)) goto fallback; if (!sna_glyph_blt(drawable, gc, x, y, n, info, ®ion, fg, -1, true)) { fallback: DBG(("%s: fallback\n", __FUNCTION__)); gc->font->get_glyphs(gc->font, count, (unsigned char *)chars, Linear8Bit, &n, info); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_READ | MOVE_WRITE)) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__)); fbPolyGlyphBlt(drawable, gc, x, y, n, info, FONTGLYPHS(gc->font)); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); } RegionUninit(®ion); return x + extents.overallRight; } static int sna_poly_text16(DrawablePtr drawable, GCPtr gc, int x, int y, int count, unsigned short *chars) { struct sna_font *priv = gc->font->devPrivates[sna_font_key]; CharInfoPtr info[255]; ExtentInfoRec extents; RegionRec region; long unsigned i, n; uint32_t fg; for (i = n = 0; i < count; i++) { if (sna_get_glyph16(gc->font, priv, chars[i], &info[n])) n++; } if (n == 0) return x; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + extents.overallLeft; region.extents.y1 = y - extents.overallAscent; region.extents.x2 = x + extents.overallRight; region.extents.y2 = y + extents.overallDescent; translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return x + extents.overallRight; region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return x + extents.overallRight; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_TEXT16) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (!gc_is_solid(gc, &fg)) goto fallback; if (!sna_glyph_blt(drawable, gc, x, y, n, info, ®ion, fg, -1, true)) { fallback: DBG(("%s: fallback\n", __FUNCTION__)); gc->font->get_glyphs(gc->font, count, (unsigned char *)chars, FONTLASTROW(gc->font) ? TwoD16Bit : Linear16Bit, &n, info); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_READ | MOVE_WRITE)) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__)); fbPolyGlyphBlt(drawable, gc, x, y, n, info, FONTGLYPHS(gc->font)); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); } RegionUninit(®ion); return x + extents.overallRight; } static void sna_image_text8(DrawablePtr drawable, GCPtr gc, int x, int y, int count, char *chars) { struct sna_font *priv = gc->font->devPrivates[sna_font_key]; CharInfoPtr info[255]; ExtentInfoRec extents; RegionRec region; long unsigned i, n; for (i = n = 0; i < count; i++) { if (sna_get_glyph8(gc->font, priv, chars[i], &info[n])) n++; } if (n == 0) return; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + MIN(0, extents.overallLeft); region.extents.y1 = y - extents.fontAscent; region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); region.extents.y2 = y + extents.fontDescent; DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", __FUNCTION__, n, count, extents.overallLeft, extents.overallRight, extents.overallWidth, extents.fontAscent, extents.fontDescent, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return; region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_IMAGE_TEXT8) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (!sna_glyph_blt(drawable, gc, x, y, n, info, ®ion, gc->fgPixel, gc->bgPixel, false)) { fallback: DBG(("%s: fallback\n", __FUNCTION__)); gc->font->get_glyphs(gc->font, count, (unsigned char *)chars, Linear8Bit, &n, info); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_WRITE)) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__)); fbImageGlyphBlt(drawable, gc, x, y, n, info, FONTGLYPHS(gc->font)); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); } RegionUninit(®ion); } static void sna_image_text16(DrawablePtr drawable, GCPtr gc, int x, int y, int count, unsigned short *chars) { struct sna_font *priv = gc->font->devPrivates[sna_font_key]; CharInfoPtr info[255]; ExtentInfoRec extents; RegionRec region; long unsigned i, n; for (i = n = 0; i < count; i++) { if (sna_get_glyph16(gc->font, priv, chars[i], &info[n])) n++; } if (n == 0) return; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + MIN(0, extents.overallLeft); region.extents.y1 = y - extents.fontAscent; region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); region.extents.y2 = y + extents.fontDescent; DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", __FUNCTION__, n, count, extents.overallLeft, extents.overallRight, extents.overallWidth, extents.fontAscent, extents.fontDescent, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return; region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (FORCE_FALLBACK) goto fallback; if (!ACCEL_IMAGE_TEXT16) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (!sna_glyph_blt(drawable, gc, x, y, n, info, ®ion, gc->fgPixel, gc->bgPixel, false)) { fallback: DBG(("%s: fallback\n", __FUNCTION__)); gc->font->get_glyphs(gc->font, count, (unsigned char *)chars, FONTLASTROW(gc->font) ? TwoD16Bit : Linear16Bit, &n, info); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_WRITE)) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__)); fbImageGlyphBlt(drawable, gc, x, y, n, info, FONTGLYPHS(gc->font)); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); } RegionUninit(®ion); } /* XXX Damage bypasses the Text interface and so we lose our custom gluphs */ static bool sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc, int _x, int _y, unsigned int _n, CharInfoPtr *_info, pointer _base, struct kgem_bo *bo, struct sna_damage **damage, RegionPtr clip, uint32_t fg, uint32_t bg, bool transparent) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); const BoxRec *extents, *last_extents; uint32_t *b; int16_t dx, dy; uint8_t rop = transparent ? copy_ROP[gc->alu] : ROP_S; uint16_t unwind_batch, unwind_reloc; DBG(("%s: pixmap=%ld, bo=%d, damage=%p, fg=%08x, bg=%08x\n", __FUNCTION__, pixmap->drawable.serialNumber, bo->handle, damage, fg, bg)); if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&sna->kgem, bo)) return false; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) RegionTranslate(clip, dx, dy); _x += drawable->x + dx; _y += drawable->y + dy; extents = region_rects(clip); last_extents = extents + region_num_rects(clip); if (!transparent) { /* emulate miImageGlyphBlt */ if (!sna_blt_fill_boxes(sna, GXcopy, bo, drawable->bitsPerPixel, bg, extents, last_extents - extents)) { RegionTranslate(clip, -dx, -dy); return false; } } kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!kgem_check_batch(&sna->kgem, 20) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc(&sna->kgem, 1)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) { RegionTranslate(clip, -dx, -dy); return false; } _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 1 << 20 | 8; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = bg; b[7] = fg; b[8] = 0; b[9] = 0; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 1 << 20 | 6; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = bg; b[6] = fg; b[7] = 0; sna->kgem.nbatch += 8; } do { CharInfoPtr *info = _info; int x = _x, y = _y, n = _n; do { CharInfoPtr c = *info++; uint8_t *glyph = FONTGLYPHBITS(base, c); int w = GLYPHWIDTHPIXELS(c); int h = GLYPHHEIGHTPIXELS(c); int stride = GLYPHWIDTHBYTESPADDED(c); int w8 = (w + 7) >> 3; int x1, y1, len, i; uint8_t *byte; if (w == 0 || h == 0) goto skip; len = (w8 * h + 7) >> 3 << 1; x1 = x + c->metrics.leftSideBearing; y1 = y - c->metrics.ascent; DBG(("%s glyph: (%d, %d) -> (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__, x,y, x1, y1, w, w8, h, len)); if (x1 >= extents->x2 || y1 >= extents->y2 || x1 + w <= extents->x1 || y1 + h <= extents->y1) { DBG(("%s: glyph is clipped (%d, %d)x(%d,%d) against extents (%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, w, h, extents->x1, extents->y1, extents->x2, extents->y2)); goto skip; } { int clear = 1, j = h; uint8_t *g = glyph; do { i = w8; do { clear = *g++ == 0; } while (clear && --i); g += stride - w8; } while (clear && --j); if (clear) { DBG(("%s: skipping clear glyph for ImageGlyph\n", __FUNCTION__)); goto skip; } } assert(len > 0); if (!kgem_check_batch(&sna->kgem, 3+len)) { _kgem_submit(&sna->kgem); _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); unwind_batch = sna->kgem.nbatch; unwind_reloc = sna->kgem.nreloc; DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_BLT | 1 << 20 | 8; b[1] = bo->pitch; if (bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = bg; b[7] = fg; b[8] = 0; b[9] = 0; sna->kgem.nbatch += 10; } else { b[0] = XY_SETUP_BLT | 1 << 20 | 6; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; b[2] = extents->y1 << 16 | extents->x1; b[3] = extents->y2 << 16 | extents->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = bg; b[6] = fg; b[7] = 0; sna->kgem.nbatch += 8; } } assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3 + len; b[0] = XY_TEXT_IMMEDIATE_BLT | (1 + len); if (bo->tiling && sna->kgem.gen >= 040) b[0] |= BLT_DST_TILED; b[1] = (uint16_t)y1 << 16 | (uint16_t)x1; b[2] = (uint16_t)(y1+h) << 16 | (uint16_t)(x1+w); byte = (uint8_t *)&b[3]; stride -= w8; do { i = w8; do { *byte++ = byte_reverse(*glyph++); } while (--i); glyph += stride; } while (--h); while ((byte - (uint8_t *)&b[3]) & 7) *byte++ = 0; assert((uint32_t *)byte == sna->kgem.batch + sna->kgem.nbatch); if (damage) { BoxRec r; r.x1 = x1; r.y1 = y1; r.x2 = x1 + w; r.y2 = y1 + h; if (box_intersect(&r, extents)) sna_damage_add_box(damage, &r); } skip: x += c->metrics.characterWidth; } while (--n); if (++extents == last_extents) break; if (kgem_check_batch(&sna->kgem, 3 + 5)) { assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; sna->kgem.nbatch += 3; DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); b[0] = XY_SETUP_CLIP; b[1] = extents->y1 << 16 | extents->x1; b[2] = extents->y2 << 16 | extents->x2; } } while (1); if (sna->kgem.nbatch == unwind_batch + (sna->kgem.gen >= 0100 ? 10 : 8)) { sna->kgem.nbatch = unwind_batch; sna->kgem.nreloc = unwind_reloc; if (sna->kgem.nbatch == 0) kgem_bo_undo(&sna->kgem, bo); } assert_pixmap_damage(pixmap); blt_done(sna); return true; } static void sna_image_glyph(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int n, CharInfoPtr *info, pointer base) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); ExtentInfoRec extents; RegionRec region; struct sna_damage **damage; struct kgem_bo *bo; unsigned hint; if (n == 0) return; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + MIN(0, extents.overallLeft); region.extents.y1 = y - extents.fontAscent; region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); region.extents.y2 = y + extents.fontDescent; DBG(("%s: count=%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", __FUNCTION__, n, extents.overallLeft, extents.overallRight, extents.overallWidth, extents.fontAscent, extents.fontDescent, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return; DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_IMAGE_GLYPH) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if (region.data == NULL) hint = IGNORE_DAMAGE | PREFER_GPU; else hint = PREFER_GPU; if ((bo = sna_drawable_use_bo(drawable, hint, ®ion.extents, &damage)) && sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base, bo, damage, ®ion, gc->fgPixel, gc->bgPixel, false)) goto out; fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out_gc; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_WRITE)) goto out_gc; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__)); fbImageGlyphBlt(drawable, gc, x, y, n, info, base); FALLBACK_FLUSH(drawable); sigtrap_put(); } out_gc: sna_gc_move_to_gpu(gc); out: RegionUninit(®ion); } static void sna_poly_glyph(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int n, CharInfoPtr *info, pointer base) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); ExtentInfoRec extents; RegionRec region; struct sna_damage **damage; struct kgem_bo *bo; uint32_t fg; if (n == 0) return; sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + extents.overallLeft; region.extents.y1 = y - extents.overallAscent; region.extents.x2 = x + extents.overallRight; region.extents.y2 = y + extents.overallDescent; translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return; DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; if (FORCE_FALLBACK) goto fallback; if (!ACCEL_POLY_GLYPH) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!PM_IS_SOLID(drawable, gc->planemask)) goto fallback; if (!gc_is_solid(gc, &fg)) goto fallback; if (sna_font_too_large(gc->font)) goto fallback; if ((bo = sna_drawable_use_bo(drawable, PREFER_GPU, ®ion.extents, &damage)) && sna_reversed_glyph_blt(drawable, gc, x, y, n, info, base, bo, damage, ®ion, fg, -1, true)) goto out; fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out_gc; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_READ | MOVE_WRITE)) goto out_gc; if (sigtrap_get() == 0) { DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__)); fbPolyGlyphBlt(drawable, gc, x, y, n, info, base); FALLBACK_FLUSH(drawable); sigtrap_put(); } out_gc: sna_gc_move_to_gpu(gc); out: RegionUninit(®ion); } static bool sna_push_pixels_solid_blt(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, RegionPtr region) { PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_damage **damage; struct kgem_bo *bo; const BoxRec *box; int16_t dx, dy; int n; uint8_t rop = copy_ROP[gc->alu]; bo = sna_drawable_use_bo(drawable, PREFER_GPU, ®ion->extents, &damage); if (bo == NULL) return false; if (bo->tiling == I915_TILING_Y) { DBG(("%s: converting bo from Y-tiling\n", __FUNCTION__)); assert(bo == __sna_pixmap_get_bo(pixmap)); bo = sna_pixmap_change_tiling(pixmap, I915_TILING_X); if (bo == NULL) { DBG(("%s: fallback -- unable to change tiling\n", __FUNCTION__)); return false; } } if (!kgem_bo_can_blt(&sna->kgem, bo)) return false; if (get_drawable_deltas(drawable, pixmap, &dx, &dy)) RegionTranslate(region, dx, dy); assert_pixmap_contains_box(pixmap, RegionExtents(region)); if (damage) sna_damage_add_to_pixmap(damage, region, pixmap); assert_pixmap_damage(pixmap); DBG(("%s: upload(%d, %d, %d, %d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); kgem_set_mode(&sna->kgem, KGEM_BLT, bo); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); /* Region is pre-clipped and translated into pixmap space */ box = region_rects(region); n = region_num_rects(region); do { int bx1 = (box->x1 - region->extents.x1) & ~7; int bx2 = (box->x2 - region->extents.x1 + 7) & ~7; int bw = (bx2 - bx1)/8; int bh = box->y2 - box->y1; int bstride = ALIGN(bw, 2); struct kgem_bo *upload; void *ptr; if (!kgem_check_batch(&sna->kgem, 10) || !kgem_check_bo_fenced(&sna->kgem, bo) || !kgem_check_reloc_and_exec(&sna->kgem, 2)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); upload = kgem_create_buffer(&sna->kgem, bstride*bh, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!upload) break; if (sigtrap_get() == 0) { uint8_t *dst = ptr; int src_stride = bitmap->devKind; uint8_t *src; uint32_t *b; assert(src_stride); src = (uint8_t*)bitmap->devPrivate.ptr; src += (box->y1 - region->extents.y1) * src_stride + bx1/8; src_stride -= bstride; do { int i = bstride; do { *dst++ = byte_reverse(*src++); *dst++ = byte_reverse(*src++); i -= 2; } while (i); src += src_stride; } while (--bh); assert(sna->kgem.mode == KGEM_BLT); b = sna->kgem.batch + sna->kgem.nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_MONO_SRC_COPY | 3 << 20 | 8; b[0] |= ((box->x1 - region->extents.x1) & 7) << 17; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 29; b[1] |= blt_depth(drawable->depth) << 24; b[1] |= rop << 16; b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; *(uint64_t *)(b+4) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); *(uint64_t *)(b+6) = kgem_add_reloc64(&sna->kgem, sna->kgem.nbatch + 6, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = gc->bgPixel; b[9] = gc->fgPixel; sna->kgem.nbatch += 10; } else { b[0] = XY_MONO_SRC_COPY | 3 << 20 | 6; b[0] |= ((box->x1 - region->extents.x1) & 7) << 17; b[1] = bo->pitch; if (sna->kgem.gen >= 040 && bo->tiling) { b[0] |= BLT_DST_TILED; b[1] >>= 2; } b[1] |= 1 << 29; b[1] |= blt_depth(drawable->depth) << 24; b[1] |= rop << 16; b[2] = box->y1 << 16 | box->x1; b[3] = box->y2 << 16 | box->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 5, upload, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[6] = gc->bgPixel; b[7] = gc->fgPixel; sna->kgem.nbatch += 8; } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, upload); box++; } while (--n); blt_done(sna); return true; } static void sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, int w, int h, int x, int y) { RegionRec region; if (w == 0 || h == 0) return; DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); region.extents.x1 = x; region.extents.y1 = y; region.extents.x2 = region.extents.x1 + w; region.extents.y2 = region.extents.y1 + h; clip_box(®ion.extents, gc); if (box_empty(®ion.extents)) return; DBG(("%s: extents(%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!region_maybe_clip(®ion, gc->pCompositeClip)) return; switch (gc->fillStyle) { case FillSolid: if (sna_push_pixels_solid_blt(gc, bitmap, drawable, ®ion)) return; break; default: break; } DBG(("%s: fallback\n", __FUNCTION__)); if (!sna_gc_move_to_cpu(gc, drawable, ®ion)) goto out; if (!sna_pixmap_move_to_cpu(bitmap, MOVE_READ)) goto out; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, drawable_gc_flags(drawable, gc, false))) goto out; if (sigtrap_get() == 0) { DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n", __FUNCTION__, w, h, x, y)); fbPushPixels(gc, bitmap, drawable, w, h, x, y); FALLBACK_FLUSH(drawable); sigtrap_put(); } out: sna_gc_move_to_gpu(gc); RegionUninit(®ion); } static const GCOps sna_gc_ops = { sna_fill_spans, sna_set_spans, sna_put_image, sna_copy_area, sna_copy_plane, sna_poly_point, sna_poly_line, sna_poly_segment, sna_poly_rectangle, sna_poly_arc, sna_poly_fill_polygon, sna_poly_fill_rect, sna_poly_fill_arc, sna_poly_text8, sna_poly_text16, sna_image_text8, sna_image_text16, sna_image_glyph, sna_poly_glyph, sna_push_pixels, }; static const GCOps sna_gc_ops__cpu = { fbFillSpans, fbSetSpans, fbPutImage, fbCopyArea, fbCopyPlane, sna_poly_point__cpu, fbPolyLine, fbPolySegment, miPolyRectangle, fbPolyArc, miFillPolygon, fbPolyFillRect, miPolyFillArc, miPolyText8, miPolyText16, miImageText8, miImageText16, fbImageGlyphBlt, fbPolyGlyphBlt, fbPushPixels }; static GCOps sna_gc_ops__tmp = { sna_fill_spans, sna_set_spans, sna_put_image, sna_copy_area, sna_copy_plane, sna_poly_point, sna_poly_line, sna_poly_segment, sna_poly_rectangle, sna_poly_arc, sna_poly_fill_polygon, sna_poly_fill_rect, sna_poly_fill_arc, sna_poly_text8, sna_poly_text16, sna_image_text8, sna_image_text16, sna_image_glyph, sna_poly_glyph, sna_push_pixels, }; static void sna_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { DBG(("%s(%p) changes=%lx, previous serial=%lx, drawable=%lx\n", __FUNCTION__, gc, changes, gc->serialNumber, drawable->serialNumber)); if (changes & (GCClipMask|GCSubwindowMode) || drawable->serialNumber != (gc->serialNumber & DRAWABLE_SERIAL_BITS) || (has_clip(gc) && (changes & (GCClipXOrigin | GCClipYOrigin)))) { DBG(("%s: recomputing clip\n", __FUNCTION__)); miComputeCompositeClip(gc, drawable); DBG(("%s: composite clip=%dx[(%d, %d), (%d, %d)] [%p]\n", __FUNCTION__, region_num_rects(gc->pCompositeClip), gc->pCompositeClip->extents.x1, gc->pCompositeClip->extents.y1, gc->pCompositeClip->extents.x2, gc->pCompositeClip->extents.y2, gc->pCompositeClip)); } assert(gc->pCompositeClip); assert(RegionNil(gc->pCompositeClip) || gc->pCompositeClip->extents.x1 >= drawable->x); assert(RegionNil(gc->pCompositeClip) || gc->pCompositeClip->extents.y1 >= drawable->y); assert(RegionNil(gc->pCompositeClip) || gc->pCompositeClip->extents.x2 - drawable->x <= drawable->width); assert(RegionNil(gc->pCompositeClip) || gc->pCompositeClip->extents.y2 - drawable->y <= drawable->height); sna_gc(gc)->changes |= changes; sna_gc(gc)->serial = gc->serialNumber; } static const GCFuncs sna_gc_funcs = { sna_validate_gc, miChangeGC, miCopyGC, miDestroyGC, miChangeClip, miDestroyClip, miCopyClip }; static const GCFuncs sna_gc_funcs__cpu = { fbValidateGC, miChangeGC, miCopyGC, miDestroyGC, miChangeClip, miDestroyClip, miCopyClip }; static int sna_create_gc(GCPtr gc) { gc->miTranslate = 1; gc->fExpose = 1; gc->freeCompClip = 0; gc->pCompositeClip = 0; gc->pRotatedPixmap = 0; fb_gc(gc)->bpp = bits_per_pixel(gc->depth); gc->funcs = (GCFuncs *)&sna_gc_funcs; gc->ops = (GCOps *)&sna_gc_ops; return true; } static bool sna_get_image__inplace(PixmapPtr pixmap, RegionPtr region, char *dst, unsigned flags, bool idle) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna *sna = to_sna_from_pixmap(pixmap); char *src; if (!USE_INPLACE) return false; assert(priv && priv->gpu_bo); switch (priv->gpu_bo->tiling) { case I915_TILING_Y: return false; case I915_TILING_X: if (!sna->kgem.memcpy_from_tiled_x) return false; default: break; } if ((flags & MOVE_INPLACE_HINT) == 0 && !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC)) return false; if (idle && __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) return false; if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ)) return false; assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT); if (kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC)) { src = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo); if (src == NULL) return false; kgem_bo_sync__cpu_full(&sna->kgem, priv->gpu_bo, FORCE_FULL_SYNC); } else { src = kgem_bo_map__wc(&sna->kgem, priv->gpu_bo); if (src == NULL) return false; kgem_bo_sync__gtt(&sna->kgem, priv->gpu_bo); } if (sigtrap_get()) return false; if (priv->gpu_bo->tiling) { DBG(("%s: download through a tiled CPU map\n", __FUNCTION__)); memcpy_from_tiled_x(&sna->kgem, src, dst, pixmap->drawable.bitsPerPixel, priv->gpu_bo->pitch, PixmapBytePad(region->extents.x2 - region->extents.x1, pixmap->drawable.depth), region->extents.x1, region->extents.y1, 0, 0, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1); } else { DBG(("%s: download through a linear CPU map\n", __FUNCTION__)); memcpy_blt(src, dst, pixmap->drawable.bitsPerPixel, priv->gpu_bo->pitch, PixmapBytePad(region->extents.x2 - region->extents.x1, pixmap->drawable.depth), region->extents.x1, region->extents.y1, 0, 0, region->extents.x2 - region->extents.x1, region->extents.y2 - region->extents.y1); if (!priv->shm) { pixmap->devPrivate.ptr = src; pixmap->devKind = priv->gpu_bo->pitch; priv->mapped = src == MAP(priv->gpu_bo->map__cpu) ? MAPPED_CPU : MAPPED_GTT; assert_pixmap_map(pixmap, priv); priv->cpu &= priv->mapped == MAPPED_CPU; } } sigtrap_put(); return true; } static bool sna_get_image__blt(PixmapPtr pixmap, RegionPtr region, char *dst, unsigned flags) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna *sna = to_sna_from_pixmap(pixmap); struct kgem_bo *dst_bo; bool ok = false; int pitch; assert(priv && priv->gpu_bo); if (!sna->kgem.has_userptr || !USE_USERPTR_DOWNLOADS) return false; if (!sna->kgem.can_blt_cpu) return false; if ((priv->create & (KGEM_CAN_CREATE_GTT | KGEM_CAN_CREATE_LARGE)) == KGEM_CAN_CREATE_GTT && kgem_bo_can_map(&sna->kgem, priv->gpu_bo)) { if (flags & (MOVE_WHOLE_HINT | MOVE_INPLACE_HINT)) return false; if (priv->gpu_damage == NULL) return false; assert(priv->gpu_bo); if (!__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) return false; } else { if (priv->gpu_damage == NULL) return false; assert(priv->gpu_bo); } if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ)) return false; DBG(("%s: download through a temporary map\n", __FUNCTION__)); assert(sna_damage_contains_box(&priv->gpu_damage, ®ion->extents) == PIXMAN_REGION_IN); assert(sna_damage_contains_box(&priv->cpu_damage, ®ion->extents) == PIXMAN_REGION_OUT); pitch = PixmapBytePad(region->extents.x2 - region->extents.x1, pixmap->drawable.depth); dst_bo = kgem_create_map(&sna->kgem, dst, pitch * (region->extents.y2 - region->extents.y1), false); if (dst_bo) { dst_bo->pitch = pitch; kgem_bo_mark_unreusable(dst_bo); ok = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, dst_bo, -region->extents.x1, -region->extents.y1, ®ion->extents, 1, COPY_LAST); kgem_bo_sync__cpu(&sna->kgem, dst_bo); assert(dst_bo->rq == NULL); kgem_bo_destroy(&sna->kgem, dst_bo); } return ok; } static bool sna_get_image__fast(PixmapPtr pixmap, RegionPtr region, char *dst, unsigned flags) { struct sna_pixmap *priv = sna_pixmap(pixmap); DBG(("%s: attached?=%d, has gpu damage?=%d\n", __FUNCTION__, priv != NULL, priv && priv->gpu_damage)); if (priv == NULL || priv->gpu_damage == NULL) return false; if (priv->clear && sigtrap_get() == 0) { int w = region->extents.x2 - region->extents.x1; int h = region->extents.y2 - region->extents.y1; int pitch = PixmapBytePad(w, pixmap->drawable.depth); DBG(("%s: applying clear [%08x]\n", __FUNCTION__, priv->clear_color)); assert(DAMAGE_IS_ALL(priv->gpu_damage)); assert(priv->cpu_damage == NULL); sigtrap_assert_active(); if (priv->clear_color == 0 || pixmap->drawable.bitsPerPixel == 8 || priv->clear_color == (1U << pixmap->drawable.depth) - 1) { DBG(("%s: memset clear [%02x]\n", __FUNCTION__, priv->clear_color & 0xff)); memset(dst, priv->clear_color, pitch * h); } else { pixman_fill((uint32_t *)dst, pitch/sizeof(uint32_t), pixmap->drawable.bitsPerPixel, 0, 0, w, h, priv->clear_color); } sigtrap_put(); return true; } if (!DAMAGE_IS_ALL(priv->gpu_damage) && !sna_damage_contains_box__no_reduce(priv->gpu_damage, ®ion->extents)) return false; if (sna_get_image__inplace(pixmap, region, dst, flags, true)) return true; if (sna_get_image__blt(pixmap, region, dst, flags)) return true; if (sna_get_image__inplace(pixmap, region, dst, flags, false)) return true; return false; } static void sna_get_image(DrawablePtr drawable, int x, int y, int w, int h, unsigned int format, unsigned long mask, char *dst) { RegionRec region; unsigned int flags; if (!fbDrawableEnabled(drawable)) return; DBG(("%s: pixmap=%ld (%d, %d)x(%d, %d), format=%d, mask=%lx, depth=%d\n", __FUNCTION__, (long)get_drawable_pixmap(drawable)->drawable.serialNumber, x, y, w, h, format, mask, drawable->depth)); flags = MOVE_READ; if ((w | h) == 1) flags |= MOVE_INPLACE_HINT; if (w == drawable->width) flags |= MOVE_WHOLE_HINT; if (ACCEL_GET_IMAGE && !FORCE_FALLBACK && format == ZPixmap && drawable->bitsPerPixel >= 8 && PM_IS_SOLID(drawable, mask)) { PixmapPtr pixmap = get_drawable_pixmap(drawable); int16_t dx, dy; get_drawable_deltas(drawable, pixmap, &dx, &dy); region.extents.x1 = x + drawable->x + dx; region.extents.y1 = y + drawable->y + dy; region.extents.x2 = region.extents.x1 + w; region.extents.y2 = region.extents.y1 + h; region.data = NULL; if (sna_get_image__fast(pixmap, ®ion, dst, flags)) return; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, flags)) return; DBG(("%s: copy box (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); assert(has_coherent_ptr(to_sna_from_pixmap(pixmap), sna_pixmap(pixmap), MOVE_READ)); if (sigtrap_get() == 0) { assert(pixmap->devKind); memcpy_blt(pixmap->devPrivate.ptr, dst, drawable->bitsPerPixel, pixmap->devKind, PixmapBytePad(w, drawable->depth), region.extents.x1, region.extents.y1, 0, 0, w, h); sigtrap_put(); } } else { region.extents.x1 = x + drawable->x; region.extents.y1 = y + drawable->y; region.extents.x2 = region.extents.x1 + w; region.extents.y2 = region.extents.y1 + h; region.data = NULL; if (sna_drawable_move_region_to_cpu(drawable, ®ion, flags)) fbGetImage(drawable, x, y, w, h, format, mask, dst); } } static void sna_get_spans(DrawablePtr drawable, int wMax, DDXPointPtr pt, int *width, int n, char *start) { RegionRec region; if (!fbDrawableEnabled(drawable)) return; if (sna_spans_extents(drawable, NULL, n, pt, width, ®ion.extents) == 0) return; region.data = NULL; if (!sna_drawable_move_region_to_cpu(drawable, ®ion, MOVE_READ)) return; fbGetSpans(drawable, wMax, pt, width, n, start); } static void sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src) { PixmapPtr pixmap = get_window_pixmap(win); struct sna *sna = to_sna_from_pixmap(pixmap); RegionRec dst; int dx, dy; DBG(("%s origin=(%d, %d)\n", __FUNCTION__, origin.x, origin.y)); if (!fbWindowEnabled(win)) return; dx = origin.x - win->drawable.x; dy = origin.y - win->drawable.y; RegionTranslate(src, -dx, -dy); RegionNull(&dst); RegionIntersect(&dst, &win->borderClip, src); if (box_empty(&dst.extents)) return; #ifdef COMPOSITE if (pixmap->screen_x | pixmap->screen_y) RegionTranslate(&dst, -pixmap->screen_x, -pixmap->screen_y); #endif if (wedged(sna) || FORCE_FALLBACK || !ACCEL_COPY_WINDOW) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE)) return; if (sigtrap_get() == 0) { miCopyRegion(&pixmap->drawable, &pixmap->drawable, 0, &dst, dx, dy, fbCopyNtoN, 0, NULL); sigtrap_put(); } } else { sna_self_copy_boxes(&pixmap->drawable, &pixmap->drawable, NULL, &dst, dx, dy, 0, NULL); } RegionUninit(&dst); } static Bool sna_change_window_attributes(WindowPtr win, unsigned long mask) { bool ret = true; DBG(("%s\n", __FUNCTION__)); /* Check if the fb layer wishes to modify the attached pixmaps, * to fix up mismatches between the window and pixmap depths. */ if (mask & CWBackPixmap && win->backgroundState == BackgroundPixmap) { DBG(("%s: flushing background pixmap\n", __FUNCTION__)); ret &= sna_validate_pixmap(&win->drawable, win->background.pixmap); } if (mask & CWBorderPixmap && win->borderIsPixel == false) { DBG(("%s: flushing border pixmap\n", __FUNCTION__)); ret &= sna_validate_pixmap(&win->drawable, win->border.pixmap); } return ret; } void sna_accel_flush(struct sna *sna) { struct sna_pixmap *priv; /* XXX we should be able to reduce the frequency of flushes further * by checking for outgoing damage events or sync replies. Tricky, * and doesn't appear to mitigate the performance loss. */ DBG(("%s: flush?=%d, dirty?=%d\n", __FUNCTION__, sna->kgem.flush, !list_is_empty(&sna->flush_pixmaps))); /* flush any pending damage from shadow copies to tfp clients */ while (!list_is_empty(&sna->flush_pixmaps)) { bool ret; priv = list_first_entry(&sna->flush_pixmaps, struct sna_pixmap, flush_list); list_del(&priv->flush_list); if (priv->shm) { DBG(("%s: syncing SHM pixmap=%ld (refcnt=%d)\n", __FUNCTION__, priv->pixmap->drawable.serialNumber, priv->pixmap->refcnt)); assert(!priv->flush); ret = sna_pixmap_move_to_cpu(priv->pixmap, MOVE_READ | MOVE_WRITE); assert(!ret || priv->gpu_bo == NULL); if (priv->pixmap->refcnt == 0) { sna_damage_destroy(&priv->cpu_damage); __sna_free_pixmap(sna, priv->pixmap, priv); } } else { unsigned hints; DBG(("%s: flushing DRI pixmap=%ld\n", __FUNCTION__, priv->pixmap->drawable.serialNumber)); assert(priv->flush); hints = MOVE_READ | __MOVE_FORCE; if (priv->flush & FLUSH_WRITE) hints |= MOVE_WRITE; if (sna_pixmap_move_to_gpu(priv->pixmap, hints)) { if (priv->flush & FLUSH_WRITE) { kgem_bo_unclean(&sna->kgem, priv->gpu_bo); sna_damage_all(&priv->gpu_damage, priv->pixmap); assert(priv->cpu_damage == NULL); assert(priv->clear == false); } } } (void)ret; } if (sna->kgem.flush) kgem_submit(&sna->kgem); } static void sna_accel_flush_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { sna_accel_flush(user_data); } static struct sna_pixmap *sna_accel_scanout(struct sna *sna) { struct sna_pixmap *priv; if (sna->mode.front_active == 0) return NULL; assert(sna->vblank_interval); assert(sna->front); assert(!sna->mode.hidden); priv = sna_pixmap(sna->front); if (priv->gpu_bo == NULL) return NULL; return priv; } #define TIME currentTime.milliseconds static void sna_accel_disarm_timer(struct sna *sna, int id) { DBG(("%s[%d] (time=%ld)\n", __FUNCTION__, id, (long)TIME)); sna->timer_active &= ~(1<pixmap_dirty_list, ent) { assert(dirty->src == sna->front); if (RegionNotEmpty(DamageRegion(dirty->damage))) return true; } #endif return false; } static bool has_shadow(struct sna *sna) { DamagePtr damage; if (!sna->mode.shadow_enabled) return false; damage = sna->mode.shadow_damage; assert(damage); DBG(("%s: has pending damage? %d, outstanding flips: %d\n", __FUNCTION__, RegionNotEmpty(DamageRegion(damage)), sna->mode.flip_active)); return RegionNotEmpty(DamageRegion(damage)); } static bool start_flush(struct sna *sna) { struct sna_pixmap *scanout; if (has_offload_slaves(sna)) { DBG(("%s: has offload slaves\n", __FUNCTION__)); return true; } if (has_shadow(sna)) { DBG(("%s: has dirty shadow\n", __FUNCTION__)); return true; } scanout = sna_accel_scanout(sna); if (!scanout) return false; if (sna->flags & SNA_FLUSH_GTT && scanout->gpu_bo->gtt_dirty) { scanout->gpu_bo->needs_flush = true; return true; } if (scanout->cpu_damage || scanout->gpu_bo->needs_flush) return true; kgem_scanout_flush(&sna->kgem, scanout->gpu_bo); return false; } static bool stop_flush(struct sna *sna, struct sna_pixmap *scanout) { DBG(("%s: scanout=%d shadow?=%d, slaves?=%d, (cpu?=%d || gpu?=%d))\n", __FUNCTION__, scanout && scanout->gpu_bo ? scanout->gpu_bo->handle : 0, has_shadow(sna), has_offload_slaves(sna), scanout && scanout->cpu_damage != NULL, scanout && scanout->gpu_bo && scanout->gpu_bo->rq != NULL)); if (has_offload_slaves(sna)) return true; if (has_shadow(sna)) return true; if (!scanout) return false; if (sna->flags & SNA_FLUSH_GTT && scanout->gpu_bo->gtt_dirty) { scanout->gpu_bo->needs_flush = true; return true; } return scanout->cpu_damage || scanout->gpu_bo->needs_flush; } static void timer_enable(struct sna *sna, int whom, int interval) { if (!sna->timer_active) UpdateCurrentTimeIf(); sna->timer_active |= 1 << whom; sna->timer_expire[whom] = TIME + interval; DBG(("%s (time=%ld), starting timer %d\n", __FUNCTION__, (long)TIME, whom)); } static bool sna_scanout_do_flush(struct sna *sna) { int interval = sna->vblank_interval ?: 50; if (sna->timer_active & (1<<(FLUSH_TIMER))) { int32_t delta = sna->timer_expire[FLUSH_TIMER] - TIME; DBG(("%s: flush timer active: delta=%d\n", __FUNCTION__, delta)); if (delta <= 3) { DBG(("%s (time=%ld), triggered\n", __FUNCTION__, (long)TIME)); sna->timer_expire[FLUSH_TIMER] = TIME + interval; return true; } } else { if (start_flush(sna)) timer_enable(sna, FLUSH_TIMER, interval/2); } return false; } static bool sna_accel_do_throttle(struct sna *sna) { if (sna->timer_active & (1<<(THROTTLE_TIMER))) { int32_t delta = sna->timer_expire[THROTTLE_TIMER] - TIME; if (delta <= 3) { DBG(("%s (time=%ld), triggered\n", __FUNCTION__, (long)TIME)); sna->timer_expire[THROTTLE_TIMER] = TIME + 20; return true; } } else if (!sna->kgem.need_retire) { DBG(("%s -- no pending activity\n", __FUNCTION__)); } else timer_enable(sna, THROTTLE_TIMER, 20); return false; } static bool sna_accel_do_expire(struct sna *sna) { if (sna->timer_active & (1<<(EXPIRE_TIMER))) { int32_t delta = sna->timer_expire[EXPIRE_TIMER] - TIME; if (delta <= 3) { DBG(("%s (time=%ld), triggered\n", __FUNCTION__, (long)TIME)); sna->timer_expire[EXPIRE_TIMER] = TIME + MAX_INACTIVE_TIME * 1000; return true; } } else if (sna->kgem.need_expire) timer_enable(sna, EXPIRE_TIMER, MAX_INACTIVE_TIME * 1000); return false; } static void sna_accel_post_damage(struct sna *sna) { #if HAS_PIXMAP_SHARING ScreenPtr screen = to_screen_from_sna(sna); PixmapDirtyUpdatePtr dirty; xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { RegionRec region, *damage; PixmapPtr src, dst; const BoxRec *box; int16_t dx, dy; int n; assert(dirty->src == sna->front); damage = DamageRegion(dirty->damage); if (RegionNil(damage)) continue; src = dirty->src; dst = dirty->slave_dst->master_pixmap; region.extents.x1 = dirty->x; region.extents.x2 = dirty->x + dst->drawable.width; region.extents.y1 = dirty->y; region.extents.y2 = dirty->y + dst->drawable.height; region.data = NULL; DBG(("%s: pushing damage ((%d, %d), (%d, %d))x%d to slave pixmap=%d, ((%d, %d), (%d, %d))\n", __FUNCTION__, damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2, region_num_rects(damage), dst->drawable.serialNumber, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); RegionIntersect(®ion, ®ion, damage); if (RegionNil(®ion)) goto skip; dx = -dirty->x; dy = -dirty->y; #if HAS_DIRTYTRACKING2 dx += dirty->dst_x; dy += dirty->dst_y; #endif RegionTranslate(®ion, dx, dy); DamageRegionAppend(&dirty->slave_dst->drawable, ®ion); DBG(("%s: slave: ((%d, %d), (%d, %d))x%d\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, region_num_rects(®ion))); box = region_rects(®ion); n = region_num_rects(®ion); if (wedged(sna)) { fallback: if (!sna_pixmap_move_to_cpu(src, MOVE_READ)) goto skip; if (!sna_pixmap_move_to_cpu(dst, MOVE_READ | MOVE_WRITE | MOVE_INPLACE_HINT)) goto skip; if (sigtrap_get() == 0) { assert(src->drawable.bitsPerPixel == dst->drawable.bitsPerPixel); do { DBG(("%s: copy box (%d, %d)->(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1 - dx, box->y1 - dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 - dx >= 0); assert(box->y1 - dy >= 0); assert(box->x2 - dx <= src->drawable.width); assert(box->y2 - dy <= src->drawable.height); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= src->drawable.width); assert(box->y2 <= src->drawable.height); assert(has_coherent_ptr(sna, sna_pixmap(src), MOVE_READ)); assert(has_coherent_ptr(sna, sna_pixmap(dst), MOVE_WRITE)); assert(src->devKind); assert(dst->devKind); memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, box->x1 - dx, box->y1 - dy, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); } } else { if (!sna_pixmap_move_to_gpu(src, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_FORCE)) goto fallback; if (!sna_pixmap_move_to_gpu(dst, MOVE_READ | MOVE_WRITE | MOVE_ASYNC_HINT | __MOVE_FORCE)) goto fallback; if (!sna->render.copy_boxes(sna, GXcopy, &src->drawable, __sna_pixmap_get_bo(src), -dx, -dy, &dst->drawable, __sna_pixmap_get_bo(dst), 0, 0, box, n, COPY_LAST)) goto fallback; /* Before signalling the slave via ProcessPending, * ensure not only the batch is submitted as the * slave may be using the Damage callback to perform * its copy, but also that the memory must be coherent * - we need to treat it as uncached for the PCI slave * will bypass LLC. */ kgem_bo_sync__gtt(&sna->kgem, __sna_pixmap_get_bo(dst)); } DamageRegionProcessPending(&dirty->slave_dst->drawable); skip: RegionUninit(®ion); DamageEmpty(dirty->damage); } #endif } static void sna_scanout_flush(struct sna *sna) { struct sna_pixmap *priv = sna_accel_scanout(sna); bool busy; DBG(("%s (time=%ld), cpu damage? %d, exec? %d nbatch=%d, busy? %d\n", __FUNCTION__, (long)TIME, priv && priv->cpu_damage, priv && priv->gpu_bo->exec != NULL, sna->kgem.nbatch, sna->kgem.busy)); busy = stop_flush(sna, priv); if (!sna->kgem.busy && !busy) sna_accel_disarm_timer(sna, FLUSH_TIMER); sna->kgem.busy = busy; if (priv && sna->mode.shadow_damage == NULL && sna_pixmap_force_to_gpu(priv->pixmap, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT)) kgem_scanout_flush(&sna->kgem, priv->gpu_bo); sna_mode_redisplay(sna); sna_accel_post_damage(sna); } static void sna_accel_throttle(struct sna *sna) { DBG(("%s (time=%ld)\n", __FUNCTION__, (long)TIME)); if (sna->kgem.need_throttle) { kgem_submit(&sna->kgem); kgem_throttle(&sna->kgem); } if (!sna->kgem.need_retire) sna_accel_disarm_timer(sna, THROTTLE_TIMER); } static void sna_pixmap_expire(struct sna *sna) { while (sna->freed_pixmap) { PixmapPtr pixmap = __pop_freed_pixmap(sna); free(sna_pixmap(pixmap)); FreePixmap(pixmap); } } static void sna_accel_expire(struct sna *sna) { DBG(("%s (time=%ld)\n", __FUNCTION__, (long)TIME)); kgem_expire_cache(&sna->kgem); sna_pixmap_expire(sna); if (!sna->kgem.need_expire) sna_accel_disarm_timer(sna, EXPIRE_TIMER); } #ifdef DEBUG_MEMORY static bool sna_accel_do_debug_memory(struct sna *sna) { int32_t delta = sna->timer_expire[DEBUG_MEMORY_TIMER] - TIME; if (delta <= 3) { sna->timer_expire[DEBUG_MEMORY_TIMER] = TIME + 10 * 1000; return true; } else return false; } static void sna_accel_debug_memory(struct sna *sna) { ErrorF("Allocated pixmaps: %d (cached: %d), bo: %d, %lu bytes (CPU bo: %d, %lu bytes)\n", sna->debug_memory.pixmap_allocs, sna->debug_memory.pixmap_cached, sna->kgem.debug_memory.bo_allocs, (unsigned long)sna->kgem.debug_memory.bo_bytes, sna->debug_memory.cpu_bo_allocs, (unsigned long)sna->debug_memory.cpu_bo_bytes); #ifdef VALGRIND_DO_ADDED_LEAK_CHECK VG(VALGRIND_DO_ADDED_LEAK_CHECK); #endif } #else #define sna_accel_do_debug_memory(x) 0 static void sna_accel_debug_memory(struct sna *sna) { } #endif static ShmFuncs shm_funcs = { sna_pixmap_create_shm, NULL }; static PixmapPtr sna_get_window_pixmap(WindowPtr window) { return get_window_pixmap(window); } static void sna_set_window_pixmap(WindowPtr window, PixmapPtr pixmap) { DBG(("%s: window=%ld, old pixmap=%ld new pixmap=%ld\n", __FUNCTION__, window->drawable.id, get_window_pixmap(window) ? get_window_pixmap(window)->drawable.serialNumber : 0, pixmap->drawable.serialNumber)); sna_dri2_decouple_window(window); *(PixmapPtr *)__get_private(window, sna_window_key) = pixmap; } struct sna_visit_set_pixmap_window { PixmapPtr old, new; }; static int sna_visit_set_window_pixmap(WindowPtr window, pointer data) { struct sna_visit_set_pixmap_window *visit = data; if (sna_get_window_pixmap(window) == visit->old) { window->drawable.pScreen->SetWindowPixmap(window, visit->new); return WT_WALKCHILDREN; } return WT_DONTWALKCHILDREN; } static void migrate_dirty_tracking(PixmapPtr old_front, PixmapPtr new_front) { #if HAS_PIXMAP_SHARING ScreenPtr screen = old_front->drawable.pScreen; PixmapDirtyUpdatePtr dirty, safe; xorg_list_for_each_entry_safe(dirty, safe, &screen->pixmap_dirty_list, ent) { assert(dirty->src == old_front); if (dirty->src != old_front) continue; DamageUnregister(&dirty->src->drawable, dirty->damage); DamageDestroy(dirty->damage); dirty->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, screen, screen); if (!dirty->damage) { xorg_list_del(&dirty->ent); free(dirty); continue; } DamageRegister(&new_front->drawable, dirty->damage); dirty->src = new_front; } #endif } static void sna_set_screen_pixmap(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; PixmapPtr old_front = screen->devPrivate; WindowPtr root; DBG(("%s: changing from pixmap=%ld to pixmap=%ld, (sna->front=%ld)\n", __FUNCTION__, old_front ? (long)old_front->drawable.serialNumber : 0, pixmap ? (long)pixmap->drawable.serialNumber : 0, to_sna_from_pixmap(pixmap)->front ? (long)to_sna_from_pixmap(pixmap)->front->drawable.serialNumber : 0)); assert(to_sna_from_pixmap(pixmap) == to_sna_from_screen(screen)); assert(to_sna_from_pixmap(pixmap)->front == old_front); if (old_front) { assert(to_sna_from_pixmap(old_front)->front == old_front); migrate_dirty_tracking(old_front, pixmap); } root = get_root_window(screen); if (root) { struct sna_visit_set_pixmap_window visit = { old_front, pixmap }; TraverseTree(root, sna_visit_set_window_pixmap, &visit); assert(fbGetWindowPixmap(root) == pixmap); } to_sna_from_pixmap(pixmap)->front = pixmap; screen->devPrivate = pixmap; pixmap->refcnt++; if (old_front) screen->DestroyPixmap(old_front); } static Bool sna_create_window(WindowPtr win) { DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); sna_set_window_pixmap(win, win->drawable.pScreen->devPrivate); return TRUE; } static Bool sna_map_window(WindowPtr win) { return TRUE; } static Bool sna_position_window(WindowPtr win, int x, int y) { return TRUE; } static Bool sna_unmap_window(WindowPtr win) { return TRUE; } static Bool sna_destroy_window(WindowPtr win) { DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); sna_video_destroy_window(win); sna_dri2_destroy_window(win); return TRUE; } static void sna_query_best_size(int class, unsigned short *width, unsigned short *height, ScreenPtr screen) { unsigned short w; switch (class) { case CursorShape: if (*width > screen->width) *width = screen->width; if (*height > screen->height) *height = screen->height; break; case TileShape: case StippleShape: w = *width; if ((w & (w - 1)) && w < FB_UNIT) { for (w = 1; w < *width; w <<= 1) ; *width = w; } break; } } static void sna_store_colors(ColormapPtr cmap, int n, xColorItem *def) { } static bool sna_picture_init(ScreenPtr screen) { PictureScreenPtr ps; DBG(("%s\n", __FUNCTION__)); if (!miPictureInit(screen, NULL, 0)) return false; ps = GetPictureScreen(screen); assert(ps != NULL); assert(ps->CreatePicture != NULL); assert(ps->DestroyPicture != NULL); ps->Composite = sna_composite; ps->CompositeRects = sna_composite_rectangles; ps->Glyphs = sna_glyphs; if (xf86IsEntityShared(xf86ScreenToScrn(screen)->entityList[0])) ps->Glyphs = sna_glyphs__shared; ps->UnrealizeGlyph = sna_glyph_unrealize; ps->AddTraps = sna_add_traps; ps->Trapezoids = sna_composite_trapezoids; #if HAS_PIXMAN_TRIANGLES ps->Triangles = sna_composite_triangles; #if PICTURE_SCREEN_VERSION >= 2 ps->TriStrip = sna_composite_tristrip; ps->TriFan = sna_composite_trifan; #endif #endif return true; } static bool sna_option_accel_none(struct sna *sna) { const char *s; if (wedged(sna)) return true; if (!xf86ReturnOptValBool(sna->Options, OPTION_ACCEL_ENABLE, TRUE)) return true; if (sna->kgem.gen >= 0120) return true; if (!intel_option_cast_to_bool(sna->Options, OPTION_ACCEL_METHOD, !IS_DEFAULT_ACCEL_METHOD(NOACCEL))) return false; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) s = xf86GetOptValString(sna->Options, OPTION_ACCEL_METHOD); if (s == NULL) return IS_DEFAULT_ACCEL_METHOD(NOACCEL); return strcasecmp(s, "none") == 0; #else return IS_DEFAULT_ACCEL_METHOD(NOACCEL); #endif } static bool sna_option_accel_blt(struct sna *sna) { const char *s; if (sna->kgem.gen >= 0110) return true; s = xf86GetOptValString(sna->Options, OPTION_ACCEL_METHOD); if (s == NULL) return false; return strcasecmp(s, "blt") == 0; } bool sna_accel_init(ScreenPtr screen, struct sna *sna) { const char *backend; DBG(("%s\n", __FUNCTION__)); sna_font_key = AllocateFontPrivateIndex(); list_init(&sna->flush_pixmaps); list_init(&sna->active_pixmaps); AddGeneralSocket(sna->kgem.fd); #ifdef DEBUG_MEMORY sna->timer_expire[DEBUG_MEMORY_TIMER] = GetTimeInMillis()+ 10 * 1000; #endif screen->defColormap = FakeClientID(0); /* let CreateDefColormap do whatever it wants for pixels */ screen->blackPixel = screen->whitePixel = (Pixel) 0; screen->QueryBestSize = sna_query_best_size; assert(screen->GetImage == NULL); screen->GetImage = sna_get_image; assert(screen->GetSpans == NULL); screen->GetSpans = sna_get_spans; assert(screen->CreateWindow == NULL); screen->CreateWindow = sna_create_window; assert(screen->DestroyWindow == NULL); screen->DestroyWindow = sna_destroy_window; screen->PositionWindow = sna_position_window; screen->ChangeWindowAttributes = sna_change_window_attributes; screen->RealizeWindow = sna_map_window; screen->UnrealizeWindow = sna_unmap_window; screen->CopyWindow = sna_copy_window; assert(screen->CreatePixmap == NULL); screen->CreatePixmap = sna_create_pixmap; assert(screen->DestroyPixmap == NULL); screen->DestroyPixmap = sna_destroy_pixmap; #ifdef CREATE_PIXMAP_USAGE_SHARED screen->SharePixmapBacking = sna_share_pixmap_backing; screen->SetSharedPixmapBacking = sna_set_shared_pixmap_backing; #endif screen->RealizeFont = sna_realize_font; screen->UnrealizeFont = sna_unrealize_font; assert(screen->CreateGC == NULL); screen->CreateGC = sna_create_gc; screen->CreateColormap = miInitializeColormap; screen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA; screen->InstallColormap = miInstallColormap; screen->UninstallColormap = miUninstallColormap; screen->ListInstalledColormaps = miListInstalledColormaps; screen->ResolveColor = miResolveColor; assert(screen->StoreColors == NULL); screen->StoreColors = sna_store_colors; screen->BitmapToRegion = fbBitmapToRegion; #if HAS_PIXMAP_SHARING screen->StartPixmapTracking = PixmapStartDirtyTracking; screen->StopPixmapTracking = PixmapStopDirtyTracking; #endif assert(screen->GetWindowPixmap == NULL); screen->GetWindowPixmap = sna_get_window_pixmap; assert(screen->SetWindowPixmap == NULL); screen->SetWindowPixmap = sna_set_window_pixmap; screen->SetScreenPixmap = sna_set_screen_pixmap; if (sna->kgem.has_userptr) ShmRegisterFuncs(screen, &shm_funcs); else ShmRegisterFbFuncs(screen); if (!sna_picture_init(screen)) return false; backend = no_render_init(sna); if (sna_option_accel_none(sna)) { backend = "disabled"; sna->kgem.wedged = true; sna_render_mark_wedged(sna); } else if (sna_option_accel_blt(sna)) (void)backend; else if (sna->kgem.gen >= 0100) backend = gen8_render_init(sna, backend); else if (sna->kgem.gen >= 070) backend = gen7_render_init(sna, backend); else if (sna->kgem.gen >= 060) backend = gen6_render_init(sna, backend); else if (sna->kgem.gen >= 050) backend = gen5_render_init(sna, backend); else if (sna->kgem.gen >= 040) backend = gen4_render_init(sna, backend); else if (sna->kgem.gen >= 030) backend = gen3_render_init(sna, backend); else if (sna->kgem.gen >= 020) backend = gen2_render_init(sna, backend); DBG(("%s(backend=%s, prefer_gpu=%x)\n", __FUNCTION__, backend, sna->render.prefer_gpu)); kgem_reset(&sna->kgem); sigtrap_init(); xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "SNA initialized with %s backend\n", backend); return true; } void sna_accel_create(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); if (!sna_glyphs_create(sna)) goto fail; if (!sna_gradients_create(sna)) goto fail; if (!sna_composite_create(sna)) goto fail; return; fail: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Failed to allocate caches, disabling RENDER acceleration\n"); no_render_init(sna); } void sna_accel_watch_flush(struct sna *sna, int enable) { DBG(("%s: enable=%d\n", __FUNCTION__, enable)); assert(enable); if (sna->watch_flush == 0) { DBG(("%s: installing watchers\n", __FUNCTION__)); assert(enable > 0); if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna)) { xf86DrvMsg(sna->scrn->scrnIndex, X_Error, "Failed to attach ourselves to the flush callbacks, expect missing synchronisation with DRI clients (e.g a compositor)\n"); } sna->watch_flush++; } sna->watch_flush += enable; } void sna_accel_leave(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); sna_scanout_flush(sna); /* as root we always have permission to render */ if (geteuid() == 0) return; /* as a user, we can only render now if we have a rendernode */ if (intel_has_render_node(sna->dev)) return; /* no longer authorized to use our fd */ DBG(("%s: dropping render privileges\n", __FUNCTION__)); kgem_submit(&sna->kgem); sna->kgem.wedged |= 2; } void sna_accel_enter(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); sna->kgem.wedged &= kgem_is_wedged(&sna->kgem); kgem_throttle(&sna->kgem); } void sna_accel_close(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); sna_composite_close(sna); sna_gradients_close(sna); sna_glyphs_close(sna); sna_pixmap_expire(sna); DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna); RemoveGeneralSocket(sna->kgem.fd); kgem_cleanup_cache(&sna->kgem); } void sna_accel_block(struct sna *sna, struct timeval **tv) { sigtrap_assert_inactive(); if (sna->kgem.need_retire) kgem_retire(&sna->kgem); kgem_retire__buffers(&sna->kgem); if (sna->timer_active) UpdateCurrentTimeIf(); if (sna->kgem.nbatch && (sna->kgem.scanout_busy || kgem_ring_is_idle(&sna->kgem, sna->kgem.ring))) { DBG(("%s: GPU idle, flushing\n", __FUNCTION__)); _kgem_submit(&sna->kgem); } if (sna->mode.dirty) sna_crtc_config_notify(xf86ScrnToScreen(sna->scrn)); restart: if (sna_scanout_do_flush(sna)) sna_scanout_flush(sna); assert(sna_accel_scanout(sna) == NULL || !sna_accel_scanout(sna)->gpu_bo->needs_flush || sna->timer_active & (1<<(FLUSH_TIMER))); if (sna_accel_do_throttle(sna)) sna_accel_throttle(sna); assert(!sna->kgem.need_retire || sna->timer_active & (1<<(THROTTLE_TIMER))); if (sna_accel_do_expire(sna)) sna_accel_expire(sna); assert(!sna->kgem.need_expire || sna->timer_active & (1<<(EXPIRE_TIMER))); if (sna_accel_do_debug_memory(sna)) sna_accel_debug_memory(sna); if (sna->watch_flush == 1) { DBG(("%s: removing watchers\n", __FUNCTION__)); DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna); sna->watch_flush = 0; } if (sna->timer_active & 1) { int32_t timeout; DBG(("%s: evaluating timers, active=%x\n", __FUNCTION__, sna->timer_active)); timeout = sna->timer_expire[FLUSH_TIMER] - TIME; DBG(("%s: flush timer expires in %d [%d]\n", __FUNCTION__, timeout, sna->timer_expire[FLUSH_TIMER])); if (timeout < 3) goto restart; if (*tv == NULL) { *tv = &sna->timer_tv; goto set_tv; } if ((*tv)->tv_sec * 1000 + (*tv)->tv_usec / 1000 > timeout) { set_tv: (*tv)->tv_sec = timeout / 1000; (*tv)->tv_usec = timeout % 1000 * 1000; } } sna->kgem.scanout_busy = false; if (FAULT_INJECTION && (rand() % FAULT_INJECTION) == 0) { DBG(("%s hardware acceleration\n", sna->kgem.wedged ? "Re-enabling" : "Disabling")); kgem_submit(&sna->kgem); sna->kgem.wedged = !sna->kgem.wedged; } } void sna_accel_free(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); sigtrap_assert_inactive(); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_acpi.c000066400000000000000000000117671267532330400236000ustar00rootroot00000000000000/* * Copyright (c) 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "sna.h" #define ACPI_SOCKET "/var/run/acpid.socket" int sna_acpi_open(void) { struct sockaddr_un addr; int fd, ret; DBG(("%s\n", __FUNCTION__)); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return -1; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, ACPI_SOCKET); ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { close(fd); return -1; } DBG(("%s: opened socket to APCI daemon, fd=%d\n", __FUNCTION__, fd)); return fd; } void _sna_acpi_wakeup(struct sna *sna) { char *eol; int n; n = read(sna->acpi.fd, sna->acpi.event + sna->acpi.offset, sna->acpi.remain); DBG(("%s: read %d bytes from acpid\n", __FUNCTION__, n)); if (n <= 0) { /* We will get '0' if we run out of space whilst reading * one event - that should never happen, so treat it as * an error and give up. */ if (n < 0) n = errno; switch (n) { case EAGAIN: case EINTR: return; } DBG(("%s: error [%d], detaching from acpid\n", __FUNCTION__, n)); /* XXX reattach later? */ RemoveGeneralSocket(sna->acpi.fd); sna_acpi_fini(sna); return; } sna->acpi.event[sna->acpi.offset + n] = '\0'; sna->acpi.offset += n; sna->acpi.remain -= n; DBG(("%s: event string [%d]: '%s'\n", __FUNCTION__, sna->acpi.offset, sna->acpi.event)); do { eol = strchr(sna->acpi.event, '\n'); if (eol == NULL) return; if (strncmp(sna->acpi.event, "ac_adapter", 10) == 0) { char *space = sna->acpi.event; int state = -1; /* ac_adapter ACAD 00000080 00000001 */ space = strchr(space, ' '); if (space) space = strchr(space + 1, ' '); if (space) space = strchr(space + 1, ' '); if (space) state = atoi(space + 1); DBG(("%s: ac_adapter event new state=%d\n", __FUNCTION__, state)); if (state) sna->flags &= ~SNA_POWERSAVE; else sna->flags |= SNA_POWERSAVE; } n = (sna->acpi.event + sna->acpi.offset) - ++eol; memmove(sna->acpi.event, eol, n+1); sna->acpi.offset = n; sna->acpi.remain = sizeof(sna->acpi.event) - 1 - n; } while (n); } static int read_power_state(const char *path) { DIR *dir; struct dirent *de; int i = -1; DBG(("%s: searching '%s'\n", __FUNCTION__, path)); dir = opendir(path); if (dir == NULL) return -1; while ((de = readdir(dir))) { char buf[1024]; int fd; if (*de->d_name == '.') continue; DBG(("%s: checking '%s'\n", __FUNCTION__, de->d_name)); snprintf(buf, sizeof(buf), "%s/%s/type", path, de->d_name); fd = open(buf, 0); if (fd < 0) continue; i = read(fd, buf, sizeof(buf)); buf[i > 0 ? i - 1: 0] = '\0'; close(fd); DBG(("%s: %s is of type '%s'\n", __FUNCTION__, de->d_name, buf)); if (strcmp(buf, "Mains")) continue; snprintf(buf, sizeof(buf), "%s/%s/online", path, de->d_name); fd = open(buf, 0); if (fd < 0) continue; i = read(fd, buf, sizeof(buf)); buf[i > 0 ? i - 1: 0] = '\0'; if (i > 0) i = atoi(buf); DBG(("%s: %s is online? '%s'\n", __FUNCTION__, de->d_name, buf)); close(fd); break; } closedir(dir); return i; } void sna_acpi_init(struct sna *sna) { if (sna->acpi.fd < 0) return; if (sna->flags & SNA_PERFORMANCE) return; DBG(("%s: attaching to acpid\n", __FUNCTION__)); AddGeneralSocket(sna->acpi.fd); sna->acpi.remain = sizeof(sna->acpi.event) - 1; sna->acpi.offset = 0; /* Read initial states */ if (read_power_state("/sys/class/power_supply") == 0) { DBG(("%s: AC adapter is currently offline\n", __FUNCTION__)); sna->flags |= SNA_POWERSAVE; } } void sna_acpi_fini(struct sna *sna) { if (sna->acpi.fd < 0) return; close(sna->acpi.fd); sna->acpi.fd = -1; sna->flags &= ~SNA_POWERSAVE; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_blt.c000066400000000000000000003446061267532330400234460ustar00rootroot00000000000000/* * Based on code from intel_uxa.c and i830_xaa.c * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright (c) 2005 Jesse Barnes * Copyright (c) 2009-2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_reg.h" #include "rop.h" #define NO_BLT_COMPOSITE 0 #define NO_BLT_COPY 0 #define NO_BLT_COPY_BOXES 0 #define NO_BLT_FILL 0 #define NO_BLT_FILL_BOXES 0 #ifndef PICT_TYPE_BGRA #define PICT_TYPE_BGRA 8 #endif static const uint8_t copy_ROP[] = { ROP_0, /* GXclear */ ROP_DSa, /* GXand */ ROP_SDna, /* GXandReverse */ ROP_S, /* GXcopy */ ROP_DSna, /* GXandInverted */ ROP_D, /* GXnoop */ ROP_DSx, /* GXxor */ ROP_DSo, /* GXor */ ROP_DSon, /* GXnor */ ROP_DSxn, /* GXequiv */ ROP_Dn, /* GXinvert */ ROP_SDno, /* GXorReverse */ ROP_Sn, /* GXcopyInverted */ ROP_DSno, /* GXorInverted */ ROP_DSan, /* GXnand */ ROP_1 /* GXset */ }; static const uint8_t fill_ROP[] = { ROP_0, ROP_DPa, ROP_PDna, ROP_P, ROP_DPna, ROP_D, ROP_DPx, ROP_DPo, ROP_DPon, ROP_PDxn, ROP_Dn, ROP_PDno, ROP_Pn, ROP_DPno, ROP_DPan, ROP_1 }; static void sig_done(struct sna *sna, const struct sna_composite_op *op) { sigtrap_put(); } static void nop_done(struct sna *sna, const struct sna_composite_op *op) { assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem)); if (sna->kgem.nexec > 1 && __kgem_ring_empty(&sna->kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(&sna->kgem); } (void)op; } static void gen6_blt_copy_done(struct sna *sna, const struct sna_composite_op *op) { struct kgem *kgem = &sna->kgem; assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem)); if (kgem->nexec > 1 && __kgem_ring_empty(kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(kgem); return; } if (kgem_check_batch(kgem, 3)) { uint32_t *b = kgem->batch + kgem->nbatch; assert(sna->kgem.mode == KGEM_BLT); b[0] = XY_SETUP_CLIP; b[1] = b[2] = 0; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); } assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem)); (void)op; } static bool sna_blt_fill_init(struct sna *sna, struct sna_blt_state *blt, struct kgem_bo *bo, int bpp, uint8_t alu, uint32_t pixel) { struct kgem *kgem = &sna->kgem; assert(kgem_bo_can_blt (kgem, bo)); blt->bo[0] = bo; blt->br13 = bo->pitch; blt->cmd = XY_SCANLINE_BLT; if (kgem->gen >= 040 && bo->tiling) { blt->cmd |= BLT_DST_TILED; blt->br13 >>= 2; } assert(blt->br13 <= MAXSHORT); if (alu == GXclear) pixel = 0; else if (alu == GXcopy) { if (pixel == 0) alu = GXclear; else if (pixel == -1) alu = GXset; } blt->br13 |= 1<<31 | (fill_ROP[alu] << 16); switch (bpp) { default: assert(0); case 32: blt->br13 |= 1 << 25; /* RGB8888 */ case 16: blt->br13 |= 1 << 24; /* RGB565 */ case 8: break; } blt->pixel = pixel; blt->bpp = bpp; blt->alu = alu; kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 14) || !kgem_check_bo_fenced(kgem, bo)) { kgem_submit(kgem); if (!kgem_check_bo_fenced(kgem, bo)) return false; _kgem_set_mode(kgem, KGEM_BLT); } if (sna->blt_state.fill_bo != bo->unique_id || sna->blt_state.fill_pixel != pixel || sna->blt_state.fill_alu != alu) { uint32_t *b; if (!kgem_check_batch(kgem, 24) || !kgem_check_reloc(kgem, 1)) { _kgem_submit(kgem); if (!kgem_check_bo_fenced(kgem, bo)) return false; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 8; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling) b[0] |= BLT_DST_TILED; b[1] = blt->br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = pixel; b[7] = pixel; b[8] = 0; b[9] = 0; kgem->nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 7; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling && kgem->gen >= 040) b[0] |= BLT_DST_TILED; b[1] = blt->br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = pixel; b[6] = pixel; b[7] = 0; b[8] = 0; kgem->nbatch += 9; } assert(kgem->nbatch < kgem->surface); sna->blt_state.fill_bo = bo->unique_id; sna->blt_state.fill_pixel = pixel; sna->blt_state.fill_alu = alu; } assert(sna->kgem.mode == KGEM_BLT); return true; } noinline static void __sna_blt_fill_begin(struct sna *sna, const struct sna_blt_state *blt) { struct kgem *kgem = &sna->kgem; uint32_t *b; kgem_bcs_set_tiling(&sna->kgem, NULL, blt->bo[0]); assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; if (sna->kgem.gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 8; if (blt->bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (blt->bo[0]->tiling) b[0] |= BLT_DST_TILED; b[1] = blt->br13; b[2] = 0; b[3] = 0; *(uint32_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = blt->pixel; b[7] = blt->pixel; b[8] = 0; b[9] = 0; kgem->nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 7; if (blt->bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (blt->bo[0]->tiling && kgem->gen >= 040) b[0] |= BLT_DST_TILED; b[1] = blt->br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = blt->pixel; b[6] = blt->pixel; b[7] = 0; b[8] = 0; kgem->nbatch += 9; } } inline static void sna_blt_fill_begin(struct sna *sna, const struct sna_blt_state *blt) { struct kgem *kgem = &sna->kgem; if (kgem->nreloc) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(kgem, NULL, blt->bo[0]); assert(kgem->nbatch == 0); } __sna_blt_fill_begin(sna, blt); } inline static void sna_blt_fill_one(struct sna *sna, const struct sna_blt_state *blt, int16_t x, int16_t y, int16_t width, int16_t height) { struct kgem *kgem = &sna->kgem; uint32_t *b; DBG(("%s: (%d, %d) x (%d, %d): %08x\n", __FUNCTION__, x, y, width, height, blt->pixel)); assert(x >= 0); assert(y >= 0); assert((y+height) * blt->bo[0]->pitch <= kgem_bo_size(blt->bo[0])); if (!kgem_check_batch(kgem, 3)) sna_blt_fill_begin(sna, blt); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); b[0] = blt->cmd; b[1] = y << 16 | x; b[2] = b[1] + (height << 16 | width); } static bool sna_blt_copy_init(struct sna *sna, struct sna_blt_state *blt, struct kgem_bo *src, struct kgem_bo *dst, int bpp, uint8_t alu) { struct kgem *kgem = &sna->kgem; assert(kgem_bo_can_blt(kgem, src)); assert(kgem_bo_can_blt(kgem, dst)); blt->bo[0] = src; blt->bo[1] = dst; blt->cmd = XY_SRC_COPY_BLT_CMD | (kgem->gen >= 0100 ? 8 : 6); if (bpp == 32) blt->cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; blt->pitch[0] = src->pitch; if (kgem->gen >= 040 && src->tiling) { blt->cmd |= BLT_SRC_TILED; blt->pitch[0] >>= 2; } assert(blt->pitch[0] <= MAXSHORT); blt->pitch[1] = dst->pitch; if (kgem->gen >= 040 && dst->tiling) { blt->cmd |= BLT_DST_TILED; blt->pitch[1] >>= 2; } assert(blt->pitch[1] <= MAXSHORT); blt->overwrites = alu == GXcopy || alu == GXclear || alu == GXset; blt->br13 = (copy_ROP[alu] << 16) | blt->pitch[1]; switch (bpp) { default: assert(0); case 32: blt->br13 |= 1 << 25; /* RGB8888 */ case 16: blt->br13 |= 1 << 24; /* RGB565 */ case 8: break; } kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) return false; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, src, dst); sna->blt_state.fill_bo = 0; return true; } static bool sna_blt_alpha_fixup_init(struct sna *sna, struct sna_blt_state *blt, struct kgem_bo *src, struct kgem_bo *dst, int bpp, uint32_t alpha) { struct kgem *kgem = &sna->kgem; DBG(("%s: dst handle=%d, src handle=%d, bpp=%d, fixup=%08x\n", __FUNCTION__, dst->handle, src->handle, bpp, alpha)); assert(kgem_bo_can_blt(kgem, src)); assert(kgem_bo_can_blt(kgem, dst)); blt->bo[0] = src; blt->bo[1] = dst; blt->cmd = XY_FULL_MONO_PATTERN_BLT | (kgem->gen >= 0100 ? 12 : 10); blt->pitch[0] = src->pitch; if (kgem->gen >= 040 && src->tiling) { blt->cmd |= BLT_SRC_TILED; blt->pitch[0] >>= 2; } assert(blt->pitch[0] <= MAXSHORT); blt->pitch[1] = dst->pitch; if (kgem->gen >= 040 && dst->tiling) { blt->cmd |= BLT_DST_TILED; blt->pitch[1] >>= 2; } assert(blt->pitch[1] <= MAXSHORT); blt->overwrites = 1; blt->br13 = (0xfc << 16) | blt->pitch[1]; switch (bpp) { default: assert(0); case 32: blt->cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; blt->br13 |= 1 << 25; /* RGB8888 */ case 16: blt->br13 |= 1 << 24; /* RGB565 */ case 8: break; } blt->pixel = alpha; kgem_set_mode(kgem, KGEM_BLT, dst); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) { kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, src, dst, NULL)) return false; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, src, dst); sna->blt_state.fill_bo = 0; return true; } static void sna_blt_alpha_fixup_one(struct sna *sna, const struct sna_blt_state *blt, int src_x, int src_y, int width, int height, int dst_x, int dst_y) { struct kgem *kgem = &sna->kgem; uint32_t *b; DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d)\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height)); assert(src_x >= 0); assert(src_y >= 0); assert((src_y + height) * blt->bo[0]->pitch <= kgem_bo_size(blt->bo[0])); assert(dst_x >= 0); assert(dst_y >= 0); assert((dst_y + height) * blt->bo[1]->pitch <= kgem_bo_size(blt->bo[1])); assert(width > 0); assert(height > 0); if (!kgem_check_batch(kgem, 14) || !kgem_check_reloc(kgem, 2)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, blt->bo[0], blt->bo[1]); } assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = blt->cmd; b[1] = blt->br13; b[2] = (dst_y << 16) | dst_x; b[3] = ((dst_y + height) << 16) | (dst_x + width); if (sna->kgem.gen >= 0100) { *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, blt->bo[1], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = blt->pitch[0]; b[7] = (src_y << 16) | src_x; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[10] = blt->pixel; b[11] = blt->pixel; b[12] = 0; b[13] = 0; kgem->nbatch += 14; } else { b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, blt->bo[1], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = blt->pitch[0]; b[6] = (src_y << 16) | src_x; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = blt->pixel; b[9] = blt->pixel; b[10] = 0; b[11] = 0; kgem->nbatch += 12; } assert(kgem->nbatch < kgem->surface); } static void sna_blt_copy_one(struct sna *sna, const struct sna_blt_state *blt, int src_x, int src_y, int width, int height, int dst_x, int dst_y) { struct kgem *kgem = &sna->kgem; uint32_t *b; DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d)\n", __FUNCTION__, src_x, src_y, dst_x, dst_y, width, height)); assert(src_x >= 0); assert(src_y >= 0); assert((src_y + height) * blt->bo[0]->pitch <= kgem_bo_size(blt->bo[0])); assert(dst_x >= 0); assert(dst_y >= 0); assert((dst_y + height) * blt->bo[1]->pitch <= kgem_bo_size(blt->bo[1])); assert(width > 0); assert(height > 0); /* Compare against a previous fill */ if (blt->overwrites && kgem->reloc[kgem->nreloc-1].target_handle == blt->bo[1]->target_handle) { if (sna->kgem.gen >= 0100) { if (kgem->nbatch >= 7 && kgem->batch[kgem->nbatch-7] == (XY_COLOR_BLT | (blt->cmd & (BLT_DST_TILED | BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 5) && kgem->batch[kgem->nbatch-5] == ((uint32_t)dst_y << 16 | (uint16_t)dst_x) && kgem->batch[kgem->nbatch-4] == ((uint32_t)(dst_y+height) << 16 | (uint16_t)(dst_x+width))) { DBG(("%s: replacing last fill\n", __FUNCTION__)); if (kgem_check_batch(kgem, 3)) { assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch - 7; b[0] = blt->cmd; b[1] = blt->br13; b[6] = (src_y << 16) | src_x; b[7] = blt->pitch[0]; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8 - 7, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); return; } kgem->nbatch -= 7; kgem->nreloc--; } } else { if (kgem->nbatch >= 6 && kgem->batch[kgem->nbatch-6] == (XY_COLOR_BLT | (blt->cmd & (BLT_DST_TILED | BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 4) && kgem->batch[kgem->nbatch-4] == ((uint32_t)dst_y << 16 | (uint16_t)dst_x) && kgem->batch[kgem->nbatch-3] == ((uint32_t)(dst_y+height) << 16 | (uint16_t)(dst_x+width))) { DBG(("%s: replacing last fill\n", __FUNCTION__)); if (kgem_check_batch(kgem, 8-6)) { assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch - 6; b[0] = blt->cmd; b[1] = blt->br13; b[5] = (src_y << 16) | src_x; b[6] = blt->pitch[0]; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7 - 6, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8 - 6; assert(kgem->nbatch < kgem->surface); return; } kgem->nbatch -= 6; kgem->nreloc--; } } } if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc(kgem, 2)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, blt->bo[0], blt->bo[1]); } assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = blt->cmd; b[1] = blt->br13; b[2] = (dst_y << 16) | dst_x; b[3] = ((dst_y + height) << 16) | (dst_x + width); if (kgem->gen >= 0100) { *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, blt->bo[1], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = (src_y << 16) | src_x; b[7] = blt->pitch[0]; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; } else { b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, blt->bo[1], I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = (src_y << 16) | src_x; b[6] = blt->pitch[0]; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, blt->bo[0], I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; } assert(kgem->nbatch < kgem->surface); } bool sna_get_rgba_from_pixel(uint32_t pixel, uint16_t *red, uint16_t *green, uint16_t *blue, uint16_t *alpha, uint32_t format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { rshift = gshift = bshift = ashift = 0; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { bshift = 0; gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { ashift = 0; rshift = abits; if (abits == 0) rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); gshift = rshift + rbits; bshift = gshift + gbits; } else { return false; } if (rbits) { *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits); while (rbits < 16) { *red |= *red >> rbits; rbits <<= 1; } } else *red = 0; if (gbits) { *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits); while (gbits < 16) { *green |= *green >> gbits; gbits <<= 1; } } else *green = 0; if (bbits) { *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits); while (bbits < 16) { *blue |= *blue >> bbits; bbits <<= 1; } } else *blue = 0; if (abits) { *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits); while (abits < 16) { *alpha |= *alpha >> abits; abits <<= 1; } } else *alpha = 0xffff; return true; } bool _sna_get_pixel_from_rgba(uint32_t * pixel, uint16_t red, uint16_t green, uint16_t blue, uint16_t alpha, uint32_t format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (abits == 0) abits = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { *pixel = alpha >> (16 - abits); return true; } if (!PICT_FORMAT_COLOR(format)) return false; if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { bshift = 0; gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { ashift = 0; rshift = abits; gshift = rshift + rbits; bshift = gshift + gbits; } else return false; *pixel = 0; *pixel |= (blue >> (16 - bbits)) << bshift; *pixel |= (green >> (16 - gbits)) << gshift; *pixel |= (red >> (16 - rbits)) << rshift; *pixel |= (alpha >> (16 - abits)) << ashift; return true; } uint32_t sna_rgba_for_color(uint32_t color, int depth) { return color_convert(color, sna_format_for_depth(depth), PICT_a8r8g8b8); } uint32_t sna_rgba_to_color(uint32_t rgba, uint32_t format) { return color_convert(rgba, PICT_a8r8g8b8, format); } static uint32_t get_pixel(PicturePtr picture) { PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); DBG(("%s: %p\n", __FUNCTION__, pixmap)); if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return 0; switch (pixmap->drawable.bitsPerPixel) { case 32: return *(uint32_t *)pixmap->devPrivate.ptr; case 16: return *(uint16_t *)pixmap->devPrivate.ptr; default: return *(uint8_t *)pixmap->devPrivate.ptr; } } static uint32_t get_solid_color(PicturePtr picture, uint32_t format) { if (picture->pSourcePict) { PictSolidFill *fill = (PictSolidFill *)picture->pSourcePict; return color_convert(fill->color, PICT_a8r8g8b8, format); } else return color_convert(get_pixel(picture), picture->format, format); } static bool is_solid(PicturePtr picture) { if (picture->pSourcePict) { if (picture->pSourcePict->type == SourcePictTypeSolidFill) return true; } if (picture->pDrawable) { if (picture->pDrawable->width == 1 && picture->pDrawable->height == 1 && picture->repeat) return true; } return false; } bool sna_picture_is_solid(PicturePtr picture, uint32_t *color) { if (!is_solid(picture)) return false; if (color) *color = get_solid_color(picture, PICT_a8r8g8b8); return true; } static bool pixel_is_transparent(uint32_t pixel, uint32_t format) { unsigned int abits; abits = PICT_FORMAT_A(format); if (!abits) return false; if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A || PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { return (pixel & ((1 << abits) - 1)) == 0; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB || PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { unsigned int ashift = PICT_FORMAT_BPP(format) - abits; return (pixel >> ashift) == 0; } else return false; } static bool pixel_is_opaque(uint32_t pixel, uint32_t format) { unsigned int abits; abits = PICT_FORMAT_A(format); if (!abits) return true; if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A || PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { return (pixel & ((1 << abits) - 1)) == (unsigned)((1 << abits) - 1); } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB || PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { unsigned int ashift = PICT_FORMAT_BPP(format) - abits; return (pixel >> ashift) == (unsigned)((1 << abits) - 1); } else return false; } static bool pixel_is_white(uint32_t pixel, uint32_t format) { switch (PICT_FORMAT_TYPE(format)) { case PICT_TYPE_A: case PICT_TYPE_ARGB: case PICT_TYPE_ABGR: case PICT_TYPE_BGRA: return pixel == ((1U << PICT_FORMAT_BPP(format)) - 1); default: return false; } } static bool is_opaque_solid(PicturePtr picture) { if (picture->pSourcePict) { PictSolidFill *fill = (PictSolidFill *) picture->pSourcePict; return (fill->color >> 24) == 0xff; } else return pixel_is_opaque(get_pixel(picture), picture->format); } static bool is_white(PicturePtr picture) { if (picture->pSourcePict) { PictSolidFill *fill = (PictSolidFill *) picture->pSourcePict; return fill->color == 0xffffffff; } else return pixel_is_white(get_pixel(picture), picture->format); } static bool is_transparent(PicturePtr picture) { if (picture->pSourcePict) { PictSolidFill *fill = (PictSolidFill *) picture->pSourcePict; return fill->color == 0; } else return pixel_is_transparent(get_pixel(picture), picture->format); } bool sna_composite_mask_is_opaque(PicturePtr mask) { if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) return is_solid(mask) && is_white(mask); else if (!PICT_FORMAT_A(mask->format)) return true; else if (mask->pSourcePict) { PictSolidFill *fill = (PictSolidFill *) mask->pSourcePict; return (fill->color >> 24) == 0xff; } else { struct sna_pixmap *priv; assert(mask->pDrawable); if (mask->pDrawable->width == 1 && mask->pDrawable->height == 1 && mask->repeat) return pixel_is_opaque(get_pixel(mask), mask->format); if (mask->transform) return false; priv = sna_pixmap_from_drawable(mask->pDrawable); if (priv == NULL || !priv->clear) return false; return pixel_is_opaque(priv->clear_color, mask->format); } } fastcall static void blt_composite_fill(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; if (x2 <= x1 || y2 <= y1) return; sna_blt_fill_one(sna, &op->u.blt, x1, y1, x2-x1, y2-y1); } fastcall static void blt_composite_fill__cpu(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; if (x2 <= x1 || y2 <= y1) return; assert(op->dst.pixmap->devPrivate.ptr); assert(op->dst.pixmap->devKind); sigtrap_assert_active(); pixman_fill(op->dst.pixmap->devPrivate.ptr, op->dst.pixmap->devKind / sizeof(uint32_t), op->dst.pixmap->drawable.bitsPerPixel, x1, y1, x2-x1, y2-y1, op->u.blt.pixel); } fastcall static void blt_composite_fill_box_no_offset__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= op->dst.pixmap->drawable.width); assert(box->y2 <= op->dst.pixmap->drawable.height); assert(op->dst.pixmap->devPrivate.ptr); assert(op->dst.pixmap->devKind); sigtrap_assert_active(); pixman_fill(op->dst.pixmap->devPrivate.ptr, op->dst.pixmap->devKind / sizeof(uint32_t), op->dst.pixmap->drawable.bitsPerPixel, box->x1, box->y1, box->x2-box->x1, box->y2-box->y1, op->u.blt.pixel); } static void blt_composite_fill_boxes_no_offset__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { do { assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= op->dst.pixmap->drawable.width); assert(box->y2 <= op->dst.pixmap->drawable.height); assert(op->dst.pixmap->devPrivate.ptr); assert(op->dst.pixmap->devKind); sigtrap_assert_active(); pixman_fill(op->dst.pixmap->devPrivate.ptr, op->dst.pixmap->devKind / sizeof(uint32_t), op->dst.pixmap->drawable.bitsPerPixel, box->x1, box->y1, box->x2-box->x1, box->y2-box->y1, op->u.blt.pixel); box++; } while (--n); } fastcall static void blt_composite_fill_box__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { assert(box->x1 + op->dst.x >= 0); assert(box->y1 + op->dst.y >= 0); assert(box->x2 + op->dst.x <= op->dst.pixmap->drawable.width); assert(box->y2 + op->dst.y <= op->dst.pixmap->drawable.height); assert(op->dst.pixmap->devPrivate.ptr); assert(op->dst.pixmap->devKind); sigtrap_assert_active(); pixman_fill(op->dst.pixmap->devPrivate.ptr, op->dst.pixmap->devKind / sizeof(uint32_t), op->dst.pixmap->drawable.bitsPerPixel, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2 - box->x1, box->y2 - box->y1, op->u.blt.pixel); } static void blt_composite_fill_boxes__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { do { assert(box->x1 + op->dst.x >= 0); assert(box->y1 + op->dst.y >= 0); assert(box->x2 + op->dst.x <= op->dst.pixmap->drawable.width); assert(box->y2 + op->dst.y <= op->dst.pixmap->drawable.height); assert(op->dst.pixmap->devPrivate.ptr); assert(op->dst.pixmap->devKind); sigtrap_assert_active(); pixman_fill(op->dst.pixmap->devPrivate.ptr, op->dst.pixmap->devKind / sizeof(uint32_t), op->dst.pixmap->drawable.bitsPerPixel, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2 - box->x1, box->y2 - box->y1, op->u.blt.pixel); box++; } while (--n); } inline static void _sna_blt_fill_box(struct sna *sna, const struct sna_blt_state *blt, const BoxRec *box) { struct kgem *kgem = &sna->kgem; uint32_t *b; DBG(("%s: (%d, %d), (%d, %d): %08x\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, blt->pixel)); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->y2 * blt->bo[0]->pitch <= kgem_bo_size(blt->bo[0])); if (!kgem_check_batch(kgem, 3)) sna_blt_fill_begin(sna, blt); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); b[0] = blt->cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box; } inline static void _sna_blt_fill_boxes(struct sna *sna, const struct sna_blt_state *blt, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; uint32_t cmd = blt->cmd; DBG(("%s: %08x x %d\n", __FUNCTION__, blt->pixel, nbox)); if (!kgem_check_batch(kgem, 3)) sna_blt_fill_begin(sna, blt); do { uint32_t *b = kgem->batch + kgem->nbatch; int nbox_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (3*nbox_this_time > rem) nbox_this_time = rem / 3; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; kgem->nbatch += 3 * nbox_this_time; assert(kgem->nbatch < kgem->surface); while (nbox_this_time >= 8) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b[6] = cmd; *(uint64_t *)(b+7) = *(const uint64_t *)box++; b[9] = cmd; *(uint64_t *)(b+10) = *(const uint64_t *)box++; b[12] = cmd; *(uint64_t *)(b+13) = *(const uint64_t *)box++; b[15] = cmd; *(uint64_t *)(b+16) = *(const uint64_t *)box++; b[18] = cmd; *(uint64_t *)(b+19) = *(const uint64_t *)box++; b[21] = cmd; *(uint64_t *)(b+22) = *(const uint64_t *)box++; b += 24; nbox_this_time -= 8; } if (nbox_this_time & 4) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b[6] = cmd; *(uint64_t *)(b+7) = *(const uint64_t *)box++; b[9] = cmd; *(uint64_t *)(b+10) = *(const uint64_t *)box++; b += 12; } if (nbox_this_time & 2) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b += 6; } if (nbox_this_time & 1) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; } if (!nbox) return; sna_blt_fill_begin(sna, blt); } while (1); } static inline void _sna_blt_maybe_clear(const struct sna_composite_op *op, const BoxRec *box) { if (box->x2 - box->x1 >= op->dst.width && box->y2 - box->y1 >= op->dst.height) { struct sna_pixmap *priv = sna_pixmap(op->dst.pixmap); if (op->dst.bo == priv->gpu_bo) { sna_damage_all(&priv->gpu_damage, op->dst.pixmap); priv->clear = true; priv->clear_color = op->u.blt.pixel; DBG(("%s: pixmap=%ld marking clear [%08x]\n", __FUNCTION__, op->dst.pixmap->drawable.serialNumber, op->u.blt.pixel)); } } } fastcall static void blt_composite_fill_box_no_offset(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { _sna_blt_fill_box(sna, &op->u.blt, box); _sna_blt_maybe_clear(op, box); } static void blt_composite_fill_boxes_no_offset(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { _sna_blt_fill_boxes(sna, &op->u.blt, box, n); } static void blt_composite_fill_boxes_no_offset__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; const struct sna_blt_state *blt = &op->u.blt; uint32_t cmd = blt->cmd; DBG(("%s: %08x x %d\n", __FUNCTION__, blt->pixel, nbox)); sna_vertex_lock(&sna->render); assert(kgem->mode == KGEM_BLT); if (!kgem_check_batch(kgem, 3)) { sna_vertex_wait__locked(&sna->render); sna_blt_fill_begin(sna, blt); } do { uint32_t *b = kgem->batch + kgem->nbatch; int nbox_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (3*nbox_this_time > rem) nbox_this_time = rem / 3; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; kgem->nbatch += 3 * nbox_this_time; assert(kgem->nbatch < kgem->surface); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); while (nbox_this_time >= 8) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b[6] = cmd; *(uint64_t *)(b+7) = *(const uint64_t *)box++; b[9] = cmd; *(uint64_t *)(b+10) = *(const uint64_t *)box++; b[12] = cmd; *(uint64_t *)(b+13) = *(const uint64_t *)box++; b[15] = cmd; *(uint64_t *)(b+16) = *(const uint64_t *)box++; b[18] = cmd; *(uint64_t *)(b+19) = *(const uint64_t *)box++; b[21] = cmd; *(uint64_t *)(b+22) = *(const uint64_t *)box++; b += 24; nbox_this_time -= 8; } if (nbox_this_time & 4) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b[6] = cmd; *(uint64_t *)(b+7) = *(const uint64_t *)box++; b[9] = cmd; *(uint64_t *)(b+10) = *(const uint64_t *)box++; b += 12; } if (nbox_this_time & 2) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; b[3] = cmd; *(uint64_t *)(b+4) = *(const uint64_t *)box++; b += 6; } if (nbox_this_time & 1) { b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box++; } sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); if (!nbox) break; sna_vertex_wait__locked(&sna->render); sna_blt_fill_begin(sna, blt); } while (1); sna_vertex_unlock(&sna->render); } fastcall static void blt_composite_fill_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { sna_blt_fill_one(sna, &op->u.blt, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2 - box->x1, box->y2 - box->y1); _sna_blt_maybe_clear(op, box); } static void blt_composite_fill_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { do { sna_blt_fill_one(sna, &op->u.blt, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } static inline uint64_t add4(const BoxRec *b, int16_t x, int16_t y) { union { uint64_t v; int16_t i[4]; } vi; vi.v = *(uint64_t *)b; vi.i[0] += x; vi.i[1] += y; vi.i[2] += x; vi.i[3] += y; return vi.v; } static void blt_composite_fill_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; const struct sna_blt_state *blt = &op->u.blt; uint32_t cmd = blt->cmd; int16_t dx = op->dst.x; int16_t dy = op->dst.y; DBG(("%s: %08x x %d\n", __FUNCTION__, blt->pixel, nbox)); sna_vertex_lock(&sna->render); assert(kgem->mode == KGEM_BLT); if (!kgem_check_batch(kgem, 3)) { sna_vertex_wait__locked(&sna->render); sna_blt_fill_begin(sna, blt); } do { uint32_t *b = kgem->batch + kgem->nbatch; int nbox_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (3*nbox_this_time > rem) nbox_this_time = rem / 3; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; kgem->nbatch += 3 * nbox_this_time; assert(kgem->nbatch < kgem->surface); sna_vertex_acquire__locked(&sna->render); sna_vertex_unlock(&sna->render); while (nbox_this_time >= 8) { b[0] = cmd; *(uint64_t *)(b+1) = add4(box++, dx, dy); b[3] = cmd; *(uint64_t *)(b+4) = add4(box++, dx, dy); b[6] = cmd; *(uint64_t *)(b+7) = add4(box++, dx, dy); b[9] = cmd; *(uint64_t *)(b+10) = add4(box++, dx, dy); b[12] = cmd; *(uint64_t *)(b+13) = add4(box++, dx, dy); b[15] = cmd; *(uint64_t *)(b+16) = add4(box++, dx, dy); b[18] = cmd; *(uint64_t *)(b+19) = add4(box++, dx, dy); b[21] = cmd; *(uint64_t *)(b+22) = add4(box++, dx, dy); b += 24; nbox_this_time -= 8; } if (nbox_this_time & 4) { b[0] = cmd; *(uint64_t *)(b+1) = add4(box++, dx, dy); b[3] = cmd; *(uint64_t *)(b+4) = add4(box++, dx, dy); b[6] = cmd; *(uint64_t *)(b+7) = add4(box++, dx, dy); b[9] = cmd; *(uint64_t *)(b+10) = add4(box++, dx, dy); b += 12; } if (nbox_this_time & 2) { b[0] = cmd; *(uint64_t *)(b+1) = add4(box++, dx, dy); b[3] = cmd; *(uint64_t *)(b+4) = add4(box++, dx, dy); b += 6; } if (nbox_this_time & 1) { b[0] = cmd; *(uint64_t *)(b+1) = add4(box++, dx, dy); } sna_vertex_lock(&sna->render); sna_vertex_release__locked(&sna->render); if (!nbox) break; sna_vertex_wait__locked(&sna->render); sna_blt_fill_begin(sna, blt); } while (1); sna_vertex_unlock(&sna->render); } fastcall static void blt_composite_nop(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { } fastcall static void blt_composite_nop_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { } static void blt_composite_nop_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { } static bool begin_blt(struct sna *sna, struct sna_composite_op *op) { assert(sna->kgem.mode == KGEM_BLT); if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo)) { kgem_submit(&sna->kgem); if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo)) return false; _kgem_set_mode(&sna->kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, op->dst.bo); } return true; } static bool prepare_blt_nop(struct sna *sna, struct sna_composite_op *op) { DBG(("%s\n", __FUNCTION__)); op->blt = blt_composite_nop; op->box = blt_composite_nop_box; op->boxes = blt_composite_nop_boxes; op->done = nop_done; return true; } static bool prepare_blt_clear(struct sna *sna, struct sna_composite_op *op) { DBG(("%s\n", __FUNCTION__)); if (op->dst.bo == NULL) { op->u.blt.pixel = 0; op->blt = blt_composite_fill__cpu; if (op->dst.x|op->dst.y) { op->box = blt_composite_fill_box__cpu; op->boxes = blt_composite_fill_boxes__cpu; op->thread_boxes = blt_composite_fill_boxes__cpu; } else { op->box = blt_composite_fill_box_no_offset__cpu; op->boxes = blt_composite_fill_boxes_no_offset__cpu; op->thread_boxes = blt_composite_fill_boxes_no_offset__cpu; } op->done = sig_done; return sigtrap_get() == 0; } op->blt = blt_composite_fill; if (op->dst.x|op->dst.y) { op->box = blt_composite_fill_box; op->boxes = blt_composite_fill_boxes; op->thread_boxes = blt_composite_fill_boxes__thread; } else { op->box = blt_composite_fill_box_no_offset; op->boxes = blt_composite_fill_boxes_no_offset; op->thread_boxes = blt_composite_fill_boxes_no_offset__thread; } op->done = nop_done; if (!sna_blt_fill_init(sna, &op->u.blt, op->dst.bo, op->dst.pixmap->drawable.bitsPerPixel, GXclear, 0)) return false; return begin_blt(sna, op); } static bool prepare_blt_fill(struct sna *sna, struct sna_composite_op *op, uint32_t pixel) { DBG(("%s\n", __FUNCTION__)); if (op->dst.bo == NULL) { op->u.blt.pixel = pixel; op->blt = blt_composite_fill__cpu; if (op->dst.x|op->dst.y) { op->box = blt_composite_fill_box__cpu; op->boxes = blt_composite_fill_boxes__cpu; op->thread_boxes = blt_composite_fill_boxes__cpu; } else { op->box = blt_composite_fill_box_no_offset__cpu; op->boxes = blt_composite_fill_boxes_no_offset__cpu; op->thread_boxes = blt_composite_fill_boxes_no_offset__cpu; } op->done = sig_done; return sigtrap_get() == 0; } op->blt = blt_composite_fill; if (op->dst.x|op->dst.y) { op->box = blt_composite_fill_box; op->boxes = blt_composite_fill_boxes; op->thread_boxes = blt_composite_fill_boxes__thread; } else { op->box = blt_composite_fill_box_no_offset; op->boxes = blt_composite_fill_boxes_no_offset; op->thread_boxes = blt_composite_fill_boxes_no_offset__thread; } op->done = nop_done; if (!sna_blt_fill_init(sna, &op->u.blt, op->dst.bo, op->dst.pixmap->drawable.bitsPerPixel, GXcopy, pixel)) return false; return begin_blt(sna, op); } fastcall static void blt_composite_copy(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; int src_x, src_y; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, r->dst.x, r->dst.y, r->width, r->height)); /* XXX higher layer should have clipped? */ x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; src_x = r->src.x - x1 + op->u.blt.sx; src_y = r->src.y - y1 + op->u.blt.sy; /* clip against dst */ if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; DBG(("%s: box=(%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 <= x1 || y2 <= y1) return; sna_blt_copy_one(sna, &op->u.blt, x1 + src_x, y1 + src_y, x2 - x1, y2 - y1, x1, y1); } fastcall static void blt_composite_copy_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_blt_copy_one(sna, &op->u.blt, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x2 - box->x1, box->y2 - box->y1, box->x1 + op->dst.x, box->y1 + op->dst.y); } static void blt_composite_copy_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_blt_copy_one(sna, &op->u.blt, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x2 - box->x1, box->y2 - box->y1, box->x1 + op->dst.x, box->y1 + op->dst.y); box++; } while(--nbox); } static inline uint32_t add2(uint32_t v, int16_t x, int16_t y) { x += v & 0xffff; y += v >> 16; return (uint16_t)y << 16 | x; } static void blt_composite_copy_boxes__thread(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; int dst_dx = op->dst.x; int dst_dy = op->dst.y; int src_dx = op->src.offset[0]; int src_dy = op->src.offset[1]; uint32_t cmd = op->u.blt.cmd; uint32_t br13 = op->u.blt.br13; struct kgem_bo *src_bo = op->u.blt.bo[0]; struct kgem_bo *dst_bo = op->u.blt.bo[1]; int src_pitch = op->u.blt.pitch[0]; DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); if ((dst_dx | dst_dy) == 0) { uint64_t hdr = (uint64_t)br13 << 32 | cmd; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + src_dx <= INT16_MAX); assert(box->y1 + src_dy <= INT16_MAX); assert(box->x1 >= 0); assert(box->y1 >= 0); *(uint64_t *)&b[0] = hdr; *(uint64_t *)&b[2] = *(const uint64_t *)box; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = add2(b[2], src_dx, src_dy); b[6] = src_pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } else { do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); b[0] = cmd; b[1] = br13; b[2] = ((box->y1 + dst_dy) << 16) | (box->x1 + dst_dx); b[3] = ((box->y2 + dst_dy) << 16) | (box->x2 + dst_dx); b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = ((box->y1 + src_dy) << 16) | (box->x1 + src_dx); b[6] = src_pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } sna_vertex_unlock(&sna->render); } static void blt_composite_copy_boxes__thread64(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; int dst_dx = op->dst.x; int dst_dy = op->dst.y; int src_dx = op->src.offset[0]; int src_dy = op->src.offset[1]; uint32_t cmd = op->u.blt.cmd; uint32_t br13 = op->u.blt.br13; struct kgem_bo *src_bo = op->u.blt.bo[0]; struct kgem_bo *dst_bo = op->u.blt.bo[1]; int src_pitch = op->u.blt.pitch[0]; DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_vertex_lock(&sna->render); if ((dst_dx | dst_dy) == 0) { uint64_t hdr = (uint64_t)br13 << 32 | cmd; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 10; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(kgem->mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + src_dx <= INT16_MAX); assert(box->y1 + src_dy <= INT16_MAX); assert(box->x1 >= 0); assert(box->y1 >= 0); *(uint64_t *)&b[0] = hdr; *(uint64_t *)&b[2] = *(const uint64_t *)box; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = add2(b[2], src_dx, src_dy); b[7] = src_pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } else { do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 10; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(kgem->mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); b[0] = cmd; b[1] = br13; b[2] = ((box->y1 + dst_dy) << 16) | (box->x1 + dst_dx); b[3] = ((box->y2 + dst_dy) << 16) | (box->x2 + dst_dx); *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = ((box->y1 + src_dy) << 16) | (box->x1 + src_dx); b[7] = src_pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } sna_vertex_unlock(&sna->render); } fastcall static void blt_composite_copy_with_alpha(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; int src_x, src_y; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, r->dst.x, r->dst.y, r->width, r->height)); /* XXX higher layer should have clipped? */ x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; src_x = r->src.x - x1 + op->u.blt.sx; src_y = r->src.y - y1 + op->u.blt.sy; /* clip against dst */ if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; DBG(("%s: box=(%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 <= x1 || y2 <= y1) return; sna_blt_alpha_fixup_one(sna, &op->u.blt, x1 + src_x, y1 + src_y, x2 - x1, y2 - y1, x1, y1); } fastcall static void blt_composite_copy_box_with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_blt_alpha_fixup_one(sna, &op->u.blt, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x2 - box->x1, box->y2 - box->y1, box->x1 + op->dst.x, box->y1 + op->dst.y); } static void blt_composite_copy_boxes_with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); do { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_blt_alpha_fixup_one(sna, &op->u.blt, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x2 - box->x1, box->y2 - box->y1, box->x1 + op->dst.x, box->y1 + op->dst.y); box++; } while(--nbox); } static bool prepare_blt_copy(struct sna *sna, struct sna_composite_op *op, struct kgem_bo *bo, uint32_t alpha_fixup) { PixmapPtr src = op->u.blt.src_pixmap; assert(op->dst.bo); assert(kgem_bo_can_blt(&sna->kgem, op->dst.bo)); assert(kgem_bo_can_blt(&sna->kgem, bo)); kgem_set_mode(&sna->kgem, KGEM_BLT, op->dst.bo); if (!kgem_check_many_bo_fenced(&sna->kgem, op->dst.bo, bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_many_bo_fenced(&sna->kgem, op->dst.bo, bo, NULL)) { DBG(("%s: fallback -- no room in aperture\n", __FUNCTION__)); return sna_tiling_blt_composite(sna, op, bo, src->drawable.bitsPerPixel, alpha_fixup); } _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, bo, op->dst.bo); DBG(("%s\n", __FUNCTION__)); if (sna->kgem.gen >= 060 && op->dst.bo == bo) op->done = gen6_blt_copy_done; else op->done = nop_done; if (alpha_fixup) { op->blt = blt_composite_copy_with_alpha; op->box = blt_composite_copy_box_with_alpha; op->boxes = blt_composite_copy_boxes_with_alpha; if (!sna_blt_alpha_fixup_init(sna, &op->u.blt, bo, op->dst.bo, src->drawable.bitsPerPixel, alpha_fixup)) return false; } else { op->blt = blt_composite_copy; op->box = blt_composite_copy_box; op->boxes = blt_composite_copy_boxes; if (sna->kgem.gen >= 0100) op->thread_boxes = blt_composite_copy_boxes__thread64; else op->thread_boxes = blt_composite_copy_boxes__thread; if (!sna_blt_copy_init(sna, &op->u.blt, bo, op->dst.bo, src->drawable.bitsPerPixel, GXcopy)) return false; } return true; } fastcall static void blt_put_composite__cpu(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, r->src.x + op->u.blt.sx, r->src.y + op->u.blt.sy, r->dst.x + op->dst.x, r->dst.y + op->dst.y, r->width, r->height); } fastcall static void blt_put_composite_box__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2-box->x1, box->y2-box->y1); } static void blt_put_composite_boxes__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); do { memcpy_blt(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2-box->x1, box->y2-box->y1); box++; } while (--n); } fastcall static void blt_put_composite_with_alpha__cpu(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, r->src.x + op->u.blt.sx, r->src.y + op->u.blt.sy, r->dst.x + op->dst.x, r->dst.y + op->dst.y, r->width, r->height, 0xffffffff, op->u.blt.pixel); } fastcall static void blt_put_composite_box_with_alpha__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2-box->x1, box->y2-box->y1, 0xffffffff, op->u.blt.pixel); } static void blt_put_composite_boxes_with_alpha__cpu(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; assert(src->devPrivate.ptr); assert(src->devKind); assert(dst->devPrivate.ptr); assert(dst->devKind); do { memcpy_xor(src->devPrivate.ptr, dst->devPrivate.ptr, src->drawable.bitsPerPixel, src->devKind, dst->devKind, box->x1 + op->u.blt.sx, box->y1 + op->u.blt.sy, box->x1 + op->dst.x, box->y1 + op->dst.y, box->x2-box->x1, box->y2-box->y1, 0xffffffff, op->u.blt.pixel); box++; } while (--n); } fastcall static void blt_put_composite(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(dst); int pitch = src->devKind; char *data = src->devPrivate.ptr; int bpp = src->drawable.bitsPerPixel; int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; int16_t src_x = r->src.x + op->u.blt.sx; int16_t src_y = r->src.y + op->u.blt.sy; if (!dst_priv->pinned && dst_x <= 0 && dst_y <= 0 && dst_x + r->width >= op->dst.width && dst_y + r->height >= op->dst.height) { data += (src_x - dst_x) * bpp / 8; data += (src_y - dst_y) * pitch; assert(op->dst.bo == dst_priv->gpu_bo); sna_replace(sna, op->dst.pixmap, data, pitch); } else { BoxRec box; bool ok; box.x1 = dst_x; box.y1 = dst_y; box.x2 = dst_x + r->width; box.y2 = dst_y + r->height; ok = sna_write_boxes(sna, dst, dst_priv->gpu_bo, 0, 0, data, pitch, src_x, src_y, &box, 1); assert(ok); (void)ok; } } fastcall static void blt_put_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap); DBG(("%s: src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, op->u.blt.sx, op->u.blt.sy, op->dst.x, op->dst.y)); assert(src->devPrivate.ptr); assert(src->devKind); if (!dst_priv->pinned && box->x2 - box->x1 == op->dst.width && box->y2 - box->y1 == op->dst.height) { int pitch = src->devKind; int bpp = src->drawable.bitsPerPixel / 8; char *data = src->devPrivate.ptr; data += (box->y1 + op->u.blt.sy) * pitch; data += (box->x1 + op->u.blt.sx) * bpp; assert(op->dst.bo == dst_priv->gpu_bo); sna_replace(sna, op->dst.pixmap, data, pitch); } else { bool ok; ok = sna_write_boxes(sna, op->dst.pixmap, op->dst.bo, op->dst.x, op->dst.y, src->devPrivate.ptr, src->devKind, op->u.blt.sx, op->u.blt.sy, box, 1); assert(ok); (void)ok; } } static void blt_put_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap); DBG(("%s: src=(%d, %d), dst=(%d, %d), [(%d, %d), (%d, %d) x %d]\n", __FUNCTION__, op->u.blt.sx, op->u.blt.sy, op->dst.x, op->dst.y, box->x1, box->y1, box->x2, box->y2, n)); assert(src->devPrivate.ptr); assert(src->devKind); if (n == 1 && !dst_priv->pinned && box->x2 - box->x1 == op->dst.width && box->y2 - box->y1 == op->dst.height) { int pitch = src->devKind; int bpp = src->drawable.bitsPerPixel / 8; char *data = src->devPrivate.ptr; data += (box->y1 + op->u.blt.sy) * pitch; data += (box->x1 + op->u.blt.sx) * bpp; assert(op->dst.bo == dst_priv->gpu_bo); sna_replace(sna, op->dst.pixmap, data, pitch); } else { bool ok; ok = sna_write_boxes(sna, op->dst.pixmap, op->dst.bo, op->dst.x, op->dst.y, src->devPrivate.ptr, src->devKind, op->u.blt.sx, op->u.blt.sy, box, n); assert(ok); (void)ok; } } fastcall static void blt_put_composite_with_alpha(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { PixmapPtr dst = op->dst.pixmap; PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(dst); int pitch = src->devKind; char *data = src->devPrivate.ptr; int16_t dst_x = r->dst.x + op->dst.x; int16_t dst_y = r->dst.y + op->dst.y; int16_t src_x = r->src.x + op->u.blt.sx; int16_t src_y = r->src.y + op->u.blt.sy; assert(src->devPrivate.ptr); assert(src->devKind); if (!dst_priv->pinned && dst_x <= 0 && dst_y <= 0 && dst_x + r->width >= op->dst.width && dst_y + r->height >= op->dst.height) { int bpp = dst->drawable.bitsPerPixel / 8; data += (src_x - dst_x) * bpp; data += (src_y - dst_y) * pitch; assert(op->dst.bo == dst_priv->gpu_bo); sna_replace__xor(sna, op->dst.pixmap, data, pitch, 0xffffffff, op->u.blt.pixel); } else { BoxRec box; box.x1 = dst_x; box.y1 = dst_y; box.x2 = dst_x + r->width; box.y2 = dst_y + r->height; sna_write_boxes__xor(sna, dst, dst_priv->gpu_bo, 0, 0, data, pitch, src_x, src_y, &box, 1, 0xffffffff, op->u.blt.pixel); } } fastcall static void blt_put_composite_box_with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap); DBG(("%s: src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, op->u.blt.sx, op->u.blt.sy, op->dst.x, op->dst.y)); assert(src->devPrivate.ptr); assert(src->devKind); if (!dst_priv->pinned && box->x2 - box->x1 == op->dst.width && box->y2 - box->y1 == op->dst.height) { int pitch = src->devKind; int bpp = src->drawable.bitsPerPixel / 8; char *data = src->devPrivate.ptr; data += (box->y1 + op->u.blt.sy) * pitch; data += (box->x1 + op->u.blt.sx) * bpp; assert(op->dst.bo == dst_priv->gpu_bo); sna_replace__xor(sna, op->dst.pixmap, data, pitch, 0xffffffff, op->u.blt.pixel); } else { sna_write_boxes__xor(sna, op->dst.pixmap, op->dst.bo, op->dst.x, op->dst.y, src->devPrivate.ptr, src->devKind, op->u.blt.sx, op->u.blt.sy, box, 1, 0xffffffff, op->u.blt.pixel); } } static void blt_put_composite_boxes_with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int n) { PixmapPtr src = op->u.blt.src_pixmap; struct sna_pixmap *dst_priv = sna_pixmap(op->dst.pixmap); DBG(("%s: src=(%d, %d), dst=(%d, %d), [(%d, %d), (%d, %d) x %d]\n", __FUNCTION__, op->u.blt.sx, op->u.blt.sy, op->dst.x, op->dst.y, box->x1, box->y1, box->x2, box->y2, n)); assert(src->devPrivate.ptr); assert(src->devKind); if (n == 1 && !dst_priv->pinned && box->x2 - box->x1 == op->dst.width && box->y2 - box->y1 == op->dst.height) { int pitch = src->devKind; int bpp = src->drawable.bitsPerPixel / 8; char *data = src->devPrivate.ptr; data += (box->y1 + op->u.blt.sy) * pitch; data += (box->x1 + op->u.blt.sx) * bpp; assert(dst_priv->gpu_bo == op->dst.bo); sna_replace__xor(sna, op->dst.pixmap, data, pitch, 0xffffffff, op->u.blt.pixel); } else { sna_write_boxes__xor(sna, op->dst.pixmap, op->dst.bo, op->dst.x, op->dst.y, src->devPrivate.ptr, src->devKind, op->u.blt.sx, op->u.blt.sy, box, n, 0xffffffff, op->u.blt.pixel); } } static bool prepare_blt_put(struct sna *sna, struct sna_composite_op *op, uint32_t alpha_fixup) { DBG(("%s\n", __FUNCTION__)); assert(!sna_pixmap(op->dst.pixmap)->clear); if (op->dst.bo) { assert(op->dst.bo == sna_pixmap(op->dst.pixmap)->gpu_bo); if (alpha_fixup) { op->u.blt.pixel = alpha_fixup; op->blt = blt_put_composite_with_alpha; op->box = blt_put_composite_box_with_alpha; op->boxes = blt_put_composite_boxes_with_alpha; } else { op->blt = blt_put_composite; op->box = blt_put_composite_box; op->boxes = blt_put_composite_boxes; } op->done = nop_done; return true; } else { if (alpha_fixup) { op->u.blt.pixel = alpha_fixup; op->blt = blt_put_composite_with_alpha__cpu; op->box = blt_put_composite_box_with_alpha__cpu; op->boxes = blt_put_composite_boxes_with_alpha__cpu; } else { op->blt = blt_put_composite__cpu; op->box = blt_put_composite_box__cpu; op->boxes = blt_put_composite_boxes__cpu; } op->done = sig_done; return sigtrap_get() == 0; } } static bool is_clear(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); return priv && priv->clear; } static inline uint32_t over(uint32_t src, uint32_t dst) { uint32_t a = ~src >> 24; #define G_SHIFT 8 #define RB_MASK 0xff00ff #define RB_ONE_HALF 0x800080 #define RB_MASK_PLUS_ONE 0x10000100 #define UN8_rb_MUL_UN8(x, a, t) do { \ t = ((x) & RB_MASK) * (a); \ t += RB_ONE_HALF; \ x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ x &= RB_MASK; \ } while (0) #define UN8_rb_ADD_UN8_rb(x, y, t) do { \ t = ((x) + (y)); \ t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \ x = (t & RB_MASK); \ } while (0) #define UN8x4_MUL_UN8_ADD_UN8x4(x, a, y) do { \ uint32_t r1__, r2__, r3__, t__; \ \ r1__ = (x); \ r2__ = (y) & RB_MASK; \ UN8_rb_MUL_UN8(r1__, (a), t__); \ UN8_rb_ADD_UN8_rb(r1__, r2__, t__); \ \ r2__ = (x) >> G_SHIFT; \ r3__ = ((y) >> G_SHIFT) & RB_MASK; \ UN8_rb_MUL_UN8(r2__, (a), t__); \ UN8_rb_ADD_UN8_rb(r2__, r3__, t__); \ \ (x) = r1__ | (r2__ << G_SHIFT); \ } while (0) UN8x4_MUL_UN8_ADD_UN8x4(dst, a, src); return dst; } static inline uint32_t add(uint32_t src, uint32_t dst) { #define UN8x4_ADD_UN8x4(x, y) do { \ uint32_t r1__, r2__, r3__, t__; \ \ r1__ = (x) & RB_MASK; \ r2__ = (y) & RB_MASK; \ UN8_rb_ADD_UN8_rb(r1__, r2__, t__); \ \ r2__ = ((x) >> G_SHIFT) & RB_MASK; \ r3__ = ((y) >> G_SHIFT) & RB_MASK; \ UN8_rb_ADD_UN8_rb(r2__, r3__, t__); \ \ x = r1__ | (r2__ << G_SHIFT); \ } while (0) UN8x4_ADD_UN8x4(src, dst); return src; } bool sna_blt_composite(struct sna *sna, uint32_t op, PicturePtr src, PicturePtr dst, int16_t x, int16_t y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { PictFormat src_format = src->format; PixmapPtr src_pixmap; struct kgem_bo *bo; int16_t tx, ty; BoxRec dst_box, src_box; uint32_t alpha_fixup; uint32_t color, hint; bool was_clear; bool ret; #if DEBUG_NO_BLT || NO_BLT_COMPOSITE return false; #endif DBG(("%s (%d, %d), (%d, %d), %dx%d\n", __FUNCTION__, x, y, dst_x, dst_y, width, height)); switch (dst->pDrawable->bitsPerPixel) { case 8: case 16: case 32: break; default: DBG(("%s: unhandled bpp: %d\n", __FUNCTION__, dst->pDrawable->bitsPerPixel)); return false; } tmp->dst.pixmap = get_drawable_pixmap(dst->pDrawable); was_clear = is_clear(tmp->dst.pixmap); if (width | height) { dst_box.x1 = dst_x; dst_box.x2 = bound(dst_x, width); dst_box.y1 = dst_y; dst_box.y2 = bound(dst_y, height); } else sna_render_picture_extents(dst, &dst_box); tmp->dst.format = dst->format; tmp->dst.width = tmp->dst.pixmap->drawable.width; tmp->dst.height = tmp->dst.pixmap->drawable.height; get_drawable_deltas(dst->pDrawable, tmp->dst.pixmap, &tmp->dst.x, &tmp->dst.y); if (op == PictOpClear) { clear: if (was_clear && sna_pixmap(tmp->dst.pixmap)->clear_color == 0) { sna_pixmap(tmp->dst.pixmap)->clear = true; return prepare_blt_nop(sna, tmp); } hint = 0; if (can_render(sna)) { hint |= PREFER_GPU; if ((flags & COMPOSITE_PARTIAL) == 0) { hint |= IGNORE_DAMAGE; if (width == tmp->dst.pixmap->drawable.width && height == tmp->dst.pixmap->drawable.height) hint |= REPLACES; } } tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &dst_box, &tmp->damage); if (tmp->dst.bo) { if (!kgem_bo_can_blt(&sna->kgem, tmp->dst.bo)) { DBG(("%s: can not blit to dst, tiling? %d, pitch? %d\n", __FUNCTION__, tmp->dst.bo->tiling, tmp->dst.bo->pitch)); return false; } if (hint & REPLACES) kgem_bo_undo(&sna->kgem, tmp->dst.bo); if (flags & COMPOSITE_UPLOAD) return false; } else { RegionRec region; region.extents = dst_box; region.data = NULL; hint = MOVE_WRITE | MOVE_INPLACE_HINT; if (flags & COMPOSITE_PARTIAL) hint |= MOVE_READ; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, hint)) return false; } return prepare_blt_clear(sna, tmp); } if (is_solid(src)) { if ((op == PictOpOver || op == PictOpAdd) && is_transparent(src)) { sna_pixmap(tmp->dst.pixmap)->clear = was_clear; return prepare_blt_nop(sna, tmp); } if (op == PictOpOver && is_opaque_solid(src)) op = PictOpSrc; if (op == PictOpAdd && is_white(src)) op = PictOpSrc; if (was_clear && (op == PictOpAdd || op == PictOpOver)) { if (sna_pixmap(tmp->dst.pixmap)->clear_color == 0) op = PictOpSrc; if (op == PictOpOver) { color = over(get_solid_color(src, PICT_a8r8g8b8), solid_color(dst->format, sna_pixmap(tmp->dst.pixmap)->clear_color)); op = PictOpSrc; DBG(("%s: precomputing solid OVER (%08x, %08x) -> %08x\n", __FUNCTION__, get_solid_color(src, PICT_a8r8g8b8), solid_color(dst->format, sna_pixmap(tmp->dst.pixmap)->clear_color), color)); } if (op == PictOpAdd) { color = add(get_solid_color(src, PICT_a8r8g8b8), solid_color(dst->format, sna_pixmap(tmp->dst.pixmap)->clear_color)); op = PictOpSrc; DBG(("%s: precomputing solid ADD (%08x, %08x) -> %08x\n", __FUNCTION__, get_solid_color(src, PICT_a8r8g8b8), solid_color(dst->format, sna_pixmap(tmp->dst.pixmap)->clear_color), color)); } } if (op == PictOpOutReverse && is_opaque_solid(src)) goto clear; if (op != PictOpSrc) { DBG(("%s: unsupported op [%d] for blitting\n", __FUNCTION__, op)); return false; } color = get_solid_color(src, tmp->dst.format); fill: if (color == 0) goto clear; if (was_clear && sna_pixmap(tmp->dst.pixmap)->clear_color == color) { sna_pixmap(tmp->dst.pixmap)->clear = true; return prepare_blt_nop(sna, tmp); } hint = 0; if (can_render(sna)) { hint |= PREFER_GPU; if ((flags & COMPOSITE_PARTIAL) == 0) { hint |= IGNORE_DAMAGE; if (width == tmp->dst.pixmap->drawable.width && height == tmp->dst.pixmap->drawable.height) hint |= REPLACES; } } tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &dst_box, &tmp->damage); if (tmp->dst.bo) { if (!kgem_bo_can_blt(&sna->kgem, tmp->dst.bo)) { DBG(("%s: can not blit to dst, tiling? %d, pitch? %d\n", __FUNCTION__, tmp->dst.bo->tiling, tmp->dst.bo->pitch)); return false; } if (hint & REPLACES) kgem_bo_undo(&sna->kgem, tmp->dst.bo); if (flags & COMPOSITE_UPLOAD) return false; } else { RegionRec region; region.extents = dst_box; region.data = NULL; hint = MOVE_WRITE | MOVE_INPLACE_HINT; if (flags & COMPOSITE_PARTIAL) hint |= MOVE_READ; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, hint)) return false; } return prepare_blt_fill(sna, tmp, color); } if (!src->pDrawable) { DBG(("%s: unsupported procedural source\n", __FUNCTION__)); return false; } if (src->filter == PictFilterConvolution) { DBG(("%s: convolutions filters not handled\n", __FUNCTION__)); return false; } if (op == PictOpOver && PICT_FORMAT_A(src_format) == 0) op = PictOpSrc; if (op != PictOpSrc) { DBG(("%s: unsupported op [%d] for blitting\n", __FUNCTION__, op)); return false; } if (!sna_transform_is_imprecise_integer_translation(src->transform, src->filter, dst->polyMode == PolyModePrecise, &tx, &ty)) { DBG(("%s: source transform is not an integer translation\n", __FUNCTION__)); return false; } DBG(("%s: converting transform to integer translation? (%d, %d)\n", __FUNCTION__, src->transform != NULL, tx, ty)); x += tx; y += ty; if ((x >= src->pDrawable->width || y >= src->pDrawable->height || x + width <= 0 || y + height <= 0) && (!src->repeat || src->repeatType == RepeatNone)) { DBG(("%s: source is outside of valid area, converting to clear\n", __FUNCTION__)); goto clear; } src_pixmap = get_drawable_pixmap(src->pDrawable); if (is_clear(src_pixmap)) { if (src->repeat || (x >= 0 && y >= 0 && x + width <= src_pixmap->drawable.width && y + height <= src_pixmap->drawable.height)) { color = color_convert(sna_pixmap(src_pixmap)->clear_color, src->format, tmp->dst.format); goto fill; } } alpha_fixup = 0; if (!(dst->format == src_format || dst->format == alphaless(src_format) || (alphaless(dst->format) == alphaless(src_format) && sna_get_pixel_from_rgba(&alpha_fixup, 0, 0, 0, 0xffff, dst->format)))) { DBG(("%s: incompatible src/dst formats src=%08x, dst=%08x\n", __FUNCTION__, (unsigned)src_format, dst->format)); return false; } /* XXX tiling? fixup extend none? */ if (x < 0 || y < 0 || x + width > src->pDrawable->width || y + height > src->pDrawable->height) { DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d, repeat=%d\n", __FUNCTION__, x, y, x+width, y+width, src->pDrawable->width, src->pDrawable->height, src->repeatType)); if (src->repeat && src->repeatType == RepeatNormal) { x = x % src->pDrawable->width; y = y % src->pDrawable->height; if (x < 0) x += src->pDrawable->width; if (y < 0) y += src->pDrawable->height; if (x + width > src->pDrawable->width || y + height > src->pDrawable->height) return false; } else return false; } get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty); x += tx + src->pDrawable->x; y += ty + src->pDrawable->y; if (x < 0 || y < 0 || x + width > src_pixmap->drawable.width || y + height > src_pixmap->drawable.height) { DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid pixmap %dx%d\n", __FUNCTION__, x, y, x+width, y+width, src_pixmap->drawable.width, src_pixmap->drawable.height)); return false; } tmp->u.blt.src_pixmap = src_pixmap; tmp->u.blt.sx = x - dst_x; tmp->u.blt.sy = y - dst_y; DBG(("%s: blt dst offset (%d, %d), source offset (%d, %d), with alpha fixup? %x\n", __FUNCTION__, tmp->dst.x, tmp->dst.y, tmp->u.blt.sx, tmp->u.blt.sy, alpha_fixup)); src_box.x1 = x; src_box.y1 = y; src_box.x2 = x + width; src_box.y2 = y + height; bo = __sna_render_pixmap_bo(sna, src_pixmap, &src_box, true); if (bo && !kgem_bo_can_blt(&sna->kgem, bo)) { DBG(("%s: can not blit from src size=%dx%d, tiling? %d, pitch? %d\n", __FUNCTION__, src_pixmap->drawable.width < sna->render.max_3d_size, src_pixmap->drawable.height < sna->render.max_3d_size, bo->tiling, bo->pitch)); if (src_pixmap->drawable.width <= sna->render.max_3d_size && src_pixmap->drawable.height <= sna->render.max_3d_size && bo->pitch <= sna->render.max_3d_pitch && (flags & (COMPOSITE_UPLOAD | COMPOSITE_FALLBACK)) == 0) { return false; } bo = NULL; } hint = 0; if (bo || can_render(sna)) { hint |= PREFER_GPU; if ((flags & COMPOSITE_PARTIAL) == 0) { hint |= IGNORE_DAMAGE; if (width == tmp->dst.pixmap->drawable.width && height == tmp->dst.pixmap->drawable.height) hint |= REPLACES; } if (bo) hint |= FORCE_GPU; } tmp->dst.bo = sna_drawable_use_bo(dst->pDrawable, hint, &dst_box, &tmp->damage); if (tmp->dst.bo && hint & REPLACES) { struct sna_pixmap *priv = sna_pixmap(tmp->dst.pixmap); kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); } if (tmp->dst.pixmap == src_pixmap) bo = __sna_render_pixmap_bo(sna, src_pixmap, &src_box, true); ret = false; if (bo) { if (!tmp->dst.bo) { DBG(("%s: fallback -- unaccelerated read back\n", __FUNCTION__)); fallback: if (flags & COMPOSITE_FALLBACK || !kgem_bo_is_busy(bo)) goto put; } else if (!kgem_bo_can_blt(&sna->kgem, bo)) { DBG(("%s: fallback -- cannot blit from source\n", __FUNCTION__)); goto fallback; } else if (bo->snoop && tmp->dst.bo->snoop) { DBG(("%s: fallback -- can not copy between snooped bo\n", __FUNCTION__)); goto put; } else if (!kgem_bo_can_blt(&sna->kgem, tmp->dst.bo)) { DBG(("%s: fallback -- unaccelerated upload\n", __FUNCTION__)); goto fallback; } else if ((flags & COMPOSITE_UPLOAD) == 0) { ret = prepare_blt_copy(sna, tmp, bo, alpha_fixup); if (!ret) goto fallback; } } else { RegionRec region; put: if (tmp->dst.bo == sna_pixmap(tmp->dst.pixmap)->cpu_bo) { DBG(("%s: dropping upload into CPU bo\n", __FUNCTION__)); tmp->dst.bo = NULL; tmp->damage = NULL; } if (tmp->dst.bo == NULL) { hint = MOVE_INPLACE_HINT | MOVE_WRITE; if (flags & COMPOSITE_PARTIAL) hint |= MOVE_READ; region.extents = dst_box; region.data = NULL; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, hint)) return false; assert(tmp->damage == NULL); } region.extents = src_box; region.data = NULL; if (!sna_drawable_move_region_to_cpu(&src_pixmap->drawable, ®ion, MOVE_READ)) return false; ret = prepare_blt_put(sna, tmp, alpha_fixup); } return ret; } static void convert_done(struct sna *sna, const struct sna_composite_op *op) { struct kgem *kgem = &sna->kgem; assert(kgem->nbatch <= KGEM_BATCH_SIZE(kgem)); if (kgem->nexec > 1 && __kgem_ring_empty(kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(kgem); } kgem_bo_destroy(kgem, op->src.bo); sna_render_composite_redirect_done(sna, op); } static void gen6_convert_done(struct sna *sna, const struct sna_composite_op *op) { struct kgem *kgem = &sna->kgem; if (kgem_check_batch(kgem, 3)) { uint32_t *b = kgem->batch + kgem->nbatch; assert(sna->kgem.mode == KGEM_BLT); b[0] = XY_SETUP_CLIP; b[1] = b[2] = 0; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); } convert_done(sna, op); } bool sna_blt_composite__convert(struct sna *sna, int x, int y, int width, int height, struct sna_composite_op *tmp) { uint32_t alpha_fixup; int sx, sy; uint8_t op; #if DEBUG_NO_BLT || NO_BLT_COMPOSITE return false; #endif DBG(("%s src=%d, dst=%d (redirect? %d)\n", __FUNCTION__, tmp->src.bo->handle, tmp->dst.bo->handle, tmp->redirect.real_bo ? tmp->redirect.real_bo->handle : 0)); if (!kgem_bo_can_blt(&sna->kgem, tmp->dst.bo) || !kgem_bo_can_blt(&sna->kgem, tmp->src.bo)) { DBG(("%s: cannot blt from src or to dst\n", __FUNCTION__)); return false; } if (tmp->src.transform) { DBG(("%s: transforms not handled by the BLT\n", __FUNCTION__)); return false; } if (tmp->src.filter == PictFilterConvolution) { DBG(("%s: convolutions filters not handled\n", __FUNCTION__)); return false; } op = tmp->op; if (op == PictOpOver && PICT_FORMAT_A(tmp->src.pict_format) == 0) op = PictOpSrc; if (op != PictOpSrc) { DBG(("%s: unsupported op [%d] for blitting\n", __FUNCTION__, op)); return false; } alpha_fixup = 0; if (!(tmp->dst.format == tmp->src.pict_format || tmp->dst.format == alphaless(tmp->src.pict_format) || (alphaless(tmp->dst.format) == alphaless(tmp->src.pict_format) && sna_get_pixel_from_rgba(&alpha_fixup, 0, 0, 0, 0xffff, tmp->dst.format)))) { DBG(("%s: incompatible src/dst formats src=%08x, dst=%08x\n", __FUNCTION__, (unsigned)tmp->src.pict_format, (unsigned)tmp->dst.format)); return false; } sx = tmp->src.offset[0]; sy = tmp->src.offset[1]; x += sx; y += sy; if (x < 0 || y < 0 || x + width > tmp->src.width || y + height > tmp->src.height) { DBG(("%s: source extends outside (%d, %d), (%d, %d) of valid drawable %dx%d\n", __FUNCTION__, x, y, x+width, y+width, tmp->src.width, tmp->src.height)); if (tmp->src.repeat == RepeatNormal) { int xx = x % tmp->src.width; int yy = y % tmp->src.height; if (xx < 0) xx += tmp->src.width; if (yy < 0) yy += tmp->src.height; if (xx + width > tmp->src.width || yy + height > tmp->src.height) return false; sx += xx - x; sy += yy - y; } else return false; } DBG(("%s: blt dst offset (%d, %d), source offset (%d, %d), with alpha fixup? %x\n", __FUNCTION__, tmp->dst.x, tmp->dst.y, sx, sy, alpha_fixup)); tmp->u.blt.src_pixmap = NULL; tmp->u.blt.sx = sx; tmp->u.blt.sy = sy; kgem_set_mode(&sna->kgem, KGEM_BLT, tmp->dst.bo); if (!kgem_check_many_bo_fenced(&sna->kgem, tmp->dst.bo, tmp->src.bo, NULL)) { kgem_submit(&sna->kgem); if (!kgem_check_many_bo_fenced(&sna->kgem, tmp->dst.bo, tmp->src.bo, NULL)) { DBG(("%s: fallback -- no room in aperture\n", __FUNCTION__)); return sna_tiling_blt_composite(sna, tmp, tmp->src.bo, PICT_FORMAT_BPP(tmp->src.pict_format), alpha_fixup); } _kgem_set_mode(&sna->kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, tmp->src.bo, tmp->dst.bo); if (alpha_fixup) { tmp->blt = blt_composite_copy_with_alpha; tmp->box = blt_composite_copy_box_with_alpha; tmp->boxes = blt_composite_copy_boxes_with_alpha; if (!sna_blt_alpha_fixup_init(sna, &tmp->u.blt, tmp->src.bo, tmp->dst.bo, PICT_FORMAT_BPP(tmp->src.pict_format), alpha_fixup)) return false; } else { tmp->blt = blt_composite_copy; tmp->box = blt_composite_copy_box; tmp->boxes = blt_composite_copy_boxes; tmp->thread_boxes = blt_composite_copy_boxes__thread; if (!sna_blt_copy_init(sna, &tmp->u.blt, tmp->src.bo, tmp->dst.bo, PICT_FORMAT_BPP(tmp->src.pict_format), GXcopy)) return false; } tmp->done = convert_done; if (sna->kgem.gen >= 060 && tmp->src.bo == tmp->dst.bo) tmp->done = gen6_convert_done; return true; } static void sna_blt_fill_op_blt(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t width, int16_t height) { if (sna->blt_state.fill_bo != op->base.u.blt.bo[0]->unique_id) { const struct sna_blt_state *blt = &op->base.u.blt; __sna_blt_fill_begin(sna, blt); sna->blt_state.fill_bo = blt->bo[0]->unique_id; sna->blt_state.fill_pixel = blt->pixel; sna->blt_state.fill_alu = blt->alu; } sna_blt_fill_one(sna, &op->base.u.blt, x, y, width, height); } fastcall static void sna_blt_fill_op_box(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box) { if (sna->blt_state.fill_bo != op->base.u.blt.bo[0]->unique_id) { const struct sna_blt_state *blt = &op->base.u.blt; __sna_blt_fill_begin(sna, blt); sna->blt_state.fill_bo = blt->bo[0]->unique_id; sna->blt_state.fill_pixel = blt->pixel; sna->blt_state.fill_alu = blt->alu; } _sna_blt_fill_box(sna, &op->base.u.blt, box); } fastcall static void sna_blt_fill_op_boxes(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int nbox) { if (sna->blt_state.fill_bo != op->base.u.blt.bo[0]->unique_id) { const struct sna_blt_state *blt = &op->base.u.blt; __sna_blt_fill_begin(sna, blt); sna->blt_state.fill_bo = blt->bo[0]->unique_id; sna->blt_state.fill_pixel = blt->pixel; sna->blt_state.fill_alu = blt->alu; } _sna_blt_fill_boxes(sna, &op->base.u.blt, box, nbox); } static inline uint64_t pt_add(uint32_t cmd, const DDXPointRec *pt, int16_t dx, int16_t dy) { union { DDXPointRec pt; uint32_t i; } u; u.pt.x = pt->x + dx; u.pt.y = pt->y + dy; return cmd | (uint64_t)u.i<<32; } fastcall static void sna_blt_fill_op_points(struct sna *sna, const struct sna_fill_op *op, int16_t dx, int16_t dy, const DDXPointRec *p, int n) { const struct sna_blt_state *blt = &op->base.u.blt; struct kgem *kgem = &sna->kgem; uint32_t cmd; DBG(("%s: %08x x %d\n", __FUNCTION__, blt->pixel, n)); if (sna->blt_state.fill_bo != op->base.u.blt.bo[0]->unique_id) { __sna_blt_fill_begin(sna, blt); sna->blt_state.fill_bo = blt->bo[0]->unique_id; sna->blt_state.fill_pixel = blt->pixel; sna->blt_state.fill_alu = blt->alu; } if (!kgem_check_batch(kgem, 2)) sna_blt_fill_begin(sna, blt); cmd = XY_PIXEL_BLT; if (kgem->gen >= 040 && op->base.u.blt.bo[0]->tiling) cmd |= BLT_DST_TILED; do { uint32_t *b = kgem->batch + kgem->nbatch; int n_this_time, rem; assert(sna->kgem.mode == KGEM_BLT); n_this_time = n; rem = kgem_batch_space(kgem); if (2*n_this_time > rem) n_this_time = rem / 2; assert(n_this_time); n -= n_this_time; kgem->nbatch += 2 * n_this_time; assert(kgem->nbatch < kgem->surface); if ((dx|dy) == 0) { do { *(uint64_t *)b = pt_add(cmd, p++, 0, 0); b += 2; } while (--n_this_time); } else { do { *(uint64_t *)b = pt_add(cmd, p++, dx, dy); b += 2; } while (--n_this_time); } if (!n) return; sna_blt_fill_begin(sna, blt); } while (1); } bool sna_blt_fill(struct sna *sna, uint8_t alu, struct kgem_bo *bo, int bpp, uint32_t pixel, struct sna_fill_op *fill) { #if DEBUG_NO_BLT || NO_BLT_FILL return false; #endif DBG(("%s(alu=%d, pixel=%x, bpp=%d)\n", __FUNCTION__, alu, pixel, bpp)); if (!kgem_bo_can_blt(&sna->kgem, bo)) { DBG(("%s: rejected due to incompatible Y-tiling\n", __FUNCTION__)); return false; } if (!sna_blt_fill_init(sna, &fill->base.u.blt, bo, bpp, alu, pixel)) return false; assert(sna->kgem.mode == KGEM_BLT); fill->blt = sna_blt_fill_op_blt; fill->box = sna_blt_fill_op_box; fill->boxes = sna_blt_fill_op_boxes; fill->points = sna_blt_fill_op_points; fill->done = (void (*)(struct sna *, const struct sna_fill_op *))nop_done; return true; } static void sna_blt_copy_op_blt(struct sna *sna, const struct sna_copy_op *op, int16_t src_x, int16_t src_y, int16_t width, int16_t height, int16_t dst_x, int16_t dst_y) { sna_blt_copy_one(sna, &op->base.u.blt, src_x, src_y, width, height, dst_x, dst_y); } bool sna_blt_copy(struct sna *sna, uint8_t alu, struct kgem_bo *src, struct kgem_bo *dst, int bpp, struct sna_copy_op *op) { #if DEBUG_NO_BLT || NO_BLT_COPY return false; #endif if (!kgem_bo_can_blt(&sna->kgem, src)) return false; if (!kgem_bo_can_blt(&sna->kgem, dst)) return false; if (!sna_blt_copy_init(sna, &op->base.u.blt, src, dst, bpp, alu)) return false; op->blt = sna_blt_copy_op_blt; if (sna->kgem.gen >= 060 && src == dst) op->done = (void (*)(struct sna *, const struct sna_copy_op *)) gen6_blt_copy_done; else op->done = (void (*)(struct sna *, const struct sna_copy_op *)) nop_done; return true; } static bool sna_blt_fill_box(struct sna *sna, uint8_t alu, struct kgem_bo *bo, int bpp, uint32_t color, const BoxRec *box) { struct kgem *kgem = &sna->kgem; uint32_t br13, cmd, *b; bool overwrites; assert(kgem_bo_can_blt (kgem, bo)); DBG(("%s: box=((%d, %d), (%d, %d))\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); assert(box->x1 >= 0); assert(box->y1 >= 0); cmd = XY_COLOR_BLT | (kgem->gen >= 0100 ? 5 : 4); br13 = bo->pitch; if (kgem->gen >= 040 && bo->tiling) { cmd |= BLT_DST_TILED; br13 >>= 2; } assert(br13 <= MAXSHORT); br13 |= fill_ROP[alu] << 16; switch (bpp) { default: assert(0); case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } /* All too frequently one blt completely overwrites the previous */ overwrites = alu == GXcopy || alu == GXclear || alu == GXset; if (overwrites) { if (sna->kgem.gen >= 0100) { if (kgem->nbatch >= 7 && kgem->batch[kgem->nbatch-7] == cmd && *(uint64_t *)&kgem->batch[kgem->nbatch-5] == *(const uint64_t *)box && kgem->reloc[kgem->nreloc-1].target_handle == bo->target_handle) { DBG(("%s: replacing last fill\n", __FUNCTION__)); kgem->batch[kgem->nbatch-6] = br13; kgem->batch[kgem->nbatch-1] = color; return true; } if (kgem->nbatch >= 10 && (kgem->batch[kgem->nbatch-10] & 0xffc00000) == XY_SRC_COPY_BLT_CMD && *(uint64_t *)&kgem->batch[kgem->nbatch-8] == *(const uint64_t *)box && kgem->reloc[kgem->nreloc-2].target_handle == bo->target_handle) { DBG(("%s: replacing last copy\n", __FUNCTION__)); kgem->batch[kgem->nbatch-10] = cmd; kgem->batch[kgem->nbatch-8] = br13; kgem->batch[kgem->nbatch-4] = color; /* Keep the src bo as part of the execlist, just remove * its relocation entry. */ kgem->nreloc--; kgem->nbatch -= 3; return true; } } else { if (kgem->nbatch >= 6 && kgem->batch[kgem->nbatch-6] == cmd && *(uint64_t *)&kgem->batch[kgem->nbatch-4] == *(const uint64_t *)box && kgem->reloc[kgem->nreloc-1].target_handle == bo->target_handle) { DBG(("%s: replacing last fill\n", __FUNCTION__)); kgem->batch[kgem->nbatch-5] = br13; kgem->batch[kgem->nbatch-1] = color; return true; } if (kgem->nbatch >= 8 && (kgem->batch[kgem->nbatch-8] & 0xffc00000) == XY_SRC_COPY_BLT_CMD && *(uint64_t *)&kgem->batch[kgem->nbatch-6] == *(const uint64_t *)box && kgem->reloc[kgem->nreloc-2].target_handle == bo->target_handle) { DBG(("%s: replacing last copy\n", __FUNCTION__)); kgem->batch[kgem->nbatch-8] = cmd; kgem->batch[kgem->nbatch-7] = br13; kgem->batch[kgem->nbatch-3] = color; /* Keep the src bo as part of the execlist, just remove * its relocation entry. */ kgem->nreloc--; kgem->nbatch -= 2; return true; } } } /* If we are currently emitting SCANLINES, keep doing so */ if (sna->blt_state.fill_bo == bo->unique_id && sna->blt_state.fill_pixel == color && (sna->blt_state.fill_alu == alu || sna->blt_state.fill_alu == ~alu)) { DBG(("%s: matching last fill, converting to scanlines\n", __FUNCTION__)); return false; } kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 7) || !kgem_check_reloc(kgem, 1) || !kgem_check_bo_fenced(kgem, bo)) { kgem_submit(kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(kgem_check_batch(kgem, 6)); assert(kgem_check_reloc(kgem, 1)); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; *(uint64_t *)(b+2) = *(const uint64_t *)box; if (kgem->gen >= 0100) { *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = color; kgem->nbatch += 7; } else { b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = color; kgem->nbatch += 6; } assert(kgem->nbatch < kgem->surface); sna->blt_state.fill_bo = bo->unique_id; sna->blt_state.fill_pixel = color; sna->blt_state.fill_alu = ~alu; return true; } bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *bo, int bpp, uint32_t pixel, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; uint32_t br13, cmd; #if DEBUG_NO_BLT || NO_BLT_FILL_BOXES return false; #endif DBG(("%s (%d, %08x, %d) x %d\n", __FUNCTION__, bpp, pixel, alu, nbox)); if (!kgem_bo_can_blt(kgem, bo)) { DBG(("%s: fallback -- cannot blt to dst\n", __FUNCTION__)); return false; } if (alu == GXclear) pixel = 0; else if (alu == GXcopy) { if (pixel == 0) alu = GXclear; else if (pixel == -1) alu = GXset; } if (nbox == 1 && sna_blt_fill_box(sna, alu, bo, bpp, pixel, box)) return true; br13 = bo->pitch; cmd = XY_SCANLINE_BLT; if (kgem->gen >= 040 && bo->tiling) { cmd |= 1 << 11; br13 >>= 2; } assert(br13 <= MAXSHORT); br13 |= 1<<31 | fill_ROP[alu] << 16; switch (bpp) { default: assert(0); case 32: br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } kgem_set_mode(kgem, KGEM_BLT, bo); if (!kgem_check_batch(kgem, 14) || !kgem_check_bo_fenced(kgem, bo)) { kgem_submit(kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(kgem, KGEM_BLT); } if (sna->blt_state.fill_bo != bo->unique_id || sna->blt_state.fill_pixel != pixel || sna->blt_state.fill_alu != alu) { uint32_t *b; if (!kgem_check_batch(kgem, 24) || !kgem_check_reloc(kgem, 1)) { _kgem_submit(kgem); if (!kgem_check_bo_fenced(&sna->kgem, bo)) return false; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; if (kgem->gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 8; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling) b[0] |= BLT_DST_TILED; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = pixel; b[7] = pixel; b[8] = 0; b[9] = 0; kgem->nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 7; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling && kgem->gen >= 040) b[0] |= BLT_DST_TILED; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = pixel; b[6] = pixel; b[7] = 0; b[8] = 0; kgem->nbatch += 9; } assert(kgem->nbatch < kgem->surface); sna->blt_state.fill_bo = bo->unique_id; sna->blt_state.fill_pixel = pixel; sna->blt_state.fill_alu = alu; } do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (3*nbox_this_time > rem) nbox_this_time = rem / 3; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b; DBG(("%s: (%d, %d), (%d, %d): %08x\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, pixel)); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->y2 * bo->pitch <= kgem_bo_size(bo)); b = kgem->batch + kgem->nbatch; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); b[0] = cmd; *(uint64_t *)(b+1) = *(const uint64_t *)box; box++; } while (--nbox_this_time); if (nbox) { uint32_t *b; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, bo); assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; if (kgem->gen >= 0100) { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 8; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling) b[0] |= BLT_DST_TILED; b[1] = br13; b[2] = 0; b[3] = 0; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = pixel; b[7] = pixel; b[8] = 0; b[9] = 0; kgem->nbatch += 10; } else { b[0] = XY_SETUP_MONO_PATTERN_SL_BLT | 7; if (bpp == 32) b[0] |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; if (bo->tiling && kgem->gen >= 040) b[0] |= BLT_DST_TILED; b[1] = br13; b[2] = 0; b[3] = 0; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = pixel; b[6] = pixel; b[7] = 0; b[8] = 0; kgem->nbatch += 9; } assert(kgem->nbatch < kgem->surface); assert(kgem_check_batch(kgem, 3)); } } while (nbox); if (kgem->nexec > 1 && __kgem_ring_empty(kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(kgem); } return true; } bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; unsigned src_pitch, br13, cmd; #if DEBUG_NO_BLT || NO_BLT_COPY_BOXES return false; #endif DBG(("%s src=(%d, %d) -> (%d, %d) x %d, tiling=(%d, %d), pitch=(%d, %d)\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, nbox, src_bo->tiling, dst_bo->tiling, src_bo->pitch, dst_bo->pitch)); assert(nbox); if (wedged(sna) || !kgem_bo_can_blt(kgem, src_bo) || !kgem_bo_can_blt(kgem, dst_bo)) { DBG(("%s: cannot blt to src? %d or dst? %d\n", __FUNCTION__, kgem_bo_can_blt(kgem, src_bo), kgem_bo_can_blt(kgem, dst_bo))); return false; } cmd = XY_SRC_COPY_BLT_CMD; if (bpp == 32) cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; src_pitch = src_bo->pitch; if (kgem->gen >= 040 && src_bo->tiling) { cmd |= BLT_SRC_TILED; src_pitch >>= 2; } assert(src_pitch <= MAXSHORT); br13 = dst_bo->pitch; if (kgem->gen >= 040 && dst_bo->tiling) { cmd |= BLT_DST_TILED; br13 >>= 2; } assert(br13 <= MAXSHORT); br13 |= copy_ROP[alu] << 16; switch (bpp) { default: assert(0); case 32: br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } /* Compare first box against a previous fill */ if ((alu == GXcopy || alu == GXclear || alu == GXset) && kgem->reloc[kgem->nreloc-1].target_handle == dst_bo->target_handle) { if (kgem->gen >= 0100) { if (kgem->nbatch >= 7 && kgem->batch[kgem->nbatch-7] == (XY_COLOR_BLT | (cmd & (BLT_DST_TILED | BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 5) && kgem->batch[kgem->nbatch-5] == ((uint32_t)(box->y1 + dst_dy) << 16 | (uint16_t)(box->x1 + dst_dx)) && kgem->batch[kgem->nbatch-4] == ((uint32_t)(box->y2 + dst_dy) << 16 | (uint16_t)(box->x2 + dst_dx))) { DBG(("%s: deleting last fill\n", __FUNCTION__)); kgem->nbatch -= 7; kgem->nreloc--; } } else { if (kgem->nbatch >= 6 && kgem->batch[kgem->nbatch-6] == (XY_COLOR_BLT | (cmd & (BLT_DST_TILED | BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 4) && kgem->batch[kgem->nbatch-4] == ((uint32_t)(box->y1 + dst_dy) << 16 | (uint16_t)(box->x1 + dst_dx)) && kgem->batch[kgem->nbatch-3] == ((uint32_t)(box->y2 + dst_dy) << 16 | (uint16_t)(box->x2 + dst_dx))) { DBG(("%s: deleting last fill\n", __FUNCTION__)); kgem->nbatch -= 6; kgem->nreloc--; } } } kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc(kgem, 2) || !kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { DBG(("%s: not enough room in aperture, fallback to tiling copy\n", __FUNCTION__)); return sna_tiling_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, bpp, box, nbox); } _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); if ((dst_dx | dst_dy) == 0) { if (kgem->gen >= 0100) { uint64_t hdr = (uint64_t)br13 << 32 | cmd | 8; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 10; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + src_dx <= INT16_MAX); assert(box->y1 + src_dy <= INT16_MAX); assert(box->x1 >= 0); assert(box->y1 >= 0); *(uint64_t *)&b[0] = hdr; *(uint64_t *)&b[2] = *(const uint64_t *)box; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = add2(b[2], src_dx, src_dy); b[7] = src_pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } else { uint64_t hdr = (uint64_t)br13 << 32 | cmd | 6; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + src_dx <= INT16_MAX); assert(box->y1 + src_dy <= INT16_MAX); assert(box->x1 >= 0); assert(box->y1 >= 0); *(uint64_t *)&b[0] = hdr; *(uint64_t *)&b[2] = *(const uint64_t *)box; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = add2(b[2], src_dx, src_dy); b[6] = src_pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } } else { if (kgem->gen >= 0100) { cmd |= 8; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 10; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); b[0] = cmd; b[1] = br13; b[2] = ((box->y1 + dst_dy) << 16) | (box->x1 + dst_dx); b[3] = ((box->y2 + dst_dy) << 16) | (box->x2 + dst_dx); *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = ((box->y1 + src_dy) << 16) | (box->x1 + src_dx); b[7] = src_pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } else { cmd |= 6; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2; DBG(("%s: emitting %d boxes out of %d (batch space %d)\n", __FUNCTION__, nbox_this_time, nbox, rem)); assert(nbox_this_time > 0); nbox -= nbox_this_time; assert(sna->kgem.mode == KGEM_BLT); do { uint32_t *b = kgem->batch + kgem->nbatch; DBG((" %s: box=(%d, %d)x(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1)); assert(box->x1 + src_dx >= 0); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); b[0] = cmd; b[1] = br13; b[2] = ((box->y1 + dst_dy) << 16) | (box->x1 + dst_dx); b[3] = ((box->y2 + dst_dy) << 16) | (box->x2 + dst_dx); b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = ((box->y1 + src_dy) << 16) | (box->x1 + src_dx); b[6] = src_pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; assert(kgem->nbatch < kgem->surface); box++; } while (--nbox_this_time); if (!nbox) break; _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } while (1); } } if (kgem->nexec > 1 && __kgem_ring_empty(kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(kgem); } else if (kgem->gen >= 060 && src_bo == dst_bo && kgem_check_batch(kgem, 3)) { uint32_t *b = kgem->batch + kgem->nbatch; assert(sna->kgem.mode == KGEM_BLT); b[0] = XY_SETUP_CLIP; b[1] = b[2] = 0; kgem->nbatch += 3; assert(kgem->nbatch < kgem->surface); } sna->blt_state.fill_bo = 0; return true; } bool sna_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, int alpha_fixup, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; unsigned src_pitch, br13, cmd; #if DEBUG_NO_BLT || NO_BLT_COPY_BOXES return false; #endif DBG(("%s src=(%d, %d) -> (%d, %d) x %d, tiling=(%d, %d), pitch=(%d, %d)\n", __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, nbox, src_bo->tiling, dst_bo->tiling, src_bo->pitch, dst_bo->pitch)); if (wedged(sna) || !kgem_bo_can_blt(kgem, src_bo) || !kgem_bo_can_blt(kgem, dst_bo)) { DBG(("%s: cannot blt to src? %d or dst? %d\n", __FUNCTION__, kgem_bo_can_blt(kgem, src_bo), kgem_bo_can_blt(kgem, dst_bo))); return false; } cmd = XY_FULL_MONO_PATTERN_BLT | (kgem->gen >= 0100 ? 12 : 10); src_pitch = src_bo->pitch; if (kgem->gen >= 040 && src_bo->tiling) { cmd |= BLT_SRC_TILED; src_pitch >>= 2; } assert(src_pitch <= MAXSHORT); br13 = dst_bo->pitch; if (kgem->gen >= 040 && dst_bo->tiling) { cmd |= BLT_DST_TILED; br13 >>= 2; } assert(br13 <= MAXSHORT); br13 |= copy_ROP[alu] << 16; switch (bpp) { default: assert(0); case 32: br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { DBG(("%s: cannot fit src+dst into aperture\n", __FUNCTION__)); return false; } /* Compare first box against a previous fill */ if ((alu == GXcopy || alu == GXclear || alu == GXset) && kgem->reloc[kgem->nreloc-1].target_handle == dst_bo->target_handle) { if (kgem->gen >= 0100) { if (kgem->nbatch >= 7 && kgem->batch[kgem->nbatch-7] == (XY_COLOR_BLT | (cmd & (BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 5) && kgem->batch[kgem->nbatch-5] == ((uint32_t)(box->y1 + dst_dy) << 16 | (uint16_t)(box->x1 + dst_dx)) && kgem->batch[kgem->nbatch-4] == ((uint32_t)(box->y2 + dst_dy) << 16 | (uint16_t)(box->x2 + dst_dx))) { DBG(("%s: deleting last fill\n", __FUNCTION__)); kgem->nbatch -= 7; kgem->nreloc--; } } else { if (kgem->nbatch >= 6 && kgem->batch[kgem->nbatch-6] == (XY_COLOR_BLT | (cmd & (BLT_WRITE_ALPHA | BLT_WRITE_RGB)) | 4) && kgem->batch[kgem->nbatch-4] == ((uint32_t)(box->y1 + dst_dy) << 16 | (uint16_t)(box->x1 + dst_dx)) && kgem->batch[kgem->nbatch-3] == ((uint32_t)(box->y2 + dst_dy) << 16 | (uint16_t)(box->x2 + dst_dx))) { DBG(("%s: deleting last fill\n", __FUNCTION__)); kgem->nbatch -= 6; kgem->nreloc--; } } } while (nbox--) { uint32_t *b; if (!kgem_check_batch(kgem, 14) || !kgem_check_reloc(kgem, 2)) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo); } assert(sna->kgem.mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); if (sna->kgem.gen >= 0100) { *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = src_pitch; b[7] = (box->y1 + src_dy) << 16 | (box->x1 + src_dx); *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[10] = alpha_fixup; b[11] = alpha_fixup; b[12] = 0; b[13] = 0; kgem->nbatch += 14; } else { b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = src_pitch; b[6] = (box->y1 + src_dy) << 16 | (box->x1 + src_dx); b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); b[8] = alpha_fixup; b[9] = alpha_fixup; b[10] = 0; b[11] = 0; kgem->nbatch += 12; } assert(kgem->nbatch < kgem->surface); box++; } if (kgem->nexec > 1 && __kgem_ring_empty(kgem)) { DBG(("%s: flushing BLT operation on empty ring\n", __FUNCTION__)); _kgem_submit(kgem); } sna->blt_state.fill_bo = 0; return true; } static void box_extents(const BoxRec *box, int n, BoxRec *extents) { *extents = *box; while (--n) { box++; if (box->x1 < extents->x1) extents->x1 = box->x1; if (box->y1 < extents->y1) extents->y1 = box->y1; if (box->x2 > extents->x2) extents->x2 = box->x2; if (box->y2 > extents->y2) extents->y2 = box->y2; } } bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int nbox) { struct kgem_bo *free_bo = NULL; bool ret; DBG(("%s: alu=%d, n=%d\n", __FUNCTION__, alu, nbox)); if (!sna_blt_compare_depth(src, dst)) { DBG(("%s: mismatching depths %d -> %d\n", __FUNCTION__, src->depth, dst->depth)); return false; } if (src_bo == dst_bo) { DBG(("%s: dst == src\n", __FUNCTION__)); if (src_bo->tiling == I915_TILING_Y && !sna->kgem.can_blt_y && kgem_bo_blt_pitch_is_ok(&sna->kgem, src_bo)) { struct kgem_bo *bo; DBG(("%s: src is Y-tiled\n", __FUNCTION__)); if (src->type != DRAWABLE_PIXMAP) return false; assert(sna_pixmap((PixmapPtr)src)->gpu_bo == src_bo); bo = sna_pixmap_change_tiling((PixmapPtr)src, I915_TILING_X); if (bo == NULL) { BoxRec extents; DBG(("%s: y-tiling conversion failed\n", __FUNCTION__)); box_extents(box, nbox, &extents); free_bo = kgem_create_2d(&sna->kgem, extents.x2 - extents.x1, extents.y2 - extents.y1, src->bitsPerPixel, I915_TILING_X, 0); if (free_bo == NULL) { DBG(("%s: fallback -- temp allocation failed\n", __FUNCTION__)); return false; } if (!sna_blt_copy_boxes(sna, GXcopy, src_bo, src_dx, src_dy, free_bo, -extents.x1, -extents.y1, src->bitsPerPixel, box, nbox)) { DBG(("%s: fallback -- temp copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, free_bo); return false; } src_dx = -extents.x1; src_dy = -extents.y1; src_bo = free_bo; } else dst_bo = src_bo = bo; } } else { if (src_bo->tiling == I915_TILING_Y && !sna->kgem.can_blt_y && kgem_bo_blt_pitch_is_ok(&sna->kgem, src_bo)) { DBG(("%s: src is y-tiled\n", __FUNCTION__)); if (src->type != DRAWABLE_PIXMAP) return false; assert(sna_pixmap((PixmapPtr)src)->gpu_bo == src_bo); src_bo = sna_pixmap_change_tiling((PixmapPtr)src, I915_TILING_X); if (src_bo == NULL) { DBG(("%s: fallback -- src y-tiling conversion failed\n", __FUNCTION__)); return false; } } if (dst_bo->tiling == I915_TILING_Y && !sna->kgem.can_blt_y && kgem_bo_blt_pitch_is_ok(&sna->kgem, dst_bo)) { DBG(("%s: dst is y-tiled\n", __FUNCTION__)); if (dst->type != DRAWABLE_PIXMAP) return false; assert(sna_pixmap((PixmapPtr)dst)->gpu_bo == dst_bo); dst_bo = sna_pixmap_change_tiling((PixmapPtr)dst, I915_TILING_X); if (dst_bo == NULL) { DBG(("%s: fallback -- dst y-tiling conversion failed\n", __FUNCTION__)); return false; } } } ret = sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, nbox); if (free_bo) kgem_bo_destroy(&sna->kgem, free_bo); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_composite.c000066400000000000000000001011021267532330400246450ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "fb/fbpict.h" #include #define NO_COMPOSITE 0 #define NO_COMPOSITE_RECTANGLES 0 #define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v)) bool sna_composite_create(struct sna *sna) { xRenderColor color = { 0 }; int error; sna->clear = CreateSolidPicture(0, &color, &error); return sna->clear != NULL; } void sna_composite_close(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); if (sna->clear) { FreePicture(sna->clear, 0); sna->clear = NULL; } } static inline bool region_is_singular(pixman_region16_t *region) { return region->data == NULL; } static inline bool region_is_empty(pixman_region16_t *region) { return region->data && region->data->numRects == 0; } static inline pixman_bool_t clip_to_dst(pixman_region16_t *region, pixman_region16_t *clip, int dx, int dy) { DBG(("%s: region: %dx[(%d, %d), (%d, %d)], clip: %dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, pixman_region_n_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, pixman_region_n_rects(clip), clip->extents.x1, clip->extents.y1, clip->extents.x2, clip->extents.y2)); if (region_is_singular(region) && region_is_singular(clip)) { pixman_box16_t *r = ®ion->extents; pixman_box16_t *c = &clip->extents; int v; if (r->x1 < (v = c->x1 + dx)) r->x1 = BOUND(v); if (r->x2 > (v = c->x2 + dx)) r->x2 = BOUND(v); if (r->y1 < (v = c->y1 + dy)) r->y1 = BOUND(v); if (r->y2 > (v = c->y2 + dy)) r->y2 = BOUND(v); if (r->x1 >= r->x2 || r->y1 >= r->y2) { pixman_region_init(region); return FALSE; } return true; } else if (region_is_empty(clip)) { return FALSE; } else { if (dx | dy) pixman_region_translate(region, -dx, -dy); if (!pixman_region_intersect(region, region, clip)) return FALSE; if (dx | dy) pixman_region_translate(region, dx, dy); return !region_is_empty(region); } } static inline bool picture_has_clip(PicturePtr p) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,16,99,1,0) return p->clientClip; #else return p->clientClipType != CT_NONE; #endif } static inline bool clip_to_src(RegionPtr region, PicturePtr p, int dx, int dy) { bool result; if (!picture_has_clip(p)) return true; pixman_region_translate(p->clientClip, p->clipOrigin.x + dx, p->clipOrigin.y + dy); result = RegionIntersect(region, region, p->clientClip); pixman_region_translate(p->clientClip, -(p->clipOrigin.x + dx), -(p->clipOrigin.y + dy)); return result && !region_is_empty(region); } bool sna_compute_composite_region(RegionPtr region, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height) { int v; DBG(("%s: dst=(%d, %d)x(%d, %d)\n", __FUNCTION__, dst_x, dst_y, width, height)); region->extents.x1 = dst_x < 0 ? 0 : dst_x; v = dst_x + width; if (v > dst->pDrawable->width) v = dst->pDrawable->width; region->extents.x2 = v; region->extents.y1 = dst_y < 0 ? 0 : dst_y; v = dst_y + height; if (v > dst->pDrawable->height) v = dst->pDrawable->height; region->extents.y2 = v; region->data = 0; DBG(("%s: initial clip against dst->pDrawable: (%d, %d), (%d, %d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (region->extents.x1 >= region->extents.x2 || region->extents.y1 >= region->extents.y2) return false; region->extents.x1 += dst->pDrawable->x; region->extents.x2 += dst->pDrawable->x; region->extents.y1 += dst->pDrawable->y; region->extents.y2 += dst->pDrawable->y; dst_x += dst->pDrawable->x; dst_y += dst->pDrawable->y; /* clip against dst */ if (!clip_to_dst(region, dst->pCompositeClip, 0, 0)) return false; DBG(("%s: clip against dst->pCompositeClip: (%d, %d), (%d, %d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (dst->alphaMap) { if (!clip_to_dst(region, dst->alphaMap->pCompositeClip, -dst->alphaOrigin.x, -dst->alphaOrigin.y)) { pixman_region_fini (region); return false; } } /* clip against src */ if (src) { if (src->pDrawable) { src_x += src->pDrawable->x; src_y += src->pDrawable->y; } if (!clip_to_src(region, src, dst_x - src_x, dst_y - src_y)) { pixman_region_fini (region); return false; } DBG(("%s: clip against src (%dx%d clip=%d): (%d, %d), (%d, %d)\n", __FUNCTION__, src->pDrawable ? src->pDrawable->width : 0, src->pDrawable ? src->pDrawable->height : 0, picture_has_clip(src), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (src->alphaMap) { if (!clip_to_src(region, src->alphaMap, dst_x - (src_x - src->alphaOrigin.x), dst_y - (src_y - src->alphaOrigin.y))) { pixman_region_fini(region); return false; } } } /* clip against mask */ if (mask) { if (mask->pDrawable) { mask_x += mask->pDrawable->x; mask_y += mask->pDrawable->y; } if (!clip_to_src(region, mask, dst_x - mask_x, dst_y - mask_y)) { pixman_region_fini(region); return false; } if (mask->alphaMap) { if (!clip_to_src(region, mask->alphaMap, dst_x - (mask_x - mask->alphaOrigin.x), dst_y - (mask_y - mask->alphaOrigin.y))) { pixman_region_fini(region); return false; } } DBG(("%s: clip against mask: (%d, %d), (%d, %d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); } return !region_is_empty(region); } static void trim_extents(BoxPtr extents, const PicturePtr p, int dx, int dy) { const BoxPtr box = REGION_EXTENTS(NULL, p->pCompositeClip); DBG(("%s: trim((%d, %d), (%d, %d)) against ((%d, %d), (%d, %d)) + (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2, box->x1, box->y1, box->x2, box->y2, dx, dy)); if (extents->x1 < box->x1 + dx) extents->x1 = box->x1 + dx; if (extents->x2 > box->x2 + dx) extents->x2 = box->x2 + dx; if (extents->y1 < box->y1 + dy) extents->y1 = box->y1 + dy; if (extents->y2 > box->y2 + dy) extents->y2 = box->y2 + dy; } static void _trim_source_extents(BoxPtr extents, const PicturePtr p, int dx, int dy) { if (picture_has_clip(p)) trim_extents(extents, p, dx, dy); } static void trim_source_extents(BoxPtr extents, const PicturePtr p, int dx, int dy) { if (p->pDrawable) { dx += p->pDrawable->x; dy += p->pDrawable->y; } _trim_source_extents(extents, p, dx, dy); if (p->alphaMap) _trim_source_extents(extents, p->alphaMap, dx - p->alphaOrigin.x, dy - p->alphaOrigin.y); DBG(("%s: -> (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); } bool sna_compute_composite_extents(BoxPtr extents, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height) { int v; DBG(("%s: dst=(%d, %d)x(%d, %d)\n", __FUNCTION__, dst_x, dst_y, width, height)); extents->x1 = dst_x < 0 ? 0 : dst_x; v = dst_x + width; if (v > dst->pDrawable->width) v = dst->pDrawable->width; extents->x2 = v; extents->y1 = dst_y < 0 ? 0 : dst_y; v = dst_y + height; if (v > dst->pDrawable->height) v = dst->pDrawable->height; extents->y2 = v; DBG(("%s: initial clip against dst->pDrawable: (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); if (extents->x1 >= extents->x2 || extents->y1 >= extents->y2) return false; extents->x1 += dst->pDrawable->x; extents->x2 += dst->pDrawable->x; extents->y1 += dst->pDrawable->y; extents->y2 += dst->pDrawable->y; if (extents->x1 < dst->pCompositeClip->extents.x1) extents->x1 = dst->pCompositeClip->extents.x1; if (extents->x2 > dst->pCompositeClip->extents.x2) extents->x2 = dst->pCompositeClip->extents.x2; if (extents->y1 < dst->pCompositeClip->extents.y1) extents->y1 = dst->pCompositeClip->extents.y1; if (extents->y2 > dst->pCompositeClip->extents.y2) extents->y2 = dst->pCompositeClip->extents.y2; DBG(("%s: initial clip against dst->pCompositeClip: (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); if (extents->x1 >= extents->x2 || extents->y1 >= extents->y2) return false; dst_x += dst->pDrawable->x; dst_y += dst->pDrawable->y; /* clip against dst */ trim_extents(extents, dst, 0, 0); if (dst->alphaMap) trim_extents(extents, dst->alphaMap, -dst->alphaOrigin.x, -dst->alphaOrigin.y); DBG(("%s: clip against dst: (%d, %d), (%d, %d)\n", __FUNCTION__, extents->x1, extents->y1, extents->x2, extents->y2)); if (src) trim_source_extents(extents, src, dst_x - src_x, dst_y - src_y); if (mask) trim_source_extents(extents, mask, dst_x - mask_x, dst_y - mask_y); if (extents->x1 >= extents->x2 || extents->y1 >= extents->y2) return false; if (region_is_singular(dst->pCompositeClip)) return true; return pixman_region_contains_rectangle(dst->pCompositeClip, extents) != PIXMAN_REGION_OUT; } #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif static void apply_damage(struct sna_composite_op *op, RegionPtr region) { DBG(("%s: damage=%p, region=%d [(%d, %d), (%d, %d) + (%d, %d)]\n", __FUNCTION__, op->damage, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, op->dst.x, op->dst.y)); if (op->damage == NULL) return; if (op->dst.x | op->dst.y) RegionTranslate(region, op->dst.x, op->dst.y); assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region)); if (region->data == NULL && region->extents.x2 - region->extents.x1 == op->dst.width && region->extents.y2 - region->extents.y1 == op->dst.height) { *op->damage = _sna_damage_all(*op->damage, op->dst.width, op->dst.height); op->damage = NULL; } else sna_damage_add(op->damage, region); } static inline bool use_cpu(PixmapPtr pixmap, struct sna_pixmap *priv, CARD8 op, INT16 width, INT16 height) { if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return false; if (DAMAGE_IS_ALL(priv->cpu_damage) && (op > PictOpSrc || width < pixmap->drawable.width || height < pixmap->drawable.height)) return true; if (priv->gpu_bo) return false; return (priv->create & KGEM_CAN_CREATE_GPU) == 0; } static void validate_source(PicturePtr picture) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,99,901,0) miCompositeSourceValidate(picture); #else miCompositeSourceValidate(picture, 0, 0, picture->pDrawable ? picture->pDrawable->width : 0, picture->pDrawable ? picture->pDrawable->height : 0); #endif } void sna_composite_fb(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, RegionPtr region, INT16 src_x, INT16 src_y, INT16 msk_x, INT16 msk_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height) { pixman_image_t *src_image, *mask_image, *dest_image; int src_xoff, src_yoff; int msk_xoff, msk_yoff; int dst_xoff, dst_yoff; int16_t tx, ty; unsigned flags; DBG(("%s -- op=%d, fallback dst=(%d, %d)+(%d, %d), size=(%d, %d): region=((%d,%d), (%d, %d))\n", __FUNCTION__, op, dst_x, dst_y, dst->pDrawable->x, dst->pDrawable->y, width, height, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (src->pDrawable) { DBG(("%s: fallback -- move src to cpu\n", __FUNCTION__)); if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) return; if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) return; } validate_source(src); if (mask) { if (mask->pDrawable) { DBG(("%s: fallback -- move mask to cpu\n", __FUNCTION__)); if (!sna_drawable_move_to_cpu(mask->pDrawable, MOVE_READ)) return; if (mask->alphaMap && !sna_drawable_move_to_cpu(mask->alphaMap->pDrawable, MOVE_READ)) return; } validate_source(mask); } DBG(("%s: fallback -- move dst to cpu\n", __FUNCTION__)); if (op <= PictOpSrc && !dst->alphaMap) flags = MOVE_WRITE | MOVE_INPLACE_HINT; else flags = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, region, flags)) return; if (dst->alphaMap && !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, flags)) return; if (mask == NULL && src->pDrawable && dst->pDrawable->bitsPerPixel >= 8 && src->filter != PictFilterConvolution && (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) && (dst->format == src->format || dst->format == alphaless(src->format)) && sna_transform_is_imprecise_integer_translation(src->transform, src->filter, dst->polyMode == PolyModePrecise, &tx, &ty)) { PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable); PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable); int16_t sx = src_x + tx - (dst->pDrawable->x + dst_x); int16_t sy = src_y + ty - (dst->pDrawable->y + dst_y); assert(src->pDrawable->bitsPerPixel == dst->pDrawable->bitsPerPixel); assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel); if (region->extents.x1 + sx >= 0 && region->extents.y1 + sy >= 0 && region->extents.x2 + sx <= src->pDrawable->width && region->extents.y2 + sy <= src->pDrawable->height) { if (sigtrap_get() == 0) { const BoxRec *box = region_rects(region); int nbox = region_num_rects(region); sx += src->pDrawable->x; sy += src->pDrawable->y; if (get_drawable_deltas(src->pDrawable, src_pixmap, &tx, &ty)) sx += tx, sy += ty; assert(region->extents.x1 + sx >= 0); assert(region->extents.x2 + sx <= src_pixmap->drawable.width); assert(region->extents.y1 + sy >= 0); assert(region->extents.y2 + sy <= src_pixmap->drawable.height); get_drawable_deltas(dst->pDrawable, dst_pixmap, &tx, &ty); assert(nbox); do { assert(box->x1 + sx >= 0); assert(box->x2 + sx <= src_pixmap->drawable.width); assert(box->y1 + sy >= 0); assert(box->y2 + sy <= src_pixmap->drawable.height); assert(box->x1 + tx >= 0); assert(box->x2 + tx <= dst_pixmap->drawable.width); assert(box->y1 + ty >= 0); assert(box->y2 + ty <= dst_pixmap->drawable.height); assert(box->x2 > box->x1 && box->y2 > box->y1); sigtrap_assert_active(); memcpy_blt(src_pixmap->devPrivate.ptr, dst_pixmap->devPrivate.ptr, dst_pixmap->drawable.bitsPerPixel, src_pixmap->devKind, dst_pixmap->devKind, box->x1 + sx, box->y1 + sy, box->x1 + tx, box->y1 + ty, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--nbox); sigtrap_put(); } return; } } src_image = image_from_pict(src, FALSE, &src_xoff, &src_yoff); mask_image = image_from_pict(mask, FALSE, &msk_xoff, &msk_yoff); dest_image = image_from_pict(dst, TRUE, &dst_xoff, &dst_yoff); if (src_image && dest_image && !(mask && !mask_image)) sna_image_composite(op, src_image, mask_image, dest_image, src_x + src_xoff, src_y + src_yoff, msk_x + msk_xoff, msk_y + msk_yoff, dst_x + dst_xoff, dst_y + dst_yoff, width, height); free_pixman_pict(src, src_image); free_pixman_pict(mask, mask_image); free_pixman_pict(dst, dest_image); } void sna_composite(CARD8 op, PicturePtr src, PicturePtr mask, PicturePtr dst, INT16 src_x, INT16 src_y, INT16 mask_x, INT16 mask_y, INT16 dst_x, INT16 dst_y, CARD16 width, CARD16 height) { PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; struct sna_composite_op tmp; RegionRec region; int dx, dy; DBG(("%s(pixmap=%ld, op=%d, src=%ld+(%d, %d), mask=%ld+(%d, %d), dst=%ld+(%d, %d)+(%d, %d), size=(%d, %d)\n", __FUNCTION__, pixmap->drawable.serialNumber, op, get_picture_id(src), src_x, src_y, get_picture_id(mask), mask_x, mask_y, get_picture_id(dst), dst_x, dst_y, dst->pDrawable->x, dst->pDrawable->y, width, height)); if (region_is_empty(dst->pCompositeClip)) { DBG(("%s: empty clip, skipping\n", __FUNCTION__)); return; } if (op == PictOpClear) { DBG(("%s: discarding source and mask for clear\n", __FUNCTION__)); mask = NULL; if (sna->clear) src = sna->clear; } if (!sna_compute_composite_region(®ion, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height)) return; if (mask && sna_composite_mask_is_opaque(mask)) { DBG(("%s: removing opaque %smask\n", __FUNCTION__, mask->componentAlpha && PICT_FORMAT_RGB(mask->format) ? "CA " : "")); mask = NULL; } if (NO_COMPOSITE) goto fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto fallback; } if (!can_render_to_picture(dst)) { DBG(("%s: fallback due to unhandled picture\n", __FUNCTION__)); goto fallback; } priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: fallback as destination pixmap=%ld is unattached\n", __FUNCTION__, pixmap->drawable.serialNumber)); goto fallback; } if (use_cpu(pixmap, priv, op, width, height) && !picture_is_gpu(sna, src, PREFER_GPU_RENDER) && !picture_is_gpu(sna, mask, PREFER_GPU_RENDER)) { DBG(("%s: fallback, dst pixmap=%ld is too small (or completely damaged)\n", __FUNCTION__, pixmap->drawable.serialNumber)); goto fallback; } dx = region.extents.x1 - (dst_x + dst->pDrawable->x); dy = region.extents.y1 - (dst_y + dst->pDrawable->y); DBG(("%s: composite region extents:+(%d, %d) -> (%d, %d), (%d, %d) + (%d, %d)\n", __FUNCTION__, dx, dy, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, get_drawable_dx(dst->pDrawable), get_drawable_dy(dst->pDrawable))); if (op <= PictOpSrc && priv->cpu_damage) { int16_t x, y; if (get_drawable_deltas(dst->pDrawable, pixmap, &x, &y)) pixman_region_translate(®ion, x, y); sna_damage_subtract(&priv->cpu_damage, ®ion); if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); priv->cpu = false; } if (x|y) pixman_region_translate(®ion, -x, -y); } if (!sna->render.composite(sna, op, src, mask, dst, src_x + dx, src_y + dy, mask_x + dx, mask_y + dy, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, region.data ? COMPOSITE_PARTIAL : 0, memset(&tmp, 0, sizeof(tmp)))) { DBG(("%s: fallback due unhandled composite op\n", __FUNCTION__)); goto fallback; } if (region.data == NULL) tmp.box(sna, &tmp, ®ion.extents); else tmp.boxes(sna, &tmp, RegionBoxptr(®ion), region_num_rects(®ion)); apply_damage(&tmp, ®ion); tmp.done(sna, &tmp); goto out; fallback: DBG(("%s: fallback -- fbComposite\n", __FUNCTION__)); sna_composite_fb(op, src, mask, dst, ®ion, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); out: REGION_UNINIT(NULL, ®ion); } void sna_composite_rectangles(CARD8 op, PicturePtr dst, xRenderColor *color, int num_rects, xRectangle *rects) { struct sna *sna = to_sna_from_drawable(dst->pDrawable); PixmapPtr pixmap; struct sna_pixmap *priv; struct kgem_bo *bo; struct sna_damage **damage; pixman_region16_t region; pixman_box16_t stack_boxes[64], *boxes = stack_boxes, *b; int16_t dst_x, dst_y; int i, num_boxes; unsigned hint; DBG(("%s(pixmap=%ld, op=%d, %08x x %d [(%d, %d)x(%d, %d) ...])\n", __FUNCTION__, get_drawable_pixmap(dst->pDrawable)->drawable.serialNumber, op, (color->alpha >> 8 << 24) | (color->red >> 8 << 16) | (color->green >> 8 << 8) | (color->blue >> 8 << 0), num_rects, rects[0].x, rects[0].y, rects[0].width, rects[0].height)); if (!num_rects) return; if (region_is_empty(dst->pCompositeClip)) { DBG(("%s: empty clip, skipping\n", __FUNCTION__)); return; } if (color->alpha <= 0x00ff) { if (PICT_FORMAT_TYPE(dst->format) == PICT_TYPE_A || (color->red|color->green|color->blue) <= 0x00ff) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: return; case PictOpInReverse: case PictOpSrc: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOut; break; case PictOpXor: op = PictOpOverReverse; break; } } else { switch (op) { case PictOpOver: case PictOpOutReverse: return; case PictOpInReverse: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOut; break; case PictOpXor: op = PictOpOverReverse; break; } } } else if (color->alpha >= 0xff00) { switch (op) { case PictOpOver: op = PictOpSrc; break; case PictOpInReverse: return; case PictOpOutReverse: op = PictOpClear; break; case PictOpAtopReverse: op = PictOpOverReverse; break; case PictOpXor: op = PictOpOut; break; case PictOpAdd: if (PICT_FORMAT_TYPE(dst->format) == PICT_TYPE_A || (color->red&color->green&color->blue) >= 0xff00) op = PictOpSrc; break; } } /* Avoid reducing overlapping translucent rectangles */ if ((op == PictOpOver || op == PictOpAdd) && num_rects == 1 && sna_drawable_is_clear(dst->pDrawable)) op = PictOpSrc; DBG(("%s: converted to op %d\n", __FUNCTION__, op)); if (num_rects > ARRAY_SIZE(stack_boxes)) { boxes = malloc(sizeof(pixman_box16_t) * num_rects); if (boxes == NULL) return; } for (i = num_boxes = 0; i < num_rects; i++) { boxes[num_boxes].x1 = rects[i].x + dst->pDrawable->x; if (boxes[num_boxes].x1 < dst->pCompositeClip->extents.x1) boxes[num_boxes].x1 = dst->pCompositeClip->extents.x1; boxes[num_boxes].y1 = rects[i].y + dst->pDrawable->y; if (boxes[num_boxes].y1 < dst->pCompositeClip->extents.y1) boxes[num_boxes].y1 = dst->pCompositeClip->extents.y1; boxes[num_boxes].x2 = bound(rects[i].x + dst->pDrawable->x, rects[i].width); if (boxes[num_boxes].x2 > dst->pCompositeClip->extents.x2) boxes[num_boxes].x2 = dst->pCompositeClip->extents.x2; boxes[num_boxes].y2 = bound(rects[i].y + dst->pDrawable->y, rects[i].height); if (boxes[num_boxes].y2 > dst->pCompositeClip->extents.y2) boxes[num_boxes].y2 = dst->pCompositeClip->extents.y2; DBG(("%s[%d] (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", __FUNCTION__, i, rects[i].x, rects[i].y, rects[i].width, rects[i].height, boxes[num_boxes].x1, boxes[num_boxes].y1, boxes[num_boxes].x2, boxes[num_boxes].y2)); if (boxes[num_boxes].x2 > boxes[num_boxes].x1 && boxes[num_boxes].y2 > boxes[num_boxes].y1) num_boxes++; } if (num_boxes == 0) goto cleanup_boxes; if (!pixman_region_init_rects(®ion, boxes, num_boxes)) goto cleanup_boxes; DBG(("%s: nrects=%d, region=(%d, %d), (%d, %d) x %d\n", __FUNCTION__, num_rects, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, num_boxes)); if (dst->pCompositeClip->data && (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip) || region_is_empty(®ion))) { DBG(("%s: zero-intersection between rectangles and clip\n", __FUNCTION__)); goto cleanup_region; } DBG(("%s: clipped extents (%d, %d),(%d, %d) x %d\n", __FUNCTION__, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2, region_num_rects(®ion))); /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must * manually append the damaged regions ourselves. * * Note that DamageRegionAppend() will apply the drawable-deltas itself. */ DamageRegionAppend(dst->pDrawable, ®ion); pixmap = get_drawable_pixmap(dst->pDrawable); if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y)) pixman_region_translate(®ion, dst_x, dst_y); DBG(("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n", __FUNCTION__, dst_x, dst_y, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2)); assert_pixmap_contains_box(pixmap, RegionExtents(®ion)); if (NO_COMPOSITE_RECTANGLES) goto fallback; if (wedged(sna)) goto fallback; if (!can_render_to_picture(dst)) { DBG(("%s: fallback, dst has an incompatible picture\n", __FUNCTION__)); goto fallback; } priv = sna_pixmap(pixmap); if (priv == NULL || too_small(priv)) { DBG(("%s: fallback, dst pixmap=%ld too small or not attached\n", __FUNCTION__, pixmap->drawable.serialNumber)); goto fallback; } /* If we going to be overwriting any CPU damage with a subsequent * operation, then we may as well delete it without moving it * first to the GPU. */ hint = can_render(sna) ? PREFER_GPU : 0; if (op <= PictOpSrc) { if (priv->clear) { uint32_t pixel; bool ok; if (op == PictOpClear) { if (priv->clear_color == 0) goto done; ok = sna_get_pixel_from_rgba(&pixel, 0, 0, 0, 0, dst->format); } else { ok = sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, dst->format); } if (ok && priv->clear_color == pixel) { DBG(("%s: matches current clear, skipping\n", __FUNCTION__)); goto done; } } if (region.data == NULL) { hint |= IGNORE_DAMAGE; if (region_subsumes_drawable(®ion, &pixmap->drawable)) hint |= REPLACES; if (priv->cpu_damage && (hint & REPLACES || region_subsumes_damage(®ion, priv->cpu_damage))) { DBG(("%s: discarding existing CPU damage\n", __FUNCTION__)); if (priv->gpu_bo && priv->gpu_bo->proxy) { assert(priv->gpu_damage == NULL); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = NULL; } sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } if (hint & REPLACES || box_inplace(pixmap, ®ion.extents)) { if (priv->gpu_bo && priv->cpu_damage == NULL) { DBG(("%s: promoting to full GPU\n", __FUNCTION__)); assert(priv->gpu_bo->proxy == NULL); sna_damage_all(&priv->gpu_damage, pixmap); } } } if (priv->cpu_damage == NULL) { DBG(("%s: dropping last-cpu hint\n", __FUNCTION__)); priv->cpu = false; } } bo = sna_drawable_use_bo(&pixmap->drawable, hint, ®ion.extents, &damage); if (bo == NULL) { DBG(("%s: fallback due to no GPU bo\n", __FUNCTION__)); goto fallback; } if (hint & REPLACES) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo); if (op <= PictOpSrc) { b = pixman_region_rectangles(®ion, &num_boxes); if (!sna->render.fill_boxes(sna, op, dst->format, color, &pixmap->drawable, bo, b, num_boxes)) { DBG(("%s: fallback - acceleration failed\n", __FUNCTION__)); goto fallback; } } else if (dst->pCompositeClip->data == NULL) { for (i = 0; i < num_boxes; i++) { boxes[i].x1 += dst_x; boxes[i].x2 += dst_x; boxes[i].y1 += dst_y; boxes[i].y2 += dst_y; } if (!sna->render.fill_boxes(sna, op, dst->format, color, &pixmap->drawable, bo, boxes, num_boxes)) { DBG(("%s: fallback - acceleration failed\n", __FUNCTION__)); goto fallback; } } else { for (i = 0; i < num_boxes; i++) { RegionRec tmp = { boxes[i] }; if (pixman_region_intersect(&tmp, &tmp, dst->pCompositeClip)) { int n = 0; b = pixman_region_rectangles(&tmp, &n); if (n) { if (dst_x | dst_y) pixman_region_translate(&tmp, dst_x, dst_y); n = !sna->render.fill_boxes(sna, op, dst->format, color, &pixmap->drawable, bo, b, n); } pixman_region_fini(&tmp); if (n) { DBG(("%s: fallback - acceleration failed\n", __FUNCTION__)); goto fallback; } } } } if (damage) sna_damage_add(damage, ®ion); /* Clearing a pixmap after creation is a common operation, so take * advantage and reduce further damage operations. */ if (region_subsumes_drawable(®ion, &pixmap->drawable)) { if (damage) { sna_damage_all(damage, pixmap); sna_damage_destroy(damage == &priv->gpu_damage ? &priv->cpu_damage : &priv->gpu_damage); } if (op <= PictOpSrc && bo == priv->gpu_bo) { bool ok; assert(DAMAGE_IS_ALL(priv->gpu_damage)); priv->clear_color = 0; ok = true; if (op == PictOpSrc) ok = sna_get_pixel_from_rgba(&priv->clear_color, color->red, color->green, color->blue, color->alpha, dst->format); priv->clear = ok; DBG(("%s: pixmap=%ld marking clear [%08x]? %d\n", __FUNCTION__, pixmap->drawable.serialNumber, priv->clear_color, ok)); } } goto done; fallback: DBG(("%s: fallback\n", __FUNCTION__)); if (op <= PictOpSrc) hint = MOVE_WRITE; else hint = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, hint)) goto done; if (dst->alphaMap && !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, hint)) goto done; assert(pixmap->devPrivate.ptr); if (sigtrap_get() == 0) { if (op <= PictOpSrc) { int nbox = region_num_rects(®ion); const BoxRec *box = region_rects(®ion); uint32_t pixel; if (op == PictOpClear) pixel = 0; else if (!sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, dst->format)) goto fallback_composite; sigtrap_assert_active(); if (pixel == 0 && box->x2 - box->x1 == pixmap->drawable.width && box->y2 - box->y1 == pixmap->drawable.height) { memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*pixmap->drawable.height); } else do { DBG(("%s: fallback fill: (%d, %d)x(%d, %d) %08x\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, pixel)); pixman_fill(pixmap->devPrivate.ptr, pixmap->devKind/sizeof(uint32_t), pixmap->drawable.bitsPerPixel, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, pixel); box++; } while (--nbox); } else { PicturePtr src; int error; fallback_composite: DBG(("%s: fallback -- fbComposite()\n", __FUNCTION__)); src = CreateSolidPicture(0, color, &error); if (src) { do { fbComposite(op, src, NULL, dst, 0, 0, 0, 0, rects->x, rects->y, rects->width, rects->height); rects++; } while (--num_rects); FreePicture(src, 0); } } sigtrap_put(); } done: DamageRegionProcessPending(dst->pDrawable); cleanup_region: pixman_region_fini(®ion); cleanup_boxes: if (boxes != stack_boxes) free(boxes); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_cpu.c000066400000000000000000000056201267532330400234420ustar00rootroot00000000000000/* * Copyright (c) 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_cpuid.h" #define xgetbv(index,eax,edx) \ __asm__ ("xgetbv" : "=a"(eax), "=d"(edx) : "c" (index)) #define has_YMM 0x1 unsigned sna_cpu_detect(void) { unsigned max = __get_cpuid_max(BASIC_CPUID, NULL); unsigned eax, ebx, ecx, edx; unsigned features = 0; unsigned extra = 0; if (max >= 1) { __cpuid(1, eax, ebx, ecx, edx); if (ecx & bit_SSE3) features |= SSE3; if (ecx & bit_SSSE3) features |= SSSE3; if (ecx & bit_SSE4_1) features |= SSE4_1; if (ecx & bit_SSE4_2) features |= SSE4_2; if (ecx & bit_OSXSAVE) { unsigned int bv_eax, bv_ecx; xgetbv(0, bv_eax, bv_ecx); if ((bv_eax & 6) == 6) extra |= has_YMM; } if ((extra & has_YMM) && (ecx & bit_AVX)) features |= AVX; if (edx & bit_MMX) features |= MMX; if (edx & bit_SSE) features |= SSE; if (edx & bit_SSE2) features |= SSE2; } if (max >= 7) { __cpuid_count(7, 0, eax, ebx, ecx, edx); if ((extra & has_YMM) && (ebx & bit_AVX2)) features |= AVX2; } return features; } char *sna_cpu_features_to_string(unsigned features, char *line) { char *ret = line; #ifdef __x86_64__ line += sprintf (line, "x86-64"); #else line += sprintf (line, "x86"); #endif if (features & SSE2) line += sprintf (line, ", sse2"); if (features & SSE3) line += sprintf (line, ", sse3"); if (features & SSSE3) line += sprintf (line, ", ssse3"); if (features & SSE4_1) line += sprintf (line, ", sse4.1"); if (features & SSE4_2) line += sprintf (line, ", sse4.2"); if (features & AVX) line += sprintf (line, ", avx"); if (features & AVX2) line += sprintf (line, ", avx2"); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_cpuid.h000066400000000000000000000041551267532330400237660ustar00rootroot00000000000000/* * Copyright (c) 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ /* Small wrapper around compiler specific implementation details of cpuid */ #ifndef SNA_CPUID_H #define SNA_CPUID_H #ifdef HAVE_CPUID_H #include #else #define __get_cpuid_max(x, y) 0 #define __cpuid(level, a, b, c, d) a = b = c = d = 0 #define __cpuid_count(level, count, a, b, c, d) a = b = c = d = 0 #endif #define BASIC_CPUID 0x0 #define EXTENDED_CPUID 0x80000000 #ifndef bit_MMX #define bit_MMX (1 << 23) #endif #ifndef bit_SSE #define bit_SSE (1 << 25) #endif #ifndef bit_SSE2 #define bit_SSE2 (1 << 26) #endif #ifndef bit_SSE3 #define bit_SSE3 (1 << 0) #endif #ifndef bit_SSSE3 #define bit_SSSE3 (1 << 9) #endif #ifndef bit_SSE4_1 #define bit_SSE4_1 (1 << 19) #endif #ifndef bit_SSE4_2 #define bit_SSE4_2 (1 << 20) #endif #ifndef bit_OSXSAVE #define bit_OSXSAVE (1 << 27) #endif #ifndef bit_AVX #define bit_AVX (1 << 28) #endif #ifndef bit_AVX2 #define bit_AVX2 (1<<5) #endif #endif /* SNA_CPUID_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_damage.c000066400000000000000000001325011267532330400240700ustar00rootroot00000000000000/************************************************************************** Copyright (c) 2011 Intel Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_damage.h" /* * sna_damage is a batching layer on top of the regular pixman_region_t. * It is required as the ever-growing accumulation of invidual small * damage regions is an O(n^2) operation. Instead the accumulation of a * batch can be done in closer to O(n.lgn), and so prevents abysmal * performance in x11perf -copywinwin10. * * As with the core of SNA, damage is handled modally. That is, it * accumulates whilst rendering and then subtracts during migration of the * pixmap from GPU to CPU or vice versa. As such we can track the current * mode globally and when that mode switches perform the update of the region * in a single operation. * * Furthermore, we can track whether the whole pixmap is damaged and so * cheapy discard no-ops. */ struct sna_damage_box { struct list list; int size; } __attribute__((packed)); static struct sna_damage *__freed_damage; static inline bool region_is_singular(const RegionRec *r) { return r->data == NULL; } static inline bool region_is_singular_or_empty(const RegionRec *r) { return r->data == NULL || r->data->numRects == 0; } #if HAS_DEBUG_FULL static const char *_debug_describe_region(char *buf, int max, const RegionRec *region) { const BoxRec *box; int n, len; if (region == NULL) return "nil"; n = region_num_rects(region); if (n == 0) return "[0]"; if (n == 1) { sprintf(buf, "[(%d, %d), (%d, %d)]", region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2); return buf; } len = sprintf(buf, "[(%d, %d), (%d, %d) x %d: ", region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, n) + 3; max -= 2; box = region_rects(region); while (n--) { char tmp[80]; int this; this = snprintf(tmp, sizeof(tmp), "((%d, %d), (%d, %d))%s", box->x1, box->y1, box->x2, box->y2, n ? ", ..." : ""); box++; if (this > max - len) break; len -= 3; memcpy(buf + len, tmp, this); len += this; } buf[len++] = ']'; buf[len] = '\0'; return buf; } static const char *_debug_describe_damage(char *buf, int max, const struct sna_damage *damage) { char damage_str[500], region_str[500]; int str_max; if (damage == NULL) return "None"; str_max = max/2 - 6; if (str_max > sizeof(damage_str)) str_max = sizeof(damage_str); if (damage->mode == DAMAGE_ALL) { snprintf(buf, max, "[[(%d, %d), (%d, %d)]: all]", damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2); } else { if (damage->dirty) { sprintf(damage_str, "%c[ ...]", damage->mode == DAMAGE_SUBTRACT ? '-' : '+'); } else damage_str[0] = '\0'; snprintf(buf, max, "[[(%d, %d), (%d, %d)]: %s %s]%c", damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2, _debug_describe_region(region_str, str_max, &damage->region), damage_str, damage->dirty ? '*' : ' '); } return buf; } #endif static struct sna_damage_box * last_box(struct sna_damage *damage) { return list_entry(damage->embedded_box.list.prev, struct sna_damage_box, list); } static void reset_embedded_box(struct sna_damage *damage) { damage->dirty = false; damage->box = damage->embedded_box.box; damage->embedded_box.size = damage->remain = ARRAY_SIZE(damage->embedded_box.box); list_init(&damage->embedded_box.list); } static void reset_extents(struct sna_damage *damage) { damage->extents.x1 = damage->extents.y1 = MAXSHORT; damage->extents.x2 = damage->extents.y2 = MINSHORT; } static struct sna_damage *_sna_damage_create(void) { struct sna_damage *damage; if (__freed_damage) { damage = __freed_damage; __freed_damage = *(void **)__freed_damage; } else { damage = malloc(sizeof(*damage)); if (damage == NULL) return NULL; } reset_embedded_box(damage); damage->mode = DAMAGE_ADD; pixman_region_init(&damage->region); reset_extents(damage); return damage; } struct sna_damage *sna_damage_create(void) { return _sna_damage_create(); } static void free_list(struct list *head) { while (!list_is_empty(head)) { struct list *l = head->next; list_del(l); free(l); } } static void __sna_damage_reduce(struct sna_damage *damage) { int n, nboxes; BoxPtr boxes, free_boxes = NULL; pixman_region16_t *region = &damage->region; struct sna_damage_box *iter; assert(damage->mode != DAMAGE_ALL); assert(damage->dirty); DBG((" reduce: before region.n=%d\n", region_num_rects(region))); nboxes = damage->embedded_box.size; list_for_each_entry(iter, &damage->embedded_box.list, list) nboxes += iter->size; DBG((" nboxes=%d, residual=%d\n", nboxes, damage->remain)); nboxes -= damage->remain; if (nboxes == 0) goto done; if (nboxes == 1) { pixman_region16_t tmp; tmp.extents = damage->embedded_box.box[0]; tmp.data = NULL; if (damage->mode == DAMAGE_ADD) pixman_region_union(region, region, &tmp); else pixman_region_subtract(region, region, &tmp); damage->extents = region->extents; goto done; } if (damage->mode == DAMAGE_ADD) nboxes += region_num_rects(region); iter = last_box(damage); n = iter->size - damage->remain; boxes = (BoxRec *)(iter+1); DBG((" last box count=%d/%d, need=%d\n", n, iter->size, nboxes)); if (nboxes > iter->size) { boxes = malloc(sizeof(BoxRec)*nboxes); if (boxes == NULL) goto done; free_boxes = boxes; } if (boxes != damage->embedded_box.box) { if (list_is_empty(&damage->embedded_box.list)) { DBG((" copying embedded boxes\n")); memcpy(boxes, damage->embedded_box.box, n*sizeof(BoxRec)); } else { if (boxes != (BoxPtr)(iter+1)) { DBG((" copying %d boxes from last\n", n)); memcpy(boxes, iter+1, n*sizeof(BoxRec)); } iter = list_entry(iter->list.prev, struct sna_damage_box, list); while (&iter->list != &damage->embedded_box.list) { DBG((" copy %d boxes from %d\n", iter->size, n)); memcpy(boxes + n, iter+1, iter->size * sizeof(BoxRec)); n += iter->size; iter = list_entry(iter->list.prev, struct sna_damage_box, list); } DBG((" copying embedded boxes to %d\n", n)); memcpy(boxes + n, damage->embedded_box.box, sizeof(damage->embedded_box.box)); n += damage->embedded_box.size; } } if (damage->mode == DAMAGE_ADD) { memcpy(boxes + n, region_rects(region), region_num_rects(region)*sizeof(BoxRec)); assert(n + region_num_rects(region) == nboxes); pixman_region_fini(region); pixman_region_init_rects(region, boxes, nboxes); assert(pixman_region_not_empty(region)); assert(damage->extents.x1 == region->extents.x1 && damage->extents.y1 == region->extents.y1 && damage->extents.x2 == region->extents.x2 && damage->extents.y2 == region->extents.y2); } else { pixman_region16_t tmp; assert(n == nboxes); pixman_region_init_rects(&tmp, boxes, nboxes); pixman_region_subtract(region, region, &tmp); pixman_region_fini(&tmp); assert(damage->extents.x1 <= region->extents.x1 && damage->extents.y1 <= region->extents.y1 && damage->extents.x2 >= region->extents.x2 && damage->extents.y2 >= region->extents.y2); if (pixman_region_not_empty(region)) damage->extents = region->extents; else reset_extents(damage); } free(free_boxes); done: damage->mode = DAMAGE_ADD; free_list(&damage->embedded_box.list); reset_embedded_box(damage); DBG((" reduce: after region.n=%d\n", region_num_rects(region))); } static bool _sna_damage_create_boxes(struct sna_damage *damage, int count) { struct sna_damage_box *box; int n; box = last_box(damage); n = 4*box->size; if (n < count) n = ALIGN(count, 64); DBG((" %s(%d->%d): new\n", __FUNCTION__, count, n)); if (n >= (INT_MAX - sizeof(*box)) / sizeof(BoxRec)) return false; box = malloc(sizeof(*box) + sizeof(BoxRec)*n); if (box == NULL) return false; list_add_tail(&box->list, &damage->embedded_box.list); box->size = damage->remain = n; damage->box = (BoxRec *)(box + 1); return true; } static struct sna_damage * _sna_damage_create_elt(struct sna_damage *damage, const BoxRec *boxes, int count) { int n; DBG((" %s: prev=(remain %d), count=%d\n", __FUNCTION__, damage->remain, count)); assert(count); restart: n = count; if (n > damage->remain) n = damage->remain; if (n) { memcpy(damage->box, boxes, n * sizeof(BoxRec)); damage->box += n; damage->remain -= n; damage->dirty = true; count -= n; boxes += n; if (count == 0) return damage; } DBG((" %s(): new elt\n", __FUNCTION__)); assert(damage->remain == 0); assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size); if (!_sna_damage_create_boxes(damage, count)) { unsigned mode; if (!damage->dirty) return damage; mode = damage->mode; __sna_damage_reduce(damage); damage->mode = mode; goto restart; } memcpy(damage->box, boxes, count * sizeof(BoxRec)); damage->box += count; damage->remain -= count; damage->dirty = true; assert(damage->remain >= 0); return damage; } static struct sna_damage * _sna_damage_create_elt_from_boxes(struct sna_damage *damage, const BoxRec *boxes, int count, int16_t dx, int16_t dy) { int i, n; DBG((" %s: prev=(remain %d)\n", __FUNCTION__, damage->remain)); assert(count); restart: n = count; if (n > damage->remain) n = damage->remain; if (n) { for (i = 0; i < n; i++) { damage->box[i].x1 = boxes[i].x1 + dx; damage->box[i].x2 = boxes[i].x2 + dx; damage->box[i].y1 = boxes[i].y1 + dy; damage->box[i].y2 = boxes[i].y2 + dy; } damage->box += n; damage->remain -= n; damage->dirty = true; count -= n; boxes += n; if (count == 0) return damage; } DBG((" %s(): new elt\n", __FUNCTION__)); assert(damage->remain == 0); assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size); if (!_sna_damage_create_boxes(damage, count)) { unsigned mode; if (!damage->dirty) return damage; mode = damage->mode; __sna_damage_reduce(damage); damage->mode = mode; goto restart; } for (i = 0; i < count; i++) { damage->box[i].x1 = boxes[i].x1 + dx; damage->box[i].x2 = boxes[i].x2 + dx; damage->box[i].y1 = boxes[i].y1 + dy; damage->box[i].y2 = boxes[i].y2 + dy; } damage->box += count; damage->remain -= count; damage->dirty = true; assert(damage->remain >= 0); return damage; } static struct sna_damage * _sna_damage_create_elt_from_rectangles(struct sna_damage *damage, const xRectangle *r, int count, int16_t dx, int16_t dy) { int i, n; DBG((" %s: prev=(remain %d), count=%d\n", __FUNCTION__, damage->remain, count)); assert(count); restart: n = count; if (n > damage->remain) n = damage->remain; if (n) { for (i = 0; i < n; i++) { damage->box[i].x1 = r[i].x + dx; damage->box[i].x2 = damage->box[i].x1 + r[i].width; damage->box[i].y1 = r[i].y + dy; damage->box[i].y2 = damage->box[i].y1 + r[i].height; } damage->box += n; damage->remain -= n; damage->dirty = true; count -= n; r += n; if (count == 0) return damage; } DBG((" %s(): new elt\n", __FUNCTION__)); assert(damage->remain == 0); assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size); if (!_sna_damage_create_boxes(damage, count)) { unsigned mode; if (!damage->dirty) return damage; mode = damage->mode; __sna_damage_reduce(damage); damage->mode = mode; goto restart; } for (i = 0; i < count; i++) { damage->box[i].x1 = r[i].x + dx; damage->box[i].x2 = damage->box[i].x1 + r[i].width; damage->box[i].y1 = r[i].y + dy; damage->box[i].y2 = damage->box[i].y1 + r[i].height; } damage->box += count; damage->remain -= count; damage->dirty = true; assert(damage->remain >= 0); return damage; } static struct sna_damage * _sna_damage_create_elt_from_points(struct sna_damage *damage, const DDXPointRec *p, int count, int16_t dx, int16_t dy) { int i, n; DBG((" %s: prev=(remain %d), count=%d\n", __FUNCTION__, damage->remain, count)); assert(count); restart: n = count; if (n > damage->remain) n = damage->remain; if (n) { for (i = 0; i < n; i++) { damage->box[i].x1 = p[i].x + dx; damage->box[i].x2 = damage->box[i].x1 + 1; damage->box[i].y1 = p[i].y + dy; damage->box[i].y2 = damage->box[i].y1 + 1; } damage->box += n; damage->remain -= n; damage->dirty = true; count -= n; p += n; if (count == 0) return damage; } DBG((" %s(): new elt\n", __FUNCTION__)); assert(damage->remain == 0); assert(damage->box - (BoxRec *)(last_box(damage)+1) == last_box(damage)->size); if (!_sna_damage_create_boxes(damage, count)) { unsigned mode; if (!damage->dirty) return damage; mode = damage->mode; __sna_damage_reduce(damage); damage->mode = mode; goto restart; } for (i = 0; i < count; i++) { damage->box[i].x1 = p[i].x + dx; damage->box[i].x2 = damage->box[i].x1 + 1; damage->box[i].y1 = p[i].y + dy; damage->box[i].y2 = damage->box[i].y1 + 1; } damage->box += count; damage->remain -= count; damage->dirty = true; assert(damage->remain >= 0); return damage; } static void damage_union(struct sna_damage *damage, const BoxRec *box) { DBG(("%s: extending damage (%d, %d), (%d, %d) by (%d, %d), (%d, %d)\n", __FUNCTION__, damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2, box->x1, box->y1, box->x2, box->y2)); assert(box->x2 > box->x1 && box->y2 > box->y1); if (damage->extents.x2 < damage->extents.x1) { damage->extents = *box; } else { if (damage->extents.x1 > box->x1) damage->extents.x1 = box->x1; if (damage->extents.x2 < box->x2) damage->extents.x2 = box->x2; if (damage->extents.y1 > box->y1) damage->extents.y1 = box->y1; if (damage->extents.y2 < box->y2) damage->extents.y2 = box->y2; } assert(damage->extents.x2 > damage->extents.x1); assert(damage->extents.y2 > damage->extents.y1); } static void _pixman_region_union_box(RegionRec *region, const BoxRec *box) { RegionRec u = { *box, NULL }; pixman_region_union(region, region, &u); } static bool box_contains_region(const BoxRec *b, const RegionRec *r) { return (b->x1 <= r->extents.x1 && b->x2 >= r->extents.x2 && b->y1 <= r->extents.y1 && b->y2 >= r->extents.y2); } static struct sna_damage *__sna_damage_add_box(struct sna_damage *damage, const BoxRec *box) { if (box->y2 <= box->y1 || box->x2 <= box->x1) return damage; if (!damage) { damage = _sna_damage_create(); if (damage == NULL) return NULL; } else switch (damage->mode) { case DAMAGE_ALL: return damage; case DAMAGE_SUBTRACT: __sna_damage_reduce(damage); case DAMAGE_ADD: break; } if (region_is_singular_or_empty(&damage->region) || box_contains_region(box, &damage->region)) { _pixman_region_union_box(&damage->region, box); assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); damage_union(damage, box); return damage; } if (pixman_region_contains_rectangle(&damage->region, (BoxPtr)box) == PIXMAN_REGION_IN) return damage; damage_union(damage, box); return _sna_damage_create_elt(damage, box, 1); } inline static struct sna_damage *__sna_damage_add(struct sna_damage *damage, RegionPtr region) { assert(RegionNotEmpty(region)); if (!damage) { damage = _sna_damage_create(); if (damage == NULL) return NULL; } else switch (damage->mode) { case DAMAGE_ALL: return damage; case DAMAGE_SUBTRACT: __sna_damage_reduce(damage); case DAMAGE_ADD: break; } if (region_is_singular(region)) return __sna_damage_add_box(damage, ®ion->extents); if (region_is_singular_or_empty(&damage->region)) { pixman_region_union(&damage->region, &damage->region, region); assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); damage_union(damage, ®ion->extents); return damage; } if (pixman_region_contains_rectangle(&damage->region, ®ion->extents) == PIXMAN_REGION_IN) return damage; damage_union(damage, ®ion->extents); return _sna_damage_create_elt(damage, region_rects(region), region_num_rects(region)); } #if HAS_DEBUG_FULL fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage, RegionPtr region) { char region_buf[120]; char damage_buf[1000]; DBG(("%s(%s + %s)\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), _debug_describe_region(region_buf, sizeof(region_buf), region))); damage = __sna_damage_add(damage, region); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); assert(region_num_rects(&damage->region)); assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); return damage; } #else fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage, RegionPtr region) { return __sna_damage_add(damage, region); } #endif inline static struct sna_damage * __sna_damage_add_boxes(struct sna_damage *damage, const BoxRec *box, int n, int16_t dx, int16_t dy) { BoxRec extents; int i; assert(n); if (!damage) { damage = _sna_damage_create(); if (damage == NULL) return NULL; } else switch (damage->mode) { case DAMAGE_ALL: return damage; case DAMAGE_SUBTRACT: __sna_damage_reduce(damage); case DAMAGE_ADD: break; } assert(box[0].x2 > box[0].x1 && box[0].y2 > box[0].y1); extents = box[0]; for (i = 1; i < n; i++) { assert(box[i].x2 > box[i].x1 && box[i].y2 > box[i].y1); if (extents.x1 > box[i].x1) extents.x1 = box[i].x1; if (extents.x2 < box[i].x2) extents.x2 = box[i].x2; if (extents.y1 > box[i].y1) extents.y1 = box[i].y1; if (extents.y2 < box[i].y2) extents.y2 = box[i].y2; } assert(extents.y2 > extents.y1 && extents.x2 > extents.x1); extents.x1 += dx; extents.x2 += dx; extents.y1 += dy; extents.y2 += dy; if (n == 1) return __sna_damage_add_box(damage, &extents); if (pixman_region_contains_rectangle(&damage->region, &extents) == PIXMAN_REGION_IN) return damage; damage_union(damage, &extents); return _sna_damage_create_elt_from_boxes(damage, box, n, dx, dy); } #if HAS_DEBUG_FULL struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage, const BoxRec *b, int n, int16_t dx, int16_t dy) { char damage_buf[1000]; DBG(("%s(%s + [(%d, %d), (%d, %d) ... x %d])\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), b->x1, b->y1, b->x2, b->y2, n)); damage = __sna_damage_add_boxes(damage, b, n, dx, dy); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); if (region_num_rects(&damage->region)) { assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); } return damage; } #else struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage, const BoxRec *b, int n, int16_t dx, int16_t dy) { return __sna_damage_add_boxes(damage, b, n, dx, dy); } #endif inline static struct sna_damage * __sna_damage_add_rectangles(struct sna_damage *damage, const xRectangle *r, int n, int16_t dx, int16_t dy) { BoxRec extents; int i; assert(n); assert(r[0].width && r[0].height); extents.x1 = r[0].x; extents.x2 = r[0].x + r[0].width; extents.y1 = r[0].y; extents.y2 = r[0].y + r[0].height; for (i = 1; i < n; i++) { assert(r[i].width && r[i].height); if (extents.x1 > r[i].x) extents.x1 = r[i].x; if (extents.x2 < r[i].x + r[i].width) extents.x2 = r[i].x + r[i].width; if (extents.y1 > r[i].y) extents.y1 = r[i].y; if (extents.y2 < r[i].y + r[i].height) extents.y2 = r[i].y + r[i].height; } assert(extents.y2 > extents.y1 && extents.x2 > extents.x1); extents.x1 += dx; extents.x2 += dx; extents.y1 += dy; extents.y2 += dy; if (n == 1) return __sna_damage_add_box(damage, &extents); if (!damage) { damage = _sna_damage_create(); if (damage == NULL) return NULL; } else switch (damage->mode) { case DAMAGE_ALL: return damage; case DAMAGE_SUBTRACT: __sna_damage_reduce(damage); case DAMAGE_ADD: break; } if (pixman_region_contains_rectangle(&damage->region, &extents) == PIXMAN_REGION_IN) return damage; damage_union(damage, &extents); return _sna_damage_create_elt_from_rectangles(damage, r, n, dx, dy); } #if HAS_DEBUG_FULL struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage, const xRectangle *r, int n, int16_t dx, int16_t dy) { char damage_buf[1000]; DBG(("%s(%s + [(%d, %d)x(%d, %d) ... x %d])\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), r->x, r->y, r->width, r->height, n)); damage = __sna_damage_add_rectangles(damage, r, n, dx, dy); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); if (region_num_rects(&damage->region)) { assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); } return damage; } #else struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage, const xRectangle *r, int n, int16_t dx, int16_t dy) { return __sna_damage_add_rectangles(damage, r, n, dx, dy); } #endif /* XXX pass in extents? */ inline static struct sna_damage * __sna_damage_add_points(struct sna_damage *damage, const DDXPointRec *p, int n, int16_t dx, int16_t dy) { BoxRec extents; int i; assert(n); extents.x2 = extents.x1 = p[0].x; extents.y2 = extents.y1 = p[0].y; for (i = 1; i < n; i++) { if (extents.x1 > p[i].x) extents.x1 = p[i].x; else if (extents.x2 < p[i].x) extents.x2 = p[i].x; if (extents.y1 > p[i].y) extents.y1 = p[i].y; else if (extents.y2 < p[i].y) extents.y2 = p[i].y; } extents.x1 += dx; extents.x2 += dx + 1; extents.y1 += dy; extents.y2 += dy + 1; if (n == 1) return __sna_damage_add_box(damage, &extents); if (!damage) { damage = _sna_damage_create(); if (damage == NULL) return NULL; } else switch (damage->mode) { case DAMAGE_ALL: return damage; case DAMAGE_SUBTRACT: __sna_damage_reduce(damage); case DAMAGE_ADD: break; } if (pixman_region_contains_rectangle(&damage->region, &extents) == PIXMAN_REGION_IN) return damage; damage_union(damage, &extents); return _sna_damage_create_elt_from_points(damage, p, n, dx, dy); } #if HAS_DEBUG_FULL struct sna_damage *_sna_damage_add_points(struct sna_damage *damage, const DDXPointRec *p, int n, int16_t dx, int16_t dy) { char damage_buf[1000]; DBG(("%s(%s + [(%d, %d) ... x %d])\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), p->x, p->y, n)); damage = __sna_damage_add_points(damage, p, n, dx, dy); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); if (region_num_rects(&damage->region)) { assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); } return damage; } #else struct sna_damage *_sna_damage_add_points(struct sna_damage *damage, const DDXPointRec *p, int n, int16_t dx, int16_t dy) { return __sna_damage_add_points(damage, p, n, dx, dy); } #endif #if HAS_DEBUG_FULL fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage, const BoxRec *box) { char damage_buf[1000]; DBG(("%s(%s + [(%d, %d), (%d, %d)])\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), box->x1, box->y1, box->x2, box->y2)); damage = __sna_damage_add_box(damage, box); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); assert(region_num_rects(&damage->region)); assert(damage->region.extents.x2 > damage->region.extents.x1); assert(damage->region.extents.y2 > damage->region.extents.y1); return damage; } #else fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage, const BoxRec *box) { return __sna_damage_add_box(damage, box); } #endif struct sna_damage *__sna_damage_all(struct sna_damage *damage, int width, int height) { DBG(("%s(%d, %d)\n", __FUNCTION__, width, height)); if (damage) { pixman_region_fini(&damage->region); free_list(&damage->embedded_box.list); reset_embedded_box(damage); } else { damage = _sna_damage_create(); if (damage == NULL) return NULL; } pixman_region_init_rect(&damage->region, 0, 0, width, height); damage->extents = damage->region.extents; damage->mode = DAMAGE_ALL; return damage; } struct sna_damage *_sna_damage_is_all(struct sna_damage *damage, int width, int height) { DBG(("%s(%d, %d)%s?\n", __FUNCTION__, width, height, damage->dirty ? "*" : "")); DBG(("%s: (%d, %d), (%d, %d)\n", __FUNCTION__, damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2)); assert(damage->mode == DAMAGE_ADD); assert(damage->extents.x1 == 0 && damage->extents.y1 == 0 && damage->extents.x2 == width && damage->extents.y2 == height); if (damage->dirty) { __sna_damage_reduce(damage); assert(RegionNotEmpty(&damage->region)); } if (damage->region.data) { DBG(("%s: no, not singular\n", __FUNCTION__)); return damage; } assert(damage->extents.x1 == 0 && damage->extents.y1 == 0 && damage->extents.x2 == width && damage->extents.y2 == height); return __sna_damage_all(damage, width, height); } static bool box_contains(const BoxRec *a, const BoxRec *b) { if (b->x1 < a->x1 || b->x2 > a->x2) return false; if (b->y1 < a->y1 || b->y2 > a->y2) return false; return true; } static struct sna_damage *__sna_damage_subtract(struct sna_damage *damage, RegionPtr region) { if (damage == NULL) return NULL; if (RegionNil(&damage->region)) { no_damage: __sna_damage_destroy(damage); return NULL; } assert(RegionNotEmpty(region)); if (!sna_damage_overlaps_box(damage, ®ion->extents)) return damage; if (region_is_singular(region) && box_contains(®ion->extents, &damage->extents)) goto no_damage; if (damage->mode == DAMAGE_ALL) { pixman_region_subtract(&damage->region, &damage->region, region); if (damage->region.extents.x2 <= damage->region.extents.x1 || damage->region.extents.y2 <= damage->region.extents.y1) goto no_damage; damage->extents = damage->region.extents; damage->mode = DAMAGE_ADD; return damage; } if (damage->mode != DAMAGE_SUBTRACT) { if (damage->dirty) { __sna_damage_reduce(damage); assert(RegionNotEmpty(&damage->region)); } if (pixman_region_equal(region, &damage->region)) goto no_damage; if (region_is_singular(&damage->region) && region_is_singular(region)) { pixman_region_subtract(&damage->region, &damage->region, region); if (damage->region.extents.x2 <= damage->region.extents.x1 || damage->region.extents.y2 <= damage->region.extents.y1) goto no_damage; damage->extents = damage->region.extents; assert(pixman_region_not_empty(&damage->region)); return damage; } damage->mode = DAMAGE_SUBTRACT; } return _sna_damage_create_elt(damage, region_rects(region), region_num_rects(region)); } #if HAS_DEBUG_FULL fastcall struct sna_damage *_sna_damage_subtract(struct sna_damage *damage, RegionPtr region) { char damage_buf[1000]; char region_buf[120]; DBG(("%s(%s - %s)...\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), _debug_describe_region(region_buf, sizeof(region_buf), region))); damage = __sna_damage_subtract(damage, region); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); return damage; } #else fastcall struct sna_damage *_sna_damage_subtract(struct sna_damage *damage, RegionPtr region) { return __sna_damage_subtract(damage, region); } #endif inline static struct sna_damage *__sna_damage_subtract_box(struct sna_damage *damage, const BoxRec *box) { assert(box->x2 > box->x1 && box->y2 > box->y1); if (damage == NULL) return NULL; if (RegionNil(&damage->region)) { __sna_damage_destroy(damage); return NULL; } if (!sna_damage_overlaps_box(damage, box)) return damage; if (box_contains(box, &damage->extents)) { __sna_damage_destroy(damage); return NULL; } if (damage->mode != DAMAGE_SUBTRACT) { if (damage->dirty) { __sna_damage_reduce(damage); assert(RegionNotEmpty(&damage->region)); } if (region_is_singular(&damage->region)) { pixman_region16_t region; pixman_region_init_rects(®ion, box, 1); pixman_region_subtract(&damage->region, &damage->region, ®ion); damage->extents = damage->region.extents; damage->mode = DAMAGE_ADD; return damage; } damage->mode = DAMAGE_SUBTRACT; } return _sna_damage_create_elt(damage, box, 1); } #if HAS_DEBUG_FULL fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage, const BoxRec *box) { char damage_buf[1000]; DBG(("%s(%s - (%d, %d), (%d, %d))...\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), box->x1, box->y1, box->x2, box->y2)); damage = __sna_damage_subtract_box(damage, box); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); return damage; } #else fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage, const BoxRec *box) { return __sna_damage_subtract_box(damage, box); } #endif static struct sna_damage *__sna_damage_subtract_boxes(struct sna_damage *damage, const BoxRec *box, int n, int dx, int dy) { BoxRec extents; int i; if (damage == NULL) return NULL; if (RegionNil(&damage->region)) { __sna_damage_destroy(damage); return NULL; } assert(n); assert(box[0].x2 > box[0].x1 && box[0].y2 > box[0].y1); extents = box[0]; for (i = 1; i < n; i++) { assert(box[i].x2 > box[i].x1 && box[i].y2 > box[i].y1); if (extents.x1 > box[i].x1) extents.x1 = box[i].x1; if (extents.x2 < box[i].x2) extents.x2 = box[i].x2; if (extents.y1 > box[i].y1) extents.y1 = box[i].y1; if (extents.y2 < box[i].y2) extents.y2 = box[i].y2; } assert(extents.y2 > extents.y1 && extents.x2 > extents.x1); extents.x1 += dx; extents.x2 += dx; extents.y1 += dy; extents.y2 += dy; if (!sna_damage_overlaps_box(damage, &extents)) return damage; if (n == 1) return __sna_damage_subtract_box(damage, &extents); if (damage->mode != DAMAGE_SUBTRACT) { if (damage->dirty) { __sna_damage_reduce(damage); assert(RegionNotEmpty(&damage->region)); } damage->mode = DAMAGE_SUBTRACT; } return _sna_damage_create_elt_from_boxes(damage, box, n, dx, dy); } #if HAS_DEBUG_FULL fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage, const BoxRec *box, int n, int dx, int dy) { char damage_buf[1000]; DBG(("%s(%s - [(%d,%d), (%d,%d)...x%d])...\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), box->x1 + dx, box->y1 + dy, box->x2 + dx, box->y2 + dy, n)); damage = __sna_damage_subtract_boxes(damage, box, n, dx, dy); DBG((" = %s\n", _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); return damage; } #else fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage, const BoxRec *box, int n, int dx, int dy) { return __sna_damage_subtract_boxes(damage, box, n, dx, dy); } #endif static int __sna_damage_contains_box(struct sna_damage **_damage, const BoxRec *box) { struct sna_damage *damage = *_damage; const BoxRec *b; int n, count, ret; if (damage->mode == DAMAGE_ALL) return PIXMAN_REGION_IN; if (!sna_damage_overlaps_box(damage, box)) return PIXMAN_REGION_OUT; ret = pixman_region_contains_rectangle(&damage->region, (BoxPtr)box); if (!damage->dirty) return ret; if (damage->mode == DAMAGE_ADD) { if (ret == PIXMAN_REGION_IN) return ret; count = damage->embedded_box.size; if (list_is_empty(&damage->embedded_box.list)) count -= damage->remain; b = damage->embedded_box.box; for (n = 0; n < count; n++) { if (box_contains(&b[n], box)) return PIXMAN_REGION_IN; } } else { if (ret == PIXMAN_REGION_OUT) return ret; count = damage->embedded_box.size; if (list_is_empty(&damage->embedded_box.list)) count -= damage->remain; b = damage->embedded_box.box; for (n = 0; n < count; n++) { if (box_contains(&b[n], box)) return PIXMAN_REGION_OUT; } } __sna_damage_reduce(damage); if (!pixman_region_not_empty(&damage->region)) { __sna_damage_destroy(damage); *_damage = NULL; return PIXMAN_REGION_OUT; } return pixman_region_contains_rectangle(&damage->region, (BoxPtr)box); } #if HAS_DEBUG_FULL int _sna_damage_contains_box(struct sna_damage **damage, const BoxRec *box) { char damage_buf[1000]; int ret; DBG(("%s(%s, [(%d, %d), (%d, %d)])\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), *damage), box->x1, box->y1, box->x2, box->y2)); ret = __sna_damage_contains_box(damage, box); DBG((" = %d", ret)); if (ret) DBG((" [(%d, %d), (%d, %d)...]", box->x1, box->y1, box->x2, box->y2)); DBG(("\n")); return ret; } #else int _sna_damage_contains_box(struct sna_damage **damage, const BoxRec *box) { return __sna_damage_contains_box(damage, box); } #endif static bool box_overlaps(const BoxRec *a, const BoxRec *b) { return (a->x1 < b->x2 && a->x2 > b->x1 && a->y1 < b->y2 && a->y2 > b->y1); } bool _sna_damage_contains_box__no_reduce(const struct sna_damage *damage, const BoxRec *box) { int n, count; const BoxRec *b; assert(damage && damage->mode != DAMAGE_ALL); if (!box_contains(&damage->extents, box)) return false; n = pixman_region_contains_rectangle((pixman_region16_t *)&damage->region, (BoxPtr)box); if (!damage->dirty) return n == PIXMAN_REGION_IN; if (damage->mode == DAMAGE_ADD) { if (n == PIXMAN_REGION_IN) return true; count = damage->embedded_box.size; if (list_is_empty(&damage->embedded_box.list)) count -= damage->remain; b = damage->embedded_box.box; for (n = 0; n < count; n++) { if (box_contains(&b[n], box)) return true; } return false; } else { if (n != PIXMAN_REGION_IN) return false; if (!list_is_empty(&damage->embedded_box.list)) return false; count = damage->embedded_box.size - damage->remain; b = damage->embedded_box.box; for (n = 0; n < count; n++) { if (box_overlaps(&b[n], box)) return false; } return true; } } static bool __sna_damage_intersect(struct sna_damage *damage, RegionPtr region, RegionPtr result) { assert(damage && damage->mode != DAMAGE_ALL); assert(RegionNotEmpty(region)); if (region->extents.x2 <= damage->extents.x1 || region->extents.x1 >= damage->extents.x2) return false; if (region->extents.y2 <= damage->extents.y1 || region->extents.y1 >= damage->extents.y2) return false; if (damage->dirty) __sna_damage_reduce(damage); if (!pixman_region_not_empty(&damage->region)) return false; RegionNull(result); RegionIntersect(result, &damage->region, region); return RegionNotEmpty(result); } #if HAS_DEBUG_FULL bool _sna_damage_intersect(struct sna_damage *damage, RegionPtr region, RegionPtr result) { char damage_buf[1000]; char region_buf[120]; bool ret; DBG(("%s(%s, %s)...\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage), _debug_describe_region(region_buf, sizeof(region_buf), region))); ret = __sna_damage_intersect(damage, region, result); if (ret) DBG((" = %s\n", _debug_describe_region(region_buf, sizeof(region_buf), result))); else DBG((" = none\n")); return ret; } #else bool _sna_damage_intersect(struct sna_damage *damage, RegionPtr region, RegionPtr result) { return __sna_damage_intersect(damage, region, result); } #endif static int __sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes) { assert(damage && damage->mode != DAMAGE_ALL); if (damage->dirty) __sna_damage_reduce(damage); assert(!damage->dirty); assert(damage->mode == DAMAGE_ADD); *boxes = region_rects(&damage->region); return region_num_rects(&damage->region); } struct sna_damage *_sna_damage_reduce(struct sna_damage *damage) { DBG(("%s\n", __FUNCTION__)); __sna_damage_reduce(damage); assert(!damage->dirty); assert(damage->mode == DAMAGE_ADD); if (!pixman_region_not_empty(&damage->region)) { __sna_damage_destroy(damage); damage = NULL; } return damage; } #if HAS_DEBUG_FULL int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes) { char damage_buf[1000]; int count; DBG(("%s(%s)...\n", __FUNCTION__, _debug_describe_damage(damage_buf, sizeof(damage_buf), damage))); count = __sna_damage_get_boxes(damage, boxes); DBG((" = %d\n", count)); return count; } #else int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes) { return __sna_damage_get_boxes(damage, boxes); } #endif struct sna_damage *_sna_damage_combine(struct sna_damage *l, struct sna_damage *r, int dx, int dy) { if (r->dirty) __sna_damage_reduce(r); if (pixman_region_not_empty(&r->region)) { pixman_region_translate(&r->region, dx, dy); l = __sna_damage_add(l, &r->region); } return l; } void __sna_damage_destroy(struct sna_damage *damage) { free_list(&damage->embedded_box.list); pixman_region_fini(&damage->region); *(void **)damage = __freed_damage; __freed_damage = damage; } #if TEST_DAMAGE && HAS_DEBUG_FULL struct sna_damage_selftest{ int width, height; }; static void st_damage_init_random_box(struct sna_damage_selftest *test, BoxPtr box) { int x, y, w, h; if (test->width == 1) { x = 0, w = 1; } else { x = rand() % (test->width - 1); w = 1 + rand() % (test->width - x - 1); } if (test->height == 1) { y = 0, h = 1; } else { y = rand() % (test->height - 1); h = 1 + rand() % (test->height - y - 1); } box->x1 = x; box->x2 = x+w; box->y1 = y; box->y2 = y+h; } static void st_damage_init_random_region1(struct sna_damage_selftest *test, pixman_region16_t *region) { int x, y, w, h; if (test->width == 1) { x = 0, w = 1; } else { x = rand() % (test->width - 1); w = 1 + rand() % (test->width - x - 1); } if (test->height == 1) { y = 0, h = 1; } else { y = rand() % (test->height - 1); h = 1 + rand() % (test->height - y - 1); } pixman_region_init_rect(region, x, y, w, h); } static void st_damage_add(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { pixman_region16_t tmp; st_damage_init_random_region1(test, &tmp); if (!DAMAGE_IS_ALL(*damage)) sna_damage_add(damage, &tmp); pixman_region_union(region, region, &tmp); } static void st_damage_add_box(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { RegionRec r; st_damage_init_random_box(test, &r.extents); r.data = NULL; if (!DAMAGE_IS_ALL(*damage)) sna_damage_add_box(damage, &r.extents); pixman_region_union(region, region, &r); } static void st_damage_subtract(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { pixman_region16_t tmp; st_damage_init_random_region1(test, &tmp); sna_damage_subtract(damage, &tmp); pixman_region_subtract(region, region, &tmp); } static void st_damage_subtract_box(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { RegionRec r; st_damage_init_random_box(test, &r.extents); r.data = NULL; sna_damage_subtract_box(damage, &r.extents); pixman_region_subtract(region, region, &r); } static void st_damage_all(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { pixman_region16_t tmp; pixman_region_init_rect(&tmp, 0, 0, test->width, test->height); if (!DAMAGE_IS_ALL(*damage)) sna_damage_all(damage, test->width, test->height); pixman_region_union(region, region, &tmp); } static bool st_check_equal(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) { int d_num, r_num; BoxPtr d_boxes, r_boxes; d_num = *damage ? sna_damage_get_boxes(*damage, &d_boxes) : 0; r_boxes = pixman_region_rectangles(region, &r_num); if (d_num != r_num) { ERR(("%s: damage and ref contain different number of rectangles\n", __FUNCTION__)); return false; } if (memcmp(d_boxes, r_boxes, d_num*sizeof(BoxRec))) { ERR(("%s: damage and ref contain different rectangles\n", __FUNCTION__)); return false; } return true; } void sna_damage_selftest(void) { void (*const op[])(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) = { st_damage_add, st_damage_add_box, st_damage_subtract, st_damage_subtract_box, st_damage_all }; bool (*const check[])(struct sna_damage_selftest *test, struct sna_damage **damage, pixman_region16_t *region) = { st_check_equal, //st_check_contains, }; char region_buf[120]; char damage_buf[1000]; int pass; for (pass = 0; pass < 16384; pass++) { struct sna_damage_selftest test; struct sna_damage *damage; pixman_region16_t ref; int iter, i; iter = 1 + rand() % (1 + (pass / 64)); DBG(("%s: pass %d, iters=%d\n", __FUNCTION__, pass, iter)); test.width = 1 + rand() % 2048; test.height = 1 + rand() % 2048; damage = _sna_damage_create(); pixman_region_init(&ref); for (i = 0; i < iter; i++) { op[rand() % ARRAY_SIZE(op)](&test, &damage, &ref); } if (!check[rand() % ARRAY_SIZE(check)](&test, &damage, &ref)) { FatalError("%s: failed - region = %s, damage = %s\n", __FUNCTION__, _debug_describe_region(region_buf, sizeof(region_buf), &ref), _debug_describe_damage(damage_buf, sizeof(damage_buf), damage)); } pixman_region_fini(&ref); sna_damage_destroy(&damage); } } #endif void _sna_damage_debug_get_region(struct sna_damage *damage, RegionRec *r) { int n, nboxes; BoxPtr boxes; struct sna_damage_box *iter; RegionCopy(r, &damage->region); if (!damage->dirty) return; nboxes = damage->embedded_box.size; list_for_each_entry(iter, &damage->embedded_box.list, list) nboxes += iter->size; nboxes -= damage->remain; if (nboxes == 0) return; if (nboxes == 1) { pixman_region16_t tmp; tmp.extents = damage->embedded_box.box[0]; tmp.data = NULL; if (damage->mode == DAMAGE_ADD) pixman_region_union(r, r, &tmp); else pixman_region_subtract(r, r, &tmp); return; } if (damage->mode == DAMAGE_ADD) nboxes += region_num_rects(r); iter = last_box(damage); n = iter->size - damage->remain; boxes = malloc(sizeof(BoxRec)*nboxes); if (boxes == NULL) return; if (list_is_empty(&damage->embedded_box.list)) { memcpy(boxes, damage->embedded_box.box, n*sizeof(BoxRec)); } else { if (boxes != (BoxPtr)(iter+1)) memcpy(boxes, iter+1, n*sizeof(BoxRec)); iter = list_entry(iter->list.prev, struct sna_damage_box, list); while (&iter->list != &damage->embedded_box.list) { memcpy(boxes + n, iter+1, iter->size * sizeof(BoxRec)); n += iter->size; iter = list_entry(iter->list.prev, struct sna_damage_box, list); } memcpy(boxes + n, damage->embedded_box.box, sizeof(damage->embedded_box.box)); n += damage->embedded_box.size; } if (damage->mode == DAMAGE_ADD) { memcpy(boxes + n, region_rects(r), region_num_rects(r)*sizeof(BoxRec)); assert(n + region_num_rects(r) == nboxes); pixman_region_fini(r); pixman_region_init_rects(r, boxes, nboxes); assert(pixman_region_not_empty(r)); assert(damage->extents.x1 == r->extents.x1 && damage->extents.y1 == r->extents.y1 && damage->extents.x2 == r->extents.x2 && damage->extents.y2 == r->extents.y2); } else { pixman_region16_t tmp; pixman_region_init_rects(&tmp, boxes, nboxes); pixman_region_subtract(r, r, &tmp); pixman_region_fini(&tmp); assert(damage->extents.x1 <= r->extents.x1 && damage->extents.y1 <= r->extents.y1 && damage->extents.x2 >= r->extents.x2 && damage->extents.y2 >= r->extents.y2); } free(boxes); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_damage.h000066400000000000000000000217601267532330400241010ustar00rootroot00000000000000#ifndef SNA_DAMAGE_H #define SNA_DAMAGE_H #include #include "compiler.h" struct sna_damage { BoxRec extents; pixman_region16_t region; enum sna_damage_mode { DAMAGE_ADD = 0, DAMAGE_SUBTRACT, DAMAGE_ALL, } mode; int remain, dirty; BoxPtr box; struct { struct list list; int size; BoxRec box[8]; } embedded_box; }; #define DAMAGE_IS_ALL(ptr) (((uintptr_t)(ptr))&1) #define DAMAGE_MARK_ALL(ptr) ((struct sna_damage *)(((uintptr_t)(ptr))|1)) #define DAMAGE_PTR(ptr) ((struct sna_damage *)(((uintptr_t)(ptr))&~1)) #define DAMAGE_REGION(ptr) (&DAMAGE_PTR(ptr)->region) struct sna_damage *sna_damage_create(void); struct sna_damage *__sna_damage_all(struct sna_damage *damage, int width, int height); static inline struct sna_damage * _sna_damage_all(struct sna_damage *damage, int width, int height) { damage = __sna_damage_all(damage, width, height); return DAMAGE_MARK_ALL(damage); } static inline void sna_damage_all(struct sna_damage **damage, PixmapPtr pixmap) { if (!DAMAGE_IS_ALL(*damage)) *damage = _sna_damage_all(*damage, pixmap->drawable.width, pixmap->drawable.height); } struct sna_damage *_sna_damage_combine(struct sna_damage *l, struct sna_damage *r, int dx, int dy); static inline void sna_damage_combine(struct sna_damage **l, struct sna_damage *r, int dx, int dy) { assert(!DAMAGE_IS_ALL(*l)); *l = _sna_damage_combine(*l, DAMAGE_PTR(r), dx, dy); } fastcall struct sna_damage *_sna_damage_add(struct sna_damage *damage, RegionPtr region); static inline void sna_damage_add(struct sna_damage **damage, RegionPtr region) { assert(!DAMAGE_IS_ALL(*damage)); *damage = _sna_damage_add(*damage, region); } static inline bool sna_damage_add_to_pixmap(struct sna_damage **damage, RegionPtr region, PixmapPtr pixmap) { assert(!DAMAGE_IS_ALL(*damage)); if (region->data == NULL && region->extents.x2 - region->extents.x1 >= pixmap->drawable.width && region->extents.y2 - region->extents.y1 >= pixmap->drawable.height) { *damage = _sna_damage_all(*damage, pixmap->drawable.width, pixmap->drawable.height); return true; } else { *damage = _sna_damage_add(*damage, region); return false; } } fastcall struct sna_damage *_sna_damage_add_box(struct sna_damage *damage, const BoxRec *box); static inline void sna_damage_add_box(struct sna_damage **damage, const BoxRec *box) { assert(!DAMAGE_IS_ALL(*damage)); *damage = _sna_damage_add_box(*damage, box); } struct sna_damage *_sna_damage_add_boxes(struct sna_damage *damage, const BoxRec *box, int n, int16_t dx, int16_t dy); static inline void sna_damage_add_boxes(struct sna_damage **damage, const BoxRec *box, int n, int16_t dx, int16_t dy) { assert(!DAMAGE_IS_ALL(*damage)); *damage = _sna_damage_add_boxes(*damage, box, n, dx, dy); } struct sna_damage *_sna_damage_add_rectangles(struct sna_damage *damage, const xRectangle *r, int n, int16_t dx, int16_t dy); static inline void sna_damage_add_rectangles(struct sna_damage **damage, const xRectangle *r, int n, int16_t dx, int16_t dy) { if (damage) { assert(!DAMAGE_IS_ALL(*damage)); *damage = _sna_damage_add_rectangles(*damage, r, n, dx, dy); } } struct sna_damage *_sna_damage_add_points(struct sna_damage *damage, const DDXPointRec *p, int n, int16_t dx, int16_t dy); static inline void sna_damage_add_points(struct sna_damage **damage, const DDXPointRec *p, int n, int16_t dx, int16_t dy) { if (damage) { assert(!DAMAGE_IS_ALL(*damage)); *damage = _sna_damage_add_points(*damage, p, n, dx, dy); } } struct sna_damage *_sna_damage_is_all(struct sna_damage *damage, int width, int height); static inline bool sna_damage_is_all(struct sna_damage **_damage, int width, int height) { struct sna_damage *damage = *_damage; if (damage == NULL) return false; if (DAMAGE_IS_ALL(damage)) return true; switch (damage->mode) { case DAMAGE_ALL: assert(0); return true; case DAMAGE_SUBTRACT: return false; default: assert(0); case DAMAGE_ADD: if (damage->extents.x2 < width || damage->extents.x1 > 0) return false; if (damage->extents.y2 < height || damage->extents.y1 > 0) return false; damage = _sna_damage_is_all(damage, width, height); if (damage->mode == DAMAGE_ALL) { *_damage = DAMAGE_MARK_ALL(damage); return true; } else { *_damage = damage; return false; } } } fastcall struct sna_damage *_sna_damage_subtract(struct sna_damage *damage, RegionPtr region); static inline void sna_damage_subtract(struct sna_damage **damage, RegionPtr region) { *damage = _sna_damage_subtract(DAMAGE_PTR(*damage), region); assert(*damage == NULL || (*damage)->mode != DAMAGE_ALL); } fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage, const BoxRec *box); static inline void sna_damage_subtract_box(struct sna_damage **damage, const BoxRec *box) { *damage = _sna_damage_subtract_box(DAMAGE_PTR(*damage), box); assert(*damage == NULL || (*damage)->mode != DAMAGE_ALL); } fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage, const BoxRec *box, int n, int dx, int dy); static inline void sna_damage_subtract_boxes(struct sna_damage **damage, const BoxRec *box, int n, int dx, int dy) { *damage = _sna_damage_subtract_boxes(DAMAGE_PTR(*damage), box, n, dx, dy); assert(*damage == NULL || (*damage)->mode != DAMAGE_ALL); } bool _sna_damage_intersect(struct sna_damage *damage, RegionPtr region, RegionPtr result); static inline bool sna_damage_intersect(struct sna_damage *damage, RegionPtr region, RegionPtr result) { assert(damage); assert(RegionNotEmpty(region)); assert(!DAMAGE_IS_ALL(damage)); return _sna_damage_intersect(damage, region, result); } static inline bool sna_damage_overlaps_box(const struct sna_damage *damage, const BoxRec *box) { if (box->x2 <= damage->extents.x1 || box->x1 >= damage->extents.x2) return false; if (box->y2 <= damage->extents.y1 || box->y1 >= damage->extents.y2) return false; return true; } int _sna_damage_contains_box(struct sna_damage **damage, const BoxRec *box); static inline int sna_damage_contains_box(struct sna_damage **damage, const BoxRec *box) { if (DAMAGE_IS_ALL(*damage)) return PIXMAN_REGION_IN; if (*damage == NULL) return PIXMAN_REGION_OUT; return _sna_damage_contains_box(damage, box); } static inline int sna_damage_contains_box__offset(struct sna_damage **damage, const BoxRec *box, int dx, int dy) { BoxRec b; if (DAMAGE_IS_ALL(*damage)) return PIXMAN_REGION_IN; if (*damage == NULL) return PIXMAN_REGION_OUT; b = *box; b.x1 += dx; b.x2 += dx; b.y1 += dy; b.y2 += dy; return _sna_damage_contains_box(damage, &b); } bool _sna_damage_contains_box__no_reduce(const struct sna_damage *damage, const BoxRec *box); static inline bool sna_damage_contains_box__no_reduce(const struct sna_damage *damage, const BoxRec *box) { assert(!DAMAGE_IS_ALL(damage)); return _sna_damage_contains_box__no_reduce(damage, box); } int _sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes); static inline int sna_damage_get_boxes(struct sna_damage *damage, const BoxRec **boxes) { assert(DAMAGE_PTR(damage)); if (DAMAGE_IS_ALL(damage)) { *boxes = &DAMAGE_PTR(damage)->extents; return 1; } else return _sna_damage_get_boxes(damage, boxes); } struct sna_damage *_sna_damage_reduce(struct sna_damage *damage); static inline void sna_damage_reduce(struct sna_damage **damage) { if (*damage == NULL) return; if (!DAMAGE_IS_ALL(*damage) && (*damage)->dirty) *damage = _sna_damage_reduce(*damage); } static inline void sna_damage_reduce_all(struct sna_damage **_damage, PixmapPtr pixmap) { struct sna_damage *damage = *_damage; if (damage == NULL || DAMAGE_IS_ALL(damage)) return; DBG(("%s(width=%d, height=%d)\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height)); if (damage->mode == DAMAGE_ADD) { if (damage->extents.x1 <= 0 && damage->extents.y1 <= 0 && damage->extents.x2 >= pixmap->drawable.width && damage->extents.y2 >= pixmap->drawable.height) { if (damage->dirty) { damage = *_damage = _sna_damage_reduce(damage); if (damage == NULL) return; } if (damage->region.data == NULL) *_damage = _sna_damage_all(damage, pixmap->drawable.width, pixmap->drawable.height); } } else *_damage = _sna_damage_reduce(damage); } void __sna_damage_destroy(struct sna_damage *damage); static inline void sna_damage_destroy(struct sna_damage **damage) { if (*damage == NULL) return; if (DAMAGE_PTR(*damage)) __sna_damage_destroy(DAMAGE_PTR(*damage)); *damage = NULL; } void _sna_damage_debug_get_region(struct sna_damage *damage, RegionRec *r); #if HAS_DEBUG_FULL && TEST_DAMAGE void sna_damage_selftest(void); #else static inline void sna_damage_selftest(void) {} #endif #endif /* SNA_DAMAGE_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_display.c000066400000000000000000007304561267532330400243340ustar00rootroot00000000000000/* * Copyright © 2007 Red Hat, Inc. * Copyright © 2013-2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Dave Airlie * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #if HAVE_ALLOCA_H #include #elif defined __GNUC__ #define alloca __builtin_alloca #elif defined _AIX #define alloca __alloca #elif defined _MSC_VER #include #define alloca _alloca #else void *alloca(size_t); #endif #define _PARSE_EDID_ /* Jump through a few hoops in order to fixup EDIDs */ #undef VERSION #undef REVISION #include "sna.h" #include "sna_reg.h" #include "fb/fbpict.h" #include "intel_options.h" #include "backlight.h" #include #include #include #if XF86_CRTC_VERSION >= 3 #define HAS_GAMMA 1 #else #define HAS_GAMMA 0 #endif #include #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H) #include #else #define DPMSModeOn 0 #define DPMSModeOff 3 #endif #include /* for xf86InterpretEDID */ #include #ifdef HAVE_VALGRIND #include #include #endif #define FAIL_CURSOR_IOCTL 0 #define COLDPLUG_DELAY_MS 2000 /* Minor discrepancy between 32-bit/64-bit ABI in old kernels */ union compat_mode_get_connector{ struct drm_mode_get_connector conn; uint32_t pad[20]; }; #define KNOWN_MODE_FLAGS ((1<<14)-1) #ifndef MONITOR_EDID_COMPLETE_RAWDATA #define MONITOR_EDID_COMPLETE_RAWDATA 1 #endif #ifndef DEFAULT_DPI #define DEFAULT_DPI 96 #endif #define OUTPUT_STATUS_CACHE_MS 15000 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 #define DRM_PLANE_TYPE_OVERLAY 0 #define DRM_PLANE_TYPE_PRIMARY 1 #define DRM_PLANE_TYPE_CURSOR 2 #define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xb9, struct local_mode_obj_get_properties) struct local_mode_obj_get_properties { uint64_t props_ptr; uint64_t prop_values_ptr; uint32_t count_props; uint32_t obj_id; uint32_t obj_type; uint32_t pad; }; #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee struct local_mode_set_plane { uint32_t plane_id; uint32_t crtc_id; uint32_t fb_id; /* fb object contains surface format type */ uint32_t flags; /* Signed dest location allows it to be partially off screen */ int32_t crtc_x, crtc_y; uint32_t crtc_w, crtc_h; /* Source values are 16.16 fixed point */ uint32_t src_x, src_y; uint32_t src_h, src_w; }; #define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane) struct local_mode_get_plane { uint32_t plane_id; uint32_t crtc_id; uint32_t fb_id; uint32_t possible_crtcs; uint32_t gamma_size; uint32_t count_format_types; uint64_t format_type_ptr; }; #define LOCAL_IOCTL_MODE_GETPLANE DRM_IOWR(0xb6, struct local_mode_get_plane) struct local_mode_get_plane_res { uint64_t plane_id_ptr; uint64_t count_planes; }; #define LOCAL_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xb5, struct local_mode_get_plane_res) #if 0 #define __DBG DBG #else #define __DBG(x) #endif #define DBG_NATIVE_ROTATION ~0 /* minimum RR_Rotate_0 */ extern XF86ConfigPtr xf86configptr; struct sna_cursor { struct sna_cursor *next; uint32_t *image; bool transformed; Rotation rotation; int ref; int size; int last_width; int last_height; unsigned handle; unsigned serial; unsigned alloc; }; struct sna_crtc { unsigned long flags; xf86CrtcPtr base; struct drm_mode_modeinfo kmode; PixmapPtr slave_pixmap; DamagePtr slave_damage; struct kgem_bo *bo, *shadow_bo, *client_bo, *cache_bo; struct sna_cursor *cursor; unsigned int last_cursor_size; uint32_t offset; bool shadow; bool fallback_shadow; bool transform; bool cursor_transform; bool hwcursor; bool flip_pending; struct pict_f_transform cursor_to_fb, fb_to_cursor; RegionRec client_damage; /* XXX overlap with shadow damage? */ uint16_t shadow_bo_width, shadow_bo_height; uint32_t rotation; struct plane { uint32_t id; struct { uint32_t prop; uint32_t supported; uint32_t current; } rotation; } primary, sprite; uint32_t mode_serial, flip_serial; uint32_t last_seq, wrap_seq; struct ust_msc swap; sna_flip_handler_t flip_handler; struct kgem_bo *flip_bo; void *flip_data; struct list shadow_link; }; struct sna_property { drmModePropertyPtr kprop; int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ Atom *atoms; }; struct sna_output { xf86OutputPtr base; unsigned id; unsigned serial; unsigned possible_encoders; unsigned attached_encoders; unsigned int is_panel : 1; unsigned int add_default_modes : 1; uint32_t edid_idx; uint32_t edid_blob_id; uint32_t edid_len; void *edid_raw; xf86MonPtr fake_edid_mon; void *fake_edid_raw; bool has_panel_limits; int panel_hdisplay; int panel_vdisplay; uint32_t dpms_id; uint8_t dpms_mode; struct backlight backlight; int backlight_active_level; uint32_t last_detect; uint32_t status; bool update_properties; int num_modes; struct drm_mode_modeinfo *modes; int num_props; uint32_t *prop_ids; uint64_t *prop_values; struct sna_property *props; }; enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */ OPTION_PREFERRED_MODE, #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,1,0) OPTION_ZOOM_MODES, #endif OPTION_POSITION, OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF, OPTION_ENABLE, OPTION_DISABLE, OPTION_MIN_CLOCK, OPTION_MAX_CLOCK, OPTION_IGNORE, OPTION_ROTATE, OPTION_PANNING, OPTION_PRIMARY, OPTION_DEFAULT_MODES, }; static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup); static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc); static bool is_zaphod(ScrnInfoPtr scrn) { return xf86IsEntityShared(scrn->entityList[0]); } static bool sna_zaphod_match(struct sna *sna, const char *output) { const char *s, *colon; char t[20]; unsigned int i = 0; s = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); if (s == NULL) return false; colon = strchr(s, ':'); if (colon) /* Skip over the ZaphodPipes */ s = colon + 1; do { /* match any outputs in a comma list, stopping at whitespace */ switch (*s) { case '\0': t[i] = '\0'; return strcmp(t, output) == 0; case ',': t[i] ='\0'; if (strcmp(t, output) == 0) return TRUE; i = 0; break; case ' ': case '\t': case '\n': case '\r': break; default: t[i++] = *s; break; } s++; } while (i < sizeof(t)); return false; } static unsigned get_zaphod_crtcs(struct sna *sna) { const char *str, *colon; unsigned crtcs = 0; str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD); if (str == NULL || (colon = strchr(str, ':')) == NULL) { DBG(("%s: no zaphod pipes, using screen number: %x\n", __FUNCTION__, sna->scrn->confScreen->device->screen)); return 1 << sna->scrn->confScreen->device->screen; } DBG(("%s: ZaphodHeads='%s'\n", __FUNCTION__, str)); while (str < colon) { char *end; unsigned crtc = strtoul(str, &end, 0); if (end == str) break; DBG(("%s: adding CRTC %d to zaphod pipes\n", __FUNCTION__, crtc)); crtcs |= 1 << crtc; str = end + 1; } DBG(("%s: ZaphodPipes=%x\n", __FUNCTION__, crtcs)); return crtcs; } inline static unsigned count_to_mask(int x) { return (1 << x) - 1; } static inline struct sna_output *to_sna_output(xf86OutputPtr output) { return output->driver_private; } static inline int to_connector_id(xf86OutputPtr output) { assert(to_sna_output(output)); assert(to_sna_output(output)->id); return to_sna_output(output)->id; } static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc) { return crtc->driver_private; } static inline unsigned __sna_crtc_pipe(struct sna_crtc *crtc) { return crtc->flags >> 8 & 0xff; } static inline unsigned __sna_crtc_id(struct sna_crtc *crtc) { return crtc->flags >> 16 & 0xff; } static inline bool event_pending(int fd) { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; return poll(&pfd, 1, 0) == 1; } static bool sna_mode_wait_for_event(struct sna *sna) { struct pollfd pfd; pfd.fd = sna->kgem.fd; pfd.events = POLLIN; return poll(&pfd, 1, -1) == 1; } static inline uint32_t fb_id(struct kgem_bo *bo) { return bo->delta; } uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) { assert(to_sna_crtc(crtc)); return to_sna_crtc(crtc)->sprite.id; } bool sna_crtc_is_transformed(xf86CrtcPtr crtc) { assert(to_sna_crtc(crtc)); return to_sna_crtc(crtc)->transform; } static inline bool msc64(struct sna_crtc *sna_crtc, uint32_t seq, uint64_t *msc) { bool record = true; if (seq < sna_crtc->last_seq) { if (sna_crtc->last_seq - seq > 0x40000000) { sna_crtc->wrap_seq++; DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq, sna_crtc->wrap_seq)); } else { DBG(("%s: pipe=%d msc went backwards; was %u, now %u; ignoring for last_swap\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq)); record = false; } } *msc = (uint64_t)sna_crtc->wrap_seq << 32 | seq; return record; } uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, int tv_sec, int tv_usec, unsigned seq) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); uint64_t msc; assert(sna_crtc); if (msc64(sna_crtc, seq, &msc)) { DBG(("%s: recording last swap on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc, tv_sec, tv_usec)); sna_crtc->swap.tv_sec = tv_sec; sna_crtc->swap.tv_usec = tv_usec; sna_crtc->swap.msc = msc; } else { DBG(("%s: swap event on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc, tv_sec, tv_usec)); } return msc; } const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc) { static struct ust_msc zero; if (crtc == NULL) { return &zero; } else { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); assert(sna_crtc); return &sna_crtc->swap; } } #ifndef NDEBUG static void gem_close(int fd, uint32_t handle); static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo, int width, int height) { struct drm_mode_fb_cmd info; assert(bo->scanout); VG_CLEAR(info); info.fb_id = fb_id(bo); assert(drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info) == 0); gem_close(kgem->fd, info.handle); assert(width == info.width && height == info.height); } #else #define assert_scanout(k, b, w, h) #endif static unsigned get_fb(struct sna *sna, struct kgem_bo *bo, int width, int height) { ScrnInfoPtr scrn = sna->scrn; struct drm_mode_fb_cmd arg; if (!kgem_bo_is_fenced(&sna->kgem, bo)) return 0; assert(bo->refcnt); assert(bo->proxy == NULL); assert(!bo->snoop); assert(8*bo->pitch >= width * scrn->bitsPerPixel); assert(height * bo->pitch <= kgem_bo_size(bo)); /* XXX crtc offset */ if (fb_id(bo)) { DBG(("%s: reusing fb=%d for handle=%d\n", __FUNCTION__, fb_id(bo), bo->handle)); assert_scanout(&sna->kgem, bo, width, height); return fb_id(bo); } DBG(("%s: create fb %dx%d@%d/%d\n", __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel)); assert(bo->tiling != I915_TILING_Y || sna->kgem.can_scanout_y); assert((bo->pitch & 63) == 0); assert(scrn->vtSema); /* must be master */ VG_CLEAR(arg); arg.width = width; arg.height = height; arg.pitch = bo->pitch; arg.bpp = scrn->bitsPerPixel; arg.depth = scrn->depth; arg.handle = bo->handle; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) { /* Try again with the fancy version */ struct local_mode_fb_cmd2 { uint32_t fb_id; uint32_t width, height; uint32_t pixel_format; uint32_t flags; uint32_t handles[4]; uint32_t pitches[4]; /* pitch for each plane */ uint32_t offsets[4]; /* offset of each plane */ uint64_t modifiers[4]; } f; #define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2) memset(&f, 0, sizeof(f)); f.width = width; f.height = height; /* XXX interlaced */ f.flags = 1 << 1; /* +modifiers */ f.handles[0] = bo->handle; f.pitches[0] = bo->pitch; switch (bo->tiling) { case I915_TILING_NONE: break; case I915_TILING_X: /* I915_FORMAT_MOD_X_TILED */ f.modifiers[0] = (uint64_t)1 << 56 | 1; break; case I915_TILING_Y: /* I915_FORMAT_MOD_X_TILED */ f.modifiers[0] = (uint64_t)1 << 56 | 2; break; } #define fourcc(a,b,c,d) ((a) | (b) << 8 | (c) << 16 | (d) << 24) switch (scrn->depth) { default: ERR(("%s: unhandled screen format, depth=%d\n", __FUNCTION__, scrn->depth)); goto fail; case 8: f.pixel_format = fourcc('C', '8', ' ', ' '); break; case 15: f.pixel_format = fourcc('X', 'R', '1', '5'); break; case 16: f.pixel_format = fourcc('R', 'G', '1', '6'); break; case 24: f.pixel_format = fourcc('X', 'R', '2', '4'); break; case 30: f.pixel_format = fourcc('X', 'R', '3', '0'); break; } #undef fourcc if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_ADDFB2, &f)) { fail: xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n", __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel, bo->pitch, errno); return 0; } arg.fb_id = f.fb_id; } assert(arg.fb_id != 0); bo->delta = arg.fb_id; DBG(("%s: attached fb=%d to handle=%d\n", __FUNCTION__, bo->delta, arg.handle)); bo->scanout = true; return bo->delta; } static uint32_t gem_create(int fd, int size) { struct drm_i915_gem_create create; assert((size & 4095) == 0); VG_CLEAR(create); create.handle = 0; create.size = size; (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); return create.handle; } static void *gem_mmap(int fd, int handle, int size) { struct drm_i915_gem_mmap_gtt mmap_arg; struct drm_i915_gem_set_domain set_domain; void *ptr; VG_CLEAR(mmap_arg); mmap_arg.handle = handle; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) return NULL; ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset); if (ptr == MAP_FAILED) return NULL; VG_CLEAR(set_domain); set_domain.handle = handle; set_domain.read_domains = I915_GEM_DOMAIN_GTT; set_domain.write_domain = I915_GEM_DOMAIN_GTT; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { munmap(ptr, size); return NULL; } return ptr; } static void gem_close(int fd, uint32_t handle) { struct drm_gem_close close; VG_CLEAR(close); close.handle = handle; (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close); } #define BACKLIGHT_NAME "Backlight" #define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" static Atom backlight_atom, backlight_deprecated_atom; #if HAVE_UDEV static void sna_backlight_uevent(int fd, void *closure) { struct sna *sna = closure; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; DBG(("%s()\n", __FUNCTION__)); /* Drain the event queue */ while (event_pending(fd)) { struct udev_device *dev; DBG(("%s: waiting for uevent\n", __FUNCTION__)); dev = udev_monitor_receive_device(sna->mode.backlight_monitor); if (dev == NULL) break; udev_device_unref(dev); } /* Query all backlights for any changes */ DBG(("%s: probing backlights for changes\n", __FUNCTION__)); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; struct sna_output *sna_output = to_sna_output(output); int val; if (sna_output->dpms_mode != DPMSModeOn) continue; val = backlight_get(&sna_output->backlight); if (val < 0) continue; DBG(("%s(%s): backlight '%s' was %d, now %d\n", __FUNCTION__, output->name, sna_output->backlight.iface, sna_output->backlight_active_level, val)); if (val == sna_output->backlight_active_level) continue; sna_output->backlight_active_level = val; if (output->randr_output) { DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name)); RRChangeOutputProperty(output->randr_output, backlight_atom, XA_INTEGER, 32, PropModeReplace, 1, &val, TRUE, FALSE); RRChangeOutputProperty(output->randr_output, backlight_deprecated_atom, XA_INTEGER, 32, PropModeReplace, 1, &val, TRUE, FALSE); } } DBG(("%s: complete\n", __FUNCTION__)); } static void sna_backlight_pre_init(struct sna *sna) { struct udev *u; struct udev_monitor *mon; #if !USE_BACKLIGHT return; #endif u = udev_new(); if (!u) return; mon = udev_monitor_new_from_netlink(u, "udev"); if (!mon) goto free_udev; if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL)) goto free_monitor; if (udev_monitor_enable_receiving(mon)) goto free_monitor; sna->mode.backlight_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), sna_backlight_uevent, sna); if (!sna->mode.backlight_handler) goto free_monitor; DBG(("%s: installed backlight monitor\n", __FUNCTION__)); sna->mode.backlight_monitor = mon; return; free_monitor: udev_monitor_unref(mon); free_udev: udev_unref(u); } static void sna_backlight_drain_uevents(struct sna *sna) { if (sna->mode.backlight_monitor == NULL) return; DBG(("%s()\n", __FUNCTION__)); sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor), sna); } static void sna_backlight_close(struct sna *sna) { struct udev *u; if (sna->mode.backlight_handler == NULL) return; xf86RemoveGeneralHandler(sna->mode.backlight_handler); u = udev_monitor_get_udev(sna->mode.backlight_monitor); udev_monitor_unref(sna->mode.backlight_monitor); udev_unref(u); sna->mode.backlight_handler = NULL; sna->mode.backlight_monitor = NULL; } #else static void sna_backlight_pre_init(struct sna *sna) { } static void sna_backlight_drain_uevents(struct sna *sna) { } static void sna_backlight_close(struct sna *sna) { } #endif static void sna_output_backlight_disable(struct sna_output *sna_output) { xf86OutputPtr output = sna_output->base; xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Failed to set backlight %s for output %s, disabling\n", sna_output->backlight.iface, output->name); backlight_disable(&sna_output->backlight); if (output->randr_output) { RRDeleteOutputProperty(output->randr_output, backlight_atom); RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom); } } static int sna_output_backlight_set(struct sna_output *sna_output, int level) { int ret = 0; DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, sna_output->base->name, level, sna_output->backlight.max)); if (backlight_set(&sna_output->backlight, level)) { sna_output_backlight_disable(sna_output); ret = -1; } /* Consume the uevent notification now so that we don't misconstrue * the change latter when we wake up and the output is in a different * state. */ sna_backlight_drain_uevents(to_sna(sna_output->base->scrn)); return ret; } static bool has_native_backlight(struct sna_output *sna_output) { return sna_output->backlight.type == BL_RAW; } static void sna_output_backlight_off(struct sna_output *sna_output) { /* Trust the kernel to turn the native backlight off. However, we * do explicitly turn the backlight back on (when we wake the output) * just in case a third party turns it off! */ if (has_native_backlight(sna_output)) return; DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name)); backlight_off(&sna_output->backlight); sna_output_backlight_set(sna_output, 0); } static void sna_output_backlight_on(struct sna_output *sna_output) { DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name)); sna_output_backlight_set(sna_output, sna_output->backlight_active_level); if (backlight_on(&sna_output->backlight) < 0) sna_output_backlight_disable(sna_output); } static int sna_output_backlight_get(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; int level = backlight_get(&sna_output->backlight); DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__, output->name, level, sna_output->backlight.max)); return level; } static char * has_user_backlight_override(xf86OutputPtr output) { struct sna *sna = to_sna(output->scrn); const char *str; str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT); if (str == NULL) return NULL; DBG(("%s(%s) requested %s\n", __FUNCTION__, output->name, str)); if (*str == '\0') return (char *)str; if (!backlight_exists(str)) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Unrecognised backlight control interface '%s'\n", str); return NULL; } return strdup(str); } static void sna_output_backlight_init(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; struct pci_device *pci; MessageType from; char *best_iface; #if !USE_BACKLIGHT return; #endif from = X_CONFIG; best_iface = has_user_backlight_override(output); if (best_iface) goto done; /* XXX detect right backlight for multi-GPU/panels */ from = X_PROBED; pci = xf86GetPciInfoForEntity(to_sna(output->scrn)->pEnt->index); if (pci != NULL) best_iface = backlight_find_for_device(pci); done: DBG(("%s(%s) opening backlight %s\n", __FUNCTION__, output->name, best_iface ?: "none")); sna_output->backlight_active_level = backlight_open(&sna_output->backlight, best_iface); DBG(("%s(%s): initial backlight value %d\n", __FUNCTION__, output->name, sna_output->backlight_active_level)); if (sna_output->backlight_active_level < 0) return; switch (sna_output->backlight.type) { case BL_FIRMWARE: best_iface = (char *)"firmware"; break; case BL_PLATFORM: best_iface = (char *)"platform"; break; case BL_RAW: best_iface = (char *)"raw"; break; default: best_iface = (char *)"unknown"; break; } xf86DrvMsg(output->scrn->scrnIndex, from, "Found backlight control interface %s (type '%s') for output %s\n", sna_output->backlight.iface, best_iface, output->name); } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) static inline int sigio_block(void) { OsBlockSIGIO(); return 0; } static inline void sigio_unblock(int was_blocked) { OsReleaseSIGIO(); (void)was_blocked; } #else #include static inline int sigio_block(void) { return xf86BlockSIGIO(); } static inline void sigio_unblock(int was_blocked) { xf86UnblockSIGIO(was_blocked); } #endif static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode) { char tmp[32], *buf; int len; len = sprintf(tmp, "%dx%d%s", kmode->hdisplay, kmode->vdisplay, kmode->flags & V_INTERLACE ? "i" : ""); if ((unsigned)len >= sizeof(tmp)) return NULL; buf = malloc(len + 1); if (buf == NULL) return NULL; return memcpy(buf, tmp, len + 1); } static char *get_kmode_name(const struct drm_mode_modeinfo *kmode) { if (*kmode->name == '\0') return canonical_kmode_name(kmode); return strdup(kmode->name); } static DisplayModePtr mode_from_kmode(ScrnInfoPtr scrn, const struct drm_mode_modeinfo *kmode, DisplayModePtr mode) { DBG(("kmode: %s, clock=%d, %d %d %d %d %d, %d %d %d %d %d, flags=%x, type=%x\n", kmode->name, kmode->clock, kmode->hdisplay, kmode->hsync_start, kmode->hsync_end, kmode->htotal, kmode->hskew, kmode->vdisplay, kmode->vsync_start, kmode->vsync_end, kmode->vtotal, kmode->vscan, kmode->flags, kmode->type)); mode->status = MODE_OK; mode->Clock = kmode->clock; mode->HDisplay = kmode->hdisplay; mode->HSyncStart = kmode->hsync_start; mode->HSyncEnd = kmode->hsync_end; mode->HTotal = kmode->htotal; mode->HSkew = kmode->hskew; mode->VDisplay = kmode->vdisplay; mode->VSyncStart = kmode->vsync_start; mode->VSyncEnd = kmode->vsync_end; mode->VTotal = kmode->vtotal; mode->VScan = kmode->vscan; mode->VRefresh = kmode->vrefresh; mode->Flags = kmode->flags; mode->name = get_kmode_name(kmode); if (kmode->type & DRM_MODE_TYPE_DRIVER) mode->type = M_T_DRIVER; if (kmode->type & DRM_MODE_TYPE_PREFERRED) mode->type |= M_T_PREFERRED; if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS) mode->status = MODE_BAD; /* unknown flags => unhandled */ xf86SetModeCrtc(mode, scrn->adjustFlags); return mode; } static void mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode) { memset(kmode, 0, sizeof(*kmode)); kmode->clock = mode->Clock; kmode->hdisplay = mode->HDisplay; kmode->hsync_start = mode->HSyncStart; kmode->hsync_end = mode->HSyncEnd; kmode->htotal = mode->HTotal; kmode->hskew = mode->HSkew; kmode->vdisplay = mode->VDisplay; kmode->vsync_start = mode->VSyncStart; kmode->vsync_end = mode->VSyncEnd; kmode->vtotal = mode->VTotal; kmode->vscan = mode->VScan; kmode->vrefresh = mode->VRefresh; kmode->flags = mode->Flags; if (mode->name) strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; } static void sna_crtc_force_outputs_on(xf86CrtcPtr crtc) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); /* All attached outputs are valid, so update our timestamps */ unsigned now = GetTimeInMillis(); int i; assert(to_sna_crtc(crtc)); DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); /* DPMS handling by the kernel is inconsistent, so after setting a * mode on an output presume that we intend for it to be on, or that * the kernel will force it on. * * So force DPMS to be on for all connected outputs, and restore * the backlight. */ for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != crtc) continue; __sna_output_dpms(output, DPMSModeOn, false); if (to_sna_output(output)->last_detect) to_sna_output(output)->last_detect = now; } #if XF86_CRTC_VERSION >= 3 crtc->active = TRUE; #endif } static void sna_crtc_force_outputs_off(xf86CrtcPtr crtc) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); int i; assert(to_sna_crtc(crtc)); DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); /* DPMS handling by the kernel is inconsistent, so after setting a * mode on an output presume that we intend for it to be on, or that * the kernel will force it on. * * So force DPMS to be on for all connected outputs, and restore * the backlight. */ for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != crtc) continue; __sna_output_dpms(output, DPMSModeOff, false); } } static unsigned rotation_reflect(unsigned rotation) { unsigned other_bits; /* paranoia for future extensions */ other_bits = rotation & ~RR_Rotate_All; /* flip the reflection to compensate for reflecting the rotation */ other_bits ^= RR_Reflect_X | RR_Reflect_Y; /* Reflect the screen by rotating the rotation bit, * which has to have at least RR_Rotate_0 set. This allows * us to reflect any of the rotation bits, not just 0. */ rotation &= RR_Rotate_All; assert(rotation); rotation <<= 2; /* RR_Rotate_0 -> RR_Rotate_180 etc */ rotation |= rotation >> 4; /* RR_Rotate_270' to RR_Rotate_90 */ rotation &= RR_Rotate_All; assert(rotation); return rotation | other_bits; } static unsigned rotation_reduce(struct plane *p, unsigned rotation) { /* If unsupported try exchanging rotation for a reflection */ if (rotation & ~p->rotation.supported) { unsigned new_rotation = rotation_reflect(rotation); if ((new_rotation & p->rotation.supported) == new_rotation) rotation = new_rotation; } /* Only one rotation bit should be set */ assert(is_power_of_two(rotation & RR_Rotate_All)); return rotation; } static bool rotation_set(struct sna *sna, struct plane *p, uint32_t desired) { #define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xbA, struct local_mode_obj_set_property) struct local_mode_obj_set_property { uint64_t value; uint32_t prop_id; uint32_t obj_id; uint32_t obj_type; uint32_t pad; } prop; if (desired == p->rotation.current) return true; if ((desired & p->rotation.supported) != desired) { errno = EINVAL; return false; } DBG(("%s: obj=%d, type=%x prop=%d set-rotation=%x\n", __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, p->rotation.prop, desired)); assert(p->id); assert(p->rotation.prop); VG_CLEAR(prop); prop.obj_id = p->id; prop.obj_type = LOCAL_MODE_OBJECT_PLANE; prop.prop_id = p->rotation.prop; prop.value = desired; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop)) return false; p->rotation.current = desired; return true; } static void rotation_reset(struct plane *p) { if (p->rotation.prop == 0) return; p->rotation.current = 0; } bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) { assert(to_sna_crtc(crtc)); DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), to_sna_crtc(crtc)->sprite.id, rotation)); return rotation_set(to_sna(crtc->scrn), &to_sna_crtc(crtc)->sprite, rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation)); } #if HAS_DEBUG_FULL struct kmsg { int fd; int saved_loglevel; }; static int kmsg_get_debug(void) { FILE *file; int v = -1; file = fopen("/sys/module/drm/parameters/debug", "r"); if (file) { fscanf(file, "%d", &v); fclose(file); } return v; } static void kmsg_set_debug(int v) { FILE *file; file = fopen("/sys/module/drm/parameters/debug", "w"); if (file) { fprintf(file, "%d\n", v); fclose(file); } } static void kmsg_open(struct kmsg *k) { k->saved_loglevel = kmsg_get_debug(); if (k->saved_loglevel != -1) kmsg_set_debug(0xff); k->fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK); if (k->fd != -1) lseek(k->fd, 0, SEEK_END); } static void kmsg_close(struct kmsg *k, int dump) { FILE *file; file = NULL; if (k->fd != -1 && dump) file = fdopen(k->fd, "r"); if (file) { size_t len = 0; char *line = NULL; while (getline(&line, &len, file) != -1) { char *start = strchr(line, ';'); if (start) LogF("KMSG: %s", start + 1); } free(line); fclose(file); } if (k->fd != -1) close(k->fd); if (k->saved_loglevel != -1) kmsg_set_debug(k->saved_loglevel); } #else struct kmsg { int unused; }; static void kmsg_open(struct kmsg *k) {} static void kmsg_close(struct kmsg *k, int dump) {} #endif static bool sna_crtc_apply(xf86CrtcPtr crtc) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); struct drm_mode_crtc arg; uint32_t output_ids[32]; int output_count = 0; int sigio, i; struct kmsg kmsg; bool ret = false; DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna_crtc->bo->handle)); if (!sna_crtc->kmode.clock) { ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc))); return false; } sigio = sigio_block(); kmsg_open(&kmsg); assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids)); sna_crtc_disable_cursor(sna, sna_crtc); if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) { memset(&arg, 0, sizeof(arg)); arg.crtc_id = __sna_crtc_id(sna_crtc); (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); } if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) { ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n", __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation; goto unblock; } DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna_crtc->rotation)); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; /* Make sure we mark the output as off (and save the backlight) * before the kernel turns it off due to changing the pipe. * This is necessary as the kernel may turn off the backlight * and we lose track of the user settings. */ if (output->crtc == NULL) __sna_output_dpms(output, DPMSModeOff, false); if (output->crtc != crtc) continue; /* Skip over any hotunplugged outputs so that we can * recover in cases where the previous mode is now * only partially valid. */ if (!to_sna_output(output)->id) continue; DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", __FUNCTION__, output->name, i, to_connector_id(output), __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), (uint32_t)output->possible_crtcs, (uint32_t)output->possible_clones)); assert(output->possible_crtcs & (1 << __sna_crtc_pipe(sna_crtc)) || is_zaphod(crtc->scrn)); output_ids[output_count] = to_connector_id(output); if (++output_count == ARRAY_SIZE(output_ids)) { DBG(("%s: too many outputs (%d) for me!\n", __FUNCTION__, output_count)); errno = EINVAL; goto unblock; } } if (output_count == 0) { DBG(("%s: no outputs\n", __FUNCTION__)); errno = EINVAL; goto unblock; } VG_CLEAR(arg); arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = fb_id(sna_crtc->bo); if (sna_crtc->transform || sna_crtc->slave_pixmap) { arg.x = 0; arg.y = 0; sna_crtc->offset = 0; } else { arg.x = crtc->x; arg.y = crtc->y; sna_crtc->offset = arg.y << 16 | arg.x; } arg.set_connectors_ptr = (uintptr_t)output_ids; arg.count_connectors = output_count; arg.mode = sna_crtc->kmode; arg.mode_valid = 1; DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), arg.mode.hdisplay, arg.mode.vdisplay, arg.x, arg.y, arg.mode.clock, arg.fb_id, sna_crtc->shadow ? " [shadow]" : "", sna_crtc->transform ? " [transformed]" : "", output_count, output_count ? output_ids[0] : 0)); ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg) == 0; if (ret) { sna_crtc->mode_serial++; sna_crtc_force_outputs_on(crtc); } unblock: kmsg_close(&kmsg, !ret); sigio_unblock(sigio); return ret; } static bool overlap(const BoxRec *a, const BoxRec *b) { if (a->x1 >= b->x2) return false; if (a->x2 <= b->x1) return false; if (a->y1 >= b->y2) return false; if (a->y2 <= b->y1) return false; return true; } static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned flags) { PixmapPtr pixmap = priv->pixmap; struct kgem_bo *bo, *tmp; int flip_active; bool ret = true; DBG(("%s: flags=%x, flips=%d, handle=%d, shadow=%d\n", __FUNCTION__, flags, sna->mode.flip_active, priv->gpu_bo->handle, sna->mode.shadow->handle)); assert(priv->move_to_gpu_data == sna); assert(sna->mode.shadow != priv->gpu_bo); if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_enabled) goto done; assert(sna->mode.shadow_damage); if ((flags & MOVE_WRITE) == 0) { if ((flags & __MOVE_SCANOUT) == 0) { struct sna_crtc *crtc; list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) { if (overlap(&sna->mode.shadow_region.extents, &crtc->base->bounds)) { DrawableRec draw; RegionRec region; draw.width = crtc->base->mode.HDisplay; draw.height = crtc->base->mode.VDisplay; draw.depth = sna->front->drawable.depth; draw.bitsPerPixel = sna->front->drawable.bitsPerPixel; DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", __FUNCTION__, crtc->base->bounds.x1, crtc->base->bounds.y1, crtc->base->bounds.x2, crtc->base->bounds.y2, crtc->client_bo->handle)); ret &= sna->render.copy_boxes(sna, GXcopy, &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, &pixmap->drawable, priv->gpu_bo, 0, 0, &crtc->base->bounds, 1, 0); region.extents = crtc->base->bounds; region.data = NULL; RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); } } } return ret; } assert(sna->mode.shadow_active); sna->mode.shadow_wait = true; sna->mode.shadow_enabled = false; flip_active = sna->mode.flip_active; if (flip_active) { struct sna_crtc *crtc; list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) flip_active -= crtc->flip_pending; DBG(("%s: %d flips still pending, shadow flip_active=%d\n", __FUNCTION__, sna->mode.flip_active, flip_active)); } if (flip_active) { /* raw cmd to avoid setting wedged in the middle of an op */ drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0); sna->kgem.need_throttle = false; while (flip_active && sna_mode_wakeup(sna)) { struct sna_crtc *crtc; flip_active = sna->mode.flip_active; list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) flip_active -= crtc->flip_pending; } DBG(("%s: after waiting %d flips outstanding, flip_active=%d\n", __FUNCTION__, sna->mode.flip_active, flip_active)); } bo = sna->mode.shadow; if (flip_active) { bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, priv->gpu_bo->tiling, CREATE_EXACT | CREATE_SCANOUT); if (bo != NULL) { DBG(("%s: replacing still-attached GPU bo handle=%d, flips=%d\n", __FUNCTION__, priv->gpu_bo->tiling, sna->mode.flip_active)); RegionUninit(&sna->mode.shadow_region); sna->mode.shadow_region.extents.x1 = 0; sna->mode.shadow_region.extents.y1 = 0; sna->mode.shadow_region.extents.x2 = pixmap->drawable.width; sna->mode.shadow_region.extents.y2 = pixmap->drawable.height; sna->mode.shadow_region.data = NULL; } else { while (sna->mode.flip_active && sna_mode_wait_for_event(sna)) sna_mode_wakeup(sna); bo = sna->mode.shadow; } } assert(!sna->mode.shadow_enabled); assert(sna->mode.shadow_wait); sna->mode.shadow_wait = false; sna->mode.shadow_enabled = true; if (bo->refcnt > 1) { bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, priv->gpu_bo->tiling, CREATE_EXACT | CREATE_SCANOUT); if (bo != NULL) { DBG(("%s: replacing exported GPU bo\n", __FUNCTION__)); RegionUninit(&sna->mode.shadow_region); sna->mode.shadow_region.extents.x1 = 0; sna->mode.shadow_region.extents.y1 = 0; sna->mode.shadow_region.extents.x2 = pixmap->drawable.width; sna->mode.shadow_region.extents.y2 = pixmap->drawable.height; sna->mode.shadow_region.data = NULL; } else bo = sna->mode.shadow; } RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, &sna->mode.shadow_cancel); while (!list_is_empty(&sna->mode.shadow_crtc)) { struct sna_crtc *crtc = list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link); if (overlap(&crtc->base->bounds, &sna->mode.shadow_region.extents)) { RegionRec region; DrawableRec draw; draw.width = crtc->base->mode.HDisplay; draw.height = crtc->base->mode.VDisplay; draw.depth = sna->front->drawable.depth; draw.bitsPerPixel = sna->front->drawable.bitsPerPixel; DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n", __FUNCTION__, crtc->base->bounds.x1, crtc->base->bounds.y1, crtc->base->bounds.x2, crtc->base->bounds.y2, crtc->client_bo->handle)); ret = sna->render.copy_boxes(sna, GXcopy, &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, &pixmap->drawable, bo, 0, 0, &crtc->base->bounds, 1, 0); region.extents = crtc->base->bounds; region.data = NULL; RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion); } crtc->client_bo->active_scanout--; kgem_bo_destroy(&sna->kgem, crtc->client_bo); crtc->client_bo = NULL; list_del(&crtc->shadow_link); } if (RegionNotEmpty(&sna->mode.shadow_region)) { DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(&sna->mode.shadow_region), sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); ret = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, region_rects(&sna->mode.shadow_region), region_num_rects(&sna->mode.shadow_region), 0); } if (priv->cow) sna_pixmap_undo_cow(sna, priv, 0); sna_pixmap_unmap(pixmap, priv); DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle)); tmp = priv->gpu_bo; priv->gpu_bo = bo; if (bo != sna->mode.shadow) kgem_bo_destroy(&sna->kgem, sna->mode.shadow); sna->mode.shadow = tmp; sna_dri2_pixmap_update_bo(sna, pixmap, bo); done: RegionEmpty(&sna->mode.shadow_cancel); RegionEmpty(&sna->mode.shadow_region); sna->mode.shadow_dirty = false; priv->move_to_gpu_data = NULL; priv->move_to_gpu = NULL; assert(!sna->mode.shadow_wait); return ret; } bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, const RegionRec *region) { struct sna *sna; if (priv->move_to_gpu != wait_for_shadow) return false; sna = priv->move_to_gpu_data; if (region) { DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n", __FUNCTION__, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(&sna->mode.shadow_region), sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, (RegionPtr)region); RegionUnion(&sna->mode.shadow_cancel, &sna->mode.shadow_cancel, (RegionPtr)region); } else { DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n", __FUNCTION__, region_num_rects(&sna->mode.shadow_region), sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1, sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2)); RegionEmpty(&sna->mode.shadow_region); RegionUninit(&sna->mode.shadow_cancel); sna->mode.shadow_cancel.extents.x1 = 0; sna->mode.shadow_cancel.extents.y1 = 0; sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width; sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height; sna->mode.shadow_cancel.data = NULL; } return RegionNil(&sna->mode.shadow_region); } static void sna_mode_damage(DamagePtr damage, RegionPtr region, void *closure) { struct sna *sna = closure; if (sna->mode.rr_active) return; /* Throw away the rectangles if the region grows too big */ region = DamageRegion(damage); if (region->data) { RegionRec dup; dup = *region; RegionUninit(&dup); region->data = NULL; } } static bool sna_mode_enable_shadow(struct sna *sna) { ScreenPtr screen = to_screen_from_sna(sna); DBG(("%s\n", __FUNCTION__)); assert(sna->mode.shadow == NULL); assert(sna->mode.shadow_damage == NULL); assert(sna->mode.shadow_active == 0); assert(!sna->mode.shadow_enabled); sna->mode.shadow_damage = DamageCreate(sna_mode_damage, NULL, DamageReportRawRegion, TRUE, screen, sna); if (!sna->mode.shadow_damage) return false; DamageRegister(&sna->front->drawable, sna->mode.shadow_damage); sna->mode.shadow_enabled = true; return true; } static void sna_mode_disable_shadow(struct sna *sna) { struct sna_pixmap *priv; if (!sna->mode.shadow_damage) { assert(!sna->mode.shadow_enabled); return; } DBG(("%s\n", __FUNCTION__)); priv = sna_pixmap(sna->front); if (priv->move_to_gpu == wait_for_shadow) priv->move_to_gpu(sna, priv, 0); DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage); DamageDestroy(sna->mode.shadow_damage); sna->mode.shadow_damage = NULL; sna->mode.shadow_enabled = false; if (sna->mode.shadow) { kgem_bo_destroy(&sna->kgem, sna->mode.shadow); sna->mode.shadow = NULL; } assert(sna->mode.shadow_active == 0); sna->mode.shadow_dirty = false; } static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *closure) { struct sna_crtc *crtc = closure; struct sna *sna = to_sna(crtc->base->scrn); RegionPtr scr; DBG(("%s: pushing damage [(%d, %d), (%d, %d) x %d] to CRTC [pipe=%d] (%d, %d)\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region), __sna_crtc_pipe(crtc), crtc->base->x, crtc->base->y)); assert(crtc->slave_damage == damage); assert(sna->mode.shadow_damage); RegionTranslate(region, crtc->base->x, crtc->base->y); scr = DamageRegion(sna->mode.shadow_damage); RegionUnion(scr, scr, region); RegionTranslate(region, -crtc->base->x, -crtc->base->y); } static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc) { if (crtc->shadow) { assert(sna->mode.shadow_damage && sna->mode.shadow_active); return true; } DBG(("%s: enabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc))); if (!sna->mode.shadow_active) { if (!sna_mode_enable_shadow(sna)) return false; assert(sna->mode.shadow_damage); assert(sna->mode.shadow == NULL); } if (crtc->slave_pixmap) { assert(crtc->slave_damage == NULL); DBG(("%s: enabling PRIME slave tracking on CRTC %d [pipe=%d], pixmap=%ld\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->slave_pixmap->drawable.serialNumber)); crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL, DamageReportRawRegion, TRUE, to_screen_from_sna(sna), crtc); if (crtc->slave_damage == NULL) { if (!--sna->mode.shadow_active) sna_mode_disable_shadow(sna); return false; } DamageRegister(&crtc->slave_pixmap->drawable, crtc->slave_damage); } crtc->shadow = true; sna->mode.shadow_active++; return true; } static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc) { if (crtc->client_bo == NULL) return; assert(crtc->client_bo->refcnt >= crtc->client_bo->active_scanout); crtc->client_bo->active_scanout--; if (!crtc->transform) { DrawableRec tmp; tmp.width = crtc->base->mode.HDisplay; tmp.height = crtc->base->mode.VDisplay; tmp.depth = sna->front->drawable.depth; tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; sna->render.copy_boxes(sna, GXcopy, &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1, &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, &crtc->base->bounds, 1, 0); list_del(&crtc->shadow_link); } kgem_bo_destroy(&sna->kgem, crtc->client_bo); crtc->client_bo = NULL; } static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc) { crtc->fallback_shadow = false; if (!crtc->shadow) return; DBG(("%s: disabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc))); assert(sna->mode.shadow_active > 0); if (crtc->slave_damage) { assert(crtc->slave_pixmap); DamageUnregister(&crtc->slave_pixmap->drawable, crtc->slave_damage); DamageDestroy(crtc->slave_damage); crtc->slave_damage = NULL; } sna_crtc_disable_override(sna, crtc); if (!--sna->mode.shadow_active) sna_mode_disable_shadow(sna); crtc->shadow = false; } static void __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc) { sna_crtc->mode_serial++; sna_crtc_disable_cursor(sna, sna_crtc); rotation_set(sna, &sna_crtc->primary, RR_Rotate_0); sna_crtc_disable_shadow(sna, sna_crtc); if (sna_crtc->bo) { DBG(("%s: releasing handle=%d from scanout, active=%d\n", __FUNCTION__,sna_crtc->bo->handle, sna_crtc->bo->active_scanout-1)); assert(sna_crtc->flags & CRTC_ON); assert(sna_crtc->bo->active_scanout); assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); sna_crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = NULL; sna_crtc->flags &= ~CRTC_ON; if (sna->mode.hidden) { sna->mode.hidden--; assert(sna->mode.hidden); assert(sna->mode.front_active == 0); } else { assert(sna->mode.front_active); sna->mode.front_active--; } sna->mode.dirty = true; } if (sna_crtc->shadow_bo) { kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo); sna_crtc->shadow_bo = NULL; } if (sna_crtc->transform) { assert(sna->mode.rr_active); sna->mode.rr_active--; sna_crtc->transform = false; } sna_crtc->cursor_transform = false; sna_crtc->hwcursor = true; assert(!sna_crtc->shadow); } static void sna_crtc_disable(xf86CrtcPtr crtc, bool force) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_crtc arg; if (sna_crtc == NULL) return; if (!force && sna_crtc->bo == NULL) return; DBG(("%s: disabling crtc [%d, pipe=%d], force?=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), force)); sna_crtc_force_outputs_off(crtc); memset(&arg, 0, sizeof(arg)); arg.crtc_id = __sna_crtc_id(sna_crtc); (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg); __sna_crtc_disable(sna, sna_crtc); } static void update_flush_interval(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i, max_vrefresh = 0; DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active)); for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; assert(to_sna_crtc(crtc) != NULL); if (!crtc->enabled) { DBG(("%s: CRTC:%d (pipe %d) disabled\n", __FUNCTION__,i, sna_crtc_pipe(crtc))); assert(to_sna_crtc(crtc)->bo == NULL); continue; } if (to_sna_crtc(crtc)->bo == NULL) { DBG(("%s: CRTC:%d (pipe %d) turned off\n", __FUNCTION__,i, sna_crtc_pipe(crtc))); continue; } DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n", __FUNCTION__, i, sna_crtc_pipe(crtc), xf86ModeVRefresh(&crtc->mode))); max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode)); } if (max_vrefresh == 0) { assert(sna->mode.front_active == 0); sna->vblank_interval = 0; } else sna->vblank_interval = 1000 / max_vrefresh; /* Hz -> ms */ DBG(("max_vrefresh=%d, vblank_interval=%d ms\n", max_vrefresh, sna->vblank_interval)); } static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna, const struct drm_mode_fb_cmd *fbcon) { struct drm_gem_flink flink; struct kgem_bo *bo; int ret; /* Create a new reference for the fbcon so that we can track it * using a normal bo and so that when we call gem_close on it we * delete our reference and not fbcon's! */ VG_CLEAR(flink); flink.handle = fbcon->handle; ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_GEM_FLINK, &flink); if (ret) return NULL; bo = kgem_create_for_name(&sna->kgem, flink.name); if (bo == NULL) return NULL; bo->pitch = fbcon->pitch; return bo; } /* Copy the current framebuffer contents into the front-buffer for a seamless * transition from e.g. plymouth. */ void sna_copy_fbcon(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); struct drm_mode_fb_cmd fbcon; PixmapRec scratch; struct sna_pixmap *priv; struct kgem_bo *bo; BoxRec box; bool ok; int sx, sy; int dx, dy; int i; if (wedged(sna) || isGPU(sna->scrn)) return; DBG(("%s\n", __FUNCTION__)); assert((sna->flags & SNA_IS_HOSTED) == 0); priv = sna_pixmap_move_to_gpu(sna->front, MOVE_WRITE | __MOVE_SCANOUT); if (priv == NULL) return; /* Scan the connectors for a framebuffer and assume that is the fbcon */ VG_CLEAR(fbcon); fbcon.fb_id = 0; for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]); struct drm_mode_crtc mode; assert(crtc != NULL); VG_CLEAR(mode); mode.crtc_id = __sna_crtc_id(crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; if (!mode.fb_id) continue; fbcon.fb_id = mode.fb_id; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETFB, &fbcon)) { fbcon.fb_id = 0; continue; } break; } if (fbcon.fb_id == 0) { DBG(("%s: no fbcon found\n", __FUNCTION__)); return; } if (fbcon.fb_id == fb_id(priv->gpu_bo)) { DBG(("%s: fb already installed as scanout\n", __FUNCTION__)); return; } DBG(("%s: found fbcon, size=%dx%d, depth=%d, bpp=%d\n", __FUNCTION__, fbcon.width, fbcon.height, fbcon.depth, fbcon.bpp)); bo = sna_create_bo_for_fbcon(sna, &fbcon); if (bo == NULL) return; DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle)); scratch.drawable.width = fbcon.width; scratch.drawable.height = fbcon.height; scratch.drawable.depth = fbcon.depth; scratch.drawable.bitsPerPixel = fbcon.bpp; scratch.devPrivate.ptr = NULL; box.x1 = box.y1 = 0; box.x2 = min(fbcon.width, sna->front->drawable.width); box.y2 = min(fbcon.height, sna->front->drawable.height); sx = dx = 0; if (box.x2 < (uint16_t)fbcon.width) sx = (fbcon.width - box.x2) / 2; if (box.x2 < sna->front->drawable.width) dx = (sna->front->drawable.width - box.x2) / 2; sy = dy = 0; if (box.y2 < (uint16_t)fbcon.height) sy = (fbcon.height - box.y2) / 2; if (box.y2 < sna->front->drawable.height) dy = (sna->front->drawable.height - box.y2) / 2; ok = sna->render.copy_boxes(sna, GXcopy, &scratch.drawable, bo, sx, sy, &sna->front->drawable, priv->gpu_bo, dx, dy, &box, 1, 0); if (!DAMAGE_IS_ALL(priv->gpu_damage)) sna_damage_add_box(&priv->gpu_damage, &box); kgem_bo_destroy(&sna->kgem, bo); #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0) to_screen_from_sna(sna)->canDoBGNoneRoot = ok; #endif } static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc) { RRTransformPtr transform; PictTransform crtc_to_fb; struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; unsigned pitch_limit; BoxRec b; assert(sna->scrn->virtualX && sna->scrn->virtualY); if (sna->flags & SNA_FORCE_SHADOW) { DBG(("%s: forcing shadow\n", __FUNCTION__)); return true; } if (to_sna_crtc(crtc)->fallback_shadow) { DBG(("%s: fallback shadow\n", __FUNCTION__)); return true; } if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) { DBG(("%s: TearFree shadow required\n", __FUNCTION__)); return true; } if (sna->scrn->virtualX > sna->mode.max_crtc_width || sna->scrn->virtualY > sna->mode.max_crtc_height) { DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n", __FUNCTION__, sna->scrn->virtualX, sna->scrn->virtualY, sna->mode.max_crtc_width, sna->mode.max_crtc_height)); return true; } if (!isGPU(sna->scrn)) { struct sna_pixmap *priv; priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT); if (priv == NULL) return true; /* maybe we can create a bo for the scanout? */ if (sna->kgem.gen == 071) pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024; else if ((sna->kgem.gen >> 3) > 4) pitch_limit = 32 * 1024; else if ((sna->kgem.gen >> 3) == 4) pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024; else if ((sna->kgem.gen >> 3) == 3) pitch_limit = priv->gpu_bo->tiling ? 8 * 1024 : 16 * 1024; else pitch_limit = 8 * 1024; DBG(("%s: gpu bo handle=%d tiling=%d pitch=%d, limit=%d\n", __FUNCTION__, priv->gpu_bo->handle, priv->gpu_bo->tiling, priv->gpu_bo->pitch, pitch_limit)); if (priv->gpu_bo->pitch > pitch_limit) return true; if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) { DBG(("%s: gpu bo is tiled, need linear, forcing shadow\n", __FUNCTION__)); return true; } } transform = NULL; if (crtc->transformPresent) transform = &crtc->transform; if (RRTransformCompute(crtc->x, crtc->y, crtc->mode.HDisplay, crtc->mode.VDisplay, crtc->rotation, transform, &crtc_to_fb, &f_crtc_to_fb, &f_fb_to_crtc)) { bool needs_transform = true; unsigned rotation = rotation_reduce(&to_sna_crtc(crtc)->primary, crtc->rotation); DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n", __FUNCTION__, rotation, to_sna_crtc(crtc)->primary.rotation.supported, rotation == (rotation & to_sna_crtc(crtc)->primary.rotation.supported))); if ((to_sna_crtc(crtc)->primary.rotation.supported & rotation) == rotation) needs_transform = RRTransformCompute(crtc->x, crtc->y, crtc->mode.HDisplay, crtc->mode.VDisplay, RR_Rotate_0, transform, NULL, NULL, NULL); if (needs_transform) { DBG(("%s: RandR transform present\n", __FUNCTION__)); return true; } } /* And finally check that it is entirely visible */ b.x1 = b.y1 = 0; b.x2 = crtc->mode.HDisplay; b.y2 = crtc->mode.VDisplay; pixman_f_transform_bounds(&f_crtc_to_fb, &b); DBG(("%s? bounds (%d, %d), (%d, %d), framebufer %dx%d\n", __FUNCTION__, b.x1, b.y1, b.x2, b.y2, sna->scrn->virtualX, sna->scrn->virtualY)); if (b.x1 < 0 || b.y1 < 0 || b.x2 > sna->scrn->virtualX || b.y2 > sna->scrn->virtualY) { DBG(("%s: scanout is partly outside the framebuffer\n", __FUNCTION__)); return true; } return false; } static void set_shadow(struct sna *sna, RegionPtr region) { struct sna_pixmap *priv = sna_pixmap(sna->front); assert(priv->gpu_bo); assert(sna->mode.shadow); DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n", __FUNCTION__, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, priv->gpu_bo->handle, sna->mode.shadow->handle)); assert(priv->pinned & PIN_SCANOUT); assert((priv->pinned & PIN_PRIME) == 0); assert(sna->mode.shadow != priv->gpu_bo); RegionCopy(&sna->mode.shadow_region, region); priv->move_to_gpu = wait_for_shadow; priv->move_to_gpu_data = sna; } static struct kgem_bo * get_scanout_bo(struct sna *sna, PixmapPtr pixmap) { struct sna_pixmap *priv; priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT); if (!priv) return NULL; if (priv->gpu_bo->pitch & 63) { struct kgem_bo *tmp; BoxRec b; DBG(("%s: converting to scanout bo due to bad pitch [%d]\n", __FUNCTION__, priv->gpu_bo->pitch)); if (priv->pinned) { DBG(("%s: failed as the Pixmap is already pinned [%x]\n", __FUNCTION__, priv->pinned)); return NULL; } tmp = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, sna->scrn->bitsPerPixel, priv->gpu_bo->tiling, CREATE_EXACT | CREATE_SCANOUT); if (tmp == NULL) { DBG(("%s: allocation failed\n", __FUNCTION__)); return NULL; } b.x1 = 0; b.y1 = 0; b.x2 = pixmap->drawable.width; b.y2 = pixmap->drawable.height; if (sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, tmp, 0, 0, &b, 1, COPY_LAST)) { DBG(("%s: copy failed\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, tmp); return NULL; } kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = tmp; } priv->pinned |= PIN_SCANOUT; return priv->gpu_bo; } static void shadow_clear(struct sna *sna, PixmapPtr front, struct kgem_bo *bo, xf86CrtcPtr crtc) { bool ok = false; if (!wedged(sna)) ok = sna->render.fill_one(sna, front, bo, 0, 0, 0, crtc->mode.HDisplay, crtc->mode.VDisplay, GXclear); if (!ok) { void *ptr = kgem_bo_map__gtt(&sna->kgem, bo); if (ptr) memset(ptr, 0, bo->pitch * crtc->mode.HDisplay); } sna->mode.shadow_dirty = true; } static bool rr_active(xf86CrtcPtr crtc) { return crtc->transformPresent || crtc->rotation != RR_Rotate_0; } static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); ScrnInfoPtr scrn = crtc->scrn; struct sna *sna = to_sna(scrn); struct kgem_bo *bo; if (sna_crtc->transform) { assert(sna->mode.rr_active); sna_crtc->transform = false; sna->mode.rr_active--; } sna_crtc->rotation = RR_Rotate_0; if (use_shadow(sna, crtc)) { PixmapPtr front; unsigned long tiled_limit; int tiling; force_shadow: if (!sna_crtc_enable_shadow(sna, sna_crtc)) { DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__)); return NULL; } DBG(("%s: attaching to per-crtc pixmap %dx%d\n", __FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay)); bo = sna_crtc->shadow_bo; if (bo) { if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay && sna_crtc->shadow_bo_height == crtc->mode.VDisplay) { DBG(("%s: reusing current shadow bo handle=%d\n", __FUNCTION__, bo->handle)); goto out_shadow; } kgem_bo_destroy(&sna->kgem, bo); sna_crtc->shadow_bo = NULL; } tiling = I915_TILING_X; if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270) && sna->kgem.can_scanout_y) tiling = I915_TILING_Y; if (sna->kgem.gen == 071) tiled_limit = 16 * 1024 * 8; else if ((sna->kgem.gen >> 3) > 4) tiled_limit = 32 * 1024 * 8; else if ((sna->kgem.gen >> 3) == 4) tiled_limit = 16 * 1024 * 8; else tiled_limit = 8 * 1024 * 8; if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit) tiling = I915_TILING_NONE; if (sna->flags & SNA_LINEAR_FB) tiling = I915_TILING_NONE; bo = kgem_create_2d(&sna->kgem, crtc->mode.HDisplay, crtc->mode.VDisplay, scrn->bitsPerPixel, tiling, CREATE_SCANOUT); if (bo == NULL) { DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__)); return NULL; } if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) { DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, bo); return NULL; } front = sna_crtc->slave_pixmap ?: sna->front; if (__sna_pixmap_get_bo(front) && !rr_active(crtc)) { BoxRec b; b.x1 = crtc->x; b.y1 = crtc->y; b.x2 = crtc->x + crtc->mode.HDisplay; b.y2 = crtc->y + crtc->mode.VDisplay; if (b.x1 < 0) b.x1 = 0; if (b.y1 < 0) b.y1 = 0; if (b.x2 > scrn->virtualX) b.x2 = scrn->virtualX; if (b.y2 > scrn->virtualY) b.y2 = scrn->virtualY; if (b.x2 - b.x1 < crtc->mode.HDisplay || b.y2 - b.y1 < crtc->mode.VDisplay) shadow_clear(sna, front, bo, crtc); if (b.y2 > b.y1 && b.x2 > b.x1) { DrawableRec tmp; DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d) [fb=%dx%d], handle=%d\n", __FUNCTION__, b.x1, b.y1, b.x2-b.x1, b.y2-b.y1, scrn->virtualX, scrn->virtualY, bo->handle)); tmp.width = crtc->mode.HDisplay; tmp.height = crtc->mode.VDisplay; tmp.depth = front->drawable.depth; tmp.bitsPerPixel = front->drawable.bitsPerPixel; if (!sna->render.copy_boxes(sna, GXcopy, &front->drawable, __sna_pixmap_get_bo(front), 0, 0, &tmp, bo, -crtc->x, -crtc->y, &b, 1, COPY_LAST)) shadow_clear(sna, front, bo, crtc); } } else shadow_clear(sna, front, bo, crtc); sna_crtc->shadow_bo_width = crtc->mode.HDisplay; sna_crtc->shadow_bo_height = crtc->mode.VDisplay; sna_crtc->shadow_bo = bo; out_shadow: sna_crtc->transform = true; sna->mode.rr_active++; return kgem_bo_reference(bo); } else { if (sna_crtc->shadow_bo) { kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo); sna_crtc->shadow_bo = NULL; } if (sna_crtc->slave_pixmap) { DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__)); bo = get_scanout_bo(sna, sna_crtc->slave_pixmap); if (bo == NULL) { DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__)); sna_crtc->fallback_shadow = true; goto force_shadow; } if (!get_fb(sna, bo, sna_crtc->slave_pixmap->drawable.width, sna_crtc->slave_pixmap->drawable.height)) { DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); sna_crtc->fallback_shadow = true; goto force_shadow; } } else { DBG(("%s: attaching to framebuffer\n", __FUNCTION__)); bo = get_scanout_bo(sna, sna->front); if (bo == NULL) { DBG(("%s: failed to pin framebuffer\n", __FUNCTION__)); sna_crtc->fallback_shadow = true; goto force_shadow; } if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) { DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__)); sna_crtc->fallback_shadow = true; goto force_shadow; } } if (sna->flags & SNA_TEAR_FREE) { RegionRec region; assert(sna_crtc->slave_pixmap == NULL); DBG(("%s: enabling TearFree shadow\n", __FUNCTION__)); region.extents.x1 = 0; region.extents.y1 = 0; region.extents.x2 = sna->scrn->virtualX; region.extents.y2 = sna->scrn->virtualY; region.data = NULL; if (!sna_crtc_enable_shadow(sna, sna_crtc)) { DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__)); return NULL; } if (sna->mode.shadow == NULL && !wedged(sna)) { struct kgem_bo *shadow; DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__)); shadow = kgem_create_2d(&sna->kgem, region.extents.x2, region.extents.y2, scrn->bitsPerPixel, kgem_choose_tiling(&sna->kgem, I915_TILING_X, region.extents.x2, region.extents.y2, sna->scrn->bitsPerPixel), CREATE_SCANOUT); if (shadow == NULL) { DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__)); sna_crtc->fallback_shadow = true; goto force_shadow; } if (!get_fb(sna, shadow, region.extents.x2, region.extents.y2)) { DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, shadow); sna_crtc->fallback_shadow = true; goto force_shadow; } assert(__sna_pixmap_get_bo(sna->front) == NULL || __sna_pixmap_get_bo(sna->front)->pitch == shadow->pitch); sna->mode.shadow = shadow; } set_shadow(sna, ®ion); sna_crtc_disable_override(sna, sna_crtc); } else sna_crtc_disable_shadow(sna, sna_crtc); sna_crtc->rotation = rotation_reduce(&sna_crtc->primary, crtc->rotation); assert(sna_crtc->primary.rotation.supported & sna_crtc->rotation); return kgem_bo_reference(bo); } } #define SCALING_EPSILON (1./256) static bool is_affine(const struct pixman_f_transform *t) { return (fabs(t->m[2][0]) < SCALING_EPSILON && fabs(t->m[2][1]) < SCALING_EPSILON); } static double determinant(const struct pixman_f_transform *t) { return t->m[0][0]*t->m[1][1] - t->m[1][0]*t->m[0][1]; } static bool affine_is_pixel_exact(const struct pixman_f_transform *t) { double det = t->m[2][2] * determinant(t); if (fabs (det * det - 1.0) < SCALING_EPSILON) { if (fabs(t->m[0][1]) < SCALING_EPSILON && fabs(t->m[1][0]) < SCALING_EPSILON) return true; if (fabs(t->m[0][0]) < SCALING_EPSILON && fabs(t->m[1][1]) < SCALING_EPSILON) return true; } return false; } static void sna_crtc_randr(xf86CrtcPtr crtc) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; PictTransform crtc_to_fb; PictFilterPtr filter; xFixed *params; int nparams; RRTransformPtr transform; int needs_transform; transform = NULL; if (crtc->transformPresent) transform = &crtc->transform; needs_transform = RRTransformCompute(crtc->x, crtc->y, crtc->mode.HDisplay, crtc->mode.VDisplay, crtc->rotation, transform, &crtc_to_fb, &f_crtc_to_fb, &f_fb_to_crtc); filter = NULL; params = NULL; nparams = 0; if (sna_crtc->transform) { #ifdef RANDR_12_INTERFACE if (transform) { if (transform->nparams) { params = malloc(transform->nparams * sizeof(xFixed)); if (params) { memcpy(params, transform->params, transform->nparams * sizeof(xFixed)); nparams = transform->nparams; filter = transform->filter; } } else filter = transform->filter; } #endif crtc->transform_in_use = needs_transform; } else crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0; if (needs_transform) { sna_crtc->hwcursor = is_affine(&f_fb_to_crtc); sna_crtc->cursor_transform = sna_crtc->hwcursor && !affine_is_pixel_exact(&f_fb_to_crtc); } else { sna_crtc->hwcursor = true; sna_crtc->cursor_transform = false; } DBG(("%s: hwcursor?=%d, cursor_transform?=%d\n", __FUNCTION__, sna_crtc->hwcursor, sna_crtc->cursor_transform)); crtc->crtc_to_framebuffer = crtc_to_fb; crtc->f_crtc_to_framebuffer = f_crtc_to_fb; crtc->f_framebuffer_to_crtc = f_fb_to_crtc; free(crtc->params); crtc->params = params; crtc->nparams = nparams; crtc->filter = filter; if (filter) { crtc->filter_width = filter->width; crtc->filter_height = filter->height; } else { crtc->filter_width = 0; crtc->filter_height = 0; } crtc->bounds.x1 = 0; crtc->bounds.x2 = crtc->mode.HDisplay; crtc->bounds.y1 = 0; crtc->bounds.y2 = crtc->mode.VDisplay; pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds); DBG(("%s: transform? %d, bounds (%d, %d), (%d, %d)\n", __FUNCTION__, crtc->transform_in_use, crtc->bounds.x1, crtc->bounds.y1, crtc->bounds.x2, crtc->bounds.y2)); } static void sna_crtc_damage(xf86CrtcPtr crtc) { ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); struct sna *sna = to_sna(crtc->scrn); RegionRec region, *damage; region.extents = crtc->bounds; region.data = NULL; if (region.extents.x1 < 0) region.extents.x1 = 0; if (region.extents.y1 < 0) region.extents.y1 = 0; if (region.extents.x2 > screen->width) region.extents.x2 = screen->width; if (region.extents.y2 > screen->height) region.extents.y2 = screen->height; if (region.extents.x2 <= region.extents.x1 || region.extents.y2 <= region.extents.y1) { DBG(("%s: crtc not damaged, all-clipped\n", __FUNCTION__)); return; } DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n", __FUNCTION__, sna_crtc_id(crtc), region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); to_sna_crtc(crtc)->client_damage = region; assert(sna->mode.shadow_damage && sna->mode.shadow_active); damage = DamageRegion(sna->mode.shadow_damage); RegionUnion(damage, damage, ®ion); DBG(("%s: damage now %dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, region_num_rects(damage), damage->extents.x1, damage->extents.y1, damage->extents.x2, damage->extents.y2)); } static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max) { struct sna *sna = to_sna(crtc->scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); int len, i; for (i = len = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != crtc) continue; len += snprintf(outputs+len, max-len, "%s, ", output->name); } assert(len >= 2); outputs[len-2] = '\0'; return outputs; } static const char *rotation_to_str(Rotation rotation) { switch (rotation & RR_Rotate_All) { case 0: case RR_Rotate_0: return "normal"; case RR_Rotate_90: return "left"; case RR_Rotate_180: return "inverted"; case RR_Rotate_270: return "right"; default: return "unknown"; } } static const char *reflection_to_str(Rotation rotation) { switch (rotation & RR_Reflect_All) { case 0: return "none"; case RR_Reflect_X: return "X axis"; case RR_Reflect_Y: return "Y axis"; case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes"; default: return "invalid"; } } static Bool __sna_crtc_set_mode(xf86CrtcPtr crtc) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct kgem_bo *saved_bo, *bo; uint32_t saved_offset; bool saved_transform; bool saved_hwcursor; bool saved_cursor_transform; DBG(("%s: CRTC=%d, pipe=%d, hidden?=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna->mode.hidden)); if (sna->mode.hidden) return TRUE; saved_bo = sna_crtc->bo; saved_transform = sna_crtc->transform; saved_cursor_transform = sna_crtc->cursor_transform; saved_hwcursor = sna_crtc->hwcursor; saved_offset = sna_crtc->offset; sna_crtc->fallback_shadow = false; retry: /* Attach per-crtc pixmap or direct */ bo = sna_crtc_attach(crtc); if (bo == NULL) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "unable to attach scanout\n"); goto error; } /* Prevent recursion when enabling outputs during execbuffer */ if (bo->exec && RQ(bo->rq)->bo == NULL) _kgem_submit(&sna->kgem); sna_crtc->bo = bo; if (!sna_crtc_apply(crtc)) { int err = errno; kgem_bo_destroy(&sna->kgem, bo); if (!sna_crtc->shadow) { sna_crtc->fallback_shadow = true; goto retry; } xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set mode: %s [%d]\n", strerror(err), err); goto error; } sna_crtc->flags |= CRTC_ON; bo->active_scanout++; DBG(("%s: marking handle=%d as active=%d (removing %d from scanout, active=%d)\n", __FUNCTION__, bo->handle, bo->active_scanout, saved_bo ? saved_bo->handle : 0, saved_bo ? saved_bo->active_scanout - 1: -1)); if (saved_bo) { assert(saved_bo->active_scanout); assert(saved_bo->refcnt >= saved_bo->active_scanout); saved_bo->active_scanout--; kgem_bo_destroy(&sna->kgem, saved_bo); } sna_crtc_randr(crtc); if (sna_crtc->transform) sna_crtc_damage(crtc); if (sna_crtc->cursor && /* Reload cursor if RandR maybe changed */ (!sna_crtc->hwcursor || saved_cursor_transform || sna_crtc->cursor_transform || sna_crtc->cursor->rotation != crtc->rotation)) sna_crtc_disable_cursor(sna, sna_crtc); assert(!sna->mode.hidden); sna->mode.front_active += saved_bo == NULL; sna->mode.dirty = true; DBG(("%s: handle=%d, scanout_active=%d, front_active=%d\n", __FUNCTION__, bo->handle, bo->active_scanout, sna->mode.front_active)); return TRUE; error: sna_crtc->offset = saved_offset; if (sna_crtc->transform) { assert(sna->mode.rr_active); sna->mode.rr_active--; } if (saved_transform) sna->mode.rr_active++; sna_crtc->transform = saved_transform; sna_crtc->cursor_transform = saved_cursor_transform; sna_crtc->hwcursor = saved_hwcursor; sna_crtc->bo = saved_bo; sna_mode_discover(sna, true); return FALSE; } static Bool sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_modeinfo saved_kmode; char outputs[256]; if (mode->HDisplay == 0 || mode->VDisplay == 0) return FALSE; assert(sna_crtc); xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n", mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode), outputs_for_crtc(crtc, outputs, sizeof(outputs)), __sna_crtc_pipe(sna_crtc), x, y, rotation_to_str(rotation), reflection_to_str(rotation)); assert(mode->HDisplay <= sna->mode.max_crtc_width && mode->VDisplay <= sna->mode.max_crtc_height); #if HAS_GAMMA drmModeCrtcSetGamma(sna->kgem.fd, __sna_crtc_id(sna_crtc), crtc->gamma_size, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue); #endif saved_kmode = sna_crtc->kmode; mode_to_kmode(&sna_crtc->kmode, mode); if (__sna_crtc_set_mode(crtc)) return TRUE; sna_crtc->kmode = saved_kmode; return FALSE; } static void sna_crtc_dpms(xf86CrtcPtr crtc, int mode) { DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n", __FUNCTION__, sna_crtc_pipe(crtc), mode, mode == DPMSModeOn)); if (mode == DPMSModeOn && crtc->enabled) { if (__sna_crtc_set_mode(crtc)) update_flush_interval(to_sna(crtc->scrn)); else mode = DPMSModeOff; } if (mode != DPMSModeOn) sna_crtc_disable(crtc, false); } void sna_mode_adjust_frame(struct sna *sna, int x, int y) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); xf86CrtcPtr crtc; int saved_x, saved_y; if ((unsigned)config->compat_output >= config->num_output) return; crtc = config->output[config->compat_output]->crtc; if (crtc == NULL || !crtc->enabled) return; if (crtc->x == x && crtc->y == y) return; saved_x = crtc->x; saved_y = crtc->y; crtc->x = x; crtc->y = y; if (to_sna_crtc(crtc) && !__sna_crtc_set_mode(crtc)) { crtc->x = saved_x; crtc->y = saved_y; } } static void sna_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size) { assert(to_sna_crtc(crtc)); drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd, sna_crtc_id(crtc), size, red, green, blue); } static void sna_crtc_destroy(xf86CrtcPtr crtc) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); if (sna_crtc == NULL) return; free(sna_crtc); crtc->driver_private = NULL; } #if HAS_PIXMAP_SHARING static Bool sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); if (sna_crtc == NULL) return FALSE; if (pixmap == sna_crtc->slave_pixmap) return TRUE; DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), pixmap ? pixmap->drawable.serialNumber : 0)); /* Disable first so that we can unregister the damage tracking */ sna_crtc_disable_shadow(to_sna(crtc->scrn), sna_crtc); sna_crtc->slave_pixmap = pixmap; return TRUE; } #endif static const xf86CrtcFuncsRec sna_crtc_funcs = { #if XF86_CRTC_VERSION >= 1 .dpms = sna_crtc_dpms, #endif .set_mode_major = sna_crtc_set_mode_major, .gamma_set = sna_crtc_gamma_set, .destroy = sna_crtc_destroy, #if HAS_PIXMAP_SHARING .set_scanout_pixmap = sna_crtc_set_scanout_pixmap, #endif }; inline static bool prop_is_rotation(struct drm_mode_get_property *prop) { if ((prop->flags & (1 << 5)) == 0) return false; if (strcmp(prop->name, "rotation")) return false; return true; } static int plane_details(struct sna *sna, struct plane *p) { struct local_mode_obj_get_properties arg; uint64_t stack_props[24]; uint32_t *props = (uint32_t *)stack_props; uint64_t *values = stack_props + 8; int i, type = DRM_PLANE_TYPE_OVERLAY; memset(&arg, 0, sizeof(struct local_mode_obj_get_properties)); arg.obj_id = p->id; arg.obj_type = LOCAL_MODE_OBJECT_PLANE; arg.props_ptr = (uintptr_t)props; arg.prop_values_ptr = (uintptr_t)values; arg.count_props = 16; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) return -1; DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, arg.count_props)); if (arg.count_props > 16) { props = malloc(2*sizeof(uint64_t)*arg.count_props); if (props == NULL) return -1; values = (uint64_t *)props + arg.count_props; arg.props_ptr = (uintptr_t)props; arg.prop_values_ptr = (uintptr_t)values; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) arg.count_props = 0; } VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props)); VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props)); for (i = 0; i < arg.count_props; i++) { struct drm_mode_get_property prop; memset(&prop, 0, sizeof(prop)); prop.prop_id = props[i]; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) { ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n", __FUNCTION__, i, props[i], errno)); continue; } DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i])); if (strcmp(prop.name, "type") == 0) { type = values[i]; } else if (prop_is_rotation(&prop)) { struct drm_mode_property_enum *enums; p->rotation.prop = props[i]; p->rotation.current = values[i]; DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", __FUNCTION__, prop.prop_id, (long)values[i], prop.count_enum_blobs)); enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); if (enums != NULL) { prop.count_values = 0; prop.enum_blob_ptr = (uintptr_t)enums; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { int j; /* XXX we assume that the mapping between kernel enum and * RandR remains fixed for our lifetimes. */ VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop.count_enum_blobs)); for (j = 0; j < prop.count_enum_blobs; j++) { DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__, j, enums[j].name, (long)enums[j].value)); p->rotation.supported |= 1 << enums[j].value; } } free(enums); } } } p->rotation.supported &= DBG_NATIVE_ROTATION; if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE)) p->rotation.supported = RR_Rotate_0; if (props != (uint32_t *)stack_props) free(props); DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, type)); return type; } static void sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc) { #define LOCAL_IOCTL_SET_CAP DRM_IOWR(0x0d, struct local_set_cap) struct local_set_cap { uint64_t name; uint64_t value; } cap; struct local_mode_get_plane_res r; uint32_t stack_planes[32]; uint32_t *planes = stack_planes; int i; VG_CLEAR(cap); cap.name = DRM_CLIENT_CAP_UNIVERSAL_PLANES; cap.value = 1; (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_SET_CAP, &cap); VG_CLEAR(r); r.plane_id_ptr = (uintptr_t)planes; r.count_planes = ARRAY_SIZE(stack_planes); if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) { ERR(("%s: GETPLANERESOURCES failed with errno=%d\n", __FUNCTION__, errno)); return; } DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes)); if (r.count_planes > ARRAY_SIZE(stack_planes)) { planes = malloc(sizeof(uint32_t)*r.count_planes); if (planes == NULL) return; r.plane_id_ptr = (uintptr_t)planes; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) r.count_planes = 0; } VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes)); for (i = 0; i < r.count_planes; i++) { struct local_mode_get_plane p; struct plane details; VG_CLEAR(p); p.plane_id = planes[i]; p.count_format_types = 0; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p)) continue; if ((p.possible_crtcs & (1 << __sna_crtc_pipe(crtc))) == 0) continue; DBG(("%s: plane %d is attached to our pipe=%d\n", __FUNCTION__, planes[i], __sna_crtc_pipe(crtc))); details.id = p.plane_id; details.rotation.prop = 0; details.rotation.supported = RR_Rotate_0; details.rotation.current = RR_Rotate_0; switch (plane_details(sna, &details)) { default: break; case DRM_PLANE_TYPE_PRIMARY: crtc->primary = details; break; case DRM_PLANE_TYPE_CURSOR: break; case DRM_PLANE_TYPE_OVERLAY: if (crtc->sprite.id == 0) crtc->sprite = details; break; } } if (planes != stack_planes) free(planes); } static void sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc) { crtc->rotation = RR_Rotate_0; crtc->primary.rotation.supported = RR_Rotate_0; crtc->primary.rotation.current = RR_Rotate_0; crtc->sprite.rotation = crtc->primary.rotation; } static void sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc) { struct drm_mode_cursor arg; VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = __sna_crtc_id(crtc); arg.width = arg.height = 0; arg.handle = 0; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg); crtc->hwcursor = true; } static bool sna_crtc_add(ScrnInfoPtr scrn, unsigned id) { struct sna *sna = to_sna(scrn); xf86CrtcPtr crtc; struct sna_crtc *sna_crtc; struct drm_i915_get_pipe_from_crtc_id get_pipe; DBG(("%s(%d): is-zaphod? %d\n", __FUNCTION__, id, is_zaphod(scrn))); sna_crtc = calloc(sizeof(struct sna_crtc), 1); if (sna_crtc == NULL) return false; assert(id < 256); sna_crtc->flags = id << 16; VG_CLEAR(get_pipe); get_pipe.pipe = 0; get_pipe.crtc_id = id; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID, &get_pipe)) { free(sna_crtc); return false; } assert((unsigned)get_pipe.pipe < 256); sna_crtc->flags |= get_pipe.pipe << 8; if (is_zaphod(scrn) && (get_zaphod_crtcs(sna) & (1 << get_pipe.pipe)) == 0) { free(sna_crtc); return true; } sna_crtc_init__rotation(sna, sna_crtc); sna_crtc_find_planes(sna, sna_crtc); DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n", __FUNCTION__, id, get_pipe.pipe, sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current, sna_crtc->sprite.id, sna_crtc->sprite.rotation.supported, sna_crtc->sprite.rotation.current)); list_init(&sna_crtc->shadow_link); crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs); if (crtc == NULL) { free(sna_crtc); return false; } sna_crtc_init__cursor(sna, sna_crtc); crtc->driver_private = sna_crtc; sna_crtc->base = crtc; DBG(("%s: attached crtc[%d] pipe=%d\n", __FUNCTION__, id, __sna_crtc_pipe(sna_crtc))); return true; } static bool is_panel(int type) { #define DRM_MODE_CONNECTOR_LVDS 7 #define DRM_MODE_CONNECTOR_eDP 14 #define DRM_MODE_CONNECTOR_DSI 16 return (type == DRM_MODE_CONNECTOR_LVDS || type == DRM_MODE_CONNECTOR_eDP || type == DRM_MODE_CONNECTOR_DSI); } static int find_property(struct sna *sna, struct sna_output *output, const char *name) { struct drm_mode_get_property prop; int i; VG_CLEAR(prop); for (i = 0; i < output->num_props; i++) { prop.prop_id = output->prop_ids[i]; prop.count_values = 0; prop.count_enum_blobs = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) continue; if (strcmp(prop.name, name) == 0) return i; } return -1; } static void update_properties(struct sna *sna, struct sna_output *output) { union compat_mode_get_connector compat_conn; struct drm_mode_modeinfo dummy; VG_CLEAR(compat_conn); compat_conn.conn.connector_id = output->id; compat_conn.conn.count_props = output->num_props; compat_conn.conn.props_ptr = (uintptr_t)output->prop_ids; compat_conn.conn.prop_values_ptr = (uintptr_t)output->prop_values; compat_conn.conn.count_modes = 1; /* skip detect */ compat_conn.conn.modes_ptr = (uintptr_t)&dummy; compat_conn.conn.count_encoders = 0; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn); assert(compat_conn.conn.count_props == output->num_props); output->update_properties = false; } static xf86OutputStatus sna_output_detect(xf86OutputPtr output) { struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; union compat_mode_get_connector compat_conn; uint32_t now; DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id)); sna_output->update_properties = false; if (!sna_output->id) { DBG(("%s(%s) hiding due to lost connection\n", __FUNCTION__, output->name)); return XF86OutputStatusDisconnected; } /* Cache detections for 15s or hotplug event */ now = GetTimeInMillis(); if (sna_output->last_detect != 0 && (int32_t)(now - sna_output->last_detect) <= OUTPUT_STATUS_CACHE_MS) { DBG(("%s(%s) reporting cached status (since %dms): %d\n", __FUNCTION__, output->name, now - sna_output->last_detect, sna_output->status)); sna_output->update_properties = true; return sna_output->status; } VG_CLEAR(compat_conn); compat_conn.conn.connector_id = sna_output->id; sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */ compat_conn.conn.count_encoders = 0; compat_conn.conn.count_props = sna_output->num_props; compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids; compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) return XF86OutputStatusUnknown; DBG(("%s(%s): num modes %d -> %d, num props %d -> %d\n", __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.count_modes, sna_output->num_props, compat_conn.conn.count_props)); assert(compat_conn.conn.count_props == sna_output->num_props); while (compat_conn.conn.count_modes && compat_conn.conn.count_modes != sna_output->num_modes) { struct drm_mode_modeinfo *new_modes; int old_count; old_count = sna_output->num_modes; new_modes = realloc(sna_output->modes, sizeof(*sna_output->modes)*compat_conn.conn.count_modes); if (new_modes == NULL) break; sna_output->modes = new_modes; sna_output->num_modes = compat_conn.conn.count_modes; compat_conn.conn.modes_ptr = (uintptr_t)sna_output->modes; compat_conn.conn.count_encoders = 0; compat_conn.conn.count_props = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { sna_output->num_modes = min(old_count, sna_output->num_modes); break; } VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->modes, sizeof(*sna_output->modes)*sna_output->num_modes)); } DBG(("%s(%s): found %d modes, connection status=%d\n", __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection)); sna_output->last_detect = now; switch (compat_conn.conn.connection) { case DRM_MODE_CONNECTED: sna_output->status = XF86OutputStatusConnected; break; case DRM_MODE_DISCONNECTED: sna_output->status = XF86OutputStatusDisconnected; break; default: case DRM_MODE_UNKNOWNCONNECTION: sna_output->status = XF86OutputStatusUnknown; break; } return sna_output->status; } static Bool sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) { struct sna_output *sna_output = output->driver_private; struct sna *sna = to_sna(output->scrn); if (mode->HDisplay > sna->mode.max_crtc_width) return MODE_VIRTUAL_X; if (mode->VDisplay > sna->mode.max_crtc_height) return MODE_VIRTUAL_Y; /* Check that we can successfully pin this into the global GTT */ if ((kgem_can_create_2d(&sna->kgem, mode->HDisplay, mode->VDisplay, sna->scrn->bitsPerPixel) & KGEM_CAN_CREATE_GTT) == 0) return MODE_MEM_VIRT; /* * If the connector type is a panel, we will use the panel limit to * verfiy whether the mode is valid. */ if (sna_output->has_panel_limits) { if (mode->HDisplay > sna_output->panel_hdisplay || mode->VDisplay > sna_output->panel_vdisplay) return MODE_PANEL; } return MODE_OK; } static void sna_output_attach_edid(xf86OutputPtr output) { struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; struct drm_mode_get_blob blob; void *old, *raw = NULL; xf86MonPtr mon = NULL; if (sna_output->edid_idx == -1) return; /* Always refresh the blob as the kernel may randomly update the * id even if the contents of the blob doesn't change, and a * request for the stale id will return nothing. */ if (sna_output->update_properties) update_properties(sna, sna_output); raw = sna_output->edid_raw; blob.length = sna_output->edid_len; if (blob.length && output->MonInfo) { old = alloca(blob.length); memcpy(old, raw, blob.length); } else old = NULL; blob.blob_id = sna_output->prop_values[sna_output->edid_idx]; if (!blob.blob_id) goto done; DBG(("%s(%s): attaching EDID id=%d, current=%d\n", __FUNCTION__, output->name, blob.blob_id, sna_output->edid_blob_id)); if (blob.blob_id == sna_output->edid_blob_id && 0) { /* sigh */ if (output->MonInfo) { /* XXX the property keeps on disappearing... */ RRChangeOutputProperty(output->randr_output, MakeAtom("EDID", strlen("EDID"), TRUE), XA_INTEGER, 8, PropModeReplace, sna_output->edid_len, sna_output->edid_raw, FALSE, FALSE); return; } goto skip_read; } blob.data = (uintptr_t)raw; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) { DBG(("%s(%s): failed to read blob, reusing previous\n", __FUNCTION__, output->name)); goto skip_read; } DBG(("%s(%s): retrieving blob id=%d, length=%d\n", __FUNCTION__, output->name, blob.blob_id, blob.length)); if (blob.length > sna_output->edid_len) { raw = realloc(raw, blob.length); if (raw == NULL) goto done; VG(memset(raw, 0, blob.length)); blob.data = (uintptr_t)raw; } if (blob.length != sna_output->edid_len && drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) goto done; if (blob.length < 128) goto done; if (blob.length & 127) { /* Truncated EDID! Make sure no one reads too far */ *SECTION(NO_EDID, (uint8_t*)raw) = blob.length/128 - 1; blob.length &= -128; } if (old && blob.length == sna_output->edid_len && memcmp(old, raw, blob.length) == 0) { DBG(("%s(%s): EDID + MonInfo is unchanged\n", __FUNCTION__, output->name)); assert(sna_output->edid_raw == raw); sna_output->edid_blob_id = blob.blob_id; RRChangeOutputProperty(output->randr_output, MakeAtom("EDID", strlen("EDID"), TRUE), XA_INTEGER, 8, PropModeReplace, sna_output->edid_len, sna_output->edid_raw, FALSE, FALSE); return; } skip_read: if (raw) { mon = xf86InterpretEDID(output->scrn->scrnIndex, raw); if (mon && blob.length > 128) mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; } done: xf86OutputSetEDID(output, mon); if (raw) { sna_output->edid_raw = raw; sna_output->edid_len = blob.length; sna_output->edid_blob_id = blob.blob_id; } } static void sna_output_attach_tile(xf86OutputPtr output) { #if XF86_OUTPUT_VERSION >= 3 struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; struct drm_mode_get_blob blob; struct xf86CrtcTileInfo tile_info, *set = NULL; char *tile; int id; id = find_property(sna, sna_output, "TILE"); DBG(("%s: found? TILE=%d\n", __FUNCTION__, id)); if (id == -1) goto out; if (sna_output->update_properties) update_properties(sna, sna_output); VG_CLEAR(blob); blob.blob_id = sna_output->prop_values[id]; blob.length = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) goto out; do { id = blob.length; tile = alloca(id + 1); blob.data = (uintptr_t)tile; VG(memset(tile, 0, id)); DBG(("%s: reading %d bytes for TILE blob\n", __FUNCTION__, id)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) goto out; } while (id != blob.length); tile[blob.length] = '\0'; /* paranoia */ DBG(("%s: TILE='%s'\n", __FUNCTION__, tile)); if (xf86OutputParseKMSTile(tile, blob.length, &tile_info)) set = &tile_info; out: xf86OutputSetTile(output, set); #endif } static bool duplicate_mode(DisplayModePtr modes, DisplayModePtr m) { if (m == NULL) return false; while (modes) { if (xf86ModesEqual(modes, m)) return true; modes = modes->next; } return false; } static struct pixel_count { int16_t width, height; } common_16_9[] = { { 640, 360 }, { 720, 405 }, { 864, 486 }, { 960, 540 }, { 1024, 576 }, { 1280, 720 }, { 1366, 768 }, { 1600, 900 }, { 1920, 1080 }, { 2048, 1152 }, { 2560, 1440 }, { 2880, 1620 }, { 3200, 1800 }, { 3840, 2160 }, { 4096, 2304 }, { 5120, 2880 }, { 7680, 4320 }, { 15360, 8640 }, }, common_16_10[] = { { 1280, 800 }, { 1400, 900 }, { 1680, 1050 }, { 1920, 1200 }, { 2560, 1600 }, }; static DisplayModePtr default_modes(DisplayModePtr preferred) { DisplayModePtr modes; int n; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0) modes = xf86GetDefaultModes(); #else modes = xf86GetDefaultModes(0, 0); #endif /* XXX O(n^2) mode list generation :( */ #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,4,99,901,0) if (preferred) { DisplayModePtr m; /* Add a half-resolution mode useful for large panels */ m = xf86GTFMode(preferred->HDisplay/2, preferred->VDisplay/2, xf86ModeVRefresh(preferred), FALSE, FALSE); if (!duplicate_mode(modes, m)) modes = xf86ModesAdd(modes, m); else free(m); if (preferred->VDisplay * 16 > preferred->HDisplay*9 - preferred->HDisplay/32 && preferred->VDisplay * 16 < preferred->HDisplay*9 + preferred->HDisplay/32) { DBG(("Adding 16:9 modes -- %d < %d > %d\n", preferred->HDisplay*9 - preferred->HDisplay/32, preferred->VDisplay * 16, preferred->HDisplay*9 + preferred->HDisplay/32)); for (n = 0; n < ARRAY_SIZE(common_16_9); n++) { if (preferred->HDisplay <= common_16_9[n].width || preferred->VDisplay <= common_16_9[n].height) break; m = xf86GTFMode(common_16_9[n].width, common_16_9[n].height, xf86ModeVRefresh(preferred), FALSE, FALSE); if (!duplicate_mode(modes, m)) modes = xf86ModesAdd(modes, m); else free(m); } } if (preferred->VDisplay * 16 > preferred->HDisplay*10 - preferred->HDisplay/32 && preferred->VDisplay * 16 < preferred->HDisplay*10 + preferred->HDisplay/32) { DBG(("Adding 16:10 modes -- %d < %d > %d\n", preferred->HDisplay*10 - preferred->HDisplay/32, preferred->VDisplay * 16, preferred->HDisplay*10 + preferred->HDisplay/32)); for (n = 0; n < ARRAY_SIZE(common_16_10); n++) { if (preferred->HDisplay <= common_16_10[n].width || preferred->VDisplay <= common_16_10[n].height) break; m = xf86GTFMode(common_16_10[n].width, common_16_10[n].height, xf86ModeVRefresh(preferred), FALSE, FALSE); if (!duplicate_mode(modes, m)) modes = xf86ModesAdd(modes, m); else free(m); } } } #endif return modes; } static DisplayModePtr sna_output_add_default_modes(xf86OutputPtr output, DisplayModePtr modes) { xf86MonPtr mon = output->MonInfo; DisplayModePtr i, m, preferred = NULL; int max_x = 0, max_y = 0; float max_vrefresh = 0.0; if (mon && GTF_SUPPORTED(mon->features.msc)) return modes; for (m = modes; m; m = m->next) { if (m->type & M_T_PREFERRED) preferred = m; max_x = max(max_x, m->HDisplay); max_y = max(max_y, m->VDisplay); max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); } max_vrefresh = max(max_vrefresh, 60.0); max_vrefresh *= (1 + SYNC_TOLERANCE); m = default_modes(preferred); xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); for (i = m; i; i = i->next) { if (xf86ModeVRefresh(i) > max_vrefresh) i->status = MODE_VSYNC; if (preferred && i->HDisplay >= preferred->HDisplay && i->VDisplay >= preferred->VDisplay && xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) i->status = MODE_PANEL; } xf86PruneInvalidModes(output->scrn, &m, FALSE); return xf86ModesAdd(modes, m); } static DisplayModePtr sna_output_override_edid(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; if (sna_output->fake_edid_mon == NULL) return NULL; xf86OutputSetEDID(output, sna_output->fake_edid_mon); return xf86DDCGetModes(output->scrn->scrnIndex, sna_output->fake_edid_mon); } static DisplayModePtr sna_output_get_modes(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; DisplayModePtr Modes, current; int i; DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id)); assert(sna_output->id); Modes = sna_output_override_edid(output); if (Modes) return Modes; sna_output_attach_edid(output); sna_output_attach_tile(output); current = NULL; if (output->crtc) { struct drm_mode_crtc mode; VG_CLEAR(mode); assert(to_sna_crtc(output->crtc)); mode.crtc_id = sna_crtc_id(output->crtc); if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) { DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, sna_crtc_id(output->crtc), sna_crtc_pipe(output->crtc), mode.mode_valid && mode.mode.clock)); if (mode.mode_valid && mode.mode.clock) { current = calloc(1, sizeof(DisplayModeRec)); if (current) { mode_from_kmode(output->scrn, &mode.mode, current); current->type |= M_T_DRIVER | M_T_PREFERRED; } } } } DBG(("%s: adding %d probed modes\n", __FUNCTION__, sna_output->num_modes)); for (i = 0; i < sna_output->num_modes; i++) { DisplayModePtr mode; mode = calloc(1, sizeof(DisplayModeRec)); if (mode == NULL) continue; mode = mode_from_kmode(output->scrn, &sna_output->modes[i], mode); Modes = xf86ModesAdd(Modes, mode); if (current && xf86ModesEqual(mode, current)) { free((void*)current->name); free(current); current = NULL; } if (current && mode->type & M_T_PREFERRED) current->type &= ~M_T_PREFERRED; } if (current) Modes = xf86ModesAdd(current, Modes); /* * If the connector type is a panel, we will traverse the kernel mode to * get the panel limit. And then add all the standard modes to fake * the fullscreen experience. * If it is incorrect, please fix me. */ sna_output->has_panel_limits = false; if (sna_output->is_panel) { sna_output->panel_hdisplay = sna_output->panel_vdisplay = 0; for (i = 0; i < sna_output->num_modes; i++) { struct drm_mode_modeinfo *m; m = &sna_output->modes[i]; if (m->hdisplay > sna_output->panel_hdisplay) sna_output->panel_hdisplay = m->hdisplay; if (m->vdisplay > sna_output->panel_vdisplay) sna_output->panel_vdisplay = m->vdisplay; } sna_output->has_panel_limits = sna_output->panel_hdisplay && sna_output->panel_vdisplay; } if (sna_output->add_default_modes) Modes = sna_output_add_default_modes(output, Modes); return Modes; } static void sna_output_destroy(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; int i; if (sna_output == NULL) return; free(sna_output->edid_raw); free(sna_output->fake_edid_raw); for (i = 0; i < sna_output->num_props; i++) { if (sna_output->props[i].kprop == NULL) continue; if (sna_output->props[i].atoms) { if (output->randr_output) RRDeleteOutputProperty(output->randr_output, sna_output->props[i].atoms[0]); free(sna_output->props[i].atoms); } drmModeFreeProperty(sna_output->props[i].kprop); } free(sna_output->props); free(sna_output->prop_ids); free(sna_output->prop_values); backlight_close(&sna_output->backlight); free(sna_output); output->driver_private = NULL; } static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup) { struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; int old_dpms = sna_output->dpms_mode; DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n", __FUNCTION__, output->name, sna_output->id, dpms, sna_output->dpms_mode, output->crtc != NULL)); if (!sna_output->id) return; if (old_dpms == dpms) return; /* Record the value of the backlight before turning * off the display, and reset if after turning it on. * Order is important as the kernel may record and also * reset the backlight across DPMS. Hence we need to * record the value before the kernel modifies it * and reapply it afterwards. */ if (sna_output->backlight.iface && dpms != DPMSModeOn) { if (old_dpms == DPMSModeOn) { sna_output->backlight_active_level = sna_output_backlight_get(output); DBG(("%s(%s:%d): saving current backlight %d\n", __FUNCTION__, output->name, sna_output->id, sna_output->backlight_active_level)); } sna_output->dpms_mode = dpms; sna_output_backlight_off(sna_output); } if (output->crtc && drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id, sna_output->dpms_id, dpms)) { DBG(("%s(%s:%d): failed to set DPMS to %d (fixup? %d)\n", __FUNCTION__, output->name, sna_output->id, dpms, fixup)); if (fixup) { sna_crtc_disable(output->crtc, false); return; } } if (sna_output->backlight.iface && dpms == DPMSModeOn) { DBG(("%s(%d:%d: restoring previous backlight %d\n", __FUNCTION__, output->name, sna_output->id, sna_output->backlight_active_level)); sna_output_backlight_on(sna_output); } sna_output->dpms_mode = dpms; } static void sna_output_dpms(xf86OutputPtr output, int dpms) { __sna_output_dpms(output, dpms, true); } static bool sna_property_ignore(drmModePropertyPtr prop) { if (!prop) return true; /* ignore blob prop */ if (prop->flags & DRM_MODE_PROP_BLOB) return true; /* ignore standard property */ if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) return true; return false; } static void sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom, const char *name, INT32 min, INT32 max, uint64_t value, Bool immutable) { int err; INT32 atom_range[2]; atom_range[0] = min; atom_range[1] = max; *atom = MakeAtom(name, strlen(name), TRUE); err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE, TRUE, immutable, 2, atom_range); if (err != 0) xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRConfigureOutputProperty error, %d\n", err); err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, FALSE); if (err != 0) xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRChangeOutputProperty error, %d\n", err); } static void sna_output_create_resources(xf86OutputPtr output) { struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; int i, j, err; sna_output->props = calloc(sna_output->num_props, sizeof(struct sna_property)); if (!sna_output->props) return; for (i = 0; i < sna_output->num_props; i++) { struct sna_property *p = &sna_output->props[i]; p->kprop = drmModeGetProperty(sna->kgem.fd, sna_output->prop_ids[i]); if (sna_property_ignore(p->kprop)) { drmModeFreeProperty(p->kprop); p->kprop = NULL; continue; } if (p->kprop->flags & DRM_MODE_PROP_RANGE) { p->num_atoms = 1; p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; sna_output_create_ranged_atom(output, &p->atoms[0], p->kprop->name, p->kprop->values[0], p->kprop->values[1], sna_output->prop_values[i], p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE); } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) { p->num_atoms = p->kprop->count_enums + 1; p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; p->atoms[0] = MakeAtom(p->kprop->name, strlen(p->kprop->name), TRUE); for (j = 1; j <= p->kprop->count_enums; j++) { struct drm_mode_property_enum *e = &p->kprop->enums[j-1]; p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); } err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], FALSE, FALSE, p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, p->num_atoms - 1, (INT32 *)&p->atoms[1]); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRConfigureOutputProperty error, %d\n", err); } for (j = 0; j < p->kprop->count_enums; j++) if (p->kprop->enums[j].value == sna_output->prop_values[i]) break; /* there's always a matching value */ err = RRChangeOutputProperty(output->randr_output, p->atoms[0], XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, FALSE); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRChangeOutputProperty error, %d\n", err); } } } if (sna_output->backlight.iface) { /* Set up the backlight property, which takes effect * immediately and accepts values only within the * backlight_range. */ sna_output_create_ranged_atom(output, &backlight_atom, BACKLIGHT_NAME, 0, sna_output->backlight.max, sna_output->backlight_active_level, FALSE); sna_output_create_ranged_atom(output, &backlight_deprecated_atom, BACKLIGHT_DEPRECATED_NAME, 0, sna_output->backlight.max, sna_output->backlight_active_level, FALSE); } } static Bool sna_output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) { struct sna *sna = to_sna(output->scrn); struct sna_output *sna_output = output->driver_private; int i; if (property == backlight_atom || property == backlight_deprecated_atom) { INT32 val; int ret = 0; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { return FALSE; } val = *(INT32 *)value->data; DBG(("%s: setting backlight to %d (max=%d)\n", __FUNCTION__, (int)val, sna_output->backlight.max)); if (val < 0 || val > sna_output->backlight.max) return FALSE; sna_output->backlight_active_level = val; if (sna_output->dpms_mode == DPMSModeOn) ret = sna_output_backlight_set(sna_output, val); return ret == 0; } if (!sna_output->id) return TRUE; for (i = 0; i < sna_output->num_props; i++) { struct sna_property *p = &sna_output->props[i]; if (p->atoms == NULL || p->atoms[0] != property) continue; if (p->kprop->flags & DRM_MODE_PROP_RANGE) { uint32_t val; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) return FALSE; val = *(uint32_t *)value->data; drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id, p->kprop->prop_id, (uint64_t)val); return TRUE; } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) { Atom atom; const char *name; int j; if (value->type != XA_ATOM || value->format != 32 || value->size != 1) return FALSE; memcpy(&atom, value->data, 4); name = NameForAtom(atom); if (name == NULL) return FALSE; /* search for matching name string, then set its value down */ for (j = 0; j < p->kprop->count_enums; j++) { if (!strcmp(p->kprop->enums[j].name, name)) { drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id, p->kprop->prop_id, p->kprop->enums[j].value); return TRUE; } } return FALSE; } } /* We didn't recognise this property, just report success in order * to allow the set to continue, otherwise we break setting of * common properties like EDID. */ return TRUE; } static Bool sna_output_get_property(xf86OutputPtr output, Atom property) { struct sna_output *sna_output = output->driver_private; int err, i, j; if (property == backlight_atom || property == backlight_deprecated_atom) { INT32 val; if (!sna_output->backlight.iface) return FALSE; if (sna_output->dpms_mode == DPMSModeOn) { val = sna_output_backlight_get(output); if (val < 0) return FALSE; DBG(("%s(%s): output on, reporting actual backlight value [%d]\n", __FUNCTION__, output->name, val)); } else { val = sna_output->backlight_active_level; DBG(("%s(%s): output off, reporting cached backlight value [%d]\n", __FUNCTION__, output->name, val)); } err = RRChangeOutputProperty(output->randr_output, property, XA_INTEGER, 32, PropModeReplace, 1, &val, FALSE, FALSE); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRChangeOutputProperty error, %d\n", err); return FALSE; } return TRUE; } for (i = 0; i < sna_output->num_props; i++) { struct sna_property *p = &sna_output->props[i]; if (p->atoms == NULL || p->atoms[0] != property) continue; if (sna_output->update_properties && output->scrn->vtSema) update_properties(to_sna(output->scrn), sna_output); err = 0; if (p->kprop->flags & DRM_MODE_PROP_RANGE) { err = RRChangeOutputProperty(output->randr_output, property, XA_INTEGER, 32, PropModeReplace, 1, &sna_output->prop_values[i], FALSE, FALSE); } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) { for (j = 0; j < p->kprop->count_enums; j++) { if (p->kprop->enums[j].value == sna_output->prop_values[i]) break; } err = RRChangeOutputProperty(output->randr_output, property, XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, FALSE); } if (err != 0) xf86DrvMsg(output->scrn->scrnIndex, X_WARNING, "RRChangeOutputProperty error, %d\n", err); return TRUE; } return FALSE; } static const xf86OutputFuncsRec sna_output_funcs = { .create_resources = sna_output_create_resources, #ifdef RANDR_12_INTERFACE .set_property = sna_output_set_property, .get_property = sna_output_get_property, #endif .dpms = sna_output_dpms, .detect = sna_output_detect, .mode_valid = sna_output_mode_valid, .get_modes = sna_output_get_modes, .destroy = sna_output_destroy }; static const int subpixel_conv_table[] = { SubPixelUnknown, SubPixelHorizontalRGB, SubPixelHorizontalBGR, SubPixelVerticalRGB, SubPixelVerticalBGR, SubPixelNone }; static const char * const output_names[] = { /* DRM_MODE_CONNECTOR_Unknown */ "None", /* DRM_MODE_CONNECTOR_VGA */ "VGA", /* DRM_MODE_CONNECTOR_DVII */ "DVI", /* DRM_MODE_CONNECTOR_DVID */ "DVI", /* DRM_MODE_CONNECTOR_DVIA */ "DVI", /* DRM_MODE_CONNECTOR_Composite */ "Composite", /* DRM_MODE_CONNECTOR_SVIDEO */ "TV", /* DRM_MODE_CONNECTOR_LVDS */ "LVDS", /* DRM_MODE_CONNECTOR_Component */ "CTV", /* DRM_MODE_CONNECTOR_9PinDIN */ "DIN", /* DRM_MODE_CONNECTOR_DisplayPort */ "DP", /* DRM_MODE_CONNECTOR_HDMIA */ "HDMI", /* DRM_MODE_CONNECTOR_HDMIB */ "HDMI", /* DRM_MODE_CONNECTOR_TV */ "TV", /* DRM_MODE_CONNECTOR_eDP */ "eDP", /* DRM_MODE_CONNECTOR_VIRTUAL */ "Virtual", /* DRM_MODE_CONNECTOR_DSI */ "DSI" }; static bool output_ignored(ScrnInfoPtr scrn, const char *name) { char monitor_name[64]; const char *monitor; XF86ConfMonitorPtr conf; snprintf(monitor_name, sizeof(monitor_name), "monitor-%s", name); monitor = xf86findOptionValue(scrn->options, monitor_name); if (!monitor) monitor = name; conf = xf86findMonitor(monitor, xf86configptr->conf_monitor_lst); if (conf == NULL && XF86_CRTC_CONFIG_PTR(scrn)->num_output == 0) conf = xf86findMonitor(scrn->monitor->id, xf86configptr->conf_monitor_lst); if (conf == NULL) return false; return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0); } static bool gather_encoders(struct sna *sna, uint32_t id, int count, struct drm_mode_get_encoder *out) { union compat_mode_get_connector compat_conn; struct drm_mode_modeinfo dummy; struct drm_mode_get_encoder enc; uint32_t *ids = NULL; DBG(("%s(%d): expected count=%d\n", __FUNCTION__, id, count)); VG_CLEAR(compat_conn); VG_CLEAR(enc); memset(out, 0, sizeof(*out)); do { uint32_t *nids; nids = realloc(ids, sizeof(*ids) * count); if (nids == NULL) { free(ids); return false; } ids = nids; compat_conn.conn.connector_id = id; compat_conn.conn.count_props = 0; compat_conn.conn.count_modes = 1; /* skip detect */ compat_conn.conn.modes_ptr = (uintptr_t)&dummy; compat_conn.conn.count_encoders = count; compat_conn.conn.encoders_ptr = (uintptr_t)ids; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno)); compat_conn.conn.count_encoders = count = 0; } VG(VALGRIND_MAKE_MEM_DEFINED(ids, sizeof(uint32_t)*compat_conn.conn.count_encoders)); if (count == compat_conn.conn.count_encoders) break; count = compat_conn.conn.count_encoders; } while (1); DBG(("%s(%d): gathering %d encoders\n", __FUNCTION__, id, count)); for (count = 0; count < compat_conn.conn.count_encoders; count++) { enc.encoder_id = ids[count]; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) { DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno)); count = 0; break; } DBG(("%s(%d): encoder=%d, possible_crtcs=%x, possible_clones=%x\n", __FUNCTION__, id, enc.encoder_id, enc.possible_crtcs, enc.possible_clones)); out->possible_crtcs |= enc.possible_crtcs; out->possible_clones |= enc.possible_clones; for (id = 0; id < sna->mode.num_real_encoder; id++) { if (enc.encoder_id == sna->mode.encoders[id]) { out->crtc_id |= 1 << id; break; } } } free(ids); return count > 0; } /* We need to map from kms encoder based possible_clones mask to X output based * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we * can have more than one output hanging off the same encoder. */ static void sna_mode_compute_possible_outputs(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int encoder_mask[32]; int i, j; assert(sna->mode.num_real_output < 32); assert(sna->mode.num_real_crtc < 32); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; struct sna_output *sna_output = to_sna_output(output); assert(sna_output); if (sna_output->id) { output->possible_clones = sna_output->possible_encoders; encoder_mask[i] = sna_output->attached_encoders; } else { output->possible_clones = 0; encoder_mask[i] = 0; } } /* Convert from encoder numbering to output numbering */ for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; unsigned clones; if (output->possible_clones == 0) continue; clones = 0; for (j = 0; j < sna->mode.num_real_output; j++) if (i != j && output->possible_clones & encoder_mask[j]) clones |= 1 << j; output->possible_clones = clones; DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n", __FUNCTION__, output->name, i, to_connector_id(output), (uint32_t)output->possible_crtcs, (uint32_t)output->possible_clones)); } } static int name_from_path(struct sna *sna, struct sna_output *sna_output, char *name) { struct drm_mode_get_blob blob; char *path; int id; id = find_property(sna, sna_output, "PATH"); DBG(("%s: found? PATH=%d\n", __FUNCTION__, id)); if (id == -1) return 0; VG_CLEAR(blob); blob.blob_id = sna_output->prop_values[id]; blob.length = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) return 0; do { id = blob.length; path = alloca(id + 1); blob.data = (uintptr_t)path; VG(memset(path, 0, id)); DBG(("%s: reading %d bytes for path blob\n", __FUNCTION__, id)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) return 0; } while (id != blob.length); path[blob.length] = '\0'; /* paranoia */ DBG(("%s: PATH='%s'\n", __FUNCTION__, path)); /* we only handle MST paths for now */ if (strncmp(path, "mst:", 4) == 0) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); char tmp[5], *c; int n; c = strchr(path + 4, '-'); if (c == NULL) return 0; id = c - (path + 4); if (id + 1> 5) return 0; memcpy(tmp, path + 4, id); tmp[id] = '\0'; id = strtoul(tmp, NULL, 0); for (n = 0; n < sna->mode.num_real_output; n++) { if (to_sna_output(config->output[n])->id == id) return snprintf(name, 32, "%s-%s", config->output[n]->name, c + 1); } } return 0; } static char *fake_edid_name(xf86OutputPtr output) { struct sna *sna = to_sna(output->scrn); const char *str, *colon; #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) str = xf86GetOptValString(sna->Options, OPTION_EDID); #else str = NULL; #endif if (str == NULL) return NULL; do { colon = strchr(str, ':'); if (colon == NULL) return NULL; if (strncmp(str, output->name, colon-str) == 0 && output->name[colon-str] == '\0') { char *path; int len; str = colon + 1; colon = strchr(str, ','); if (colon) len = colon - str; else len = strlen(str); path = malloc(len + 1); if (path == NULL) return NULL; memcpy(path, str, len); path[len] = '\0'; return path; } str = strchr(colon + 1, ','); if (str == NULL) return NULL; str++; } while (1); } static void sna_output_load_fake_edid(xf86OutputPtr output) { struct sna_output *sna_output = output->driver_private; const char *filename; FILE *file; void *raw; int size; xf86MonPtr mon; filename = fake_edid_name(output); if (filename == NULL) return; file = fopen(filename, "rb"); if (file == NULL) goto err; fseek(file, 0, SEEK_END); size = ftell(file); if (size % 128) { fclose(file); goto err; } raw = malloc(size); if (raw == NULL) { fclose(file); free(raw); goto err; } fseek(file, 0, SEEK_SET); if (fread(raw, size, 1, file) != 1) { fclose(file); free(raw); goto err; } fclose(file); mon = xf86InterpretEDID(output->scrn->scrnIndex, raw); if (mon == NULL) { free(raw); goto err; } if (mon && size > 128) mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; sna_output->fake_edid_mon = mon; sna_output->fake_edid_raw = raw; xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG, "Loading EDID from \"%s\" for output %s\n", filename, output->name); return; err: xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Could not read EDID file \"%s\" for output %s\n", filename, output->name); } static int sna_output_add(struct sna *sna, unsigned id, unsigned serial) { ScrnInfoPtr scrn = sna->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); union compat_mode_get_connector compat_conn; struct drm_mode_get_encoder enc; struct drm_mode_modeinfo dummy; struct sna_output *sna_output; xf86OutputPtr *outputs, output; unsigned possible_encoders, attached_encoders, possible_crtcs; const char *output_name; char name[32]; int path, len, i; DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial)); COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad)); VG_CLEAR(compat_conn); memset(&enc, 0, sizeof(enc)); compat_conn.conn.connector_id = id; compat_conn.conn.count_props = 0; compat_conn.conn.count_modes = 1; /* skip detect */ compat_conn.conn.modes_ptr = (uintptr_t)&dummy; compat_conn.conn.count_encoders = 1; compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno)); return -1; } assert(compat_conn.conn.connector_id == id); DBG(("%s(%d): has %d associated encoders\n", __FUNCTION__, id, compat_conn.conn.count_encoders)); if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names)) output_name = output_names[compat_conn.conn.connector_type]; else output_name = "UNKNOWN"; len = snprintf(name, 32, "%s%d", output_name, compat_conn.conn.connector_type_id); if (output_ignored(scrn, name)) return 0; if (enc.encoder_id) { if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) { DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno)); return 0; } possible_encoders = enc.possible_clones; attached_encoders = 0; for (i = 0; i < sna->mode.num_real_encoder; i++) { if (enc.encoder_id == sna->mode.encoders[i]) { attached_encoders = 1 << i; break; } } if (attached_encoders == 0) { DBG(("%s: failed to find attached encoder\n", __FUNCTION__)); return 0; } possible_crtcs = enc.possible_crtcs; assert(enc.encoder_id == compat_conn.conn.encoder_id || compat_conn.conn.encoder_id == 0); } else { DBG(("%s: unexpected number [%d] of encoders attached\n", __FUNCTION__, compat_conn.conn.count_encoders)); if (!gather_encoders(sna, id, compat_conn.conn.count_encoders, &enc)) { DBG(("%s: gather encoders failed\n", __FUNCTION__)); return 0; } possible_encoders = enc.possible_clones; attached_encoders = enc.crtc_id; possible_crtcs = enc.possible_crtcs; memset(&enc, 0, sizeof(enc)); enc.encoder_id = compat_conn.conn.encoder_id; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc); } if (is_zaphod(scrn)) { unsigned zaphod_crtcs; if (!sna_zaphod_match(sna, name)) { DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???", name)); return 0; } zaphod_crtcs = get_zaphod_crtcs(sna); possible_crtcs &= zaphod_crtcs; if (possible_crtcs == 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s is an invalid output for screen %d\n", name, scrn->confScreen->device->screen); return -1; } possible_crtcs >>= ffs(zaphod_crtcs) - 1; } sna_output = calloc(sizeof(struct sna_output), 1); if (!sna_output) return -1; sna_output->num_props = compat_conn.conn.count_props; sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props); sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props); if (sna_output->prop_ids == NULL || sna_output->prop_values == NULL) { free(sna_output->prop_ids); free(sna_output->prop_values); free(sna_output); return -1; } compat_conn.conn.count_encoders = 0; compat_conn.conn.count_modes = 1; compat_conn.conn.modes_ptr = (uintptr_t)&dummy; compat_conn.conn.count_props = sna_output->num_props; compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids; compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) { DBG(("%s: second! GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno)); goto cleanup; } assert(compat_conn.conn.connector_id == id); /* statically constructed property list */ assert(sna_output->num_props == compat_conn.conn.count_props); VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props)); VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props)); /* Construct name from topology, and recheck if output is acceptable */ path = name_from_path(sna, sna_output, name); if (path) { if (output_ignored(scrn, name)) { len = 0; goto skip; } if (is_zaphod(scrn) && !sna_zaphod_match(sna, name)) { DBG(("%s: zaphod mismatch, want %s, have %s\n", __FUNCTION__, xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???", name)); len = 0; goto skip; } len = path; } /* Check if we are dynamically reattaching an old connector */ if (serial) { for (i = 0; i < sna->mode.num_real_output; i++) { output = config->output[i]; if (strcmp(output->name, name) == 0) { assert(output->scrn == scrn); assert(output->funcs == &sna_output_funcs); assert(to_sna_output(output)->id == 0); sna_output_destroy(output); goto reset; } } } output = calloc(1, sizeof(*output) + len + 1); if (!output) goto cleanup; outputs = realloc(config->output, (config->num_output + 1) * sizeof(output)); if (outputs == NULL) { free(output); goto cleanup; } output->scrn = scrn; output->funcs = &sna_output_funcs; output->name = (char *)(output + 1); memcpy(output->name, name, len + 1); output->use_screen_monitor = config->num_output != 0; xf86OutputUseScreenMonitor(output, !output->use_screen_monitor); assert(output->options); DBG(("%s: inserting output #%d of %d\n", __FUNCTION__, sna->mode.num_real_output, config->num_output)); for (i = config->num_output; i > sna->mode.num_real_output; i--) { outputs[i] = outputs[i-1]; assert(outputs[i]->driver_private == NULL); outputs[i]->possible_clones <<= 1; } if (xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) { memmove(outputs + 1, outputs, sizeof(output)*config->num_output); outputs[0] = output; } else outputs[i] = output; sna->mode.num_real_output++; config->num_output++; config->output = outputs; reset: sna_output->id = compat_conn.conn.connector_id; sna_output->is_panel = is_panel(compat_conn.conn.connector_type); sna_output->edid_idx = find_property(sna, sna_output, "EDID"); if (find_property(sna, sna_output, "scaling mode") != -1) sna_output->add_default_modes = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE); i = find_property(sna, sna_output, "DPMS"); if (i != -1) { sna_output->dpms_id = sna_output->prop_ids[i]; sna_output->dpms_mode = sna_output->prop_values[i]; DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n", __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode)); } else sna_output->dpms_mode = DPMSModeOff; sna_output->possible_encoders = possible_encoders; sna_output->attached_encoders = attached_encoders; output->mm_width = compat_conn.conn.mm_width; output->mm_height = compat_conn.conn.mm_height; if (compat_conn.conn.subpixel >= ARRAY_SIZE(subpixel_conv_table)) compat_conn.conn.subpixel = 0; output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel]; output->driver_private = sna_output; sna_output->base = output; backlight_init(&sna_output->backlight); if (sna_output->is_panel) sna_output_backlight_init(output); output->possible_crtcs = possible_crtcs & count_to_mask(sna->mode.num_real_crtc); output->interlaceAllowed = TRUE; sna_output_load_fake_edid(output); if (serial) { if (output->randr_output == NULL) { output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output); if (output->randr_output == NULL) goto cleanup; } RROutputChanged(output->randr_output, TRUE); sna_output_create_resources(output); RRPostPendingProperties(output->randr_output); sna_output->serial = serial; } else { /* stash the active CRTC id for our probe function */ if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED) output->crtc = (void *)(uintptr_t)enc.crtc_id; } DBG(("%s: created output '%s' %d, encoder=%d (possible crtc:%x, attached encoders:%x, possible clones:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n", __FUNCTION__, name, id, enc.encoder_id, (uint32_t)output->possible_crtcs, sna_output->attached_encoders, sna_output->possible_encoders, serial, sna_output->edid_idx, sna_output->dpms_id, (unsigned long)(uintptr_t)output->crtc)); assert(sna_output->id == id); xf86DrvMsg(scrn->scrnIndex, X_INFO, "Enabled output %s\n", output->name); return 1; cleanup: len = -1; skip: free(sna_output->prop_ids); free(sna_output->prop_values); free(sna_output); return len; } static int output_rank(const void *A, const void *B) { const xf86OutputPtr *a = A; const xf86OutputPtr *b = B; struct sna_output *sa = to_sna_output(*a); struct sna_output *sb = to_sna_output(*b); if (sa->is_panel != sb->is_panel) return sb->is_panel - sa->is_panel; return strcmp((*a)->name, (*b)->name); } static void sort_config_outputs(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank); config->compat_output = 0; /* make sure it is a sane value */ sna_mode_compute_possible_outputs(sna); } static void sort_randr_outputs(struct sna *sna, ScreenPtr screen) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); rrScrPriv(screen); int i; assert(pScrPriv->numOutputs == config->num_output); for (i = 0; i < config->num_output; i++) { assert(config->output[i]->randr_output); pScrPriv->outputs[i] = config->output[i]->randr_output; } } static bool disable_unused_crtc(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); bool update = false; int o, c; DBG(("%s\n", __FUNCTION__)); for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; if (!crtc->enabled) continue; for (o = 0; o < sna->mode.num_real_output; o++) { xf86OutputPtr output = config->output[o]; if (output->crtc == crtc) break; } if (o == sna->mode.num_real_output) { DBG(("%s: CRTC:%d was enabled with no outputs\n", __FUNCTION__, sna_crtc_id(crtc))); crtc->enabled = false; update = true; } } if (update) { DBG(("%s: disabling unused functions\n", __FUNCTION__)); xf86DisableUnusedFunctions(sna->scrn); } return update; } static bool output_check_status(struct sna *sna, struct sna_output *output) { union compat_mode_get_connector compat_conn; struct drm_mode_modeinfo dummy; xf86OutputStatus status; VG_CLEAR(compat_conn); compat_conn.conn.connector_id = output->id; compat_conn.conn.count_modes = 1; /* skip detect */ compat_conn.conn.modes_ptr = (uintptr_t)&dummy; compat_conn.conn.count_encoders = 0; compat_conn.conn.count_props = 0; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn); switch (compat_conn.conn.connection) { case DRM_MODE_CONNECTED: status = XF86OutputStatusConnected; break; case DRM_MODE_DISCONNECTED: status = XF86OutputStatusDisconnected; break; default: case DRM_MODE_UNKNOWNCONNECTION: status = XF86OutputStatusUnknown; break; } return output->status == status; } void sna_mode_discover(struct sna *sna, bool tell) { ScreenPtr screen = xf86ScrnToScreen(sna->scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); struct drm_mode_card_res res; uint32_t connectors[32], now; unsigned changed = 0; unsigned serial; int i, j; DBG(("%s()\n", __FUNCTION__)); sna->flags &= ~SNA_REPROBE; VG_CLEAR(connectors); memset(&res, 0, sizeof(res)); res.count_connectors = 32; res.connector_id_ptr = (uintptr_t)connectors; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) return; DBG(("%s: now %d (was %d) connectors, %d encoders, %d crtc\n", __FUNCTION__, res.count_connectors, sna->mode.num_real_output, res.count_encoders, res.count_crtcs)); if (res.count_connectors > 32) return; assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn)); assert(sna->mode.max_crtc_width == res.max_width); assert(sna->mode.max_crtc_height == res.max_height); assert(sna->mode.num_real_encoder == res.count_encoders); serial = ++sna->mode.serial; if (serial == 0) serial = ++sna->mode.serial; now = GetTimeInMillis(); for (i = 0; i < res.count_connectors; i++) { DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i])); for (j = 0; j < sna->mode.num_real_output; j++) { xf86OutputPtr output = config->output[j]; if (to_sna_output(output)->id == connectors[i]) { DBG(("%s: found %s (id=%d)\n", __FUNCTION__, output->name, connectors[i])); assert(to_sna_output(output)->id); to_sna_output(output)->serial = serial; break; } } if (j == sna->mode.num_real_output) { DBG(("%s: adding id=%d\n", __FUNCTION__, connectors[i])); changed |= sna_output_add(sna, connectors[i], serial) > 0; } } for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; struct sna_output *sna_output = to_sna_output(output); if (sna_output->id == 0) continue; if (sna_output->serial == serial) { if (output_check_status(sna, sna_output)) { DBG(("%s: output %s (id=%d), retained state\n", __FUNCTION__, output->name, sna_output->id)); sna_output->last_detect = now; } else { DBG(("%s: output %s (id=%d), changed state, reprobing\n", __FUNCTION__, output->name, sna_output->id)); sna_output->last_detect = 0; changed |= 4; } continue; } DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n", __FUNCTION__, output->name, sna_output->id, sna_output->serial, serial)); xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "Disabled output %s\n", output->name); sna_output->id = 0; sna_output->last_detect = 0; output->crtc = NULL; RROutputChanged(output->randr_output, TRUE); changed |= 2; } /* Have the list of available outputs been updated? */ if (changed & 3) { DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__)); sna_mode_set_primary(sna); /* Reorder user visible listing */ sort_config_outputs(sna); sort_randr_outputs(sna, screen); if (changed & 2) disable_unused_crtc(sna); xf86RandR12TellChanged(screen); } /* If anything has changed, refresh the RandR information. * Note this could recurse once from udevless RRGetInfo() probes, * but only once. */ if (changed && tell) RRGetInfo(screen, TRUE); } /* Since we only probe the current mode on startup, we may not have the full * list of modes available until the user explicitly requests them. Fake a * hotplug event after a second after starting to fill in any missing modes. */ static CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data) { struct sna *sna = data; ScreenPtr screen = xf86ScrnToScreen(sna->scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); bool reprobe = false; int i; DBG(("%s()\n", __FUNCTION__)); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; struct sna_output *sna_output = to_sna_output(output); if (sna_output->id == 0) continue; if (sna_output->last_detect) continue; if (output->status == XF86OutputStatusDisconnected) continue; DBG(("%s: output %s connected, needs reprobe\n", __FUNCTION__, output->name)); reprobe = true; } if (reprobe) { RRGetInfo(screen, TRUE); RRTellChanged(screen); } free(timer); return 0; } static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new) { struct sna_pixmap *old_priv, *new_priv; DBG(("%s\n", __FUNCTION__)); if (wedged(sna) || isGPU(sna->scrn)) return; old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ); if (!old_priv) return; new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT); if (!new_priv) return; if (old_priv->clear) { bool ok = false; if (!wedged(sna)) ok = sna->render.fill_one(sna, new, new_priv->gpu_bo, old_priv->clear_color, 0, 0, new->drawable.width, new->drawable.height, GXcopy); if (!ok) { void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo); if (ptr) memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height); } new_priv->clear = true; new_priv->clear_color = old_priv->clear_color; } else { BoxRec box; int16_t sx, sy, dx, dy; if (new->drawable.width >= old->drawable.width && new->drawable.height >= old->drawable.height) { int nx = (new->drawable.width + old->drawable.width - 1) / old->drawable.width; int ny = (new->drawable.height + old->drawable.height - 1) / old->drawable.height; box.x1 = box.y1 = 0; dy = 0; for (sy = 0; sy < ny; sy++) { box.y2 = old->drawable.height; if (box.y2 + dy > new->drawable.height) box.y2 = new->drawable.height - dy; dx = 0; for (sx = 0; sx < nx; sx++) { box.x2 = old->drawable.width; if (box.x2 + dx > new->drawable.width) box.x2 = new->drawable.width - dx; (void)sna->render.copy_boxes(sna, GXcopy, &old->drawable, old_priv->gpu_bo, 0, 0, &new->drawable, new_priv->gpu_bo, dx, dy, &box, 1, 0); dx += old->drawable.width; } dy += old->drawable.height; } } else { box.x1 = box.y1 = 0; box.x2 = min(old->drawable.width, new->drawable.width); box.y2 = min(old->drawable.height, new->drawable.height); sx = dx = 0; if (box.x2 < old->drawable.width) sx = (old->drawable.width - box.x2) / 2; if (box.x2 < new->drawable.width) dx = (new->drawable.width - box.x2) / 2; sy = dy = 0; if (box.y2 < old->drawable.height) sy = (old->drawable.height - box.y2) / 2; if (box.y2 < new->drawable.height) dy = (new->drawable.height - box.y2) / 2; DBG(("%s: copying box (%dx%d) from (%d, %d) to (%d, %d)\n", __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy)); if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) { bool ok = false; if (!wedged(sna)) ok = sna->render.fill_one(sna, new, new_priv->gpu_bo, 0, 0, 0, new->drawable.width, new->drawable.height, GXclear); if (!ok) { void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo); if (ptr) memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height); } } (void)sna->render.copy_boxes(sna, GXcopy, &old->drawable, old_priv->gpu_bo, sx, sy, &new->drawable, new_priv->gpu_bo, dx, dy, &box, 1, 0); } } sna_damage_all(&new_priv->gpu_damage, new); } static Bool sna_mode_resize(ScrnInfoPtr scrn, int width, int height) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); ScreenPtr screen = xf86ScrnToScreen(scrn); PixmapPtr new_front; int i; DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__, scrn->virtualX, scrn->virtualY, width, height)); assert((sna->flags & SNA_IS_HOSTED) == 0); if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; /* Paranoid defense against rogue internal calls by Xorg */ if (width == 0 || height == 0) return FALSE; assert(sna->front); assert(screen->GetScreenPixmap(screen) == sna->front); DBG(("%s: creating new framebuffer %dx%d\n", __FUNCTION__, width, height)); new_front = screen->CreatePixmap(screen, width, height, scrn->depth, SNA_CREATE_FB); if (!new_front) return FALSE; xf86DrvMsg(scrn->scrnIndex, X_INFO, "resizing framebuffer to %dx%d\n", width, height); for (i = 0; i < sna->mode.num_real_crtc; i++) sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i])); assert(sna->mode.shadow_active == 0); assert(!sna->mode.shadow_enabled); assert(sna->mode.shadow_damage == NULL); assert(sna->mode.shadow == NULL); /* Cancel a pending [un]flip (as the pixmaps no longer match) */ sna_present_cancel_flip(sna); copy_front(sna, sna->front, new_front); screen->SetScreenPixmap(new_front); assert(screen->GetScreenPixmap(screen) == new_front); assert(sna->front == new_front); screen->DestroyPixmap(new_front); /* owned by screen now */ scrn->virtualX = width; scrn->virtualY = height; scrn->displayWidth = width; /* Flush pending shadow updates */ if (sna->mode.flip_active) { DBG(("%s: waiting for %d outstanding TearFree flips\n", __FUNCTION__, sna->mode.flip_active)); while (sna->mode.flip_active && sna_mode_wait_for_event(sna)) sna_mode_wakeup(sna); } /* Only update the CRTCs if we are in control */ if (!scrn->vtSema) return TRUE; for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; assert(to_sna_crtc(crtc) != NULL); if (to_sna_crtc(crtc)->bo == NULL) continue; if (!__sna_crtc_set_mode(crtc)) sna_crtc_disable(crtc, false); } sna_mode_wakeup(sna); kgem_clean_scanout_cache(&sna->kgem); return TRUE; } /* cursor handling */ static void rotate_coord(Rotation rotation, int size, int x_dst, int y_dst, int *x_src, int *y_src) { int t; switch (rotation & 0xf) { case RR_Rotate_0: break; case RR_Rotate_90: t = x_dst; x_dst = size - y_dst - 1; y_dst = t; break; case RR_Rotate_180: x_dst = size - x_dst - 1; y_dst = size - y_dst - 1; break; case RR_Rotate_270: t = x_dst; x_dst = y_dst; y_dst = size - t - 1; break; } if (rotation & RR_Reflect_X) x_dst = size - x_dst - 1; if (rotation & RR_Reflect_Y) y_dst = size - y_dst - 1; *x_src = x_dst; *y_src = y_dst; } static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size) { struct sna_cursor *c; for (c = sna->cursor.cursors; c; c = c->next) { if (c->ref == 0 && c->alloc >= size) { __DBG(("%s: stealing handle=%d, serial=%d, rotation=%d, alloc=%d\n", __FUNCTION__, c->handle, c->serial, c->rotation, c->alloc)); return c; } } __DBG(("%s(size=%d, num_stash=%d)\n", __FUNCTION__, size, sna->cursor.num_stash)); c = sna->cursor.stash; assert(c); c->alloc = ALIGN(size, 4096); c->handle = gem_create(sna->kgem.fd, c->alloc); if (c->handle == 0) return NULL; /* Old hardware uses physical addresses, which the kernel * implements in an incoherent fashion requiring a pwrite. */ if (sna->cursor.use_gtt) { c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc); if (c->image == NULL) { gem_close(sna->kgem.fd, c->handle); return NULL; } } else c->image = NULL; __DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size)); c->ref = 0; c->serial = 0; c->rotation = 0; c->last_width = c->last_height = 0; /* all clear */ c->size = size; sna->cursor.num_stash--; sna->cursor.stash = c->next; c->next = sna->cursor.cursors; sna->cursor.cursors = c; return c; } static uint32_t *get_cursor_argb(CursorPtr c) { #ifdef ARGB_CURSOR return (uint32_t *)c->bits->argb; #else return NULL; #endif } static int __cursor_size(int width, int height) { int i, size; i = MAX(width, height); for (size = 64; size < i; size <<= 1) ; return size; } static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc) { struct sna_cursor *cursor; const uint8_t *source, *mask; const uint32_t *argb; uint32_t *image; int width, height, pitch, size, x, y; PictTransform cursor_to_fb; bool transformed; Rotation rotation; assert(sna->cursor.ref); cursor = to_sna_crtc(crtc)->cursor; __DBG(("%s: current cursor handle=%d, serial=%d [expected %d]\n", __FUNCTION__, cursor ? cursor->handle : 0, cursor ? cursor->serial : 0, sna->cursor.serial)); if (cursor && cursor->serial == sna->cursor.serial) { assert(cursor->size == sna->cursor.size || cursor->transformed); assert(cursor->rotation == (!to_sna_crtc(crtc)->cursor_transform && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0); assert(cursor->ref); return cursor; } __DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__, sna->cursor.ref->bits->width, sna->cursor.ref->bits->height, get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width), sna->cursor.serial, get_cursor_argb(sna->cursor.ref) != NULL)); transformed = to_sna_crtc(crtc)->cursor_transform; rotation = (!transformed && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0; /* Don't allow phys cursor sharing */ if (sna->cursor.use_gtt && !transformed) { for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) { if (cursor->serial == sna->cursor.serial && cursor->rotation == rotation && !cursor->transformed) { __DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n", __FUNCTION__, cursor->handle, cursor->serial, cursor->rotation, cursor->size)); assert(cursor->size == sna->cursor.size); return cursor; } } } if (transformed) { struct pixman_box16 box; box.x1 = box.y1 = 0; box.x2 = sna->cursor.ref->bits->width; box.y2 = sna->cursor.ref->bits->height; pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box); size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1); } else size = sna->cursor.size; if (crtc->transform_in_use) RRTransformCompute(0, 0, size, size, crtc->rotation, crtc->transformPresent ? &crtc->transform : NULL, &cursor_to_fb, &to_sna_crtc(crtc)->cursor_to_fb, &to_sna_crtc(crtc)->fb_to_cursor); cursor = to_sna_crtc(crtc)->cursor; if (cursor && cursor->alloc < 4*size*size) cursor = NULL; if (cursor == NULL) { cursor = __sna_create_cursor(sna, 4*size*size); if (cursor == NULL) { DBG(("%s: failed to allocate cursor\n", __FUNCTION__)); return NULL; } } width = sna->cursor.ref->bits->width; height = sna->cursor.ref->bits->height; source = sna->cursor.ref->bits->source; mask = sna->cursor.ref->bits->mask; argb = get_cursor_argb(sna->cursor.ref); pitch = BitmapBytePad(width); image = cursor->image; if (image == NULL || transformed) { image = sna->cursor.scratch; cursor->last_width = cursor->last_height = size; } if (size > cursor->size || width < cursor->last_width || height < cursor->last_height || rotation != cursor->rotation) memset(image, 0, 4*size*size); if (rotation == RR_Rotate_0) { if (argb == NULL) { for (y = 0; y < height; y++) { uint32_t *p = image + y*size; for (x = 0; x < width; x++) { int byte = x / 8; uint8_t bit = 1 << (x & 7); uint32_t pixel; if (mask[byte] & bit) { if (source[byte] & bit) pixel = sna->cursor.fg; else pixel = sna->cursor.bg; } else pixel = 0; *p++ = pixel; } mask += pitch; source += pitch; } if (transformed) { affine_blt(image, cursor->image, 32, 0, 0, width, height, size * 4, 0, 0, size, size, size * 4, &to_sna_crtc(crtc)->cursor_to_fb); image = cursor->image; } } else if (transformed) { affine_blt(argb, cursor->image, 32, 0, 0, width, height, width * 4, 0, 0, size, size, size * 4, &to_sna_crtc(crtc)->cursor_to_fb); image = cursor->image; } else memcpy_blt(argb, image, 32, width * 4, size * 4, 0, 0, 0, 0, width, height); } else { for (y = 0; y < size; y++) for (x = 0; x < size; x++) { uint32_t pixel; int xin, yin; rotate_coord(rotation, size, x, y, &xin, &yin); if (xin < width && yin < height) if (argb == NULL) { int byte = xin / 8; int bit = xin & 7; if (mask[yin*pitch + byte] & (1 << bit)) { if (source[yin*pitch + byte] & (1 << bit)) pixel = sna->cursor.fg; else pixel = sna->cursor.bg; } else pixel = 0; } else pixel = argb[yin * width + xin]; else pixel = 0; image[y * size + x] = pixel; } } if (image != cursor->image) { struct drm_i915_gem_pwrite pwrite; VG_CLEAR(pwrite); pwrite.handle = cursor->handle; pwrite.offset = 0; pwrite.size = 4*size*size; pwrite.data_ptr = (uintptr_t)image; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite)) __DBG(("%s: cursor update (pwrite) failed: %d\n", __FUNCTION__, errno)); } cursor->size = size; cursor->rotation = rotation; cursor->transformed = transformed; cursor->serial = sna->cursor.serial; cursor->last_width = width; cursor->last_height = height; return cursor; } static unsigned char * sna_realize_cursor(xf86CursorInfoPtr info, CursorPtr cursor) { return NULL; } static void enable_fb_access(ScrnInfoPtr scrn, int state) { scrn->EnableDisableFBAccess( #ifdef XF86_HAS_SCRN_CONV scrn, #else scrn->scrnIndex, #endif state); } static void __restore_swcursor(ScrnInfoPtr scrn) { DBG(("%s: attempting to restore SW cursor\n", __FUNCTION__)); enable_fb_access(scrn, FALSE); enable_fb_access(scrn, TRUE); RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)__restore_swcursor, (WakeupHandlerProcPtr)NoopDDA, scrn); } static void restore_swcursor(struct sna *sna) { /* XXX Force the cursor to be restored (avoiding recursion) */ FreeCursor(sna->cursor.ref, None); sna->cursor.ref = NULL; RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)__restore_swcursor, (WakeupHandlerProcPtr)NoopDDA, sna->scrn); } static void sna_show_cursors(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); int sigio, c; DBG(("%s: cursor?=%d\n", __FUNCTION__, sna->cursor.ref != NULL)); if (sna->cursor.ref == NULL) return; sigio = sigio_block(); for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_cursor arg; struct sna_cursor *cursor; assert(sna_crtc != NULL); if (sna_crtc->bo == NULL) continue; if (!crtc->cursor_in_range) { DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); continue; } cursor = __sna_get_cursor(sna, crtc); if (cursor == NULL || (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) { DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc))); continue; } DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__, sna_crtc_pipe(crtc), cursor->handle)); VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = __sna_crtc_id(sna_crtc); arg.width = arg.height = cursor->size; arg.handle = cursor->handle; if (!FAIL_CURSOR_IOCTL && drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) { if (sna_crtc->cursor) { assert(sna_crtc->cursor->ref > 0); sna_crtc->cursor->ref--; } cursor->ref++; sna_crtc->cursor = cursor; sna_crtc->last_cursor_size = cursor->size; } else { ERR(("%s: failed to show cursor on CRTC:%d [pipe=%d], disabling hwcursor\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc))); sna->cursor.disable = true; } } sigio_unblock(sigio); sna->cursor.active = true; if (unlikely(sna->cursor.disable)) restore_swcursor(sna); } static void sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg) { struct sna *sna = to_sna(scrn); uint32_t fg = _fg, bg = _bg; __DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg)); /* Save ARGB versions of these colors */ fg |= 0xff000000; bg |= 0xff000000; if (fg == sna->cursor.fg && bg == sna->cursor.bg) return; sna->cursor.fg = fg; sna->cursor.bg = bg; if (sna->cursor.ref == NULL) return; if (get_cursor_argb(sna->cursor.ref)) return; sna->cursor.serial++; __DBG(("%s: serial->%d\n", __FUNCTION__, sna->cursor.serial)); sna_show_cursors(scrn); } static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc) { struct drm_mode_cursor arg; int sigio; if (!crtc->cursor) return; sigio = sigio_block(); if (crtc->cursor) { DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->cursor->handle)); assert(crtc->cursor->ref > 0); crtc->cursor->ref--; crtc->cursor = NULL; crtc->last_cursor_size = 0; VG_CLEAR(arg); arg.flags = DRM_MODE_CURSOR_BO; arg.crtc_id = __sna_crtc_id(crtc); arg.width = arg.height = 0; arg.handle = 0; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg); } sigio_unblock(sigio); } static void sna_disable_cursors(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); int sigio, c; DBG(("%s\n", __FUNCTION__)); sigio = sigio_block(); for (c = 0; c < sna->mode.num_real_crtc; c++) { assert(to_sna_crtc(xf86_config->crtc[c])); sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c])); } sigio_unblock(sigio); } static void sna_hide_cursors(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); struct sna_cursor *cursor, **prev; int sigio, c; DBG(("%s\n", __FUNCTION__)); sna->cursor.active = false; sigio = sigio_block(); for (c = 0; c < sna->mode.num_real_crtc; c++) { assert(to_sna_crtc(xf86_config->crtc[c])); sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c])); } for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) { assert(cursor->ref == 0); if (cursor->serial == sna->cursor.serial) { prev = &cursor->next; continue; } *prev = cursor->next; if (cursor->image) munmap(cursor->image, cursor->alloc); gem_close(sna->kgem.fd, cursor->handle); cursor->next = sna->cursor.stash; sna->cursor.stash = cursor; sna->cursor.num_stash++; } sigio_unblock(sigio); } static void sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); int sigio, c; __DBG(("%s(%d, %d), cursor? %d\n", __FUNCTION__, x, y, sna->cursor.ref!=NULL)); if (sna->cursor.ref == NULL) return; sigio = sigio_block(); sna->cursor.last_x = x; sna->cursor.last_y = y; /* undo what xf86HWCurs did to the coordinates */ x += scrn->frameX0; y += scrn->frameY0; for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct sna_cursor *cursor = NULL; struct drm_mode_cursor arg; assert(sna_crtc != NULL); VG_CLEAR(arg); arg.flags = 0; arg.crtc_id = __sna_crtc_id(sna_crtc); arg.handle = 0; if (sna_crtc->bo == NULL) goto disable; if (crtc->transform_in_use) { int xhot = sna->cursor.ref->bits->xhot; int yhot = sna->cursor.ref->bits->yhot; struct pict_f_vector v, hot; v.v[0] = x + xhot + .5; v.v[1] = y + yhot + .5; v.v[2] = 1.; pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v); hot.v[0] = xhot; hot.v[1] = yhot; hot.v[2] = 1.; pixman_f_transform_point(&sna_crtc->fb_to_cursor, &hot); arg.x = floor(v.v[0] - hot.v[0]); arg.y = floor(v.v[1] - hot.v[1]); } else { arg.x = x - crtc->x; arg.y = y - crtc->y; } if (arg.x < crtc->mode.HDisplay && arg.x > -sna->cursor.size && arg.y < crtc->mode.VDisplay && arg.y > -sna->cursor.size) { cursor = __sna_get_cursor(sna, crtc); if (cursor == NULL) cursor = sna_crtc->cursor; if (cursor == NULL) { __DBG(("%s: failed to grab cursor, disabling\n", __FUNCTION__)); goto disable; } if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) { arg.flags |= DRM_MODE_CURSOR_BO; arg.handle = cursor->handle; } arg.width = arg.height = cursor->size; arg.flags |= DRM_MODE_CURSOR_MOVE; crtc->cursor_in_range = true; } else { crtc->cursor_in_range = false; disable: if (sna_crtc->cursor) { arg.flags = DRM_MODE_CURSOR_BO; arg.width = arg.height = 0; } cursor = NULL; } __DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0, arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO)); if (arg.flags == 0) continue; if (!FAIL_CURSOR_IOCTL && drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) { if (arg.flags & DRM_MODE_CURSOR_BO) { if (sna_crtc->cursor) { assert(sna_crtc->cursor->ref > 0); sna_crtc->cursor->ref--; } sna_crtc->cursor = cursor; if (cursor) { sna_crtc->last_cursor_size = cursor->size; cursor->ref++; } else sna_crtc->last_cursor_size = 0; } } else { ERR(("%s: failed to update cursor on CRTC:%d [pipe=%d], disabling hwcursor\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc))); /* XXX How to force switch back to SW cursor? * Right now we just want until the next cursor image * change, which is fairly frequent. */ sna->cursor.disable = true; } } sigio_unblock(sigio); if (unlikely(sna->cursor.disable)) restore_swcursor(sna); } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2) static Bool sna_load_cursor_argb2(ScrnInfoPtr scrn, CursorPtr cursor) { return TRUE; } static Bool sna_load_cursor_image2(ScrnInfoPtr scrn, unsigned char *src) { return TRUE; } #endif static void sna_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor) { } static void sna_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src) { } static bool sna_cursor_preallocate(struct sna *sna) { while (sna->cursor.num_stash < 0) { struct sna_cursor *cursor = malloc(sizeof(*cursor)); if (!cursor) return false; cursor->next = sna->cursor.stash; sna->cursor.stash = cursor; sna->cursor.num_stash++; } return true; } static bool transformable_cursor(struct sna *sna, CursorPtr cursor) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct pixman_box16 box; int size; if (!to_sna_crtc(crtc)->hwcursor) { DBG(("%s: hwcursor disabled on CRTC:%d [pipe=%d]\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc))); return false; } if (!sna->cursor.use_gtt || !sna->cursor.scratch) { DBG(("%s: unable to use GTT curosor access [%d] or no scratch [%d]\n", __FUNCTION__, sna->cursor.use_gtt, sna->cursor.scratch)); return false; } box.x1 = box.y1 = 0; box.x2 = cursor->bits->width; box.y2 = cursor->bits->height; if (!pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box)) { DBG(("%s: unable to transform bounds\n", __FUNCTION__)); return false; } size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1); if (size > sna->cursor.max_size) { DBG(("%s: transformed cursor size=%d too large, max=%d\n", __FUNCTION__, size, sna->cursor.max_size)); return false; } } return true; } static Bool sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor) { struct sna *sna = to_sna_from_screen(screen); DBG(("%s (%dx%d)?\n", __FUNCTION__, cursor->bits->width, cursor->bits->height)); if (sna->cursor.disable) return FALSE; /* cursors are invariant */ if (cursor == sna->cursor.ref) return TRUE; if (sna->cursor.ref) { FreeCursor(sna->cursor.ref, None); sna->cursor.ref = NULL; } sna->cursor.size = __cursor_size(cursor->bits->width, cursor->bits->height); if (sna->cursor.size > sna->cursor.max_size) { DBG(("%s: cursor size=%d too large, max %d: using sw cursor\n", __FUNCTION__, sna->cursor.size, sna->cursor.max_size)); return FALSE; } if (sna->mode.rr_active && !transformable_cursor(sna, cursor)) { DBG(("%s: RandR active [%d] and non-transformable cursor: using sw cursor\n", __FUNCTION__, sna->mode.rr_active)); return FALSE; } if (!sna_cursor_preallocate(sna)) { DBG(("%s: cursor preallocation failed: using sw cursor\n", __FUNCTION__)); return FALSE; } sna->cursor.ref = cursor; cursor->refcnt++; sna->cursor.serial++; DBG(("%s(%dx%d): ARGB?=%d, serial->%d, size->%d\n", __FUNCTION__, cursor->bits->width, cursor->bits->height, get_cursor_argb(cursor) != NULL, sna->cursor.serial, sna->cursor.size)); return TRUE; } static void sna_cursor_pre_init(struct sna *sna) { struct local_get_cap { uint64_t name; uint64_t value; } cap; int v; if (sna->mode.num_real_crtc == 0) return; #define LOCAL_IOCTL_GET_CAP DRM_IOWR(0x0c, struct local_get_cap) #define DRM_CAP_CURSOR_WIDTH 8 #define DRM_CAP_CURSOR_HEIGHT 9 #define I915_PARAM_HAS_COHERENT_PHYS_GTT 29 sna->cursor.max_size = 64; cap.value = 0; cap.name = DRM_CAP_CURSOR_WIDTH; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0) sna->cursor.max_size = cap.value; cap.name = DRM_CAP_CURSOR_HEIGHT; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0 && cap.value < sna->cursor.max_size) sna->cursor.max_size = cap.value; v = -1; /* No param uses the sign bit, reserve it for errors */ if (sna->kgem.gen >= 033) { v = 1; } else { drm_i915_getparam_t gp = { I915_PARAM_HAS_COHERENT_PHYS_GTT, &v, }; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp); } sna->cursor.use_gtt = v > 0; DBG(("%s: cursor updates use_gtt?=%d\n", __FUNCTION__, sna->cursor.use_gtt)); sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4); if (!sna->cursor.scratch && !sna->cursor.use_gtt) sna->cursor.max_size = 0; sna->cursor.num_stash = -sna->mode.num_real_crtc; xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED, "Using a maximum size of %dx%d for hardware cursors\n", sna->cursor.max_size, sna->cursor.max_size); } static void sna_cursor_close(struct sna *sna) { sna->cursor.serial = 0; sna_hide_cursors(sna->scrn); while (sna->cursor.stash) { struct sna_cursor *cursor = sna->cursor.stash; sna->cursor.stash = cursor->next; free(cursor); } sna->cursor.num_stash = -sna->mode.num_real_crtc; } bool sna_cursors_init(ScreenPtr screen, struct sna *sna) { xf86CursorInfoPtr cursor_info; if (sna->cursor.max_size == 0) return false; cursor_info = xf86CreateCursorInfoRec(); if (cursor_info == NULL) return false; cursor_info->MaxWidth = sna->cursor.max_size; cursor_info->MaxHeight = sna->cursor.max_size; cursor_info->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_UPDATE_UNHIDDEN | HARDWARE_CURSOR_ARGB); cursor_info->RealizeCursor = sna_realize_cursor; cursor_info->SetCursorColors = sna_set_cursor_colors; cursor_info->SetCursorPosition = sna_set_cursor_position; cursor_info->LoadCursorImage = sna_load_cursor_image; cursor_info->HideCursor = sna_hide_cursors; cursor_info->ShowCursor = sna_show_cursors; cursor_info->UseHWCursor = sna_use_hw_cursor; #ifdef ARGB_CURSOR cursor_info->UseHWCursorARGB = sna_use_hw_cursor; cursor_info->LoadCursorARGB = sna_load_cursor_argb; #endif #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3) cursor_info->LoadCursorImageCheck = sna_load_cursor_image2; #ifdef ARGB_CURSOR cursor_info->LoadCursorARGBCheck = sna_load_cursor_argb2; #endif #endif if (!xf86InitCursor(screen, cursor_info)) { xf86DestroyCursorInfoRec(cursor_info); return false; } sna->cursor.info = cursor_info; return true; } static void sna_cursors_reload(struct sna *sna) { DBG(("%s: active?=%d\n", __FUNCTION__, sna->cursor.active)); if (sna->cursor.active) sna_set_cursor_position(sna->scrn, sna->cursor.last_x, sna->cursor.last_y); } static void sna_cursors_fini(struct sna *sna) { if (sna->cursor.info) { xf86DestroyCursorInfoRec(sna->cursor.info); sna->cursor.info = NULL; } if (sna->cursor.ref) { FreeCursor(sna->cursor.ref, None); sna->cursor.ref = NULL; } } static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); struct drm_mode_crtc arg; uint32_t output_ids[32]; int output_count = 0; int i; DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), bo->handle)); assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids)); assert(crtc->bo); assert(crtc->kmode.clock); for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != crtc->base) continue; DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n", __FUNCTION__, output->name, i, to_connector_id(output), __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), (uint32_t)output->possible_crtcs, (uint32_t)output->possible_clones)); assert(output->possible_crtcs & (1 << __sna_crtc_pipe(crtc)) || is_zaphod(sna->scrn)); output_ids[output_count] = to_connector_id(output); if (++output_count == ARRAY_SIZE(output_ids)) return false; } assert(output_count); VG_CLEAR(arg); arg.crtc_id = __sna_crtc_id(crtc); arg.fb_id = fb_id(bo); assert(arg.fb_id); arg.x = x; arg.y = y; arg.set_connectors_ptr = (uintptr_t)output_ids; arg.count_connectors = output_count; arg.mode = crtc->kmode; arg.mode_valid = 1; DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.mode.hdisplay, arg.mode.vdisplay, arg.x, arg.y, arg.mode.clock, arg.fb_id, output_count, output_count ? output_ids[0] : 0)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg)) return false; crtc->offset = y << 16 | x; return true; } static void sna_mode_restore(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int error = 0; int i; assert(!sna->mode.hidden); for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; assert(to_sna_crtc(crtc) != NULL); if (to_sna_crtc(crtc)->bo == NULL) continue; assert(crtc->enabled); if (!__sna_crtc_set_mode(crtc)) { sna_crtc_disable(crtc, false); error++; } } sna_mode_wakeup(sna); while (sna->mode.flip_active && sna_mode_wakeup(sna)) ; update_flush_interval(sna); sna_cursors_reload(sna); sna->mode.dirty = false; if (error) xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Failed to restore display configuration\n"); } int sna_page_flip(struct sna *sna, struct kgem_bo *bo, sna_flip_handler_t handler, void *data) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); const int width = sna->scrn->virtualX; const int height = sna->scrn->virtualY; int count = 0; int i; DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle)); assert(bo->refcnt); assert((sna->flags & SNA_IS_HOSTED) == 0); assert(sna->mode.flip_active == 0); assert(sna->mode.front_active); assert(!sna->mode.hidden); assert(sna->scrn->vtSema); if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0) return 0; kgem_bo_submit(&sna->kgem, bo); for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *crtc = config->crtc[i]->driver_private; struct drm_mode_crtc_page_flip arg; uint32_t crtc_offset; int fixup; DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n", __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL)); if (crtc->bo == NULL) continue; assert(!crtc->transform); assert(!crtc->slave_pixmap); assert(crtc->bo->active_scanout); assert(crtc->bo->refcnt >= crtc->bo->active_scanout); assert(crtc->flip_bo == NULL); if (data == NULL && crtc->bo == bo) goto next_crtc; arg.crtc_id = __sna_crtc_id(crtc); arg.fb_id = get_fb(sna, bo, width, height); if (arg.fb_id == 0) { assert(count == 0); return 0; } fixup = 0; crtc_offset = crtc->base->y << 16 | crtc->base->x; if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) { DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n", __FUNCTION__, bo->pitch, crtc->bo->pitch, crtc_offset, crtc->offset)); fixup_flip: fixup = 1; if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) { update_scanout: DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout, bo->handle, bo->active_scanout)); assert(crtc->bo->active_scanout); assert(crtc->bo->refcnt >= crtc->bo->active_scanout); crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, crtc->bo); if (crtc->shadow_bo) { kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); crtc->shadow_bo = NULL; } crtc->bo = kgem_bo_reference(bo); crtc->bo->active_scanout++; if (data == NULL) goto next_crtc; /* queue a flip in order to send the event */ } else goto error; } /* Only the reference crtc will finally deliver its page flip * completion event. All other crtc's events will be discarded. */ if (data) { arg.user_data = (uintptr_t)crtc; arg.flags = DRM_MODE_PAGE_FLIP_EVENT; } else { arg.user_data = 0; arg.flags = DRM_MODE_PAGE_FLIP_ASYNC; } arg.reserved = 0; retry_flip: DBG(("%s: crtc %d id=%d, pipe=%d --> fb %d\n", __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.fb_id)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno)); if (errno == EBUSY) { struct drm_mode_crtc mode; memset(&mode, 0, sizeof(mode)); mode.crtc_id = __sna_crtc_id(crtc); drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode); DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n", __FUNCTION__, mode.crtc_id, mode.mode_valid, mode.fb_id, fb_id(crtc->bo))); if (mode.fb_id != fb_id(crtc->bo)) goto fixup_flip; if (count == 0) return 0; DBG(("%s: throttling on busy flip / waiting for kernel to catch up\n", __FUNCTION__)); drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0); sna->kgem.need_throttle = false; goto retry_flip; } if (!fixup) goto fixup_flip; error: xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n", __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous"); if (count || crtc->bo == bo) sna_mode_restore(sna); sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP); return 0; } if (data) { assert(crtc->flip_bo == NULL); assert(handler); crtc->flip_handler = handler; crtc->flip_data = data; crtc->flip_bo = kgem_bo_reference(bo); crtc->flip_bo->active_scanout++; crtc->flip_serial = crtc->mode_serial; crtc->flip_pending = true; sna->mode.flip_active++; DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); } else goto update_scanout; next_crtc: count++; } DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count)); return count; } static const xf86CrtcConfigFuncsRec sna_mode_funcs = { sna_mode_resize }; static void set_size_range(struct sna *sna) { /* We lie slightly as we expect no single monitor to exceed the * crtc limits, so if the mode exceeds the scanout restrictions, * we will quietly convert that to per-crtc pixmaps. */ xf86CrtcSetSizeRange(sna->scrn, 8, 8, INT16_MAX, INT16_MAX); } #if HAS_GAMMA static void set_gamma(uint16_t *curve, int size, double value) { int i; value = 1/value; for (i = 0; i < size; i++) curve[i] = 256*(size-1)*pow(i/(double)(size-1), value); } static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { XF86ConfMonitorPtr mon = output->conf_monitor; if (!mon) return; DBG(("%s: red=%f\n", __FUNCTION__, mon->mon_gamma_red)); if (mon->mon_gamma_red >= GAMMA_MIN && mon->mon_gamma_red <= GAMMA_MAX && mon->mon_gamma_red != 1.0) set_gamma(crtc->gamma_red, crtc->gamma_size, mon->mon_gamma_red); DBG(("%s: green=%f\n", __FUNCTION__, mon->mon_gamma_green)); if (mon->mon_gamma_green >= GAMMA_MIN && mon->mon_gamma_green <= GAMMA_MAX && mon->mon_gamma_green != 1.0) set_gamma(crtc->gamma_green, crtc->gamma_size, mon->mon_gamma_green); DBG(("%s: blue=%f\n", __FUNCTION__, mon->mon_gamma_blue)); if (mon->mon_gamma_blue >= GAMMA_MIN && mon->mon_gamma_blue <= GAMMA_MAX && mon->mon_gamma_blue != 1.0) set_gamma(crtc->gamma_blue, crtc->gamma_size, mon->mon_gamma_blue); } static void crtc_init_gamma(xf86CrtcPtr crtc) { uint16_t *gamma; /* Initialize the gamma ramps */ gamma = NULL; if (crtc->gamma_size == 256) gamma = crtc->gamma_red; if (gamma == NULL) gamma = malloc(3 * 256 * sizeof(uint16_t)); if (gamma) { struct sna *sna = to_sna(crtc->scrn); struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_crtc_lut lut; bool gamma_set = false; assert(sna_crtc); lut.crtc_id = __sna_crtc_id(sna_crtc); lut.gamma_size = 256; lut.red = (uintptr_t)(gamma); lut.green = (uintptr_t)(gamma + 256); lut.blue = (uintptr_t)(gamma + 2 * 256); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) == 0) { VG(VALGRIND_MAKE_MEM_DEFINED(gamma, 3*256*sizeof(gamma[0]))); gamma_set = gamma[256 - 1] && gamma[2*256 - 1] && gamma[3*256 - 1]; } DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), gamma_set)); if (!gamma_set) { int i; for (i = 0; i < 256; i++) { gamma[i] = i << 8; gamma[256 + i] = i << 8; gamma[2*256 + i] = i << 8; } } if (gamma != crtc->gamma_red) { free(crtc->gamma_red); crtc->gamma_red = gamma; crtc->gamma_green = gamma + 256; crtc->gamma_blue = gamma + 2*256; crtc->gamma_size = 256; } } } #else static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { } static void crtc_init_gamma(xf86CrtcPtr crtc) { } #endif static const char *preferred_mode(xf86OutputPtr output) { const char *mode; mode = xf86GetOptValString(output->options, OPTION_PREFERRED_MODE); if (mode) return mode; if (output->scrn->display->modes && *output->scrn->display->modes) return *output->scrn->display->modes; return NULL; } static bool sna_probe_initial_configuration(struct sna *sna) { ScrnInfoPtr scrn = sna->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int crtc_active, crtc_enabled; int width, height; int i, j; assert((sna->flags & SNA_IS_HOSTED) == 0); if ((sna->flags & SNA_IS_SLAVED) == 0) { const int user_overrides[] = { OPTION_POSITION, OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF, OPTION_ROTATE, OPTION_PANNING, }; if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE)) { DBG(("%s: user requests reprobing\n", __FUNCTION__)); return false; } /* First scan through all outputs and look for user overrides */ for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; for (j = 0; j < ARRAY_SIZE(user_overrides); j++) { if (xf86GetOptValString(output->options, user_overrides[j])) { DBG(("%s: user placement [%d] for %s\n", __FUNCTION__, user_overrides[j], output->name)); return false; } } } } /* Copy the existing modes on each CRTCs */ crtc_active = crtc_enabled = 0; for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_crtc mode; crtc->enabled = FALSE; crtc->desiredMode.status = MODE_NOMODE; crtc_init_gamma(crtc); /* Retrieve the current mode */ VG_CLEAR(mode); mode.crtc_id = __sna_crtc_id(sna_crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), mode.mode_valid && mode.mode.clock)); if (!mode.mode_valid || mode.mode.clock == 0) continue; mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode); crtc->desiredRotation = sna_crtc->primary.rotation.current; crtc->desiredX = mode.x; crtc->desiredY = mode.y; crtc->desiredTransformPresent = FALSE; crtc_active++; } /* Reconstruct outputs pointing to active CRTC */ for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; uint32_t crtc_id; assert(to_sna_output(output)); crtc_id = (uintptr_t)output->crtc; output->crtc = NULL; output->status = XF86OutputStatusUnknown; if (sna->flags & SNA_IS_SLAVED) continue; if (crtc_id == 0) { DBG(("%s: not using output %s, disconnected\n", __FUNCTION__, output->name)); continue; } if (xf86ReturnOptValBool(output->options, OPTION_DISABLE, 0)) { DBG(("%s: not using output %s, manually disabled\n", __FUNCTION__, output->name)); continue; } for (j = 0; j < sna->mode.num_real_crtc; j++) { xf86CrtcPtr crtc = config->crtc[j]; assert(to_sna_crtc(crtc)); if (sna_crtc_id(crtc) != crtc_id) continue; if (crtc->desiredMode.status == MODE_OK) { DisplayModePtr M; const char *pref; pref = preferred_mode(output); if (pref && strcmp(pref, crtc->desiredMode.name)) { DBG(("%s: output %s user requests a different preferred mode %s, found %s\n", __FUNCTION__, output->name, pref, crtc->desiredMode.name)); return false; } xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Output %s using initial mode %s on pipe %d\n", output->name, crtc->desiredMode.name, sna_crtc_pipe(crtc)); output->crtc = crtc; output->status = XF86OutputStatusConnected; crtc->enabled = TRUE; crtc_enabled++; output_set_gamma(output, crtc); if (output->conf_monitor) { output->mm_width = output->conf_monitor->mon_width; output->mm_height = output->conf_monitor->mon_height; } #if 0 sna_output_attach_edid(output); sna_output_attach_tile(output); #endif if (output->mm_width == 0 || output->mm_height == 0) { output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI); output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI); } M = calloc(1, sizeof(DisplayModeRec)); if (M) { *M = crtc->desiredMode; M->name = strdup(M->name); output->probed_modes = xf86ModesAdd(output->probed_modes, M); } } break; } if (j == sna->mode.num_real_crtc) { /* Can not find the earlier associated CRTC, bail */ DBG(("%s: existing setup conflicts with output assignment (Zaphod), reprobing\n", __FUNCTION__)); return false; } } if (crtc_active != crtc_enabled) { DBG(("%s: only enabled %d out of %d active CRTC, forcing a reconfigure\n", __FUNCTION__, crtc_enabled, crtc_active)); return false; } width = height = 0; for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; int w, h; if (!crtc->enabled) continue; w = crtc->desiredX + crtc->desiredMode.HDisplay; if (w > width) width = w; h = crtc->desiredY + crtc->desiredMode.VDisplay; if (h > height) height = h; } /* Prefer the native panel size if any */ if (!width || !height) { for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; struct sna_output *sna_output = to_sna_output(output); if (!sna_output->is_panel) continue; DBG(("%s: querying panel '%s' for preferred unattached size\n", __FUNCTION__, output->name)); if (sna_output_detect(output) != XF86OutputStatusConnected) continue; if (sna_output->num_modes == 0) continue; width = sna_output->modes[0].hdisplay; height = sna_output->modes[0].vdisplay; DBG(("%s: panel '%s' is %dx%d\n", __FUNCTION__, output->name, width, height)); break; } } if (!width || !height) { width = 1024; height = 768; } scrn->display->frameX0 = 0; scrn->display->frameY0 = 0; scrn->display->virtualX = width; scrn->display->virtualY = height; scrn->virtualX = width; scrn->virtualY = height; xf86SetScrnInfoModes(sna->scrn); DBG(("%s: SetScrnInfoModes = %p\n", __FUNCTION__, scrn->modes)); return scrn->modes != NULL; } static void sanitize_outputs(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; for (i = 0; i < config->num_output; i++) config->output[i]->crtc = NULL; } static bool has_flip(struct sna *sna) { drm_i915_getparam_t gp; int v; if (sna->flags & SNA_NO_FLIP) return false; v = 0; VG_CLEAR(gp); gp.param = I915_PARAM_HAS_PAGEFLIPPING; gp.value = &v; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp)) return false; VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v))); return v > 0; } static bool has_flip__async(struct sna *sna) { #define DRM_CAP_ASYNC_PAGE_FLIP 0x7 struct local_get_cap { uint64_t name; uint64_t value; } cap = { DRM_CAP_ASYNC_PAGE_FLIP }; if (sna->flags & SNA_NO_FLIP) return false; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0) return cap.value > 0; return false; } static void probe_capabilities(struct sna *sna) { sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP); if (has_flip(sna)) sna->flags |= SNA_HAS_FLIP; if (has_flip__async(sna) && (sna->flags & SNA_TEAR_FREE) == 0) sna->flags |= SNA_HAS_ASYNC_FLIP; DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__, sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled", sna->flags & SNA_HAS_ASYNC_FLIP ? "enabled" : "disabled")); } void sna_crtc_config_notify(ScreenPtr screen) { struct sna *sna = to_sna_from_screen(screen); DBG(("%s(dirty?=%d)\n", __FUNCTION__, sna->mode.dirty)); if (!sna->mode.dirty) return; if (disable_unused_crtc(sna)) { /* This will have recursed, so simply bail at this point */ assert(sna->mode.dirty == false); #ifdef RANDR_12_INTERFACE xf86RandR12TellChanged(screen); #endif return; } /* Flush any events completed by the modeset */ sna_mode_wakeup(sna); update_flush_interval(sna); sna->cursor.disable = false; /* Reset HW cursor until the next fail */ sna_cursors_reload(sna); probe_capabilities(sna); sna_present_update(sna); sna->mode.dirty = false; } #if HAS_PIXMAP_SHARING #define sna_setup_provider(scrn) xf86ProviderSetup(scrn, NULL, "Intel") #else #define sna_setup_provider(scrn) #endif bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) { drmModeResPtr res; int num_fake = 0; int i; if (sna->flags & SNA_IS_HOSTED) { sna_setup_provider(scrn); return true; } probe_capabilities(sna); sna->mode.hidden = 1; if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake)) num_fake = 1; res = drmModeGetResources(sna->kgem.fd); if (res && (res->count_crtcs == 0 || res->count_encoders == 0 || res->count_connectors == 0)) { drmModeFreeResources(res); res = NULL; } if (res) { xf86CrtcConfigPtr xf86_config; DBG(("%s: found %d CRTC, %d encoders, %d connectors\n", __FUNCTION__, res->count_crtcs, res->count_encoders, res->count_connectors)); assert(res->count_crtcs); assert(res->count_connectors); xf86CrtcConfigInit(scrn, &sna_mode_funcs); xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86_config->xf86_crtc_notify = sna_crtc_config_notify; xf86_config->compat_output = 0; for (i = 0; i < res->count_crtcs; i++) if (!sna_crtc_add(scrn, res->crtcs[i])) return false; sna->mode.num_real_crtc = xf86_config->num_crtc; sna->mode.num_real_encoder = res->count_encoders; sna->mode.encoders = res->encoders; res->encoders = NULL; for (i = 0; i < res->count_connectors; i++) if (sna_output_add(sna, res->connectors[i], 0) < 0) return false; sna->mode.num_real_output = xf86_config->num_output; sna->mode.max_crtc_width = res->max_width; sna->mode.max_crtc_height = res->max_height; RegionEmpty(&sna->mode.shadow_region); RegionEmpty(&sna->mode.shadow_cancel); list_init(&sna->mode.shadow_crtc); drmModeFreeResources(res); sna_cursor_pre_init(sna); sna_backlight_pre_init(sna); set_size_range(sna); } else { if (num_fake == 0) num_fake = 1; } if (!sna_mode_fake_init(sna, num_fake)) return false; if (!sna_probe_initial_configuration(sna)) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); sanitize_outputs(sna); if (config->num_crtc && config->num_output) { if (!xf86ReturnOptValBool(config->output[0]->options, OPTION_PRIMARY, FALSE)) sort_config_outputs(sna); xf86InitialConfiguration(scrn, TRUE); } } sort_config_outputs(sna); TimerSet(NULL, 0, COLDPLUG_DELAY_MS, sna_mode_coldplug, sna); sna_setup_provider(scrn); return scrn->modes != NULL; } bool sna_mode_wants_tear_free(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); bool found = false; FILE *file; int i; file = fopen("/sys/module/i915/parameters/enable_fbc", "r"); if (file) { int fbc_enabled = 0; int value; if (fscanf(file, "%d", &value) == 1) fbc_enabled = value > 0; fclose(file); DBG(("%s: module parameter 'enable_fbc' enabled? %d\n", __FUNCTION__, fbc_enabled)); if (fbc_enabled) return true; } for (i = 0; i < sna->mode.num_real_output; i++) { struct sna_output *output = to_sna_output(config->output[i]); int id = find_property(sna, output, "Panel Self-Refresh"); if (id == -1) continue; found = true; if (output->prop_values[id] != -1) { DBG(("%s: Panel Self-Refresh detected on %s\n", __FUNCTION__, config->output[i]->name)); return true; } } if (!found) { file = fopen("/sys/module/i915/parameters/enable_psr", "r"); if (file) { int psr_enabled = 0; int value; if (fscanf(file, "%d", &value) == 1) psr_enabled = value > 0; fclose(file); DBG(("%s: module parameter 'enable_psr' enabled? %d\n", __FUNCTION__, psr_enabled)); if (psr_enabled) return true; } } return false; } void sna_mode_set_primary(struct sna *sna) { #ifdef RANDR_12_INTERFACE xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); int i; if (rr == NULL || rr->primaryOutput) return; for (i = 0; i < sna->mode.num_real_output; i++) { xf86OutputPtr output = config->output[i]; if (!xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) continue; DBG(("%s: setting PrimaryOutput %s\n", __FUNCTION__, output->name)); rr->primaryOutput = output->randr_output; RROutputChanged(rr->primaryOutput, FALSE); rr->layoutChanged = TRUE; break; } #endif } bool sna_mode_disable(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; if (sna->flags & SNA_IS_HOSTED) return false; if (!sna->scrn->vtSema) return false; sna_disable_cursors(sna->scrn); for (i = 0; i < sna->mode.num_real_crtc; i++) sna_crtc_disable(config->crtc[i], false); assert(sna->mode.front_active == 0); sna_mode_wakeup(sna); kgem_clean_scanout_cache(&sna->kgem); return true; } void sna_mode_enable(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; DBG(("%s\n", __FUNCTION__)); if (sna->flags & SNA_IS_HOSTED) return; if (!sna->scrn->vtSema) return; if (sna->mode.hidden) { DBG(("%s: hidden outputs\n", __FUNCTION__)); return; } for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; DBG(("%s: crtc[%d].enabled?=%d\n", __FUNCTION__, i, crtc->enabled)); assert(to_sna_crtc(crtc) != NULL); if (!crtc->enabled) continue; if (crtc->mode.Clock == 0) continue; __sna_crtc_set_mode(crtc); } update_flush_interval(sna); sna_cursors_reload(sna); sna->mode.dirty = false; } static void sna_randr_close(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int n; /* The RR structs are freed early during CloseScreen as they * are tracked as Resources. However, we may be tempted to * access them during shutdown so decouple them now. */ for (n = 0; n < config->num_output; n++) config->output[n]->randr_output = NULL; for (n = 0; n < config->num_crtc; n++) config->crtc[n]->randr_crtc = NULL; } void sna_mode_close(struct sna *sna) { sna_randr_close(sna); sna_mode_wakeup(sna); if (sna->flags & SNA_IS_HOSTED) return; sna_mode_reset(sna); sna_cursor_close(sna); sna_cursors_fini(sna); sna_backlight_close(sna); sna->mode.dirty = false; } void sna_mode_fini(struct sna *sna) { free(sna->mode.encoders); } static bool sna_box_intersect(BoxPtr r, const BoxRec *a, const BoxRec *b) { r->x1 = a->x1 > b->x1 ? a->x1 : b->x1; r->x2 = a->x2 < b->x2 ? a->x2 : b->x2; if (r->x1 >= r->x2) return false; r->y1 = a->y1 > b->y1 ? a->y1 : b->y1; r->y2 = a->y2 < b->y2 ? a->y2 : b->y2; DBG(("%s: (%d, %d), (%d, %d) intersect (%d, %d), (%d, %d) = (%d, %d), (%d, %d)\n", __FUNCTION__, a->x1, a->y1, a->x2, a->y2, b->x1, b->y1, b->x2, b->y2, r->x1, r->y1, r->x2, r->y2)); if (r->y1 >= r->y2) return false; return true; } static int sna_box_area(const BoxRec *box) { return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1); } /* * Return the crtc covering 'box'. If two crtcs cover a portion of * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc * with greater coverage */ xf86CrtcPtr sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); xf86CrtcPtr best_crtc = NULL; int best_coverage = -1, c; if (sna->flags & SNA_IS_HOSTED) return NULL; /* If we do not own the VT, we do not own the CRTC either */ if (!sna->scrn->vtSema) { DBG(("%s: none, VT switched\n", __FUNCTION__)); return NULL; } if (sna->mode.hidden) { DBG(("%s: none, hidden outputs\n", __FUNCTION__)); return NULL; } DBG(("%s for box=(%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); if (desired == NULL) { rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); if (rr && rr->primaryOutput) { xf86OutputPtr output = rr->primaryOutput->devPrivate; DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL)); desired = output->crtc; } } if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) { BoxRec cover_box; if (sna_box_intersect(&cover_box, &desired->bounds, box)) { DBG(("%s: box overlaps desired crtc: (%d, %d), (%d, %d)\n", __FUNCTION__, cover_box.x1, cover_box.y1, cover_box.x2, cover_box.y2)); return desired; } best_crtc = desired; best_coverage = 0; } for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; BoxRec cover_box; int coverage; assert(to_sna_crtc(crtc)); /* If the CRTC is off, treat it as not covering */ if (to_sna_crtc(crtc)->bo == NULL) { DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c)); continue; } DBG(("%s: crtc %d: (%d, %d), (%d, %d)\n", __FUNCTION__, c, crtc->bounds.x1, crtc->bounds.y1, crtc->bounds.x2, crtc->bounds.y2)); if (*(const uint64_t *)box == *(uint64_t *)&crtc->bounds) { DBG(("%s: box exactly matches crtc [%d]\n", __FUNCTION__, c)); return crtc; } if (!sna_box_intersect(&cover_box, &crtc->bounds, box)) continue; DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n", __FUNCTION__, cover_box.x1, cover_box.y1, cover_box.x2, cover_box.y2, c)); coverage = sna_box_area(&cover_box); DBG(("%s: box covers %d of crtc %d\n", __FUNCTION__, coverage, c)); if (coverage > best_coverage) { best_crtc = crtc; best_coverage = coverage; } } DBG(("%s: best crtc = %p, coverage = %d\n", __FUNCTION__, best_crtc, best_coverage)); return best_crtc; } xf86CrtcPtr sna_primary_crtc(struct sna *sna) { rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn)); if (rr && rr->primaryOutput) { xf86OutputPtr output = rr->primaryOutput->devPrivate; if (output->crtc && to_sna_crtc(output->crtc)) return output->crtc; } if (sna->mode.num_real_crtc) return XF86_CRTC_CONFIG_PTR(sna->scrn)->crtc[0]; return NULL; } #define MI_LOAD_REGISTER_IMM (0x22<<23) static bool sna_emit_wait_for_scanline_hsw(struct sna *sna, xf86CrtcPtr crtc, int pipe, int y1, int y2, bool full_height) { uint32_t event; uint32_t *b; if (!sna->kgem.has_secure_batches) return false; b = kgem_get_batch(&sna->kgem); sna->kgem.nbatch += 17; switch (pipe) { default: assert(0); case 0: event = 1 << 0; break; case 1: event = 1 << 8; break; case 2: event = 1 << 14; break; } b[0] = MI_LOAD_REGISTER_IMM | 1; b[1] = 0x44050; /* DERRMR */ b[2] = ~event; b[3] = MI_LOAD_REGISTER_IMM | 1; b[4] = 0xa188; /* FORCEWAKE_MT */ b[5] = 2 << 16 | 2; /* The documentation says that the LOAD_SCAN_LINES command * always comes in pairs. Don't ask me why. */ switch (pipe) { default: assert(0); case 0: event = 0 << 19; break; case 1: event = 1 << 19; break; case 2: event = 4 << 19; break; } b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event; b[9] = b[7] = (y1 << 16) | (y2-1); switch (pipe) { default: assert(0); case 0: event = 1 << 0; break; case 1: event = 1 << 8; break; case 2: event = 1 << 14; break; } b[10] = MI_WAIT_FOR_EVENT | event; b[11] = MI_LOAD_REGISTER_IMM | 1; b[12] = 0xa188; /* FORCEWAKE_MT */ b[13] = 2 << 16; b[14] = MI_LOAD_REGISTER_IMM | 1; b[15] = 0x44050; /* DERRMR */ b[16] = ~0; sna->kgem.batch_flags |= I915_EXEC_SECURE; return true; } static bool sna_emit_wait_for_scanline_ivb(struct sna *sna, xf86CrtcPtr crtc, int pipe, int y1, int y2, bool full_height) { uint32_t event, *b; if (!sna->kgem.has_secure_batches) return false; assert(y1 >= 0); assert(y2 > y1); assert(sna->kgem.mode); /* Always program one less than the desired value */ if (--y1 < 0) y1 = crtc->bounds.y2; y2--; switch (pipe) { default: assert(0); case 0: event = 1 << (full_height ? 3 : 0); break; case 1: event = 1 << (full_height ? 11 : 8); break; case 2: event = 1 << (full_height ? 21 : 14); break; } b = kgem_get_batch(&sna->kgem); /* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */ if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) { int dw = sna->kgem.nbatch + 6; dw = ALIGN(dw, 16) - dw; while (dw--) *b++ = MI_NOOP; } b[0] = MI_LOAD_REGISTER_IMM | 1; b[1] = 0x44050; /* DERRMR */ b[2] = ~event; b[3] = MI_LOAD_REGISTER_IMM | 1; b[4] = 0xa188; /* FORCEWAKE_MT */ b[5] = 2 << 16 | 2; b[6] = MI_LOAD_REGISTER_IMM | 1; b[7] = 0x70068 + 0x1000 * pipe; b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2; b[9] = MI_WAIT_FOR_EVENT | event; b[10] = MI_LOAD_REGISTER_IMM | 1; b[11] = 0xa188; /* FORCEWAKE_MT */ b[12] = 2 << 16; b[13] = MI_LOAD_REGISTER_IMM | 1; b[14] = 0x44050; /* DERRMR */ b[15] = ~0; sna->kgem.nbatch = b - sna->kgem.batch + 16; sna->kgem.batch_flags |= I915_EXEC_SECURE; return true; } static bool sna_emit_wait_for_scanline_gen6(struct sna *sna, xf86CrtcPtr crtc, int pipe, int y1, int y2, bool full_height) { uint32_t *b; uint32_t event; if (!sna->kgem.has_secure_batches) return false; assert(y1 >= 0); assert(y2 > y1); assert(sna->kgem.mode == KGEM_RENDER); /* Always program one less than the desired value */ if (--y1 < 0) y1 = crtc->bounds.y2; y2--; /* The scanline granularity is 3 bits */ y1 &= ~7; y2 &= ~7; if (y2 == y1) return false; event = 1 << (3*full_height + pipe*8); b = kgem_get_batch(&sna->kgem); sna->kgem.nbatch += 16; b[0] = MI_LOAD_REGISTER_IMM | 1; b[1] = 0x44050; /* DERRMR */ b[2] = ~event; b[3] = MI_LOAD_REGISTER_IMM | 1; b[4] = 0x4f100; /* magic */ b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2; b[6] = MI_LOAD_REGISTER_IMM | 1; b[7] = 0x2050; /* PSMI_CTL(rcs) */ b[8] = 1 << 16 | 1; b[9] = MI_WAIT_FOR_EVENT | event; b[10] = MI_LOAD_REGISTER_IMM | 1; b[11] = 0x2050; /* PSMI_CTL(rcs) */ b[12] = 1 << 16; b[13] = MI_LOAD_REGISTER_IMM | 1; b[14] = 0x44050; /* DERRMR */ b[15] = ~0; sna->kgem.batch_flags |= I915_EXEC_SECURE; return true; } static bool sna_emit_wait_for_scanline_gen4(struct sna *sna, xf86CrtcPtr crtc, int pipe, int y1, int y2, bool full_height) { uint32_t event; uint32_t *b; if (pipe == 0) { if (full_height) event = MI_WAIT_FOR_PIPEA_SVBLANK; else event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; } else { if (full_height) event = MI_WAIT_FOR_PIPEB_SVBLANK; else event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; } b = kgem_get_batch(&sna->kgem); sna->kgem.nbatch += 5; /* The documentation says that the LOAD_SCAN_LINES command * always comes in pairs. Don't ask me why. */ b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20; b[3] = b[1] = (y1 << 16) | (y2-1); b[4] = MI_WAIT_FOR_EVENT | event; return true; } static bool sna_emit_wait_for_scanline_gen2(struct sna *sna, xf86CrtcPtr crtc, int pipe, int y1, int y2, bool full_height) { uint32_t *b; /* * Pre-965 doesn't have SVBLANK, so we need a bit * of extra time for the blitter to start up and * do its job for a full height blit */ if (full_height) y2 -= 2; b = kgem_get_batch(&sna->kgem); sna->kgem.nbatch += 5; /* The documentation says that the LOAD_SCAN_LINES command * always comes in pairs. Don't ask me why. */ b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20; b[3] = b[1] = (y1 << 16) | (y2-1); b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe); return true; } bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap, xf86CrtcPtr crtc, const BoxRec *clip) { bool full_height; int y1, y2, pipe; bool ret; assert(crtc != NULL); assert(to_sna_crtc(crtc) != NULL); assert(to_sna_crtc(crtc)->bo != NULL); assert(pixmap == sna->front); if (sna->flags & SNA_NO_VSYNC) return false; /* * Make sure we don't wait for a scanline that will * never occur */ y1 = clip->y1 - crtc->bounds.y1; if (y1 < 0) y1 = 0; y2 = clip->y2 - crtc->bounds.y1; if (y2 > crtc->bounds.y2 - crtc->bounds.y1) y2 = crtc->bounds.y2 - crtc->bounds.y1; DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2)); if (y2 <= y1 + 4) return false; full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1; if (crtc->mode.Flags & V_INTERLACE) { /* DSL count field lines */ y1 /= 2; y2 /= 2; } pipe = sna_crtc_pipe(crtc); DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n", __FUNCTION__, pipe, y1, y2, full_height)); if (sna->kgem.gen >= 0110) ret = false; else if (sna->kgem.gen == 0101) ret = false; /* chv, vsync method unknown */ else if (sna->kgem.gen >= 075) ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height); else if (sna->kgem.gen == 071) ret = false; /* vlv, vsync method unknown */ else if (sna->kgem.gen >= 070) ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height); else if (sna->kgem.gen >= 060) ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height); else if (sna->kgem.gen >= 040) ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height); else ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height); return ret; } static bool sna_mode_shutdown_crtc(xf86CrtcPtr crtc) { struct sna *sna = to_sna(crtc->scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); bool disabled = false; int o; xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: invalid state found on pipe %d, disabling CRTC:%d\n", __FUNCTION__, __sna_crtc_pipe(to_sna_crtc(crtc)), __sna_crtc_id(to_sna_crtc(crtc))); sna_crtc_disable(crtc, true); #if XF86_CRTC_VERSION >= 3 crtc->active = FALSE; #endif if (crtc->enabled) { crtc->enabled = FALSE; disabled = true; } for (o = 0; o < sna->mode.num_real_output; o++) { xf86OutputPtr output = config->output[o]; if (output->crtc != crtc) continue; output->funcs->dpms(output, DPMSModeOff); output->crtc = NULL; } return disabled; } static xf86CrtcPtr lookup_crtc_by_id(struct sna *sna, int id) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int c; for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; if (__sna_crtc_id(to_sna_crtc(crtc)) == id) return crtc; } return NULL; } static int plane_type(struct sna *sna, int id) { struct local_mode_obj_get_properties arg; uint64_t stack_props[24]; uint32_t *props = (uint32_t *)stack_props; uint64_t *values = stack_props + 8; int i, type = -1; memset(&arg, 0, sizeof(struct local_mode_obj_get_properties)); arg.obj_id = id; arg.obj_type = LOCAL_MODE_OBJECT_PLANE; arg.props_ptr = (uintptr_t)props; arg.prop_values_ptr = (uintptr_t)values; arg.count_props = 16; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) return -1; DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__, id, LOCAL_MODE_OBJECT_PLANE, arg.count_props)); if (arg.count_props > 16) { props = malloc(2*sizeof(uint64_t)*arg.count_props); if (props == NULL) return -1; values = (uint64_t *)props + arg.count_props; arg.props_ptr = (uintptr_t)props; arg.prop_values_ptr = (uintptr_t)values; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg)) arg.count_props = 0; } VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props)); VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props)); for (i = 0; i < arg.count_props; i++) { struct drm_mode_get_property prop; memset(&prop, 0, sizeof(prop)); prop.prop_id = props[i]; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) { ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n", __FUNCTION__, i, props[i], errno)); continue; } DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i, (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i])); if (strcmp(prop.name, "type") == 0) { type = values[i]; break; } } if (props != (uint32_t *)stack_props) free(props); return type; } static bool sna_mode_disable_secondary_planes(struct sna *sna) { struct local_mode_get_plane_res r; uint32_t stack_planes[64]; uint32_t *planes = stack_planes; bool disabled = false; int i; VG_CLEAR(r); r.plane_id_ptr = (uintptr_t)planes; r.count_planes = ARRAY_SIZE(stack_planes); if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) return false; DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes)); if (r.count_planes > ARRAY_SIZE(stack_planes)) { planes = malloc(sizeof(uint32_t)*r.count_planes); if (planes == NULL) return false; r.plane_id_ptr = (uintptr_t)planes; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) r.count_planes = 0; } VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes)); for (i = 0; i < r.count_planes; i++) { struct local_mode_get_plane p; struct local_mode_set_plane s; VG_CLEAR(p); p.plane_id = planes[i]; p.count_format_types = 0; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p)) continue; if (p.fb_id == 0 || p.crtc_id == 0) continue; if (plane_type(sna, p.plane_id) == DRM_PLANE_TYPE_PRIMARY) continue; memset(&s, 0, sizeof(s)); s.plane_id = p.plane_id; s.crtc_id = p.crtc_id; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) { xf86CrtcPtr crtc = lookup_crtc_by_id(sna, p.crtc_id); if (crtc) disabled |= sna_mode_shutdown_crtc(crtc); } } if (planes != stack_planes) free(planes); return disabled; } void sna_mode_check(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); bool disabled; int c, o; if (sna->flags & SNA_IS_HOSTED) return; DBG(("%s: hidden?=%d\n", __FUNCTION__, sna->mode.hidden)); if (sna->mode.hidden) return; disabled = sna_mode_disable_secondary_planes(sna); /* Validate CRTC attachments and force consistency upon the kernel */ for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct drm_mode_crtc mode; uint32_t expected[2]; assert(sna_crtc); #if XF86_CRTC_VERSION >= 3 assert(sna_crtc->bo == NULL || crtc->active); #endif expected[0] = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0; expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1; VG_CLEAR(mode); mode.crtc_id = __sna_crtc_id(sna_crtc); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) continue; DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=(%d or %d)\n", __FUNCTION__, mode.crtc_id, mode.mode_valid, mode.fb_id, expected[0], expected[1])); if (mode.fb_id != expected[0] && mode.fb_id != expected[1]) disabled |= sna_mode_shutdown_crtc(crtc); } for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; struct sna_output *sna_output; if (output->crtc) continue; sna_output = to_sna_output(output); if (sna_output == NULL) continue; sna_output->dpms_mode = DPMSModeOff; } update_flush_interval(sna); if (disabled) xf86RandR12TellChanged(xf86ScrnToScreen(sna->scrn)); } static bool sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc) { struct local_mode_set_plane s; if (crtc->primary.id == 0) return false; memset(&s, 0, sizeof(s)); s.plane_id = crtc->primary.id; if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) return false; s.plane_id = crtc->sprite.id; (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); __sna_crtc_disable(sna, crtc); return true; } void sna_mode_reset(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; if (sna->flags & SNA_IS_HOSTED) return; DBG(("%s\n", __FUNCTION__)); sna_disable_cursors(sna->scrn); for (i = 0; i < sna->mode.num_real_crtc; i++) if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i]))) sna_crtc_disable(config->crtc[i], true); assert(sna->mode.front_active == 0); for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]); assert(sna_crtc != NULL); /* Force the rotation property to be reset on next use */ rotation_reset(&sna_crtc->primary); rotation_reset(&sna_crtc->sprite); } /* VT switching, likely to be fbcon so make the backlight usable */ for (i = 0; i < sna->mode.num_real_output; i++) { struct sna_output *sna_output = to_sna_output(config->output[i]); assert(sna_output != NULL); if (sna_output->dpms_mode != DPMSModeOff) continue; if (!sna_output->backlight.iface) continue; sna_output_backlight_set(sna_output, sna_output->backlight_active_level); } /* drain the event queue */ sna_mode_wakeup(sna); } static void transformed_box(BoxRec *box, xf86CrtcPtr crtc) { box->x1 -= crtc->filter_width >> 1; box->x2 += crtc->filter_width >> 1; box->y1 -= crtc->filter_height >> 1; box->y2 += crtc->filter_height >> 1; pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box); if (box->x1 < 0) box->x1 = 0; if (box->y1 < 0) box->y1 = 0; if (box->x2 > crtc->mode.HDisplay) box->x2 = crtc->mode.HDisplay; if (box->y2 > crtc->mode.VDisplay) box->y2 = crtc->mode.VDisplay; } inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); if (sna_crtc->slave_pixmap) { DBG(("%s: using slave pixmap=%ld, offset (%d, %d)\n", __FUNCTION__, sna_crtc->slave_pixmap->drawable.serialNumber, -crtc->x, -crtc->y)); *sx = -crtc->x; *sy = -crtc->y; return &sna_crtc->slave_pixmap->drawable; } else { DBG(("%s: using Screen pixmap=%ld\n", __FUNCTION__, to_sna(crtc->scrn)->front->drawable.serialNumber)); *sx = *sy = 0; return &to_sna(crtc->scrn)->front->drawable; } } static void sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) { int16_t sx, sy; struct sna *sna = to_sna(crtc->scrn); ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); DrawablePtr draw = crtc_source(crtc, &sx, &sy); PictFormatPtr format; PictTransform T; PicturePtr src, dst; PixmapPtr pixmap; int depth, error; void *ptr; DBG(("%s: compositing transformed damage boxes, target handle=%d\n", __FUNCTION__, bo->handle)); error = sna_render_format_for_depth(draw->depth); depth = PIXMAN_FORMAT_DEPTH(error); format = PictureMatchFormat(screen, depth, error); if (format == NULL) { DBG(("%s: can't find format for depth=%d [%08x]\n", __FUNCTION__, depth, error)); return; } DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n", __FUNCTION__, format->format, depth, draw->bitsPerPixel, bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay)); if (sx | sy) RegionTranslate(region, sx, sy); error = !sna_drawable_move_region_to_cpu(draw, region, MOVE_READ); if (sx | sy) RegionTranslate(region, -sx, -sy); if (error) return; ptr = kgem_bo_map__gtt(&sna->kgem, bo); if (ptr == NULL) return; pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); if (pixmap == NullPixmap) return; if (!screen->ModifyPixmapHeader(pixmap, crtc->mode.HDisplay, crtc->mode.VDisplay, depth, draw->bitsPerPixel, bo->pitch, ptr)) goto free_pixmap; src = CreatePicture(None, draw, format, 0, NULL, serverClient, &error); if (!src) goto free_pixmap; pixman_transform_init_translate(&T, sx << 16, sy << 16); pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer); if (!sna_transform_is_integer_translation(&T, &sx, &sy)) { #define f2d(x) (((double)(x))/65536.) DBG(("%s: transform=[[%f %f %f], [%f %f %f], [%f %f %f]] (raw [[%x %x %x], [%x %x %x], [%x %x %x]])\n", __FUNCTION__, f2d(T.matrix[0][0]), f2d(T.matrix[0][1]), f2d(T.matrix[0][2]), f2d(T.matrix[1][0]), f2d(T.matrix[1][1]), f2d(T.matrix[1][2]), f2d(T.matrix[2][0]), f2d(T.matrix[2][1]), f2d(T.matrix[2][2]), T.matrix[0][0], T.matrix[0][1], T.matrix[0][2], T.matrix[1][0], T.matrix[1][1], T.matrix[1][2], T.matrix[2][0], T.matrix[2][1], T.matrix[2][2])); #undef f2d error = SetPictureTransform(src, &T); if (error) goto free_src; sx = sy = 0; } if (crtc->filter && crtc->transform_in_use) SetPicturePictFilter(src, crtc->filter, crtc->params, crtc->nparams); dst = CreatePicture(None, &pixmap->drawable, format, 0, NULL, serverClient, &error); if (!dst) goto free_src; kgem_bo_sync__gtt(&sna->kgem, bo); if (sigtrap_get() == 0) { /* paranoia */ const BoxRec *b = region_rects(region); int n = region_num_rects(region); do { BoxRec box; box = *b++; transformed_box(&box, crtc); DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", __FUNCTION__, b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1, box.x1, box.y1, box.x2, box.y2)); fbComposite(PictOpSrc, src, NULL, dst, box.x1 + sx, box.y1 + sy, 0, 0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } while (--n); sigtrap_put(); } FreePicture(dst, None); free_src: FreePicture(src, None); free_pixmap: screen->DestroyPixmap(pixmap); } static void sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) { int16_t sx, sy; struct sna *sna = to_sna(crtc->scrn); ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); DrawablePtr draw = crtc_source(crtc, &sx, &sy); struct sna_composite_op tmp; PictFormatPtr format; PictTransform T; PicturePtr src, dst; PixmapPtr pixmap; const BoxRec *b; int n, depth, error; DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__)); error = sna_render_format_for_depth(draw->depth); depth = PIXMAN_FORMAT_DEPTH(error); format = PictureMatchFormat(screen, depth, error); if (format == NULL) { DBG(("%s: can't find format for depth=%d [%08x]\n", __FUNCTION__, depth, error)); return; } DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n", __FUNCTION__, format->format, depth, draw->bitsPerPixel, bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay)); pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); if (pixmap == NullPixmap) return; if (!screen->ModifyPixmapHeader(pixmap, crtc->mode.HDisplay, crtc->mode.VDisplay, depth, draw->bitsPerPixel, bo->pitch, NULL)) goto free_pixmap; if (!sna_pixmap_attach_to_bo(pixmap, kgem_bo_reference(bo))) { kgem_bo_destroy(&sna->kgem, bo); goto free_pixmap; } src = CreatePicture(None, draw, format, 0, NULL, serverClient, &error); if (!src) goto free_pixmap; pixman_transform_init_translate(&T, sx << 16, sy << 16); pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer); if (!sna_transform_is_integer_translation(&T, &sx, &sy)) { error = SetPictureTransform(src, &T); if (error) goto free_src; sx = sy = 0; } if (crtc->filter && crtc->transform_in_use) SetPicturePictFilter(src, crtc->filter, crtc->params, crtc->nparams); dst = CreatePicture(None, &pixmap->drawable, format, 0, NULL, serverClient, &error); if (!dst) goto free_src; ValidatePicture(src); ValidatePicture(dst); /* Composite each box individually as if we are dealing with a rotation * on a large display, we may have to perform intermediate copies. We * can then minimise the overdraw by looking at individual boxes rather * than the bbox. */ n = region_num_rects(region); b = region_rects(region); do { BoxRec box = *b; transformed_box(&box, crtc); DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n", __FUNCTION__, b->x1, b->y1, b->x2-b->x1, b->y2-b->y1, box.x1, box.y1, box.x2, box.y2)); if (!sna->render.composite(sna, PictOpSrc, src, NULL, dst, sx + box.x1, sy + box.y1, 0, 0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, 0, memset(&tmp, 0, sizeof(tmp)))) { DBG(("%s: unsupported operation!\n", __FUNCTION__)); sna_crtc_redisplay__fallback(crtc, region, bo); break; } else { tmp.box(sna, &tmp, &box); tmp.done(sna, &tmp); } } while (b++, --n); FreePicture(dst, None); free_src: FreePicture(src, None); free_pixmap: screen->DestroyPixmap(pixmap); } static void sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo) { int16_t tx, ty, sx, sy; struct sna *sna = to_sna(crtc->scrn); DrawablePtr draw = crtc_source(crtc, &sx, &sy); struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw); DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region))); assert(!wedged(sna)); if (priv->clear) { RegionRec whole; DBG(("%s: clear damage boxes\n", __FUNCTION__)); if (sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer, &tx, &ty)) { RegionTranslate(region, -tx, -ty); } else { whole.extents = region->extents; whole.data = NULL; transformed_box(&whole.extents, crtc); region = &whole; } if (sna_blt_fill_boxes(sna, GXcopy, bo, draw->bitsPerPixel, priv->clear_color, region_rects(region), region_num_rects(region))) return; } if (crtc->filter == NULL && priv->gpu_bo && priv->cpu_damage == NULL && sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer, &tx, &ty)) { DrawableRec tmp; DBG(("%s: copy damage boxes\n", __FUNCTION__)); tmp.width = crtc->mode.HDisplay; tmp.height = crtc->mode.VDisplay; tmp.depth = sna->front->drawable.depth; tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; if (sna->render.copy_boxes(sna, GXcopy, draw, priv->gpu_bo, sx, sy, &tmp, bo, -tx, -ty, region_rects(region), region_num_rects(region), 0)) return; } if (can_render(sna)) sna_crtc_redisplay__composite(crtc, region, bo); else sna_crtc_redisplay__fallback(crtc, region, bo); } static void shadow_flip_handler(struct drm_event_vblank *e, void *data) { sna_mode_redisplay(data); } void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); struct sna_pixmap *priv; assert(sna_crtc); DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), bo->handle)); assert(sna->flags & SNA_TEAR_FREE); assert(!sna_crtc->transform); if (sna_crtc->client_bo != bo) { if (sna_crtc->client_bo) { assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout); sna_crtc->client_bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo); } sna_crtc->client_bo = kgem_bo_reference(bo); sna_crtc->client_bo->active_scanout++; assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout); sna_crtc_damage(crtc); } list_move(&sna_crtc->shadow_link, &sna->mode.shadow_crtc); sna->mode.shadow_dirty = true; priv = sna_pixmap(sna->front); assert(priv->gpu_bo); priv->move_to_gpu = wait_for_shadow; priv->move_to_gpu_data = sna; } void sna_shadow_steal_crtcs(struct sna *sna, struct list *list) { list_init(list); while (!list_is_empty(&sna->mode.shadow_crtc)) { RegionRec sub, *damage; struct sna_crtc *crtc = list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link); damage = DamageRegion(sna->mode.shadow_damage); sub.extents = crtc->base->bounds; sub.data = NULL; RegionSubtract(damage, damage, &sub); list_move(&crtc->shadow_link, list); } } void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list) { while (!list_is_empty(list)) { struct sna_crtc *crtc = list_first_entry(list, struct sna_crtc, shadow_link); assert(crtc->client_bo); sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo); } } void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); DBG(("%s: clearin shadow override for CRTC:%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc))); if (sna_crtc->client_bo == NULL) return; assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout); sna_crtc->client_bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo); sna_crtc->client_bo = NULL; list_del(&sna_crtc->shadow_link); sna->mode.shadow_dirty = true; sna_crtc_damage(crtc); } static bool move_crtc_to_gpu(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]); assert(crtc); if (crtc->bo == NULL) continue; if (crtc->slave_pixmap) continue; if (crtc->client_bo) continue; DBG(("%s: CRTC %d [pipe=%d] requires frontbuffer\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc))); return sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT); } return true; } void sna_mode_redisplay(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); RegionPtr region; int i; if (sna->mode.hidden) { DBG(("%s: hidden outputs, skipping\n", __FUNCTION__)); return; } if (!sna->mode.shadow_enabled) return; assert(sna->mode.shadow_damage); DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n", __FUNCTION__, !RegionNil(DamageRegion(sna->mode.shadow_damage)), sna->mode.flip_active, sna->mode.dirty)); assert((sna->flags & SNA_IS_HOSTED) == 0); assert(sna->mode.shadow_active); if (sna->mode.dirty) return; region = DamageRegion(sna->mode.shadow_damage); if (RegionNil(region)) return; DBG(("%s: damage: %dx(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (sna->mode.flip_active) { DBG(("%s: checking for %d outstanding flip completions\n", __FUNCTION__, sna->mode.flip_active)); sna->mode.dirty = true; while (sna->mode.flip_active && sna_mode_wakeup(sna)) ; sna->mode.dirty = false; DBG(("%s: now %d outstanding flip completions (enabled? %d)\n", __FUNCTION__, sna->mode.flip_active, sna->mode.shadow_enabled)); if (sna->mode.flip_active || !sna->mode.shadow_enabled) return; } if (wedged(sna) || !move_crtc_to_gpu(sna)) { DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__)); if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ)) return; for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); RegionRec damage; assert(sna_crtc != NULL); if (!sna_crtc->shadow) continue; assert(crtc->enabled); assert(sna_crtc->transform || sna->flags & SNA_TEAR_FREE); damage.extents = crtc->bounds; damage.data = NULL; RegionIntersect(&damage, &damage, region); if (!box_empty(&damage.extents)) { struct kgem_bo *bo = NULL; DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n", __FUNCTION__, __sna_crtc_pipe(sna_crtc), damage.extents.x1, damage.extents.y1, damage.extents.x2, damage.extents.y2)); if (sna->flags & SNA_TEAR_FREE) { RegionRec new_damage; RegionNull(&new_damage); RegionCopy(&new_damage, &damage); bo = sna_crtc->cache_bo; if (bo == NULL) { damage.extents = crtc->bounds; damage.data = NULL; bo = kgem_create_2d(&sna->kgem, crtc->mode.HDisplay, crtc->mode.VDisplay, crtc->scrn->bitsPerPixel, sna_crtc->bo->tiling, CREATE_SCANOUT); } else RegionUnion(&damage, &damage, &sna_crtc->client_damage); DBG(("%s: TearFree fallback, shadow handle=%d, crtc handle=%d\n", __FUNCTION__, bo->handle, sna_crtc->bo->handle)); sna_crtc->client_damage = new_damage; } if (bo == NULL) bo = sna_crtc->bo; sna_crtc_redisplay__fallback(crtc, &damage, bo); if (bo != sna_crtc->bo) { struct drm_mode_crtc_page_flip arg; arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay); arg.user_data = (uintptr_t)sna_crtc; arg.flags = DRM_MODE_PAGE_FLIP_EVENT; arg.reserved = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) { DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", __FUNCTION__, sna_crtc->bo->handle, sna_crtc->bo->active_scanout, bo->handle, bo->active_scanout)); assert(sna_crtc->bo->active_scanout); assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); sna_crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = bo; sna_crtc->bo->active_scanout++; sna_crtc->cache_bo = NULL; } else { DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Page flipping failed, disabling TearFree\n"); sna->flags &= ~SNA_TEAR_FREE; damage.extents = crtc->bounds; damage.data = NULL; sna_crtc_redisplay__fallback(crtc, &damage, sna_crtc->bo); kgem_bo_destroy(&sna->kgem, bo); sna_crtc->cache_bo = NULL; } } else { sna->mode.flip_active++; assert(sna_crtc->flip_bo == NULL); sna_crtc->flip_handler = shadow_flip_handler; sna_crtc->flip_data = sna; sna_crtc->flip_bo = bo; sna_crtc->flip_bo->active_scanout++; sna_crtc->flip_serial = sna_crtc->mode_serial; sna_crtc->flip_pending = true; sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo); DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); } } } RegionUninit(&damage); if (sna_crtc->slave_damage) DamageEmpty(sna_crtc->slave_damage); } RegionEmpty(region); return; } { struct sna_pixmap *priv; priv = sna_pixmap(sna->front); assert(priv != NULL); if (priv->move_to_gpu) { if (priv->move_to_gpu == wait_for_shadow && !sna->mode.shadow_dirty) { /* No damage written to new scanout * (backbuffer), ignore redisplay request * and continue with the current intact * scanout (frontbuffer). */ DBG(("%s: shadow idle, skipping update\n", __FUNCTION__)); RegionEmpty(region); return; } (void)priv->move_to_gpu(sna, priv, 0); } assert(priv->move_to_gpu == NULL); } for (i = 0; i < sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct sna_crtc *sna_crtc = to_sna_crtc(crtc); RegionRec damage; assert(sna_crtc != NULL); DBG(("%s: crtc[%d] transformed? %d\n", __FUNCTION__, i, sna_crtc->transform)); if (!sna_crtc->transform) continue; assert(crtc->enabled); assert(sna_crtc->bo); damage.extents = crtc->bounds; damage.data = NULL; RegionIntersect(&damage, &damage, region); DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, i, !box_empty(&damage.extents), RegionNotEmpty(&damage), region_num_rects(&damage), damage.extents.x1, damage.extents.y1, damage.extents.x2, damage.extents.y2)); if (!box_empty(&damage.extents)) { if (sna->flags & SNA_TEAR_FREE) { struct drm_mode_crtc_page_flip arg; struct kgem_bo *bo; RegionUninit(&damage); damage.extents = crtc->bounds; damage.data = NULL; bo = sna_crtc->cache_bo; if (bo == NULL) bo = kgem_create_2d(&sna->kgem, crtc->mode.HDisplay, crtc->mode.VDisplay, crtc->scrn->bitsPerPixel, sna_crtc->bo->tiling, CREATE_SCANOUT); if (bo == NULL) continue; sna_crtc_redisplay(crtc, &damage, bo); kgem_bo_submit(&sna->kgem, bo); arg.crtc_id = __sna_crtc_id(sna_crtc); arg.fb_id = get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay); if (arg.fb_id == 0) goto disable1; arg.user_data = (uintptr_t)sna_crtc; arg.flags = DRM_MODE_PAGE_FLIP_EVENT; arg.reserved = 0; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) { DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", __FUNCTION__, sna_crtc->bo->handle, sna_crtc->bo->active_scanout - 1, bo->handle, bo->active_scanout)); assert(sna_crtc->bo->active_scanout); assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout); sna_crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, sna_crtc->bo); sna_crtc->bo = kgem_bo_reference(bo); sna_crtc->bo->active_scanout++; sna_crtc->cache_bo = kgem_bo_reference(bo); } else { BoxRec box; DrawableRec tmp; DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno)); xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Page flipping failed, disabling TearFree\n"); sna->flags &= ~SNA_TEAR_FREE; disable1: box.x1 = 0; box.y1 = 0; tmp.width = box.x2 = crtc->mode.HDisplay; tmp.height = box.y2 = crtc->mode.VDisplay; tmp.depth = sna->front->drawable.depth; tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel; if (!sna->render.copy_boxes(sna, GXcopy, &sna->front->drawable, bo, 0, 0, &tmp, sna_crtc->bo, 0, 0, &box, 1, COPY_LAST)) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc)); sna_crtc_disable(crtc, false); } kgem_bo_destroy(&sna->kgem, bo); sna_crtc->cache_bo = NULL; } continue; } sna->mode.flip_active++; assert(sna_crtc->flip_bo == NULL); sna_crtc->flip_handler = shadow_flip_handler; sna_crtc->flip_data = sna; sna_crtc->flip_bo = bo; sna_crtc->flip_bo->active_scanout++; sna_crtc->flip_serial = sna_crtc->mode_serial; sna_crtc->flip_pending = true; sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo); DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial)); } else { sna_crtc_redisplay(crtc, &damage, sna_crtc->bo); kgem_scanout_flush(&sna->kgem, sna_crtc->bo); } } RegionUninit(&damage); if (sna_crtc->slave_damage) DamageEmpty(sna_crtc->slave_damage); } if (sna->mode.shadow) { struct kgem_bo *new = __sna_pixmap_get_bo(sna->front); struct kgem_bo *old = sna->mode.shadow; struct drm_mode_crtc_page_flip arg; uint32_t fb = 0; DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n", __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout)); assert(new != old); assert(new->refcnt); arg.flags = DRM_MODE_PAGE_FLIP_EVENT; arg.reserved = 0; kgem_bo_submit(&sna->kgem, new); for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *crtc = config->crtc[i]->driver_private; struct kgem_bo *flip_bo; int x, y; assert(crtc != NULL); DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n", __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo ? crtc->bo->handle : 0, crtc->transform)); if (crtc->bo == NULL || crtc->transform) continue; assert(config->crtc[i]->enabled); assert(crtc->flip_bo == NULL); arg.crtc_id = __sna_crtc_id(crtc); arg.user_data = (uintptr_t)crtc; if (crtc->client_bo) { DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->client_bo->handle)); arg.fb_id = get_fb(sna, crtc->client_bo, crtc->base->mode.HDisplay, crtc->base->mode.VDisplay); assert(arg.fb_id != fb); flip_bo = crtc->client_bo; x = y = 0; } else { if (fb == 0) fb = get_fb(sna, new, sna->scrn->virtualX, sna->scrn->virtualY); if (fb == 0) { fixup_shadow: if (sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = sna->scrn->virtualX; box.y2 = sna->scrn->virtualY; if (sna->render.copy_boxes(sna, GXcopy, &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0, &sna->front->drawable, old, 0, 0, &box, 1, COPY_LAST)) { kgem_submit(&sna->kgem); RegionEmpty(region); } } return; } arg.fb_id = fb; flip_bo = new; x = crtc->base->x; y = crtc->base->y; } if (crtc->bo == flip_bo) { assert(crtc->bo->refcnt >= crtc->bo->active_scanout); DBG(("%s: flip handle=%d is already on the CRTC\n", __FUNCTION__, flip_bo->handle)); continue; } if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x) != crtc->offset) { DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n", __FUNCTION__, flip_bo->pitch, crtc->bo->pitch, y << 16 | x, crtc->offset)); fixup_flip: if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) { DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout-1, flip_bo->handle, flip_bo->active_scanout)); assert(flip_bo != crtc->bo); assert(crtc->bo->active_scanout); assert(crtc->bo->refcnt >= crtc->bo->active_scanout); crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, crtc->bo); if (crtc->shadow_bo) { kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); crtc->shadow_bo = NULL; } crtc->bo = kgem_bo_reference(flip_bo); crtc->bo->active_scanout++; } else { xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Failed to prepare CRTC for page flipping, disabling TearFree\n"); sna->flags &= ~SNA_TEAR_FREE; if (sna->mode.flip_active == 0) { DBG(("%s: abandoning flip attempt\n", __FUNCTION__)); goto fixup_shadow; } xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc)); sna_crtc_disable(crtc->base, false); } continue; } if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) { ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n", __FUNCTION__, arg.fb_id, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), errno)); goto fixup_flip; } sna->mode.flip_active++; assert(crtc->flip_bo == NULL); crtc->flip_handler = shadow_flip_handler; crtc->flip_data = sna; crtc->flip_bo = kgem_bo_reference(flip_bo); crtc->flip_bo->active_scanout++; crtc->flip_serial = crtc->mode_serial; crtc->flip_pending = true; DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial)); { struct drm_i915_gem_busy busy = { flip_bo->handle }; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) { if (busy.busy) { int mode = KGEM_RENDER; if (busy.busy & (0xfffe << 16)) mode = KGEM_BLT; DBG(("%s: marking flip bo as busy [%x -> mode=%d]\n", __FUNCTION__, busy.busy, mode)); kgem_bo_mark_busy(&sna->kgem, flip_bo, mode); } else __kgem_bo_clear_busy(flip_bo); } } } DBG(("%s: flipped %d outputs, shadow active? %d\n", __FUNCTION__, sna->mode.flip_active, sna->mode.shadow ? sna->mode.shadow->handle : 0)); if (sna->mode.flip_active) { assert(old == sna->mode.shadow); assert(old->refcnt >= 1); set_shadow(sna, region); } } else kgem_submit(&sna->kgem); RegionEmpty(region); } int sna_mode_wakeup(struct sna *sna) { char buffer[1024]; int len, i; int ret = 0; again: /* In order to workaround a kernel bug in not honouring O_NONBLOCK, * check that the fd is readable before attempting to read the next * event from drm. */ if (!event_pending(sna->kgem.fd)) return ret; /* The DRM read semantics guarantees that we always get only * complete events. */ len = read(sna->kgem.fd, buffer, sizeof (buffer)); if (len < (int)sizeof(struct drm_event)) return ret; /* Note that we cannot rely on the passed in struct sna matching * the struct sna used for the vblank event (in case it was submitted * by a different ZaphodHead). When processing the event, we must * ensure that we only use the pointer passed along with the event. */ DBG(("%s: len=%d\n", __FUNCTION__, len)); i = 0; while (i < len) { struct drm_event *e = (struct drm_event *)&buffer[i]; switch (e->type) { case DRM_EVENT_VBLANK: if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2) sna_present_vblank_handler((struct drm_event_vblank *)e); else sna_dri2_vblank_handler((struct drm_event_vblank *)e); break; case DRM_EVENT_FLIP_COMPLETE: { struct drm_event_vblank *vbl = (struct drm_event_vblank *)e; struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data; uint64_t msc; /* Beware Zaphod! */ sna = to_sna(crtc->base->scrn); if (msc64(crtc, vbl->sequence, &msc)) { DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n", __FUNCTION__, __sna_crtc_pipe(crtc), vbl->sequence, (long long)msc, vbl->tv_sec, vbl->tv_usec)); crtc->swap.tv_sec = vbl->tv_sec; crtc->swap.tv_usec = vbl->tv_usec; crtc->swap.msc = msc; } assert(crtc->flip_pending); crtc->flip_pending = false; assert(crtc->flip_bo); assert(crtc->flip_bo->active_scanout); assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout); if (crtc->flip_serial == crtc->mode_serial) { DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n", __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout - 1, crtc->flip_bo->handle, crtc->flip_bo->active_scanout)); assert(crtc->bo->active_scanout); assert(crtc->bo->refcnt >= crtc->bo->active_scanout); crtc->bo->active_scanout--; kgem_bo_destroy(&sna->kgem, crtc->bo); if (crtc->shadow_bo) { kgem_bo_destroy(&sna->kgem, crtc->shadow_bo); crtc->shadow_bo = NULL; } crtc->bo = crtc->flip_bo; crtc->flip_bo = NULL; } else { crtc->flip_bo->active_scanout--; kgem_bo_destroy(&sna->kgem, crtc->flip_bo); crtc->flip_bo = NULL; } DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active)); assert(sna->mode.flip_active); if (--sna->mode.flip_active == 0) { assert(crtc->flip_handler); crtc->flip_handler(vbl, crtc->flip_data); } } break; default: break; } i += e->length; ret++; } goto again; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_display_fake.c000066400000000000000000000211131267532330400253010ustar00rootroot00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" static bool add_fake_output(struct sna *sna, bool late); static void sna_crtc_dpms(xf86CrtcPtr crtc, int mode) { } static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); int len, i; for (i = len = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != crtc) continue; len += snprintf(outputs+len, max-len, "%s, ", output->name); } assert(len >= 2); outputs[len-2] = '\0'; return outputs; } static const char *rotation_to_str(Rotation rotation) { switch (rotation & RR_Rotate_All) { case 0: case RR_Rotate_0: return "normal"; case RR_Rotate_90: return "left"; case RR_Rotate_180: return "inverted"; case RR_Rotate_270: return "right"; default: return "unknown"; } } static const char *reflection_to_str(Rotation rotation) { switch (rotation & RR_Reflect_All) { case 0: return "none"; case RR_Reflect_X: return "X axis"; case RR_Reflect_Y: return "Y axis"; case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes"; default: return "invalid"; } } static Bool sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { char outputs[256]; xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "switch to mode %dx%d on %s, position (%d, %d), rotation %s, reflection %s\n", mode->HDisplay, mode->VDisplay, outputs_for_crtc(crtc, outputs, sizeof(outputs)), x, y, rotation_to_str(rotation), reflection_to_str(rotation)); return TRUE; } static void sna_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size) { } static void sna_crtc_destroy(xf86CrtcPtr crtc) { } static const xf86CrtcFuncsRec sna_crtc_funcs = { .dpms = sna_crtc_dpms, .set_mode_major = sna_crtc_set_mode_major, .gamma_set = sna_crtc_gamma_set, .destroy = sna_crtc_destroy, }; static void sna_output_create_resources(xf86OutputPtr output) { } static Bool sna_output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) { return TRUE; } static Bool sna_output_get_property(xf86OutputPtr output, Atom property) { return FALSE; } static void sna_output_dpms(xf86OutputPtr output, int dpms) { } static xf86OutputStatus sna_output_detect(xf86OutputPtr output) { DBG(("%s(%s) has user modes? %d\n", __FUNCTION__, output->name, output->randr_output && output->randr_output->numUserModes)); if (output->randr_output && output->randr_output->numUserModes) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(output->scrn); if (xf86_config->output[xf86_config->num_output-1] == output) add_fake_output(to_sna(output->scrn), true); return XF86OutputStatusConnected; } return XF86OutputStatusDisconnected; } static Bool sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode) { if (mode->type & M_T_DEFAULT) return MODE_BAD; return MODE_OK; } static DisplayModePtr sna_output_get_modes(xf86OutputPtr output) { return NULL; } static void sna_output_destroy(xf86OutputPtr output) { } static const xf86OutputFuncsRec sna_output_funcs = { .create_resources = sna_output_create_resources, #ifdef RANDR_12_INTERFACE .set_property = sna_output_set_property, .get_property = sna_output_get_property, #endif .dpms = sna_output_dpms, .detect = sna_output_detect, .mode_valid = sna_output_mode_valid, .get_modes = sna_output_get_modes, .destroy = sna_output_destroy }; static Bool sna_mode_resize(ScrnInfoPtr scrn, int width, int height) { ScreenPtr screen = xf86ScrnToScreen(scrn); PixmapPtr new_front; DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__, scrn->virtualX, scrn->virtualY, width, height)); if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; assert(to_sna_from_screen(screen)->front); assert(screen->GetScreenPixmap(screen) == to_sna_from_screen(screen)->front); DBG(("%s: creating new framebuffer %dx%d\n", __FUNCTION__, width, height)); new_front = screen->CreatePixmap(screen, width, height, scrn->depth, 0); if (!new_front) return FALSE; scrn->virtualX = width; scrn->virtualY = height; scrn->displayWidth = width; screen->SetScreenPixmap(new_front); assert(screen->GetScreenPixmap(screen) == new_front); assert(to_sna_from_screen(screen)->front == new_front); screen->DestroyPixmap(new_front); return TRUE; } static const xf86CrtcConfigFuncsRec sna_mode_funcs = { sna_mode_resize }; static bool add_fake_output(struct sna *sna, bool late) { ScrnInfoPtr scrn = sna->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86OutputPtr output; xf86CrtcPtr crtc; RROutputPtr clones[32]; RRCrtcPtr crtcs[32]; char buf[80]; int i, len; if (sna->mode.num_fake >= 32) return false; DBG(("%s(late=%d, num_fake=%d)\n", __FUNCTION__, late, sna->mode.num_fake+1)); crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs); if (crtc == NULL) return false; len = sprintf(buf, "VIRTUAL%d", sna->mode.num_fake+1); output = xf86OutputCreate(scrn, &sna_output_funcs, buf); if (!output) { xf86CrtcDestroy(crtc); return false; } output->mm_width = 0; output->mm_height = 0; output->interlaceAllowed = FALSE; output->subpixel_order = SubPixelNone; output->status = XF86OutputStatusDisconnected; output->possible_crtcs = ~((1 << sna->mode.num_real_crtc) - 1); output->possible_clones = ~((1 << sna->mode.num_real_output) - 1); if (late) { ScreenPtr screen = xf86ScrnToScreen(scrn); crtc->randr_crtc = RRCrtcCreate(screen, crtc); output->randr_output = RROutputCreate(screen, buf, len, output); if (crtc->randr_crtc == NULL || output->randr_output == NULL) { xf86OutputDestroy(output); xf86CrtcDestroy(crtc); return false; } RRPostPendingProperties(output->randr_output); for (i = sna->mode.num_real_output; i < xf86_config->num_output; i++) clones[i - sna->mode.num_real_output] = xf86_config->output[i]->randr_output; assert(i - sna->mode.num_real_output == sna->mode.num_fake + 1); for (i = sna->mode.num_real_crtc; i < xf86_config->num_crtc; i++) crtcs[i - sna->mode.num_real_crtc] = xf86_config->crtc[i]->randr_crtc; assert(i - sna->mode.num_real_crtc == sna->mode.num_fake + 1); for (i = sna->mode.num_real_output; i < xf86_config->num_output; i++) { RROutputPtr rr_output = xf86_config->output[i]->randr_output; if (!RROutputSetCrtcs(rr_output, crtcs, sna->mode.num_fake + 1) || !RROutputSetClones(rr_output, clones, sna->mode.num_fake + 1)) goto err; } RRCrtcSetRotations(crtc->randr_crtc, RR_Rotate_All | RR_Reflect_All); RRCrtcGammaGet(crtc->randr_crtc); } sna->mode.num_fake++; xf86DrvMsg(scrn->scrnIndex, X_INFO, "Enabled output %s\n", output->name); return true; err: for (i = 0; i < xf86_config->num_output; i++) { output = xf86_config->output[i]; if (output->driver_private) continue; xf86OutputDestroy(output); i--; } for (i = 0; i < xf86_config->num_crtc; i++) { crtc = xf86_config->crtc[i]; if (crtc->driver_private) continue; xf86CrtcDestroy(crtc); i--; } sna->mode.num_fake = -1; return false; } bool sna_mode_fake_init(struct sna *sna, int num_fake) { bool ret; if (num_fake == 0) return true; if (sna->mode.num_real_crtc == 0) { xf86CrtcConfigInit(sna->scrn, &sna_mode_funcs); xf86CrtcSetSizeRange(sna->scrn, 1, 1, INT16_MAX, INT16_MAX); } ret = true; while (ret && num_fake--) ret = add_fake_output(sna, false); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_dri2.c000066400000000000000000003145101267532330400235140ustar00rootroot00000000000000/************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. Copyright © 2002 by David Dawes 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 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 ATI, VA LINUX SYSTEMS AND/OR THEIR 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: Jeff Hartmann * David Dawes * Keith Whitwell */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sna.h" #include "intel_options.h" #include #include #include #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) && defined(COMPOSITE) #include #define CHECK_FOR_COMPOSITOR #endif #define DBG_CAN_FLIP 1 #define DBG_CAN_XCHG 1 #define DBG_FORCE_COPY -1 /* KGEM_BLT or KGEM_3D */ #if DRI2INFOREC_VERSION < 2 #error DRI2 version supported by the Xserver is too old #endif static inline struct kgem_bo *ref(struct kgem_bo *bo) { return kgem_bo_reference(bo); } struct sna_dri2_private { PixmapPtr pixmap; struct kgem_bo *bo; DRI2Buffer2Ptr proxy; bool stale; uint32_t size; int refcnt; }; static inline struct sna_dri2_private * get_private(void *buffer) { return (struct sna_dri2_private *)((DRI2Buffer2Ptr)buffer+1); } pure static inline DRI2BufferPtr sna_pixmap_get_buffer(PixmapPtr pixmap) { assert(pixmap->refcnt); return ((void **)__get_private(pixmap, sna_pixmap_key))[2]; } static inline void sna_pixmap_set_buffer(PixmapPtr pixmap, void *ptr) { assert(pixmap->refcnt); ((void **)__get_private(pixmap, sna_pixmap_key))[2] = ptr; } #if DRI2INFOREC_VERSION >= 4 enum event_type { WAITMSC = 0, SWAP, SWAP_COMPLETE, FLIP, FLIP_THROTTLE, FLIP_COMPLETE, FLIP_ASYNC, }; struct dri_bo { struct list link; struct kgem_bo *bo; uint32_t name; unsigned flags; }; struct sna_dri2_event { struct sna *sna; DrawablePtr draw; ClientPtr client; enum event_type type; xf86CrtcPtr crtc; int pipe; bool queued; bool sync; bool chained; /* for swaps & flips only */ DRI2SwapEventPtr event_complete; void *event_data; DRI2BufferPtr front; DRI2BufferPtr back; struct kgem_bo *bo; struct copy { struct kgem_bo *bo; unsigned flags; uint32_t name; uint32_t size; } pending; struct sna_dri2_event *chain; struct list link; int flip_continue; int keepalive; int signal; }; #if DRI2INFOREC_VERSION < 10 #undef USE_ASYNC_SWAP #endif #if USE_ASYNC_SWAP #define KEEPALIVE 8 /* wait ~100ms before discarding swap caches */ #define APPLY_DAMAGE 0 #else #define USE_ASYNC_SWAP 0 #define KEEPALIVE 1 #define APPLY_DAMAGE 1 #endif static void sna_dri2_flip_event(struct sna_dri2_event *flip); inline static DRI2BufferPtr dri2_window_get_front(WindowPtr win); static struct kgem_bo * __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, DRI2BufferPtr src, DRI2BufferPtr dst, unsigned flags); inline static void __sna_dri2_copy_event(struct sna_dri2_event *info, unsigned flags) { DBG(("%s: flags = %x\n", __FUNCTION__, flags)); assert(info->front != info->back); info->bo = __sna_dri2_copy_region(info->sna, info->draw, NULL, info->back, info->front, flags); info->front->flags = info->back->flags; } static int front_pitch(DrawablePtr draw) { DRI2BufferPtr buffer; buffer = NULL; if (draw->type != DRAWABLE_PIXMAP) buffer = dri2_window_get_front((WindowPtr)draw); if (buffer == NULL) buffer = sna_pixmap_get_buffer(get_drawable_pixmap(draw)); return buffer ? buffer->pitch : 0; } struct dri2_window { DRI2BufferPtr front; struct sna_dri2_event *chain; xf86CrtcPtr crtc; int64_t msc_delta; struct list cache; uint32_t cache_size; int scanout; }; static struct dri2_window *dri2_window(WindowPtr win) { assert(win->drawable.type != DRAWABLE_PIXMAP); return ((void **)__get_private(win, sna_window_key))[1]; } static bool use_scanout(struct sna *sna, DrawablePtr draw, struct dri2_window *priv) { if (priv->front) return true; if (priv->scanout < 0) priv->scanout = (sna->flags & (SNA_LINEAR_FB | SNA_NO_WAIT | SNA_NO_FLIP)) == 0 && draw->width == sna->front->drawable.width && draw->height == sna->front->drawable.height && draw->bitsPerPixel == sna->front->drawable.bitsPerPixel; return priv->scanout; } static void sna_dri2_get_back(struct sna *sna, DrawablePtr draw, DRI2BufferPtr back) { struct dri2_window *priv = dri2_window((WindowPtr)draw); uint32_t size; struct kgem_bo *bo; struct dri_bo *c; uint32_t name; int flags; bool reuse; DBG(("%s: draw size=%dx%d, back buffer handle=%d size=%dx%d, is-scanout? %d, active?=%d, pitch=%d, front pitch=%d\n", __FUNCTION__, draw->width, draw->height, get_private(back)->bo->handle, get_private(back)->size & 0xffff, get_private(back)->size >> 16, get_private(back)->bo->scanout, get_private(back)->bo->active_scanout, back->pitch, front_pitch(draw))); assert(priv); size = draw->height << 16 | draw->width; if (size != priv->cache_size) { while (!list_is_empty(&priv->cache)) { c = list_first_entry(&priv->cache, struct dri_bo, link); list_del(&c->link); DBG(("%s: releasing cached handle=%d\n", __FUNCTION__, c->bo ? c->bo->handle : 0)); assert(c->bo); kgem_bo_destroy(&sna->kgem, c->bo); free(c); } priv->cache_size = size; } reuse = size == get_private(back)->size; if (reuse) reuse = get_private(back)->bo->scanout == use_scanout(sna, draw, priv); DBG(("%s: reuse backbuffer? %d\n", __FUNCTION__, reuse)); if (reuse) { bo = get_private(back)->bo; assert(bo->refcnt); DBG(("%s: back buffer handle=%d, active?=%d, refcnt=%d\n", __FUNCTION__, bo->handle, bo->active_scanout, get_private(back)->refcnt)); if (bo->active_scanout == 0) { DBG(("%s: reuse unattached back\n", __FUNCTION__)); get_private(back)->stale = false; return; } } bo = NULL; list_for_each_entry(c, &priv->cache, link) { DBG(("%s: cache: handle=%d, active=%d\n", __FUNCTION__, c->bo ? c->bo->handle : 0, c->bo ? c->bo->active_scanout : -1)); assert(c->bo); if (c->bo->active_scanout == 0) { _list_del(&c->link); if (c->bo == NULL) { free(c); goto out; } bo = c->bo; name = c->name; flags = c->flags; DBG(("%s: reuse cache handle=%d, name=%d, flags=%d\n", __FUNCTION__, bo->handle, name, flags)); c->bo = NULL; break; } } if (bo == NULL) { DBG(("%s: allocating new backbuffer\n", __FUNCTION__)); flags = CREATE_EXACT; if (use_scanout(sna, draw, priv)) { DBG(("%s: requesting scanout compatible back\n", __FUNCTION__)); flags |= CREATE_SCANOUT; } bo = kgem_create_2d(&sna->kgem, draw->width, draw->height, draw->bitsPerPixel, get_private(back)->bo->tiling, flags); if (bo == NULL) return; name = kgem_bo_flink(&sna->kgem, bo); if (name == 0) { kgem_bo_destroy(&sna->kgem, bo); return; } flags = 0; if (USE_ASYNC_SWAP && back->flags) { BoxRec box; box.x1 = 0; box.y1 = 0; box.x2 = draw->width; box.y2 = draw->height; DBG(("%s: filling new buffer with old back\n", __FUNCTION__)); if (sna->render.copy_boxes(sna, GXcopy, draw, get_private(back)->bo, 0, 0, draw, bo, 0, 0, &box, 1, COPY_LAST | COPY_DRI)) flags = back->flags; } } assert(bo->active_scanout == 0); if (reuse && get_private(back)->bo->refcnt == 1 + get_private(back)->bo->active_scanout) { if (&c->link == &priv->cache) c = malloc(sizeof(*c)); if (c != NULL) { c->bo = ref(get_private(back)->bo); c->name = back->name; c->flags = back->flags; list_add(&c->link, &priv->cache); DBG(("%s: caching handle=%d (name=%d, flags=%d, active_scanout=%d)\n", __FUNCTION__, c->bo->handle, c->name, c->flags, c->bo->active_scanout)); } } else { if (&c->link != &priv->cache) free(c); } assert(bo->active_scanout == 0); assert(bo != get_private(back)->bo); kgem_bo_destroy(&sna->kgem, get_private(back)->bo); get_private(back)->bo = bo; get_private(back)->size = draw->height << 16 | draw->width; back->pitch = bo->pitch; back->name = name; back->flags = flags; assert(back->pitch); assert(back->name); out: get_private(back)->stale = false; } static struct sna_dri2_event * dri2_chain(DrawablePtr d) { struct dri2_window *priv = dri2_window((WindowPtr)d); assert(priv != NULL); assert(priv->chain == NULL || priv->chain->chained); return priv->chain; } inline static DRI2BufferPtr dri2_window_get_front(WindowPtr win) { struct dri2_window *priv = dri2_window(win); assert(priv->front == NULL || get_private(priv->front)->bo->active_scanout); return priv ? priv->front : NULL; } #else inline static void *dri2_window_get_front(WindowPtr win) { return NULL; } #define APPLY_DAMAGE 1 #endif #if DRI2INFOREC_VERSION < 6 #define xorg_can_triple_buffer() 0 #define swap_limit(d, l) false #define mark_stale(b) #else #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,904,0) /* Prime fixed for triple buffer support */ #define xorg_can_triple_buffer() 1 #elif XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,12,99,901,0) /* Before numGPUScreens was introduced */ #define xorg_can_triple_buffer() 1 #else /* Subject to crashers when combining triple buffering and Prime */ inline static bool xorg_can_triple_buffer(void) { return screenInfo.numGPUScreens == 0; } #endif static void mark_stale(DRI2BufferPtr back) { /* If we have reuse notifications, we can track when the * client tries to present an old buffer (one that has not * been updated since the last swap) and avoid showing the * stale frame. (This is mostly useful for tracking down * driver bugs!) */ DBG(("%s(handle=%d) => %d\n", __FUNCTION__, get_private(back)->bo->handle, xorg_can_triple_buffer())); get_private(back)->stale = xorg_can_triple_buffer(); } static Bool sna_dri2_swap_limit_validate(DrawablePtr draw, int swap_limit) { DBG(("%s: swap limit set to %d\n", __FUNCTION__, swap_limit)); return swap_limit >= 1; } static void sna_dri2_reuse_buffer(DrawablePtr draw, DRI2BufferPtr buffer) { DBG(("%s: reusing buffer pixmap=%ld, attachment=%d, handle=%d, name=%d\n", __FUNCTION__, get_drawable_pixmap(draw)->drawable.serialNumber, buffer->attachment, get_private(buffer)->bo->handle, buffer->name)); assert(get_private(buffer)->refcnt); assert(get_private(buffer)->bo->refcnt >= get_private(buffer)->bo->active_scanout); assert(kgem_bo_flink(&to_sna_from_drawable(draw)->kgem, get_private(buffer)->bo) == buffer->name); if (buffer->attachment == DRI2BufferBackLeft && draw->type != DRAWABLE_PIXMAP) { DBG(("%s: replacing back buffer on window %ld\n", __FUNCTION__, draw->id)); sna_dri2_get_back(to_sna_from_drawable(draw), draw, buffer); assert(get_private(buffer)->bo->refcnt); assert(get_private(buffer)->bo->active_scanout == 0); assert(kgem_bo_flink(&to_sna_from_drawable(draw)->kgem, get_private(buffer)->bo) == buffer->name); DBG(("%s: reusing back buffer handle=%d, name=%d, pitch=%d, age=%d\n", __FUNCTION__, get_private(buffer)->bo->handle, buffer->name, buffer->pitch, buffer->flags)); } } static bool swap_limit(DrawablePtr draw, int limit) { if (!xorg_can_triple_buffer()) return false; DBG(("%s: draw=%ld setting swap limit to %d\n", __FUNCTION__, (long)draw->id, limit)); DRI2SwapLimit(draw, limit); return true; } #endif #define COLOR_PREFER_TILING_Y 0 /* Prefer to enable TILING_Y if this buffer will never be a * candidate for pageflipping */ static uint32_t color_tiling(struct sna *sna, DrawablePtr draw) { uint32_t tiling; if (!sna->kgem.can_fence) return I915_TILING_NONE; if (COLOR_PREFER_TILING_Y && (draw->width != sna->front->drawable.width || draw->height != sna->front->drawable.height)) tiling = I915_TILING_Y; else tiling = I915_TILING_X; return kgem_choose_tiling(&sna->kgem, -tiling, draw->width, draw->height, draw->bitsPerPixel); } static uint32_t other_tiling(struct sna *sna, DrawablePtr draw) { /* XXX Can mix color X / depth Y? */ return kgem_choose_tiling(&sna->kgem, sna->kgem.gen >= 040 ? -I915_TILING_Y : -I915_TILING_X, draw->width, draw->height, draw->bitsPerPixel); } static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna, PixmapPtr pixmap) { struct sna_pixmap *priv; DBG(("%s: attaching DRI client to pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); priv = sna_pixmap(pixmap); if (priv != NULL && IS_STATIC_PTR(priv->ptr) && priv->cpu_bo) { DBG(("%s: SHM or unattached Pixmap, BadAlloc\n", __FUNCTION__)); return NULL; } priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | __MOVE_FORCE | __MOVE_DRI); if (priv == NULL) { DBG(("%s: failed to move to GPU, BadAlloc\n", __FUNCTION__)); return NULL; } assert(priv->flush == false || priv->pinned & PIN_DRI3); assert(priv->gpu_bo->flush == false || priv->pinned & PIN_DRI3); assert(priv->cpu_damage == NULL); assert(priv->gpu_bo); assert(priv->gpu_bo->proxy == NULL); if (!kgem_bo_is_fenced(&sna->kgem, priv->gpu_bo)) { if (priv->gpu_bo->tiling && !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { DBG(("%s: failed to discard tiling (%d) for DRI2 protocol\n", __FUNCTION__, priv->gpu_bo->tiling)); return NULL; } } else { int tiling = color_tiling(sna, &pixmap->drawable); if (tiling < 0) tiling = -tiling; if (priv->gpu_bo->tiling < tiling && !priv->gpu_bo->scanout) sna_pixmap_change_tiling(pixmap, tiling); } priv->gpu_bo->active_scanout++; return priv->gpu_bo; } void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { DRI2BufferPtr buffer; struct sna_dri2_private *private; buffer = sna_pixmap_get_buffer(pixmap); if (buffer == NULL) return; DBG(("%s: pixmap=%ld, old handle=%d, new handle=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, get_private(buffer)->bo->handle, sna_pixmap(pixmap)->gpu_bo->handle)); private = get_private(buffer); assert(private->pixmap == pixmap); assert(bo != private->bo); if (private->bo == bo) return; assert(private->bo->active_scanout > 0); private->bo->active_scanout--; DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, private->bo->handle)); private->bo->flush = false; kgem_bo_destroy(&sna->kgem, private->bo); buffer->name = kgem_bo_flink(&sna->kgem, bo); buffer->pitch = bo->pitch; private->bo = ref(bo); bo->active_scanout++; DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle)); bo->flush = true; if (bo->exec) sna->kgem.flush = 1; assert(sna_pixmap(pixmap)->flush); /* XXX DRI2InvalidateDrawable(&pixmap->drawable); */ } static DRI2Buffer2Ptr sna_dri2_create_buffer(DrawablePtr draw, unsigned int attachment, unsigned int format) { struct sna *sna = to_sna_from_drawable(draw); DRI2Buffer2Ptr buffer; struct sna_dri2_private *private; PixmapPtr pixmap; struct kgem_bo *bo; unsigned bpp = format ?: draw->bitsPerPixel; unsigned flags = CREATE_EXACT; uint32_t size; DBG(("%s pixmap=%ld, (attachment=%d, format=%d, drawable=%dx%d), window?=%d\n", __FUNCTION__, get_drawable_pixmap(draw)->drawable.serialNumber, attachment, format, draw->width, draw->height, draw->type != DRAWABLE_PIXMAP)); pixmap = NULL; size = (uint32_t)draw->height << 16 | draw->width; switch (attachment) { case DRI2BufferFrontLeft: pixmap = get_drawable_pixmap(draw); buffer = NULL; if (draw->type != DRAWABLE_PIXMAP) buffer = dri2_window_get_front((WindowPtr)draw); if (buffer == NULL) buffer = (DRI2Buffer2Ptr)sna_pixmap_get_buffer(pixmap); if (buffer) { private = get_private(buffer); DBG(("%s: reusing front buffer attachment, win=%lu %dx%d, pixmap=%ld [%ld] %dx%d, handle=%d, name=%d, active_scanout=%d\n", __FUNCTION__, draw->type != DRAWABLE_PIXMAP ? (long)draw->id : (long)0, draw->width, draw->height, pixmap->drawable.serialNumber, private->pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height, private->bo->handle, buffer->name, private->bo->active_scanout)); assert(buffer->attachment == DRI2BufferFrontLeft); assert(private->pixmap == pixmap); assert(sna_pixmap(pixmap)->flush); assert(sna_pixmap(pixmap)->pinned & PIN_DRI2); assert(kgem_bo_flink(&sna->kgem, private->bo) == buffer->name); assert(private->bo->pitch == buffer->pitch); assert(private->bo->active_scanout); private->refcnt++; return buffer; } bo = sna_pixmap_set_dri(sna, pixmap); if (bo == NULL) return NULL; assert(sna_pixmap(pixmap) != NULL); bo = ref(bo); if (pixmap == sna->front && !(sna->flags & SNA_LINEAR_FB)) flags |= CREATE_SCANOUT; DBG(("%s: attaching to front buffer %dx%d [%p:%d], scanout? %d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height, pixmap, pixmap->refcnt, flags & CREATE_SCANOUT)); size = (uint32_t)pixmap->drawable.height << 16 | pixmap->drawable.width; bpp = pixmap->drawable.bitsPerPixel; break; case DRI2BufferBackLeft: if (draw->type != DRAWABLE_PIXMAP) { if (dri2_window_get_front((WindowPtr)draw)) flags |= CREATE_SCANOUT; if (draw->width == sna->front->drawable.width && draw->height == sna->front->drawable.height && draw->bitsPerPixel == bpp && (sna->flags & (SNA_LINEAR_FB | SNA_NO_WAIT | SNA_NO_FLIP)) == 0) flags |= CREATE_SCANOUT; } case DRI2BufferBackRight: case DRI2BufferFrontRight: case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontRight: DBG(("%s: creating back buffer %dx%d, suitable for scanout? %d\n", __FUNCTION__, draw->width, draw->height, flags & CREATE_SCANOUT)); bo = kgem_create_2d(&sna->kgem, draw->width, draw->height, bpp, color_tiling(sna, draw), flags); break; case DRI2BufferStencil: /* * The stencil buffer has quirky pitch requirements. From Vol * 2a, 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface * Pitch": * The pitch must be set to 2x the value computed based on * width, as the stencil buffer is stored with two rows * interleaved. * To accomplish this, we resort to the nasty hack of doubling * the drm region's cpp and halving its height. * * If we neglect to double the pitch, then * drm_intel_gem_bo_map_gtt() maps the memory incorrectly. * * The alignment for W-tiling is quite different to the * nominal no-tiling case, so we have to account for * the tiled access pattern explicitly. * * The stencil buffer is W tiled. However, we request from * the kernel a non-tiled buffer because the kernel does * not understand W tiling and the GTT is incapable of * W fencing. */ bpp *= 2; bo = kgem_create_2d(&sna->kgem, ALIGN(draw->width, 64), ALIGN((draw->height + 1) / 2, 64), bpp, I915_TILING_NONE, flags); break; case DRI2BufferDepth: case DRI2BufferDepthStencil: case DRI2BufferHiz: case DRI2BufferAccum: bo = kgem_create_2d(&sna->kgem, draw->width, draw->height, bpp, other_tiling(sna, draw), flags); break; default: return NULL; } if (bo == NULL) return NULL; buffer = calloc(1, sizeof *buffer + sizeof *private); if (buffer == NULL) goto err; private = get_private(buffer); buffer->attachment = attachment; buffer->pitch = bo->pitch; buffer->cpp = bpp / 8; buffer->driverPrivate = private; buffer->format = format; buffer->flags = 0; buffer->name = kgem_bo_flink(&sna->kgem, bo); private->refcnt = 1; private->bo = bo; private->pixmap = pixmap; private->size = size; if (buffer->name == 0) goto err; if (pixmap) { struct sna_pixmap *priv; assert(attachment == DRI2BufferFrontLeft); assert(sna_pixmap_get_buffer(pixmap) == NULL); sna_pixmap_set_buffer(pixmap, buffer); assert(sna_pixmap_get_buffer(pixmap) == buffer); pixmap->refcnt++; priv = sna_pixmap(pixmap); assert(priv->flush == false || priv->pinned & PIN_DRI3); assert((priv->pinned & PIN_DRI2) == 0); /* Don't allow this named buffer to be replaced */ priv->pinned |= PIN_DRI2; /* We need to submit any modifications to and reads from this * buffer before we send any reply to the Client. * * As we don't track which Client, we flush for all. */ DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, priv->gpu_bo->handle)); priv->gpu_bo->flush = true; if (priv->gpu_bo->exec) sna->kgem.flush = 1; priv->flush |= FLUSH_READ; if (draw->type == DRAWABLE_PIXMAP) { /* DRI2 renders directly into GLXPixmaps, treat as hostile */ kgem_bo_unclean(&sna->kgem, priv->gpu_bo); sna_damage_all(&priv->gpu_damage, pixmap); priv->clear = false; priv->cpu = false; priv->flush |= FLUSH_WRITE; } sna_accel_watch_flush(sna, 1); } return buffer; err: kgem_bo_destroy(&sna->kgem, bo); free(buffer); return NULL; } static void sna_dri2_cache_bo(struct sna *sna, DrawablePtr draw, struct kgem_bo *bo, uint32_t name, uint32_t size, uint32_t flags) { struct dri_bo *c; DBG(("%s(handle=%d, name=%d)\n", __FUNCTION__, bo->handle, name)); if (draw == NULL) { DBG(("%s: no draw, releasing handle=%d\n", __FUNCTION__, bo->handle)); goto err; } if (draw->type == DRAWABLE_PIXMAP) { DBG(("%s: not a window, releasing handle=%d\n", __FUNCTION__, bo->handle)); goto err; } if (bo->refcnt > 1 + bo->active_scanout) { DBG(("%s: multiple references [%d], releasing handle\n", __FUNCTION__, bo->refcnt, bo->handle)); goto err; } if ((draw->height << 16 | draw->width) != size) { DBG(("%s: wrong size [%dx%d], releasing handle\n", __FUNCTION__, size & 0xffff, size >> 16, bo->handle)); goto err; } if (bo->scanout && front_pitch(draw) != bo->pitch) { DBG(("%s: scanout with pitch change [%d != %d], releasing handle\n", __FUNCTION__, bo->pitch, front_pitch(draw), bo->handle)); goto err; } c = malloc(sizeof(*c)); if (!c) goto err; DBG(("%s: caching handle=%d (name=%d, flags=%d, active_scanout=%d)\n", __FUNCTION__, bo->handle, name, flags, bo->active_scanout)); c->bo = bo; c->name = name; c->flags = flags; list_add(&c->link, &dri2_window((WindowPtr)draw)->cache); return; err: kgem_bo_destroy(&sna->kgem, bo); } static void _sna_dri2_destroy_buffer(struct sna *sna, DrawablePtr draw, DRI2Buffer2Ptr buffer) { struct sna_dri2_private *private = get_private(buffer); if (buffer == NULL) return; DBG(("%s: %p [handle=%d] -- refcnt=%d, draw=%ld, pixmap=%ld, proxy?=%d\n", __FUNCTION__, buffer, private->bo->handle, private->refcnt, draw ? draw->id : 0, private->pixmap ? private->pixmap->drawable.serialNumber : 0, private->proxy != NULL)); assert(private->refcnt > 0); if (--private->refcnt) return; assert(private->bo); if (private->proxy) { DBG(("%s: destroying proxy\n", __FUNCTION__)); assert(private->bo->active_scanout > 0); private->bo->active_scanout--; _sna_dri2_destroy_buffer(sna, draw, private->proxy); private->pixmap = NULL; } if (private->pixmap) { PixmapPtr pixmap = private->pixmap; struct sna_pixmap *priv = sna_pixmap(pixmap); assert(sna_pixmap_get_buffer(pixmap) == buffer); assert(priv->gpu_bo == private->bo); assert(priv->gpu_bo->flush); assert(priv->pinned & PIN_DRI2); assert(priv->flush); DBG(("%s: removing active_scanout=%d from pixmap handle=%d\n", __FUNCTION__, priv->gpu_bo->active_scanout, priv->gpu_bo->handle)); assert(priv->gpu_bo->active_scanout > 0); priv->gpu_bo->active_scanout--; /* Undo the DRI markings on this pixmap */ DBG(("%s: releasing last DRI pixmap=%ld, scanout?=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap == sna->front)); list_del(&priv->flush_list); DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, private->bo->handle)); priv->pinned &= ~PIN_DRI2; if ((priv->pinned & PIN_DRI3) == 0) { priv->gpu_bo->flush = false; priv->flush = false; } sna_accel_watch_flush(sna, -1); sna_pixmap_set_buffer(pixmap, NULL); pixmap->drawable.pScreen->DestroyPixmap(pixmap); } sna_dri2_cache_bo(sna, draw, private->bo, buffer->name, private->size, buffer->flags); free(buffer); } static void sna_dri2_destroy_buffer(DrawablePtr draw, DRI2Buffer2Ptr buffer) { _sna_dri2_destroy_buffer(to_sna_from_drawable(draw), draw, buffer); } static DRI2BufferPtr sna_dri2_reference_buffer(DRI2BufferPtr buffer) { assert(get_private(buffer)->refcnt > 0); get_private(buffer)->refcnt++; return buffer; } static inline void damage(PixmapPtr pixmap, struct sna_pixmap *priv, RegionPtr region) { assert(priv->gpu_bo); if (DAMAGE_IS_ALL(priv->gpu_damage)) goto done; if (region == NULL) { damage_all: priv->gpu_damage = _sna_damage_all(priv->gpu_damage, pixmap->drawable.width, pixmap->drawable.height); sna_damage_destroy(&priv->cpu_damage); list_del(&priv->flush_list); } else { sna_damage_subtract(&priv->cpu_damage, region); if (priv->cpu_damage == NULL) goto damage_all; sna_damage_add(&priv->gpu_damage, region); } done: priv->cpu = false; priv->clear = false; } static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); DBG(("%s: pixmap=%ld, handle=%d (old handle=%d)\n", __FUNCTION__, pixmap->drawable.serialNumber, bo->handle, priv->gpu_bo->handle)); assert(pixmap->drawable.width * pixmap->drawable.bitsPerPixel <= 8*bo->pitch); assert(pixmap->drawable.height * bo->pitch <= kgem_bo_size(bo)); assert(bo->proxy == NULL); assert(priv->pinned & PIN_DRI2); assert((priv->pinned & (PIN_PRIME | PIN_DRI3)) == 0); assert(priv->flush); if (APPLY_DAMAGE) { RegionRec region; /* Post damage on the new front buffer so that listeners, such * as DisplayLink know take a copy and shove it over the USB, * also for software cursors and the like. */ region.extents.x1 = region.extents.y1 = 0; region.extents.x2 = pixmap->drawable.width; region.extents.y2 = pixmap->drawable.height; region.data = NULL; /* * Eeek, beware the sw cursor copying to the old bo * causing recursion and mayhem. */ DBG(("%s: marking whole pixmap as damaged\n", __FUNCTION__)); sna->ignore_copy_area = true; DamageRegionAppend(&pixmap->drawable, ®ion); } damage(pixmap, priv, NULL); assert(bo->refcnt); if (priv->move_to_gpu) { DBG(("%s: applying final/discard move-to-gpu\n", __FUNCTION__)); priv->move_to_gpu(sna, priv, 0); } if (priv->gpu_bo != bo) { DBG(("%s: dropping flush hint from handle=%d\n", __FUNCTION__, priv->gpu_bo->handle)); priv->gpu_bo->flush = false; if (priv->cow) sna_pixmap_undo_cow(sna, priv, 0); if (priv->gpu_bo) { sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); } DBG(("%s: adding flush hint to handle=%d\n", __FUNCTION__, bo->handle)); bo->flush = true; if (bo->exec) sna->kgem.flush = 1; priv->gpu_bo = ref(bo); } if (bo->domain != DOMAIN_GPU) bo->domain = DOMAIN_NONE; assert(bo->flush); if (APPLY_DAMAGE) { DamageRegionProcessPending(&pixmap->drawable); sna->ignore_copy_area = false; } } #if defined(__GNUC__) #define popcount(x) __builtin_popcount(x) #else static int popcount(unsigned int x) { int count = 0; while (x) { count += x&1; x >>= 1; } return count; } #endif static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kgem_bo *src, bool sync) { struct drm_i915_gem_busy busy; int mode; if (sna->kgem.gen < 060) return; if (sync) { DBG(("%s: sync, force %s ring\n", __FUNCTION__, sna->kgem.gen >= 070 ? "BLT" : "RENDER")); kgem_set_mode(&sna->kgem, sna->kgem.gen >= 070 ? KGEM_BLT : KGEM_RENDER, dst); return; } if (DBG_FORCE_COPY != -1) { DBG(("%s: forcing %d\n", __FUNCTION__, DBG_FORCE_COPY)); kgem_set_mode(&sna->kgem, DBG_FORCE_COPY, dst); return; } if (sna->kgem.mode != KGEM_NONE) { DBG(("%s: busy, not switching\n", __FUNCTION__)); return; } if (sna->render_state.gt < 2 && sna->kgem.has_semaphores) { DBG(("%s: small GT [%d], not forcing selection\n", __FUNCTION__, sna->render_state.gt)); return; } VG_CLEAR(busy); busy.handle = src->handle; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy)) return; DBG(("%s: src handle=%d busy?=%x\n", __FUNCTION__, busy.handle, busy.busy)); if (busy.busy == 0) { __kgem_bo_clear_busy(src); busy.handle = dst->handle; if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy)) return; DBG(("%s: dst handle=%d busy?=%x\n", __FUNCTION__, busy.handle, busy.busy)); if (busy.busy == 0) { __kgem_bo_clear_busy(dst); DBG(("%s: src/dst is idle, using defaults\n", __FUNCTION__)); return; } } /* Sandybridge introduced a separate ring which it uses to * perform blits. Switching rendering between rings incurs * a stall as we wait upon the old ring to finish and * flush its render cache before we can proceed on with * the operation on the new ring. * * As this buffer, we presume, has just been written to by * the DRI client using the RENDER ring, we want to perform * our operation on the same ring, and ideally on the same * ring as we will flip from (which should be the RENDER ring * as well). * * The ultimate question is whether preserving the ring outweighs * the cost of the query. */ mode = KGEM_RENDER; if ((busy.busy & 0xffff) == KGEM_BLT) mode = KGEM_BLT; kgem_bo_mark_busy(&sna->kgem, busy.handle == src->handle ? src : dst, mode); _kgem_set_mode(&sna->kgem, mode); } static bool is_front(int attachment) { return attachment == DRI2BufferFrontLeft; } #define DRI2_SYNC 0x1 #define DRI2_DAMAGE 0x2 #define DRI2_BO 0x4 static struct kgem_bo * __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region, DRI2BufferPtr src, DRI2BufferPtr dst, unsigned flags) { PixmapPtr pixmap = get_drawable_pixmap(draw); DrawableRec scratch, *src_draw = &pixmap->drawable, *dst_draw = &pixmap->drawable; struct sna_dri2_private *src_priv = get_private(src); struct sna_dri2_private *dst_priv = get_private(dst); pixman_region16_t clip; struct kgem_bo *bo = NULL; struct kgem_bo *src_bo; struct kgem_bo *dst_bo; const BoxRec *boxes; int16_t dx, dy, sx, sy; unsigned hint; int n; /* To hide a stale DRI2Buffer, one may choose to substitute * pixmap->gpu_bo instead of dst/src->bo, however you then run * the risk of copying around invalid data. So either you may not * see the results of the copy, or you may see the wrong pixels. * Either way you eventually lose. * * We also have to be careful in case that the stale buffers are * now attached to invalid (non-DRI) pixmaps. */ assert(is_front(dst->attachment) || is_front(src->attachment)); assert(dst->attachment != src->attachment); clip.extents.x1 = draw->x; clip.extents.y1 = draw->y; clip.extents.x2 = draw->x + draw->width; clip.extents.y2 = draw->y + draw->height; clip.data = NULL; if (region) { pixman_region_translate(region, draw->x, draw->y); pixman_region_intersect(&clip, &clip, region); region = &clip; } if (clip.extents.x1 >= clip.extents.x2 || clip.extents.y1 >= clip.extents.y2) { DBG(("%s: all clipped\n", __FUNCTION__)); return NULL; } sx = sy = dx = dy = 0; if (is_front(dst->attachment)) { sx = -draw->x; sy = -draw->y; } else { dx = -draw->x; dy = -draw->y; } if (draw->type == DRAWABLE_WINDOW) { WindowPtr win = (WindowPtr)draw; int16_t tx, ty; if (is_clipped(&win->clipList, draw)) { DBG(("%s: draw=(%d, %d), delta=(%d, %d), draw=(%d, %d),(%d, %d), clip.extents=(%d, %d), (%d, %d)\n", __FUNCTION__, draw->x, draw->y, get_drawable_dx(draw), get_drawable_dy(draw), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2)); assert(region == NULL || region == &clip); pixman_region_intersect(&clip, &win->clipList, &clip); if (!pixman_region_not_empty(&clip)) { DBG(("%s: all clipped\n", __FUNCTION__)); return NULL; } region = &clip; } if (get_drawable_deltas(draw, pixmap, &tx, &ty)) { if (is_front(dst->attachment)) { pixman_region_translate(region ?: &clip, tx, ty); sx -= tx; sy -= ty; } else { sx += tx; sy += ty; } } } else flags &= ~DRI2_SYNC; scratch.pScreen = draw->pScreen; scratch.x = scratch.y = 0; scratch.width = scratch.height = 0; scratch.depth = draw->depth; scratch.bitsPerPixel = draw->bitsPerPixel; src_bo = src_priv->bo; assert(src_bo->refcnt); if (is_front(src->attachment)) { struct sna_pixmap *priv; priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ); if (priv) src_bo = priv->gpu_bo; DBG(("%s: updated FrontLeft src_bo from handle=%d to handle=%d\n", __FUNCTION__, src_priv->bo->handle, src_bo->handle)); assert(src_bo->refcnt); } else { RegionRec source; scratch.width = src_priv->size & 0xffff; scratch.height = src_priv->size >> 16; src_draw = &scratch; DBG(("%s: source size %dx%d, region size %dx%d, src offset %dx%d\n", __FUNCTION__, scratch.width, scratch.height, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, -sx, -sy)); source.extents.x1 = -sx; source.extents.y1 = -sy; source.extents.x2 = source.extents.x1 + scratch.width; source.extents.y2 = source.extents.y1 + scratch.height; source.data = NULL; assert(region == NULL || region == &clip); pixman_region_intersect(&clip, &clip, &source); if (!pixman_region_not_empty(&clip)) { DBG(("%s: region doesn't overlap pixmap\n", __FUNCTION__)); return NULL; } } dst_bo = dst_priv->bo; assert(dst_bo->refcnt); if (is_front(dst->attachment)) { struct sna_pixmap *priv; struct list shadow; /* Preserve the CRTC shadow overrides */ sna_shadow_steal_crtcs(sna, &shadow); hint = MOVE_WRITE | __MOVE_FORCE; if (clip.data) hint |= MOVE_READ; assert(region == NULL || region == &clip); priv = sna_pixmap_move_area_to_gpu(pixmap, &clip.extents, hint); if (priv) { damage(pixmap, priv, region); dst_bo = priv->gpu_bo; } DBG(("%s: updated FrontLeft dst_bo from handle=%d to handle=%d\n", __FUNCTION__, dst_priv->bo->handle, dst_bo->handle)); assert(dst_bo->refcnt); sna_shadow_unsteal_crtcs(sna, &shadow); } else { RegionRec target; scratch.width = dst_priv->size & 0xffff; scratch.height = dst_priv->size >> 16; dst_draw = &scratch; DBG(("%s: target size %dx%d, region size %dx%d\n", __FUNCTION__, scratch.width, scratch.height, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)); target.extents.x1 = -dx; target.extents.y1 = -dy; target.extents.x2 = target.extents.x1 + scratch.width; target.extents.y2 = target.extents.y1 + scratch.height; target.data = NULL; assert(region == NULL || region == &clip); pixman_region_intersect(&clip, &clip, &target); flags &= ~DRI2_SYNC; } if (!wedged(sna)) { xf86CrtcPtr crtc; crtc = NULL; if (flags & DRI2_SYNC && sna_pixmap_is_scanout(sna, pixmap)) crtc = sna_covering_crtc(sna, &clip.extents, NULL); sna_dri2_select_mode(sna, dst_bo, src_bo, crtc != NULL); if (crtc == NULL || !sna_wait_for_scanline(sna, pixmap, crtc, &clip.extents)) flags &= ~DRI2_SYNC; } if (region) { boxes = region_rects(region); n = region_num_rects(region); assert(n); } else { region = &clip; boxes = &clip.extents; n = 1; } if (APPLY_DAMAGE || flags & DRI2_DAMAGE) { DBG(("%s: marking region as damaged\n", __FUNCTION__)); sna->ignore_copy_area = true; DamageRegionAppend(&pixmap->drawable, region); } DBG(("%s: copying [(%d, %d), (%d, %d)]x%d src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, boxes[0].x1, boxes[0].y1, boxes[0].x2, boxes[0].y2, n, sx, sy, dx, dy)); hint = COPY_LAST | COPY_DRI; if (flags & DRI2_SYNC) hint |= COPY_SYNC; if (!sna->render.copy_boxes(sna, GXcopy, src_draw, src_bo, sx, sy, dst_draw, dst_bo, dx, dy, boxes, n, hint)) memcpy_copy_boxes(sna, GXcopy, src_draw, src_bo, sx, sy, dst_draw, dst_bo, dx, dy, boxes, n, hint); if (flags & (DRI2_SYNC | DRI2_BO)) { /* STAT! */ struct kgem_request *rq = RQ(dst_bo->rq); if (rq && rq != (void *)&sna->kgem) { if (rq->bo == NULL) kgem_submit(&sna->kgem); if (rq->bo) { /* Becareful in case the gpu is wedged */ bo = ref(rq->bo); DBG(("%s: recording sync fence handle=%d\n", __FUNCTION__, bo->handle)); } } } if (APPLY_DAMAGE || flags & DRI2_DAMAGE) { DamageRegionProcessPending(&pixmap->drawable); sna->ignore_copy_area = false; } if (clip.data) pixman_region_fini(&clip); return bo; } static void sna_dri2_copy_region(DrawablePtr draw, RegionPtr region, DRI2BufferPtr dst, DRI2BufferPtr src) { PixmapPtr pixmap = get_drawable_pixmap(draw); struct sna *sna = to_sna_from_pixmap(pixmap); DBG(("%s: pixmap=%ld, src=%u (refs=%d/%d, flush=%d, attach=%d) , dst=%u (refs=%d/%d, flush=%d, attach=%d)\n", __FUNCTION__, pixmap->drawable.serialNumber, get_private(src)->bo->handle, get_private(src)->refcnt, get_private(src)->bo->refcnt, get_private(src)->bo->flush, src->attachment, get_private(dst)->bo->handle, get_private(dst)->refcnt, get_private(dst)->bo->refcnt, get_private(dst)->bo->flush, dst->attachment)); assert(src != dst); assert(get_private(src)->refcnt); assert(get_private(dst)->refcnt); assert(get_private(src)->bo != get_private(dst)->bo); assert(get_private(src)->bo->refcnt); assert(get_private(dst)->bo->refcnt); DBG(("%s: region (%d, %d), (%d, %d) x %d\n", __FUNCTION__, region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2, region_num_rects(region))); __sna_dri2_copy_region(sna, draw, region, src, dst, DRI2_DAMAGE); } inline static uint32_t pipe_select(int pipe) { /* The third pipe was introduced with IvyBridge long after * multiple pipe support was added to the kernel, hence * we can safely ignore the capability check - if we have more * than two pipes, we can assume that they are fully supported. */ if (pipe > 1) return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT; else if (pipe > 0) return DRM_VBLANK_SECONDARY; else return 0; } static inline bool sna_next_vblank(struct sna_dri2_event *info) { union drm_wait_vblank vbl; DBG(("%s(pipe=%d, waiting until next vblank)\n", __FUNCTION__, info->pipe)); assert(info->pipe != -1); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT | pipe_select(info->pipe); vbl.request.sequence = 1; vbl.request.signal = (uintptr_t)info; assert(!info->queued); if (drmIoctl(info->sna->kgem.fd, DRM_IOCTL_WAIT_VBLANK, &vbl)) return false; info->queued = true; return true; } static inline bool sna_wait_vblank(struct sna_dri2_event *info, unsigned seq) { union drm_wait_vblank vbl; DBG(("%s(pipe=%d, waiting until vblank %u)\n", __FUNCTION__, info->pipe, seq)); assert(info->pipe != -1); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(info->pipe); vbl.request.sequence = seq; vbl.request.signal = (uintptr_t)info; assert(!info->queued); if (drmIoctl(info->sna->kgem.fd, DRM_IOCTL_WAIT_VBLANK, &vbl)) return false; info->queued = true; return true; } #if DRI2INFOREC_VERSION >= 4 static void dri2_window_attach(WindowPtr win, struct dri2_window *priv) { assert(win->drawable.type == DRAWABLE_WINDOW); assert(dri2_window(win) == NULL); ((void **)__get_private(win, sna_window_key))[1] = priv; assert(dri2_window(win) == priv); } static uint64_t draw_current_msc(DrawablePtr draw, xf86CrtcPtr crtc, uint64_t msc) { struct dri2_window *priv; assert(draw); if (draw->type != DRAWABLE_WINDOW) return msc; priv = dri2_window((WindowPtr)draw); if (priv == NULL) { priv = malloc(sizeof(*priv)); if (priv != NULL) { priv->front = NULL; priv->crtc = crtc; priv->msc_delta = 0; priv->chain = NULL; priv->scanout = -1; priv->cache_size = 0; list_init(&priv->cache); dri2_window_attach((WindowPtr)draw, priv); } } else { if (priv->crtc != crtc) { const struct ust_msc *last = sna_crtc_last_swap(priv->crtc); const struct ust_msc *this = sna_crtc_last_swap(crtc); DBG(("%s: Window transferring from pipe=%d [msc=%llu] to pipe=%d [msc=%llu], delta now %lld\n", __FUNCTION__, sna_crtc_pipe(priv->crtc), (long long)last->msc, sna_crtc_pipe(crtc), (long long)this->msc, (long long)(priv->msc_delta + this->msc - last->msc))); priv->msc_delta += this->msc - last->msc; priv->crtc = crtc; } msc -= priv->msc_delta; } return msc; } static uint32_t draw_target_seq(DrawablePtr draw, uint64_t msc) { struct dri2_window *priv = dri2_window((WindowPtr)draw); if (priv == NULL) return msc; DBG(("%s: converting target_msc=%llu to seq %u\n", __FUNCTION__, (long long)msc, (unsigned)(msc + priv->msc_delta))); return msc + priv->msc_delta; } static xf86CrtcPtr sna_dri2_get_crtc(DrawablePtr draw) { if (draw->type == DRAWABLE_PIXMAP) return NULL; /* Make sure the CRTC is valid and this is the real front buffer */ return sna_covering_crtc(to_sna_from_drawable(draw), &((WindowPtr)draw)->clipList.extents, NULL); } static void frame_swap_complete(struct sna_dri2_event *frame, int type) { const struct ust_msc *swap; assert(frame->signal); frame->signal = false; if (frame->client == NULL) { DBG(("%s: client already gone\n", __FUNCTION__)); return; } assert(frame->draw); swap = sna_crtc_last_swap(frame->crtc); DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc=%lld], tv=%d.%06d\n", __FUNCTION__, type, (long)frame->draw->id, frame->pipe, (long long)swap->msc, (long long)draw_current_msc(frame->draw, frame->crtc, swap->msc), swap->tv_sec, swap->tv_usec)); DRI2SwapComplete(frame->client, frame->draw, draw_current_msc(frame->draw, frame->crtc, swap->msc), swap->tv_sec, swap->tv_usec, type, frame->event_complete, frame->event_data); } static void fake_swap_complete(struct sna *sna, ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc, int type, DRI2SwapEventPtr func, void *data) { const struct ust_msc *swap; assert(draw); swap = sna_crtc_last_swap(crtc); DBG(("%s(type=%d): draw=%ld, pipe=%d, frame=%lld [msc %lld], tv=%d.%06d\n", __FUNCTION__, type, (long)draw->id, crtc ? sna_crtc_pipe(crtc) : -1, (long long)swap->msc, (long long)draw_current_msc(draw, crtc, swap->msc), swap->tv_sec, swap->tv_usec)); DRI2SwapComplete(client, draw, draw_current_msc(draw, crtc, swap->msc), swap->tv_sec, swap->tv_usec, type, func, data); } static void sna_dri2_remove_event(struct sna_dri2_event *info) { WindowPtr win = (WindowPtr)info->draw; struct dri2_window *priv; assert(win->drawable.type == DRAWABLE_WINDOW); DBG(("%s: remove[%p] from window %ld, active? %d\n", __FUNCTION__, info, (long)win->drawable.id, info->draw != NULL)); assert(!info->signal); priv = dri2_window(win); assert(priv); assert(priv->chain != NULL); assert(info->chained); info->chained = false; if (priv->chain != info) { struct sna_dri2_event *chain = priv->chain; while (chain->chain != info) { assert(chain->chained); chain = chain->chain; } assert(chain != info); assert(info->chain != chain); chain->chain = info->chain; return; } priv->chain = info->chain; if (priv->chain == NULL) { struct dri_bo *c, *tmp; c = list_entry(priv->cache.next->next, struct dri_bo, link); list_for_each_entry_safe_from(c, tmp, &priv->cache, link) { list_del(&c->link); DBG(("%s: releasing cached handle=%d\n", __FUNCTION__, c->bo ? c->bo->handle : 0)); assert(c->bo); kgem_bo_destroy(&info->sna->kgem, c->bo); free(c); } } } static void sna_dri2_event_free(struct sna_dri2_event *info) { DBG(("%s(draw?=%d)\n", __FUNCTION__, info->draw != NULL)); assert(!info->queued); assert(!info->signal); assert(info->pending.bo == NULL); if (info->sna->dri2.flip_pending == info) info->sna->dri2.flip_pending = NULL; assert(info->sna->dri2.flip_pending != info); if (info->chained) sna_dri2_remove_event(info); assert((info->front == NULL && info->back == NULL) || info->front != info->back); _sna_dri2_destroy_buffer(info->sna, info->draw, info->front); _sna_dri2_destroy_buffer(info->sna, info->draw, info->back); if (info->bo) { DBG(("%s: releasing batch handle=%d\n", __FUNCTION__, info->bo->handle)); kgem_bo_destroy(&info->sna->kgem, info->bo); } _list_del(&info->link); free(info); } static void sna_dri2_client_gone(CallbackListPtr *list, void *closure, void *data) { NewClientInfoRec *clientinfo = data; ClientPtr client = clientinfo->client; struct sna_client *priv = sna_client(client); struct sna *sna = closure; if (priv->events.next == NULL) return; if (client->clientState != ClientStateGone) return; DBG(("%s(active?=%d)\n", __FUNCTION__, !list_is_empty(&priv->events))); while (!list_is_empty(&priv->events)) { struct sna_dri2_event *event; event = list_first_entry(&priv->events, struct sna_dri2_event, link); assert(event->client == client); list_del(&event->link); event->signal = false; if (event->pending.bo) { assert(event->pending.bo->active_scanout > 0); event->pending.bo->active_scanout--; kgem_bo_destroy(&sna->kgem, event->pending.bo); event->pending.bo = NULL; } if (event->chained) sna_dri2_remove_event(event); event->client = NULL; event->draw = NULL; event->keepalive = 1; assert(!event->signal); if (!event->queued) sna_dri2_event_free(event); } if (--sna->dri2.client_count == 0) DeleteCallback(&ClientStateCallback, sna_dri2_client_gone, sna); } static bool add_event_to_client(struct sna_dri2_event *info, struct sna *sna, ClientPtr client) { struct sna_client *priv = sna_client(client); if (priv->events.next == NULL) { if (sna->dri2.client_count++ == 0 && !AddCallback(&ClientStateCallback, sna_dri2_client_gone, sna)) return false; list_init(&priv->events); } list_add(&info->link, &priv->events); info->client = client; return true; } static struct sna_dri2_event * sna_dri2_add_event(struct sna *sna, DrawablePtr draw, ClientPtr client, xf86CrtcPtr crtc) { struct dri2_window *priv; struct sna_dri2_event *info, *chain; assert(draw != NULL); assert(draw->type == DRAWABLE_WINDOW); DBG(("%s: adding event to window %ld)\n", __FUNCTION__, (long)draw->id)); priv = dri2_window((WindowPtr)draw); if (priv == NULL) return NULL; info = calloc(1, sizeof(struct sna_dri2_event)); if (info == NULL) return NULL; info->sna = sna; info->draw = draw; info->crtc = crtc; info->pipe = sna_crtc_pipe(crtc); info->keepalive = 1; if (!add_event_to_client(info, sna, client)) { free(info); return NULL; } assert(priv->chain != info); info->chained = true; if (priv->chain == NULL) { priv->chain = info; return info; } chain = priv->chain; while (chain->chain != NULL) chain = chain->chain; assert(chain != info); chain->chain = info; return info; } static void decouple_window(WindowPtr win, struct dri2_window *priv, struct sna *sna, bool signal) { if (priv->front) { DBG(("%s: decouple private front\n", __FUNCTION__)); assert(priv->crtc); sna_shadow_unset_crtc(sna, priv->crtc); _sna_dri2_destroy_buffer(sna, NULL, priv->front); priv->front = NULL; } if (priv->chain) { struct sna_dri2_event *info, *chain; DBG(("%s: freeing chain\n", __FUNCTION__)); chain = priv->chain; while ((info = chain)) { DBG(("%s: freeing event, pending signal? %d, pending swap? handle=%d\n", __FUNCTION__, info->signal, info->pending.bo ? info->pending.bo->handle : 0)); assert(info->draw == &win->drawable); if (info->pending.bo) { if (signal) { bool was_signalling = info->signal; info->signal = true; frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE); info->signal = was_signalling; } assert(info->pending.bo->active_scanout > 0); info->pending.bo->active_scanout--; kgem_bo_destroy(&sna->kgem, info->pending.bo); info->pending.bo = NULL; } if (info->signal && signal) frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE); info->signal = false; info->draw = NULL; info->keepalive = 1; assert(!info->signal); list_del(&info->link); chain = info->chain; info->chain = NULL; info->chained = false; if (!info->queued) sna_dri2_event_free(info); } priv->chain = NULL; } } void sna_dri2_decouple_window(WindowPtr win) { struct dri2_window *priv; priv = dri2_window(win); if (priv == NULL) return; DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); decouple_window(win, priv, to_sna_from_drawable(&win->drawable), true); priv->scanout = -1; } void sna_dri2_destroy_window(WindowPtr win) { struct dri2_window *priv; struct sna *sna; priv = dri2_window(win); if (priv == NULL) return; DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.id)); sna = to_sna_from_drawable(&win->drawable); decouple_window(win, priv, sna, false); while (!list_is_empty(&priv->cache)) { struct dri_bo *c; c = list_first_entry(&priv->cache, struct dri_bo, link); list_del(&c->link); DBG(("%s: releasing cached handle=%d\n", __FUNCTION__, c->bo ? c->bo->handle : 0)); assert(c->bo); kgem_bo_destroy(&sna->kgem, c->bo); free(c); } free(priv); } static void sna_dri2_flip_handler(struct drm_event_vblank *event, void *data) { DBG(("%s: sequence=%d\n", __FUNCTION__, event->sequence)); sna_dri2_flip_event(data); } static bool sna_dri2_flip(struct sna_dri2_event *info) { struct kgem_bo *bo = get_private(info->back)->bo; struct kgem_bo *tmp_bo; uint32_t tmp_name, tmp_flags; int tmp_pitch; DBG(("%s(type=%d)\n", __FUNCTION__, info->type)); assert(sna_pixmap_get_buffer(info->sna->front) == info->front); assert(get_drawable_pixmap(info->draw)->drawable.height * bo->pitch <= kgem_bo_size(bo)); assert(get_private(info->front)->size == get_private(info->back)->size); assert(bo->refcnt); if (info->sna->mode.flip_active) { DBG(("%s: %d flips still active, aborting\n", __FUNCTION__, info->sna->mode.flip_active)); return false; } assert(!info->queued); if (!sna_page_flip(info->sna, bo, sna_dri2_flip_handler, info->type == FLIP_ASYNC ? NULL : info)) return false; DBG(("%s: queued flip=%p\n", __FUNCTION__, info->type == FLIP_ASYNC ? NULL : info)); assert(info->signal || info->type != FLIP_THROTTLE); assert(info->sna->dri2.flip_pending == NULL || info->sna->dri2.flip_pending == info); if (info->type != FLIP_ASYNC) info->sna->dri2.flip_pending = info; DBG(("%s: marked handle=%d as scanout, swap front (handle=%d, name=%d) and back (handle=%d, name=%d)\n", __FUNCTION__, bo->handle, get_private(info->front)->bo->handle, info->front->name, get_private(info->back)->bo->handle, info->back->name)); tmp_bo = get_private(info->front)->bo; tmp_name = info->front->name; tmp_pitch = info->front->pitch; tmp_flags = info->front->flags; assert(tmp_bo->active_scanout > 0); tmp_bo->active_scanout--; set_bo(info->sna->front, bo); info->front->flags = info->back->flags; info->front->name = info->back->name; info->front->pitch = info->back->pitch; get_private(info->front)->bo = bo; bo->active_scanout++; assert(bo->active_scanout <= bo->refcnt); info->back->flags = tmp_flags; info->back->name = tmp_name; info->back->pitch = tmp_pitch; get_private(info->back)->bo = tmp_bo; mark_stale(info->back); assert(get_private(info->front)->bo->refcnt); assert(get_private(info->back)->bo->refcnt); assert(get_private(info->front)->bo != get_private(info->back)->bo); info->keepalive = KEEPALIVE; info->queued = true; return true; } static bool can_flip(struct sna * sna, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back, xf86CrtcPtr crtc) { WindowPtr win = (WindowPtr)draw; PixmapPtr pixmap; assert((sna->flags & SNA_NO_WAIT) == 0); if (!DBG_CAN_FLIP) return false; if (draw->type == DRAWABLE_PIXMAP) return false; if (!sna->mode.front_active) { DBG(("%s: no, active CRTC\n", __FUNCTION__)); return false; } assert(sna->scrn->vtSema); assert(!sna->mode.hidden); if ((sna->flags & (SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP)) == 0) { DBG(("%s: no, pageflips disabled\n", __FUNCTION__)); return false; } if (front->cpp != back->cpp) { DBG(("%s: no, format mismatch, front = %d, back = %d\n", __FUNCTION__, front->cpp, back->cpp)); return false; } if (sna->mode.shadow_active) { DBG(("%s: no, shadow enabled\n", __FUNCTION__)); return false; } if (!sna_crtc_is_on(crtc)) { DBG(("%s: ref-pipe=%d is disabled\n", __FUNCTION__, sna_crtc_pipe(crtc))); return false; } pixmap = get_window_pixmap(win); if (pixmap != sna->front) { DBG(("%s: no, window (pixmap=%ld) is not attached to the front buffer (pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber, sna->front->drawable.serialNumber)); return false; } if (sna_pixmap_get_buffer(pixmap) != front) { DBG(("%s: no, DRI2 drawable is no longer attached (old name=%d, new name=%d) to pixmap=%ld\n", __FUNCTION__, front->name, sna_pixmap_get_buffer(pixmap) ? sna_pixmap_get_buffer(pixmap)->name : 0, pixmap->drawable.serialNumber)); return false; } assert(get_private(front)->pixmap == sna->front); assert(sna_pixmap(sna->front)->gpu_bo == get_private(front)->bo); if (!get_private(back)->bo->scanout) { DBG(("%s: no, DRI2 drawable was too small at time of creation)\n", __FUNCTION__)); return false; } if (get_private(back)->size != get_private(front)->size) { DBG(("%s: no, DRI2 drawable does not fit into scanout\n", __FUNCTION__)); return false; } DBG(("%s: window size: %dx%d, clip=(%d, %d), (%d, %d) x %d\n", __FUNCTION__, win->drawable.width, win->drawable.height, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2, region_num_rects(&win->clipList))); if (!RegionEqual(&win->clipList, &draw->pScreen->root->winSize)) { DBG(("%s: no, window is clipped: clip region=(%d, %d), (%d, %d), root size=(%d, %d), (%d, %d)\n", __FUNCTION__, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2, draw->pScreen->root->winSize.extents.x1, draw->pScreen->root->winSize.extents.y1, draw->pScreen->root->winSize.extents.x2, draw->pScreen->root->winSize.extents.y2)); return false; } if (draw->x != 0 || draw->y != 0 || #ifdef COMPOSITE draw->x != pixmap->screen_x || draw->y != pixmap->screen_y || #endif draw->width != pixmap->drawable.width || draw->height != pixmap->drawable.height) { DBG(("%s: no, window is not full size (%dx%d)!=(%dx%d)\n", __FUNCTION__, draw->width, draw->height, pixmap->drawable.width, pixmap->drawable.height)); return false; } /* prevent an implicit tiling mode change */ if (get_private(back)->bo->tiling > I915_TILING_X) { DBG(("%s -- no, tiling mismatch: front %d, back=%d, want-tiled?=%d\n", __FUNCTION__, get_private(front)->bo->tiling, get_private(back)->bo->tiling, !!(sna->flags & SNA_LINEAR_FB))); return false; } if (get_private(front)->bo->pitch != get_private(back)->bo->pitch) { DBG(("%s -- no, pitch mismatch: front %d, back=%d\n", __FUNCTION__, get_private(front)->bo->pitch, get_private(back)->bo->pitch)); return false; } if (sna_pixmap(pixmap)->pinned & ~(PIN_DRI2 | PIN_SCANOUT)) { DBG(("%s -- no, pinned: front %x\n", __FUNCTION__, sna_pixmap(pixmap)->pinned)); return false; } DBG(("%s: yes, pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); return true; } static bool can_xchg(struct sna *sna, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) { WindowPtr win = (WindowPtr)draw; PixmapPtr pixmap; if (!DBG_CAN_XCHG) return false; if (draw->type == DRAWABLE_PIXMAP) return false; if (front->cpp != back->cpp) { DBG(("%s: no, format mismatch, front = %d, back = %d\n", __FUNCTION__, front->cpp, back->cpp)); return false; } pixmap = get_window_pixmap(win); if (get_private(front)->pixmap != pixmap) { DBG(("%s: no, DRI2 drawable is no longer attached, old pixmap=%ld, now pixmap=%ld\n", __FUNCTION__, get_private(front)->pixmap->drawable.serialNumber, pixmap->drawable.serialNumber)); return false; } DBG(("%s: window size: %dx%d, clip=(%d, %d), (%d, %d) x %d, pixmap size=%dx%d\n", __FUNCTION__, win->drawable.width, win->drawable.height, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2, region_num_rects(&win->clipList), pixmap->drawable.width, pixmap->drawable.height)); if (is_clipped(&win->clipList, &pixmap->drawable)) { DBG(("%s: no, %dx%d window is clipped: clip region=(%d, %d), (%d, %d)\n", __FUNCTION__, draw->width, draw->height, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2)); return false; } DBG(("%s: back size=%x, front size=%x\n", __FUNCTION__, get_private(back)->size, get_private(front)->size)); if (get_private(back)->size != get_private(front)->size) { DBG(("%s: no, back buffer %dx%d does not match front buffer %dx%d\n", __FUNCTION__, get_private(back)->size & 0x7fff, (get_private(back)->size >> 16) & 0x7fff, get_private(front)->size & 0x7fff, (get_private(front)->size >> 16) & 0x7fff)); return false; } if (pixmap == sna->front && !(sna->flags & SNA_TEAR_FREE) && sna->mode.front_active) { DBG(("%s: no, front buffer, requires flipping\n", __FUNCTION__)); return false; } if (sna_pixmap(pixmap)->pinned & ~(PIN_DRI2 | PIN_SCANOUT)) { DBG(("%s: no, pinned: %x\n", __FUNCTION__, sna_pixmap(pixmap)->pinned)); return false; } DBG(("%s: yes, pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); return true; } static bool overlaps_other_crtc(struct sna *sna, xf86CrtcPtr desired) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int c; for (c = 0; c < sna->mode.num_real_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; if (crtc == desired) continue; if (!crtc->enabled) continue; if (desired->bounds.x1 < crtc->bounds.x2 && desired->bounds.x2 > crtc->bounds.x1 && desired->bounds.y1 < crtc->bounds.y2 && desired->bounds.y2 > crtc->bounds.y1) return true; } return false; } static bool can_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc, DRI2BufferPtr front, DRI2BufferPtr back) { WindowPtr win = (WindowPtr)draw; PixmapPtr pixmap; if (!DBG_CAN_XCHG) return false; if ((sna->flags & SNA_TEAR_FREE) == 0) { DBG(("%s: no, requires TearFree\n", __FUNCTION__)); return false; } if (draw->type == DRAWABLE_PIXMAP) return false; if (front->cpp != back->cpp) { DBG(("%s: no, format mismatch, front = %d, back = %d\n", __FUNCTION__, front->cpp, back->cpp)); return false; } if (memcmp(&win->clipList.extents, &crtc->bounds, sizeof(crtc->bounds))) { DBG(("%s: no, window [(%d, %d), (%d, %d)] does not cover CRTC [(%d, %d), (%d, %d)]\n", __FUNCTION__, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2, crtc->bounds.x1, crtc->bounds.y1, crtc->bounds.x2, crtc->bounds.y2)); return false; } if (sna_crtc_is_transformed(crtc)) { DBG(("%s: no, CRTC is rotated\n", __FUNCTION__)); return false; } pixmap = get_window_pixmap(win); if (pixmap != sna->front) { DBG(("%s: no, not attached to front buffer\n", __FUNCTION__)); return false; } if (get_private(front)->pixmap != pixmap) { DBG(("%s: no, DRI2 drawable is no longer attached, old pixmap=%ld, now pixmap=%ld\n", __FUNCTION__, get_private(front)->pixmap->drawable.serialNumber, pixmap->drawable.serialNumber)); return false; } DBG(("%s: window size: %dx%d, clip=(%d, %d), (%d, %d) x %d\n", __FUNCTION__, win->drawable.width, win->drawable.height, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2, region_num_rects(&win->clipList))); if (is_clipped(&win->clipList, &win->drawable)) { DBG(("%s: no, %dx%d window is clipped: clip region=(%d, %d), (%d, %d)\n", __FUNCTION__, draw->width, draw->height, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2)); return false; } if (overlaps_other_crtc(sna, crtc)) { DBG(("%s: no, overlaps other CRTC\n", __FUNCTION__)); return false; } if (get_private(back)->size != (draw->height << 16 | draw->width)) { DBG(("%s: no, DRI2 buffers does not fit window\n", __FUNCTION__)); return false; } assert(win != win->drawable.pScreen->root); DBG(("%s: yes, pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); return true; } static void sna_dri2_xchg(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) { WindowPtr win = (WindowPtr)draw; struct kgem_bo *back_bo, *front_bo; PixmapPtr pixmap; int tmp; assert(draw->type != DRAWABLE_PIXMAP); pixmap = get_window_pixmap(win); back_bo = get_private(back)->bo; front_bo = get_private(front)->bo; DBG(("%s: win=%ld, exchange front=%d/%d,ref=%d and back=%d/%d,ref=%d, pixmap=%ld %dx%d\n", __FUNCTION__, win->drawable.id, front_bo->handle, front->name, get_private(front)->refcnt, back_bo->handle, back->name, get_private(back)->refcnt, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height)); DBG(("%s: back_bo handle=%d, pitch=%d, size=%d, ref=%d, active_scanout?=%d\n", __FUNCTION__, back_bo->handle, back_bo->pitch, kgem_bo_size(back_bo), back_bo->refcnt, back_bo->active_scanout)); DBG(("%s: front_bo handle=%d, pitch=%d, size=%d, ref=%d, active_scanout?=%d\n", __FUNCTION__, front_bo->handle, front_bo->pitch, kgem_bo_size(front_bo), front_bo->refcnt, front_bo->active_scanout)); assert(front_bo != back_bo); assert(front_bo->refcnt); assert(back_bo->refcnt); assert(sna_pixmap_get_buffer(pixmap) == front); assert(pixmap->drawable.height * back_bo->pitch <= kgem_bo_size(back_bo)); assert(pixmap->drawable.height * front_bo->pitch <= kgem_bo_size(front_bo)); set_bo(pixmap, back_bo); get_private(front)->bo = back_bo; get_private(back)->bo = front_bo; mark_stale(back); assert(front_bo->active_scanout > 0); front_bo->active_scanout--; back_bo->active_scanout++; assert(back_bo->active_scanout <= back_bo->refcnt); tmp = front->name; front->name = back->name; back->name = tmp; tmp = front->pitch; front->pitch = back->pitch; back->pitch = tmp; tmp = front->flags; front->flags = back->flags; back->flags = tmp; assert(front_bo->refcnt); assert(back_bo->refcnt); assert(front_bo->pitch == get_private(front)->bo->pitch); assert(back_bo->pitch == get_private(back)->bo->pitch); assert(get_private(front)->bo == sna_pixmap(pixmap)->gpu_bo); } static void sna_dri2_xchg_crtc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc, DRI2BufferPtr front, DRI2BufferPtr back) { WindowPtr win = (WindowPtr)draw; struct dri2_window *priv = dri2_window(win); DBG(("%s: exchange front=%d/%d and back=%d/%d, win id=%lu, pixmap=%ld %dx%d\n", __FUNCTION__, get_private(front)->bo->handle, front->name, get_private(back)->bo->handle, back->name, win->drawable.id, get_window_pixmap(win)->drawable.serialNumber, get_window_pixmap(win)->drawable.width, get_window_pixmap(win)->drawable.height)); assert(can_xchg_crtc(sna, draw, crtc, front, back)); if (APPLY_DAMAGE) { DBG(("%s: marking drawable as damaged\n", __FUNCTION__)); sna->ignore_copy_area = true; DamageRegionAppend(&win->drawable, &win->clipList); } sna_shadow_set_crtc(sna, crtc, get_private(back)->bo); if (APPLY_DAMAGE) { DamageRegionProcessPending(&win->drawable); sna->ignore_copy_area = false; } if (priv->front == NULL) { DRI2Buffer2Ptr tmp; tmp = calloc(1, sizeof(*tmp) + sizeof(struct sna_dri2_private)); if (tmp == NULL) { sna_shadow_unset_crtc(sna, crtc); return; } tmp->attachment = DRI2BufferFrontLeft; tmp->driverPrivate = tmp + 1; tmp->cpp = back->cpp; tmp->format = back->format; get_private(tmp)->refcnt = 1; get_private(tmp)->bo = kgem_create_2d(&sna->kgem, draw->width, draw->height, draw->bitsPerPixel, get_private(back)->bo->tiling, CREATE_SCANOUT | CREATE_EXACT); if (get_private(tmp)->bo != NULL) { tmp->pitch = get_private(tmp)->bo->pitch; tmp->name = kgem_bo_flink(&sna->kgem, get_private(tmp)->bo); } if (tmp->name == 0) { if (get_private(tmp)->bo != NULL) kgem_bo_destroy(&sna->kgem, get_private(tmp)->bo); sna_shadow_unset_crtc(sna, crtc); return; } get_private(tmp)->size = get_private(back)->size; get_private(tmp)->pixmap = get_private(front)->pixmap; get_private(tmp)->proxy = sna_dri2_reference_buffer(front); get_private(tmp)->bo->active_scanout++; priv->front = front = tmp; } assert(front == priv->front); { struct kgem_bo *front_bo = get_private(front)->bo; struct kgem_bo *back_bo = get_private(back)->bo; unsigned tmp; assert(front_bo->refcnt); assert(back_bo->refcnt); get_private(back)->bo = front_bo; get_private(front)->bo = back_bo; mark_stale(back); assert(front_bo->active_scanout > 0); front_bo->active_scanout--; back_bo->active_scanout++; assert(back_bo->active_scanout <= back_bo->refcnt); tmp = front->name; front->name = back->name; back->name = tmp; tmp = front->pitch; front->pitch = back->pitch; back->pitch = tmp; tmp = front->flags; front->flags = back->flags; back->flags = tmp; } } static void chain_swap(struct sna_dri2_event *chain) { DBG(("%s: draw=%ld, queued?=%d, type=%d\n", __FUNCTION__, (long)chain->draw->id, chain->queued, chain->type)); if (chain->queued) /* too early! */ return; if (chain->draw == NULL) { sna_dri2_event_free(chain); return; } assert(chain == dri2_chain(chain->draw)); assert(chain->signal); switch (chain->type) { case SWAP_COMPLETE: DBG(("%s: emitting chained vsync'ed blit\n", __FUNCTION__)); if (chain->sna->mode.shadow && chain->sna->mode.shadow_wait) { /* recursed from wait_for_shadow(), simply requeue */ DBG(("%s -- recursed from wait_for_shadow(), requeuing\n", __FUNCTION__)); if (sna_next_vblank(chain)) return; DBG(("%s -- requeue failed, errno=%d\n", __FUNCTION__, errno)); } if (can_xchg(chain->sna, chain->draw, chain->front, chain->back)) { sna_dri2_xchg(chain->draw, chain->front, chain->back); } else if (can_xchg_crtc(chain->sna, chain->draw, chain->crtc, chain->front, chain->back)) { sna_dri2_xchg_crtc(chain->sna, chain->draw, chain->crtc, chain->front, chain->back); } else { __sna_dri2_copy_event(chain, chain->sync | DRI2_BO); } assert(get_private(chain->back)->bo != get_private(chain->front)->bo); case SWAP: break; default: return; } if ((chain->type == SWAP_COMPLETE && !swap_limit(chain->draw, 2 + !chain->sync) && !chain->sync) || !sna_next_vblank(chain)) { DBG(("%s: vblank wait failed, unblocking client\n", __FUNCTION__)); frame_swap_complete(chain, DRI2_BLIT_COMPLETE); sna_dri2_event_free(chain); } } static inline bool rq_is_busy(struct kgem *kgem, struct kgem_bo *bo) { if (bo == NULL) return false; DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__, bo->handle, bo->domain, bo->exec != NULL, bo->rq != NULL)); assert(bo->refcnt); if (bo->exec) return true; if (bo->rq == NULL) return false; return __kgem_busy(kgem, bo->handle); } static bool sna_dri2_blit_complete(struct sna_dri2_event *info) { if (rq_is_busy(&info->sna->kgem, info->bo)) { DBG(("%s: vsync'ed blit is still busy, postponing\n", __FUNCTION__)); if (sna_next_vblank(info)) return false; } DBG(("%s: blit finished\n", __FUNCTION__)); if (info->bo) { kgem_bo_destroy(&info->sna->kgem, info->bo); info->bo = NULL; } return true; } void sna_dri2_vblank_handler(struct drm_event_vblank *event) { struct sna_dri2_event *info = (void *)(uintptr_t)event->user_data; struct sna *sna = info->sna; DrawablePtr draw; uint64_t msc; DBG(("%s(type=%d, sequence=%d, draw=%ld)\n", __FUNCTION__, info->type, event->sequence, info->draw ? info->draw->serialNumber : 0)); assert(info->queued); info->queued = false; msc = sna_crtc_record_event(info->crtc, event); draw = info->draw; if (draw == NULL) { DBG(("%s -- drawable gone\n", __FUNCTION__)); goto done; } assert((info->front == NULL && info->back == NULL) || info->front != info->back); switch (info->type) { case FLIP: /* If we can still flip... */ assert(info->signal); if (can_flip(sna, draw, info->front, info->back, info->crtc) && sna_dri2_flip(info)) return; /* else fall through to blit */ case SWAP: assert(info->signal); if (sna->mode.shadow && sna->mode.shadow_wait) { /* recursed from wait_for_shadow(), simply requeue */ DBG(("%s -- recursed from wait_for_shadow(), requeuing\n", __FUNCTION__)); } else if (can_xchg(info->sna, draw, info->front, info->back)) { sna_dri2_xchg(draw, info->front, info->back); info->type = SWAP_COMPLETE; } else if (can_xchg_crtc(sna, draw, info->crtc, info->front, info->back)) { sna_dri2_xchg_crtc(sna, draw, info->crtc, info->front, info->back); info->type = SWAP_COMPLETE; } else { __sna_dri2_copy_event(info, DRI2_BO | DRI2_SYNC); info->type = SWAP_COMPLETE; } if (sna_next_vblank(info)) return; DBG(("%s -- requeue failed, errno=%d\n", __FUNCTION__, errno)); assert(info->pending.bo == NULL); assert(info->keepalive == 1); /* fall through to SwapComplete */ case SWAP_COMPLETE: DBG(("%s: %d complete, frame=%d tv=%d.%06d\n", __FUNCTION__, info->type, event->sequence, event->tv_sec, event->tv_usec)); if (info->signal) { if (!sna_dri2_blit_complete(info)) return; DBG(("%s: triple buffer swap complete, unblocking client (frame=%d, tv=%d.%06d)\n", __FUNCTION__, event->sequence, event->tv_sec, event->tv_usec)); frame_swap_complete(info, DRI2_BLIT_COMPLETE); } if (info->pending.bo) { DBG(("%s: swapping old back handle=%d [name=%d, active=%d] for pending handle=%d [name=%d, active=%d], front handle=%d [name=%d, active=%d]\n", __FUNCTION__, get_private(info->back)->bo->handle, info->back->name, get_private(info->back)->bo->active_scanout, info->pending.bo->handle, info->pending.name, info->pending.bo->active_scanout, get_private(info->front)->bo->handle, info->front->name, get_private(info->front)->bo->active_scanout)); if (sna->mode.shadow && sna->mode.shadow_wait) { /* recursed from wait_for_shadow(), simply requeue */ DBG(("%s -- recursed from wait_for_shadow(), requeuing\n", __FUNCTION__)); if (sna_next_vblank(info)) return; } assert(info->pending.bo->active_scanout > 0); info->pending.bo->active_scanout--; sna_dri2_cache_bo(info->sna, info->draw, get_private(info->back)->bo, info->back->name, get_private(info->back)->size, info->back->flags); get_private(info->back)->bo = info->pending.bo; get_private(info->back)->size = info->pending.size; info->back->name = info->pending.name; info->back->pitch = info->pending.bo->pitch; info->back->flags = info->pending.flags; info->pending.bo = NULL; assert(get_private(info->back)->bo != get_private(info->front)->bo); if (can_xchg(info->sna, info->draw, info->front, info->back)) sna_dri2_xchg(info->draw, info->front, info->back); else if (can_xchg_crtc(info->sna, info->draw, info->crtc, info->front, info->back)) sna_dri2_xchg_crtc(info->sna, info->draw, info->crtc, info->front, info->back); else __sna_dri2_copy_event(info, info->sync | DRI2_BO); assert(info->draw); info->keepalive++; info->signal = true; } if (--info->keepalive) { if (sna_next_vblank(info)) return; if (info->signal) { DBG(("%s: triple buffer swap complete, unblocking client (frame=%d, tv=%d.%06d)\n", __FUNCTION__, event->sequence, event->tv_sec, event->tv_usec)); frame_swap_complete(info, DRI2_BLIT_COMPLETE); } } break; case WAITMSC: assert(info->client); DRI2WaitMSCComplete(info->client, draw, msc, event->tv_sec, event->tv_usec); break; default: xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); /* Unknown type */ break; } if (info->chain) { DBG(("%s: continuing chain\n", __FUNCTION__)); assert(info->chain != info); assert(info->draw == draw); sna_dri2_remove_event(info); chain_swap(info->chain); } done: sna_dri2_event_free(info); DBG(("%s complete\n", __FUNCTION__)); } static void sna_dri2_immediate_blit(struct sna *sna, struct sna_dri2_event *info, bool sync) { struct sna_dri2_event *chain = dri2_chain(info->draw); if (sna->flags & SNA_NO_WAIT) sync = false; DBG(("%s: emitting immediate blit, throttling client, synced? %d, chained? %d, pipe %d\n", __FUNCTION__, sync, chain != info, info->pipe)); assert(chain); info->type = SWAP_COMPLETE; info->sync = sync; info->keepalive = KEEPALIVE; if (chain == info) { DBG(("%s: no pending blit, starting chain\n", __FUNCTION__)); assert(info->front != info->back); if (can_xchg(info->sna, info->draw, info->front, info->back)) { sna_dri2_xchg(info->draw, info->front, info->back); } else if (can_xchg_crtc(info->sna, info->draw, info->crtc, info->front, info->back)) { sna_dri2_xchg_crtc(info->sna, info->draw, info->crtc, info->front, info->back); } else __sna_dri2_copy_event(info, sync | DRI2_BO); assert(info->signal); if ((!swap_limit(info->draw, 2 + !sync) && !sync) || !sna_next_vblank(info)) { DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__)); frame_swap_complete(info, DRI2_BLIT_COMPLETE); sna_dri2_event_free(info); } return; } DBG(("%s: current event front=%d [name=%d, active?=%d], back=%d [name=%d, active?=%d]\n", __FUNCTION__, get_private(chain->front)->bo->handle, chain->front->name, get_private(chain->front)->bo->active_scanout, get_private(chain->back)->bo->handle, chain->back->name, get_private(chain->back)->bo->active_scanout)); if (chain->type == SWAP_COMPLETE) { assert(chain->draw == info->draw); assert(chain->front == info->front); assert(chain->client == info->client); assert(chain->event_complete == info->event_complete); assert(chain->event_data == info->event_data); assert(chain->queued); if ((!sync || !chain->sync) && chain->pending.bo) { bool signal = chain->signal; DBG(("%s: swap elision, unblocking client\n", __FUNCTION__)); assert(chain->draw); chain->signal = true; frame_swap_complete(chain, DRI2_EXCHANGE_COMPLETE); chain->signal = signal; assert(chain->pending.bo->active_scanout > 0); chain->pending.bo->active_scanout--; sna_dri2_cache_bo(chain->sna, chain->draw, chain->pending.bo, chain->pending.name, chain->pending.size, chain->pending.flags); chain->pending.bo = NULL; } if (chain->pending.bo == NULL && swap_limit(info->draw, 2 + !sync)) { DBG(("%s: setting handle=%d as pending blit (current event front=%d, back=%d)\n", __FUNCTION__, get_private(info->back)->bo->handle, get_private(chain->front)->bo->handle, get_private(chain->back)->bo->handle)); chain->pending.bo = ref(get_private(info->back)->bo); chain->pending.size = get_private(info->back)->size; chain->pending.name = info->back->name; chain->pending.flags = info->back->flags; chain->sync = sync; info->signal = false; /* transfer signal to pending */ /* Prevent us from handing it back on next GetBuffers */ chain->pending.bo->active_scanout++; sna_dri2_event_free(info); return; } } DBG(("%s: pending blit, chained\n", __FUNCTION__)); } static bool sna_dri2_flip_continue(struct sna_dri2_event *info) { struct kgem_bo *bo = get_private(info->front)->bo; DBG(("%s(mode=%d)\n", __FUNCTION__, info->flip_continue)); assert(info->flip_continue > 0); info->type = info->flip_continue; info->flip_continue = 0; if (info->draw == NULL) return false; if (info->sna->mode.front_active == 0) return false; if (bo != sna_pixmap(info->sna->front)->gpu_bo) return false; assert(!info->queued); if (!sna_page_flip(info->sna, bo, sna_dri2_flip_handler, info)) return false; DBG(("%s: queued flip=%p\n", __FUNCTION__, info)); assert(info->sna->dri2.flip_pending == NULL || info->sna->dri2.flip_pending == info); info->sna->dri2.flip_pending = info; info->queued = true; assert(info->draw); info->signal = info->type == FLIP_THROTTLE; return true; } static bool sna_dri2_flip_keepalive(struct sna_dri2_event *info) { DBG(("%s(keepalive?=%d)\n", __FUNCTION__, info->keepalive-1)); assert(info->keepalive > 0); if (!--info->keepalive) return false; if (info->draw == NULL) return false; DBG(("%s: marking next flip as complete\n", __FUNCTION__)); info->flip_continue = FLIP_COMPLETE; return sna_dri2_flip_continue(info); } static void chain_flip(struct sna *sna) { struct sna_dri2_event *chain = sna->dri2.flip_pending; assert(chain->type == FLIP); DBG(("%s: chaining type=%d, cancelled?=%d window=%ld\n", __FUNCTION__, chain->type, chain->draw == NULL, chain->draw ? chain->draw->id : 0)); sna->dri2.flip_pending = NULL; if (chain->draw == NULL) { sna_dri2_event_free(chain); return; } assert(chain == dri2_chain(chain->draw)); assert(!chain->queued); if (can_flip(sna, chain->draw, chain->front, chain->back, chain->crtc) && sna_dri2_flip(chain)) { DBG(("%s: performing chained flip\n", __FUNCTION__)); } else { DBG(("%s: emitting chained vsync'ed blit\n", __FUNCTION__)); __sna_dri2_copy_event(chain, DRI2_SYNC); if (xorg_can_triple_buffer()) { chain->type = SWAP_COMPLETE; assert(chain->signal); if (sna_next_vblank(chain)) return; } DBG(("%s: fake triple buffering (or vblank wait failed), unblocking client\n", __FUNCTION__)); frame_swap_complete(chain, DRI2_BLIT_COMPLETE); sna_dri2_event_free(chain); } } static void sna_dri2_flip_event(struct sna_dri2_event *flip) { struct sna *sna = flip->sna; DBG(("%s flip=%p (pipe=%d, event=%d, queued?=%d)\n", __FUNCTION__, flip, flip->pipe, flip->type, flip->queued)); if (!flip->queued) /* pageflip died whilst being queued */ return; flip->queued = false; if (sna->dri2.flip_pending == flip) sna->dri2.flip_pending = NULL; /* We assume our flips arrive in order, so we don't check the frame */ switch (flip->type) { case FLIP: if (flip->signal) { DBG(("%s: swap complete, unblocking client\n", __FUNCTION__)); frame_swap_complete(flip, DRI2_FLIP_COMPLETE); } sna_dri2_event_free(flip); if (sna->dri2.flip_pending) chain_flip(sna); break; case FLIP_THROTTLE: if (flip->signal) { DBG(("%s: triple buffer swap complete, unblocking client\n", __FUNCTION__)); frame_swap_complete(flip, DRI2_FLIP_COMPLETE); } case FLIP_COMPLETE: assert(!flip->signal); if (sna->dri2.flip_pending) { DBG(("%s: pending flip\n", __FUNCTION__)); sna_dri2_event_free(flip); chain_flip(sna); } else if (!flip->flip_continue) { DBG(("%s: flip chain complete\n", __FUNCTION__)); if (!sna_dri2_flip_keepalive(flip)) { if (flip->chain) { sna_dri2_remove_event(flip); chain_swap(flip->chain); } sna_dri2_event_free(flip); } } else if (!sna_dri2_flip_continue(flip)) { DBG(("%s: no longer able to flip\n", __FUNCTION__)); if (flip->draw != NULL) __sna_dri2_copy_event(flip, 0); if (flip->signal) { DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__)); frame_swap_complete(flip, DRI2_BLIT_COMPLETE); } sna_dri2_event_free(flip); } break; default: /* Unknown type */ xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); sna_dri2_event_free(flip); if (sna->dri2.flip_pending) chain_flip(sna); break; } } static int sna_query_vblank(struct sna *sna, xf86CrtcPtr crtc, union drm_wait_vblank *vbl) { VG_CLEAR(*vbl); vbl->request.type = _DRM_VBLANK_RELATIVE | pipe_select(sna_crtc_pipe(crtc)); vbl->request.sequence = 0; return drmIoctl(sna->kgem.fd, DRM_IOCTL_WAIT_VBLANK, vbl); } static uint64_t get_current_msc(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc) { union drm_wait_vblank vbl; uint64_t ret; if (sna_query_vblank(sna, crtc, &vbl) == 0) ret = sna_crtc_record_vblank(crtc, &vbl); else ret = sna_crtc_last_swap(crtc)->msc; return draw_current_msc(draw, crtc, ret); } #if defined(CHECK_FOR_COMPOSITOR) static Bool find(pointer value, XID id, pointer cdata) { return TRUE; } #endif static int use_triple_buffer(struct sna *sna, ClientPtr client, bool async) { if ((sna->flags & SNA_TRIPLE_BUFFER) == 0) { DBG(("%s: triple buffer disabled, using FLIP\n", __FUNCTION__)); return FLIP; } if (async) { DBG(("%s: running async, using %s\n", __FUNCTION__, sna->flags & SNA_HAS_ASYNC_FLIP ? "FLIP_ASYNC" : "FLIP_COMPLETE")); return sna->flags & SNA_HAS_ASYNC_FLIP ? FLIP_ASYNC : FLIP_COMPLETE; } if (xorg_can_triple_buffer()) { DBG(("%s: triple buffer enabled, using FLIP_THROTTLE\n", __FUNCTION__)); return FLIP_THROTTLE; } #if defined(CHECK_FOR_COMPOSITOR) /* Hack: Disable triple buffering for compositors */ { struct sna_client *priv = sna_client(client); if (priv->is_compositor == 0) priv->is_compositor = LookupClientResourceComplex(client, CompositeClientWindowType+1, find, NULL) ? FLIP : FLIP_COMPLETE; DBG(("%s: fake triple buffer enabled?=%d using %s\n", __FUNCTION__, priv->is_compositor != FLIP, priv->is_compositor == FLIP ? "FLIP" : "FLIP_COMPLETE")); return priv->is_compositor; } #else DBG(("%s: fake triple buffer enabled, using FLIP_COMPLETE\n", __FUNCTION__)); return FLIP_COMPLETE; #endif } static bool immediate_swap(struct sna *sna, DrawablePtr draw, xf86CrtcPtr crtc, uint64_t *target_msc, uint64_t divisor, uint64_t remainder, uint64_t *current_msc) { /* * If divisor is zero, or current_msc is smaller than target_msc * we just need to make sure target_msc passes before initiating * the swap. */ if (divisor == 0) { *current_msc = -1; if (sna->flags & SNA_NO_WAIT) { DBG(("%s: yes, waits are disabled\n", __FUNCTION__)); return true; } if (*target_msc) *current_msc = get_current_msc(sna, draw, crtc); DBG(("%s: current_msc=%ld, target_msc=%ld -- %s\n", __FUNCTION__, (long)*current_msc, (long)*target_msc, (*current_msc >= *target_msc - 1) ? "yes" : "no")); return *current_msc >= *target_msc - 1; } DBG(("%s: explicit waits requests, divisor=%ld\n", __FUNCTION__, (long)divisor)); *current_msc = get_current_msc(sna, draw, crtc); if (*current_msc >= *target_msc) { DBG(("%s: missed target, queueing event for next: current=%lld, target=%lld, divisor=%lld, remainder=%lld\n", __FUNCTION__, (long long)*current_msc, (long long)*target_msc, (long long)divisor, (long long)remainder)); *target_msc = *current_msc + remainder - *current_msc % divisor; if (*target_msc <= *current_msc) *target_msc += divisor; } DBG(("%s: target_msc=%lld, current_msc=%lld, immediate?=%d\n", __FUNCTION__, (long long)*target_msc, (long long)*current_msc, *current_msc >= *target_msc - 1)); return *current_msc >= *target_msc - 1; } static bool sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc, DRI2BufferPtr front, DRI2BufferPtr back, bool immediate, CARD64 *target_msc, CARD64 current_msc, DRI2SwapEventPtr func, void *data) { struct sna *sna = to_sna_from_drawable(draw); struct sna_dri2_event *info; if (immediate) { bool signal = false; info = sna->dri2.flip_pending; DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d, continuation? %d\n", __FUNCTION__, sna_crtc_pipe(crtc), info != NULL, info ? info->flip_continue : 0, info && info->draw == draw)); if (info && info->draw == draw) { assert(info->type != FLIP); assert(info->queued); assert(info->front != info->back); if (info->front != front) { assert(info->front != NULL); _sna_dri2_destroy_buffer(sna, draw, info->front); info->front = sna_dri2_reference_buffer(front); } if (info->back != back) { assert(info->back != NULL); _sna_dri2_destroy_buffer(sna, draw, info->back); info->back = sna_dri2_reference_buffer(back); } assert(info->front != info->back); DBG(("%s: executing xchg of pending flip: flip_continue=%d, keepalive=%d, chain?=%d\n", __FUNCTION__, info->flip_continue, info->keepalive, current_msc < *target_msc)); sna_dri2_xchg(draw, front, back); info->keepalive = KEEPALIVE; if (xorg_can_triple_buffer() && current_msc < *target_msc) { DBG(("%s: chaining flip\n", __FUNCTION__)); info->flip_continue = FLIP_THROTTLE; goto out; } else { info->flip_continue = FLIP_COMPLETE; signal = info->signal; assert(info->draw); info->signal = true; goto new_back; } } info = sna_dri2_add_event(sna, draw, client, crtc); if (info == NULL) return false; assert(info->crtc == crtc); info->event_complete = func; info->event_data = data; assert(info->draw); info->signal = true; assert(front != back); info->front = sna_dri2_reference_buffer(front); info->back = sna_dri2_reference_buffer(back); if (sna->dri2.flip_pending) { /* We need to first wait (one vblank) for the * async flips to complete before this client * can take over. */ DBG(("%s: queueing flip after pending completion\n", __FUNCTION__)); info->type = FLIP; sna->dri2.flip_pending = info; current_msc++; } else if (sna->mode.flip_active) { DBG(("%s: %d outstanding flips from old client, queueing\n", __FUNCTION__, sna->mode.flip_active)); goto queue; } else { info->type = use_triple_buffer(sna, client, *target_msc == 0); if (!sna_dri2_flip(info)) { DBG(("%s: flip failed, falling back\n", __FUNCTION__)); info->signal = false; sna_dri2_event_free(info); return false; } assert(get_private(info->front)->bo->active_scanout); } swap_limit(draw, 1 + (info->type == FLIP_THROTTLE)); if (info->type >= FLIP_COMPLETE) { new_back: if (!xorg_can_triple_buffer()) sna_dri2_get_back(sna, draw, back); DBG(("%s: fake triple buffering, unblocking client\n", __FUNCTION__)); frame_swap_complete(info, DRI2_EXCHANGE_COMPLETE); assert(info->draw); info->signal = signal; if (info->type == FLIP_ASYNC) sna_dri2_event_free(info); } out: DBG(("%s: target_msc=%llu\n", __FUNCTION__, current_msc + 1)); *target_msc = current_msc + 1; return true; } queue: if (KEEPALIVE > 1 && sna->dri2.flip_pending) { info = sna->dri2.flip_pending; info->keepalive = 1; } info = sna_dri2_add_event(sna, draw, client, crtc); if (info == NULL) return false; assert(info->crtc == crtc); info->event_complete = func; info->event_data = data; assert(info->draw); info->signal = true; info->type = FLIP; assert(front != back); info->front = sna_dri2_reference_buffer(front); info->back = sna_dri2_reference_buffer(back); if (*target_msc <= current_msc + 1 && sna_dri2_flip(info)) { *target_msc = current_msc + 1; } else { /* Account for 1 frame extra pageflip delay */ if (!sna_wait_vblank(info, draw_target_seq(draw, *target_msc - 1))) { info->signal = false; sna_dri2_event_free(info); return false; } } DBG(("%s: reported target_msc=%llu\n", __FUNCTION__, *target_msc)); swap_limit(draw, 1); return true; } static bool has_pending_events(struct sna *sna) { struct pollfd pfd; pfd.fd = sna->kgem.fd; pfd.events = POLLIN; return poll(&pfd, 1, 0) == 1; } /* * ScheduleSwap is responsible for requesting a DRM vblank event for the * appropriate frame. * * In the case of a blit (e.g. for a windowed swap) or buffer exchange, * the vblank requested can simply be the last queued swap frame + the swap * interval for the drawable. * * In the case of a page flip, we request an event for the last queued swap * frame + swap interval - 1, since we'll need to queue the flip for the frame * immediately following the received event. * * The client will be blocked if it tries to perform further GL commands * after queueing a swap, though in the Intel case after queueing a flip, the * client is free to queue more commands; they'll block in the kernel if * they access buffers busy with the flip. * * When the swap is complete, the driver should call into the server so it * can send any swap complete events that have been requested. */ static int sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back, CARD64 *target_msc, CARD64 divisor, CARD64 remainder, DRI2SwapEventPtr func, void *data) { struct sna *sna = to_sna_from_drawable(draw); xf86CrtcPtr crtc = NULL; struct sna_dri2_event *info = NULL; int type = DRI2_EXCHANGE_COMPLETE; CARD64 current_msc; bool immediate; DBG(("%s: draw=%lu %dx%d, pixmap=%ld %dx%d, back=%u (refs=%d/%d, flush=%d) , front=%u (refs=%d/%d, flush=%d)\n", __FUNCTION__, (long)draw->id, draw->width, draw->height, get_drawable_pixmap(draw)->drawable.serialNumber, get_drawable_pixmap(draw)->drawable.width, get_drawable_pixmap(draw)->drawable.height, get_private(back)->bo->handle, get_private(back)->refcnt, get_private(back)->bo->refcnt, get_private(back)->bo->flush, get_private(front)->bo->handle, get_private(front)->refcnt, get_private(front)->bo->refcnt, get_private(front)->bo->flush)); DBG(("%s(target_msc=%llu, divisor=%llu, remainder=%llu)\n", __FUNCTION__, (long long)*target_msc, (long long)divisor, (long long)remainder)); assert(get_private(front)->refcnt); assert(get_private(back)->refcnt); assert(get_private(back)->bo != get_private(front)->bo); assert(get_private(front)->bo->refcnt); assert(get_private(back)->bo->refcnt); if (get_private(front)->pixmap != get_drawable_pixmap(draw)) { DBG(("%s: decoupled DRI2 front pixmap=%ld, actual pixmap=%ld\n", __FUNCTION__, get_private(front)->pixmap->drawable.serialNumber, get_drawable_pixmap(draw)->drawable.serialNumber)); goto fake; } if (get_private(back)->stale) { DBG(("%s: stale back buffer\n", __FUNCTION__)); goto skip; } if (draw->type != DRAWABLE_PIXMAP) { WindowPtr win = (WindowPtr)draw; struct dri2_window *priv = dri2_window(win); if (priv->front) { front = priv->front; assert(front->attachment == DRI2BufferFrontLeft); assert(get_private(front)->refcnt); assert(get_private(front)->pixmap == get_drawable_pixmap(draw)); } if (win->clipList.extents.x2 <= win->clipList.extents.x1 || win->clipList.extents.y2 <= win->clipList.extents.y1) { DBG(("%s: window clipped (%d, %d), (%d, %d)\n", __FUNCTION__, win->clipList.extents.x1, win->clipList.extents.y1, win->clipList.extents.x2, win->clipList.extents.y2)); goto skip; } } DBG(("%s: using front handle=%d, active_scanout?=%d, flush?=%d\n", __FUNCTION__, get_private(front)->bo->handle, get_private(front)->bo->active_scanout, sna_pixmap_from_drawable(draw)->flush)); assert(get_private(front)->bo->active_scanout); assert(sna_pixmap_from_drawable(draw)->flush); /* Drawable not displayed... just complete the swap */ if ((sna->flags & SNA_NO_WAIT) == 0) crtc = sna_dri2_get_crtc(draw); if (crtc == NULL) { DBG(("%s: off-screen, immediate update\n", __FUNCTION__)); goto blit; } assert(draw->type != DRAWABLE_PIXMAP); while (dri2_chain(draw) && has_pending_events(sna)) { DBG(("%s: flushing pending events\n", __FUNCTION__)); sna_mode_wakeup(sna); } immediate = immediate_swap(sna, draw, crtc, target_msc, divisor, remainder, ¤t_msc); if (can_flip(sna, draw, front, back, crtc) && sna_dri2_schedule_flip(client, draw, crtc, front, back, immediate, target_msc, current_msc, func, data)) return TRUE; info = sna_dri2_add_event(sna, draw, client, crtc); if (!info) goto blit; assert(info->crtc == crtc); info->event_complete = func; info->event_data = data; assert(info->draw); info->signal = true; assert(front != back); info->front = sna_dri2_reference_buffer(front); info->back = sna_dri2_reference_buffer(back); if (immediate) { bool sync = current_msc < *target_msc; sna_dri2_immediate_blit(sna, info, sync); *target_msc = current_msc + sync; DBG(("%s: reported target_msc=%llu\n", __FUNCTION__, *target_msc)); return TRUE; } info->type = SWAP; if (*target_msc <= current_msc + 1) { DBG(("%s: performing blit before queueing\n", __FUNCTION__)); __sna_dri2_copy_event(info, DRI2_SYNC); info->type = SWAP_COMPLETE; if (!sna_next_vblank(info)) goto fake; DBG(("%s: reported target_msc=%llu\n", __FUNCTION__, *target_msc)); *target_msc = current_msc + 1; swap_limit(draw, 2); } else { if (!sna_wait_vblank(info, draw_target_seq(draw, *target_msc - 1))) goto blit; DBG(("%s: reported target_msc=%llu (in)\n", __FUNCTION__, *target_msc)); swap_limit(draw, 1); } return TRUE; blit: DBG(("%s -- blit\n", __FUNCTION__)); if (can_xchg(sna, draw, front, back)) { sna_dri2_xchg(draw, front, back); } else { __sna_dri2_copy_region(sna, draw, NULL, back, front, 0); front->flags = back->flags; type = DRI2_BLIT_COMPLETE; } if (draw->type == DRAWABLE_PIXMAP) goto fake; skip: DBG(("%s: unable to show frame, unblocking client\n", __FUNCTION__)); if (crtc == NULL && (sna->flags & SNA_NO_WAIT) == 0) crtc = sna_primary_crtc(sna); if (crtc && sna_crtc_is_on(crtc)) { if (info == NULL) info = sna_dri2_add_event(sna, draw, client, crtc); if (info != dri2_chain(draw)) goto fake; assert(info->crtc == crtc); info->type = SWAP_COMPLETE; info->event_complete = func; info->event_data = data; assert(info->draw); info->signal = true; if (info->front == NULL) info->front = sna_dri2_reference_buffer(front); if (info->back == NULL) info->back = sna_dri2_reference_buffer(back); if (!sna_next_vblank(info)) goto fake; swap_limit(draw, 2); } else { fake: /* XXX Use a Timer to throttle the client? */ fake_swap_complete(sna, client, draw, crtc, type, func, data); if (info) { assert(info->draw); info->signal = false; sna_dri2_event_free(info); } } DBG(("%s: reported target_msc=%llu (in)\n", __FUNCTION__, *target_msc)); return TRUE; } /* * Get current frame count and frame count timestamp, based on drawable's * crtc. */ static int sna_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc) { struct sna *sna = to_sna_from_drawable(draw); xf86CrtcPtr crtc = sna_dri2_get_crtc(draw); const struct ust_msc *swap; union drm_wait_vblank vbl; DBG(("%s(draw=%ld, pipe=%d)\n", __FUNCTION__, draw->id, crtc ? sna_crtc_pipe(crtc) : -1)); /* Drawable not displayed, make up a *monotonic* value */ if (crtc == NULL) crtc = sna_primary_crtc(sna); if (crtc == NULL) return FALSE; if (sna_query_vblank(sna, crtc, &vbl) == 0) sna_crtc_record_vblank(crtc, &vbl); swap = sna_crtc_last_swap(crtc); *msc = draw_current_msc(draw, crtc, swap->msc); *ust = ust64(swap->tv_sec, swap->tv_usec); DBG(("%s: msc=%llu [raw=%llu], ust=%llu\n", __FUNCTION__, (long long)*msc, swap->msc, (long long)*ust)); return TRUE; } /* * Request a DRM event when the requested conditions will be satisfied. * * We need to handle the event and ask the server to wake up the client when * we receive it. */ static int sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, CARD64 divisor, CARD64 remainder) { struct sna *sna = to_sna_from_drawable(draw); struct sna_dri2_event *info = NULL; xf86CrtcPtr crtc; CARD64 current_msc; const struct ust_msc *swap; crtc = sna_dri2_get_crtc(draw); DBG(("%s(pipe=%d, target_msc=%llu, divisor=%llu, rem=%llu)\n", __FUNCTION__, crtc ? sna_crtc_pipe(crtc) : -1, (long long)target_msc, (long long)divisor, (long long)remainder)); /* Drawable not visible, return immediately */ if (crtc == NULL) crtc = sna_primary_crtc(sna); if (crtc == NULL) return FALSE; current_msc = get_current_msc(sna, draw, crtc); /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back * to the caller. This keeps the client from continually * sending us MSC targets from the past by forcibly updating * their count on this call. */ if (divisor == 0 && current_msc >= target_msc) goto out_complete; info = sna_dri2_add_event(sna, draw, client, crtc); if (!info) goto out_complete; assert(info->crtc == crtc); info->type = WAITMSC; /* * If divisor is zero, or current_msc is smaller than target_msc, * we just need to make sure target_msc passes before waking up the * client. Otherwise, compute the next msc to match divisor/remainder. */ if (divisor && current_msc >= target_msc) { DBG(("%s: missed target, queueing event for next: current=%lld, target=%lld, divisor=%lld, remainder=%lld\n", __FUNCTION__, (long long)current_msc, (long long)target_msc, (long long)divisor, (long long)remainder)); target_msc = current_msc + remainder - current_msc % divisor; if (target_msc <= current_msc) target_msc += divisor; } if (!sna_wait_vblank(info, draw_target_seq(draw, target_msc))) goto out_free_info; DRI2BlockClient(client, draw); return TRUE; out_free_info: sna_dri2_event_free(info); out_complete: swap = sna_crtc_last_swap(crtc); DRI2WaitMSCComplete(client, draw, draw_current_msc(draw, crtc, swap->msc), swap->tv_sec, swap->tv_usec); return TRUE; } #else void sna_dri2_destroy_window(WindowPtr win) { } void sna_dri2_decouple_window(WindowPtr win) { } #endif static bool has_i830_dri(void) { return access(DRI_DRIVER_PATH "/i830_dri.so", R_OK) == 0; } static int namecmp(const char *s1, const char *s2) { char c1, c2; if (!s1 || *s1 == 0) { if (!s2 || *s2 == 0) return 0; else return 1; } while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; while (c1 == c2) { if (c1 == '\0') return 0; s1++; while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; s2++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; } return c1 - c2; } static bool is_level(const char **str) { const char *s = *str; char *end; unsigned val; if (s == NULL || *s == '\0') return true; if (namecmp(s, "on") == 0) return true; if (namecmp(s, "true") == 0) return true; if (namecmp(s, "yes") == 0) return true; if (namecmp(s, "0") == 0) return true; if (namecmp(s, "off") == 0) return true; if (namecmp(s, "false") == 0) return true; if (namecmp(s, "no") == 0) return true; val = strtoul(s, &end, 0); if (val && *end == '\0') return true; if (val && *end == ':') *str = end + 1; return false; } static const char *options_get_dri(struct sna *sna) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) return xf86GetOptValString(sna->Options, OPTION_DRI); #else return NULL; #endif } static const char *dri_driver_name(struct sna *sna) { const char *s = options_get_dri(sna); if (is_level(&s)) { if (sna->kgem.gen < 030) return has_i830_dri() ? "i830" : "i915"; else if (sna->kgem.gen < 040) return "i915"; else return "i965"; } return s; } bool sna_dri2_open(struct sna *sna, ScreenPtr screen) { DRI2InfoRec info; int major = 1, minor = 0; #if DRI2INFOREC_VERSION >= 4 const char *driverNames[2]; #endif DBG(("%s()\n", __FUNCTION__)); if (wedged(sna)) { xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING, "loading DRI2 whilst acceleration is disabled.\n"); } if (xf86LoaderCheckSymbol("DRI2Version")) DRI2Version(&major, &minor); if (minor < 1) { xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING, "DRI2 requires DRI2 module version 1.1.0 or later\n"); return false; } memset(&info, '\0', sizeof(info)); info.fd = sna->kgem.fd; info.driverName = dri_driver_name(sna); info.deviceName = intel_get_master_name(sna->dev); DBG(("%s: loading dri driver '%s' [gen=%d] for device '%s'\n", __FUNCTION__, info.driverName, sna->kgem.gen, info.deviceName)); #if DRI2INFOREC_VERSION == 2 /* The ABI between 2 and 3 was broken so we could get rid of * the multi-buffer alloc functions. Make sure we indicate the * right version so DRI2 can reject us if it's version 3 or above. */ info.version = 2; #else info.version = 3; #endif info.CreateBuffer = sna_dri2_create_buffer; info.DestroyBuffer = sna_dri2_destroy_buffer; info.CopyRegion = sna_dri2_copy_region; #if DRI2INFOREC_VERSION >= 4 info.version = 4; info.ScheduleSwap = sna_dri2_schedule_swap; info.GetMSC = sna_dri2_get_msc; info.ScheduleWaitMSC = sna_dri2_schedule_wait_msc; info.numDrivers = 2; info.driverNames = driverNames; driverNames[0] = info.driverName; driverNames[1] = "va_gl"; #endif #if DRI2INFOREC_VERSION >= 6 if (xorg_can_triple_buffer()) { DBG(("%s: enabling Xorg triple buffering\n", __FUNCTION__)); info.version = 6; info.SwapLimitValidate = sna_dri2_swap_limit_validate; info.ReuseBufferNotify = sna_dri2_reuse_buffer; } #endif #if USE_ASYNC_SWAP DBG(("%s: enabled async swap and buffer age\n", __FUNCTION__)); info.version = 10; info.scheduleSwap0 = 1; info.bufferAge = 1; #endif return DRI2ScreenInit(screen, &info); } void sna_dri2_close(struct sna *sna, ScreenPtr screen) { DBG(("%s()\n", __FUNCTION__)); DRI2CloseScreen(screen); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_dri3.c000066400000000000000000000251271267532330400235200ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sna.h" #include #include #include #include static DevPrivateKeyRec sna_sync_fence_private_key; struct sna_sync_fence { SyncFenceSetTriggeredFunc set_triggered; }; static inline struct sna_sync_fence *sna_sync_fence(SyncFence *fence) { return dixLookupPrivate(&fence->devPrivates, &sna_sync_fence_private_key); } static inline void mark_dri3_pixmap(struct sna *sna, struct sna_pixmap *priv, struct kgem_bo *bo) { bo->flush = true; if (bo->exec) sna->kgem.flush = 1; if (bo == priv->gpu_bo) priv->flush |= FLUSH_READ | FLUSH_WRITE; else priv->shm = true; sna_accel_watch_flush(sna, 1); } static void sna_sync_flush(struct sna *sna, struct sna_pixmap *priv) { struct kgem_bo *bo = NULL; DBG(("%s(pixmap=%ld)\n", __FUNCTION__, priv->pixmap->drawable.serialNumber)); assert(priv); if (priv->pinned & PIN_DRI3) { assert(priv->gpu_bo); assert(priv->pinned & PIN_DRI3); DBG(("%s: flushing prime GPU bo, handle=%ld\n", __FUNCTION__, priv->gpu_bo->handle)); if (sna_pixmap_move_to_gpu(priv->pixmap, MOVE_READ | MOVE_WRITE | MOVE_ASYNC_HINT | __MOVE_FORCE)) { sna_damage_all(&priv->gpu_damage, priv->pixmap); bo = priv->gpu_bo; } } else { assert(priv->cpu_bo); assert(IS_STATIC_PTR(priv->ptr)); DBG(("%s: flushing prime CPU bo, handle=%ld\n", __FUNCTION__, priv->cpu_bo->handle)); if (sna_pixmap_move_to_cpu(priv->pixmap, MOVE_READ | MOVE_WRITE | MOVE_ASYNC_HINT)) bo = priv->cpu_bo; } if (bo != NULL) { kgem_bo_submit(&sna->kgem, bo); kgem_bo_unclean(&sna->kgem, bo); } } static void sna_sync_fence_set_triggered(SyncFence *fence) { struct sna *sna = to_sna_from_screen(fence->pScreen); struct sna_sync_fence *sna_fence = sna_sync_fence(fence); DBG(("%s()\n", __FUNCTION__)); sna_accel_flush(sna); fence->funcs.SetTriggered = sna_fence->set_triggered; sna_fence->set_triggered(fence); sna_fence->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = sna_sync_fence_set_triggered; } static void sna_sync_create_fence(ScreenPtr screen, SyncFence *fence, Bool initially_triggered) { struct sna *sna = to_sna_from_screen(screen); SyncScreenFuncsPtr funcs = miSyncGetScreenFuncs(screen); DBG(("%s()\n", __FUNCTION__)); funcs->CreateFence = sna->dri3.create_fence; sna->dri3.create_fence(screen, fence, initially_triggered); sna->dri3.create_fence = funcs->CreateFence; funcs->CreateFence = sna_sync_create_fence; sna_sync_fence(fence)->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = sna_sync_fence_set_triggered; } static bool sna_sync_open(struct sna *sna, ScreenPtr screen) { SyncScreenFuncsPtr funcs; DBG(("%s()\n", __FUNCTION__)); if (!miSyncShmScreenInit(screen)) return false; if (!dixPrivateKeyRegistered(&sna_sync_fence_private_key)) { if (!dixRegisterPrivateKey(&sna_sync_fence_private_key, PRIVATE_SYNC_FENCE, sizeof(struct sna_sync_fence))) return false; } funcs = miSyncGetScreenFuncs(screen); sna->dri3.create_fence = funcs->CreateFence; funcs->CreateFence = sna_sync_create_fence; return true; } static int sna_dri3_open_device(ScreenPtr screen, RRProviderPtr provider, int *out) { int fd; DBG(("%s()\n", __FUNCTION__)); fd = intel_get_client_fd(to_sna_from_screen(screen)->dev); if (fd < 0) return -fd; *out = fd; return Success; } static PixmapPtr sna_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { struct sna *sna = to_sna_from_screen(screen); PixmapPtr pixmap; struct sna_pixmap *priv; struct kgem_bo *bo; DBG(("%s(fd=%d, width=%d, height=%d, stride=%d, depth=%d, bpp=%d)\n", __FUNCTION__, fd, width, height, stride, depth, bpp)); if (width > INT16_MAX || height > INT16_MAX) return NULL; if ((uint32_t)width * bpp > (uint32_t)stride * 8) return NULL; if (depth < 8) return NULL; switch (bpp) { case 8: case 16: case 32: break; default: return NULL; } bo = kgem_create_for_prime(&sna->kgem, fd, (uint32_t)stride * height); if (bo == NULL) return NULL; /* Check for a duplicate */ list_for_each_entry(priv, &sna->dri3.pixmaps, cow_list) { int other_stride = 0; if (bo->snoop) { assert(priv->cpu_bo); assert(IS_STATIC_PTR(priv->ptr)); if (bo->handle == priv->cpu_bo->handle) other_stride = priv->cpu_bo->pitch; } else { assert(priv->gpu_bo); assert(priv->pinned & PIN_DRI3); if (bo->handle == priv->gpu_bo->handle) other_stride = priv->gpu_bo->pitch; } if (other_stride) { pixmap = priv->pixmap; DBG(("%s: imported fd matches existing DRI3 pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); bo->handle = 0; /* fudge to prevent gem_close */ kgem_bo_destroy(&sna->kgem, bo); if (width != pixmap->drawable.width || height != pixmap->drawable.height || depth != pixmap->drawable.depth || bpp != pixmap->drawable.bitsPerPixel || stride != other_stride) { DBG(("%s: imported fd mismatches existing DRI3 pixmap (width=%d, height=%d, depth=%d, bpp=%d, stride=%d)\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.depth, pixmap->drawable.bitsPerPixel, other_stride)); return NULL; } sna_sync_flush(sna, priv); pixmap->refcnt++; return pixmap; } } if (!kgem_check_surface_size(&sna->kgem, width, height, bpp, bo->tiling, stride, kgem_bo_size(bo))) { DBG(("%s: client supplied pitch=%d, size=%d too small for %dx%d surface\n", __FUNCTION__, stride, kgem_bo_size(bo), width, height)); goto free_bo; } pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth); if (pixmap == NullPixmap) goto free_bo; if (!screen->ModifyPixmapHeader(pixmap, width, height, depth, bpp, stride, NULL)) goto free_pixmap; priv = sna_pixmap_attach_to_bo(pixmap, bo); if (priv == NULL) goto free_pixmap; bo->pitch = stride; priv->stride = stride; if (bo->snoop) { assert(priv->cpu_bo == bo); pixmap->devPrivate.ptr = kgem_bo_map__cpu(&sna->kgem, priv->cpu_bo); if (pixmap->devPrivate.ptr == NULL) goto free_pixmap; pixmap->devKind = stride; priv->ptr = MAKE_STATIC_PTR(pixmap->devPrivate.ptr); } else { assert(priv->gpu_bo == bo); priv->create = kgem_can_create_2d(&sna->kgem, width, height, depth); priv->pinned |= PIN_DRI3; } list_add(&priv->cow_list, &sna->dri3.pixmaps); mark_dri3_pixmap(sna, priv, bo); return pixmap; free_pixmap: screen->DestroyPixmap(pixmap); free_bo: kgem_bo_destroy(&sna->kgem, bo); return NULL; } static int sna_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { struct sna *sna = to_sna_from_screen(screen); struct sna_pixmap *priv; struct kgem_bo *bo = NULL; int fd; DBG(("%s(pixmap=%ld, width=%d, height=%d)\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height)); if (pixmap == sna->front && sna->flags & SNA_TEAR_FREE) { DBG(("%s: DRI3 protocol cannot support TearFree frontbuffers\n", __FUNCTION__)); return -1; } priv = sna_pixmap(pixmap); if (priv && IS_STATIC_PTR(priv->ptr) && priv->cpu_bo) { if (sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE | MOVE_ASYNC_HINT)) bo = priv->cpu_bo; } else { priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE | MOVE_ASYNC_HINT | __MOVE_FORCE | __MOVE_DRI); if (priv != NULL) { sna_damage_all(&priv->gpu_damage, pixmap); bo = priv->gpu_bo; } } if (bo == NULL) { DBG(("%s: pixmap not supported by GPU\n", __FUNCTION__)); return -1; } assert(priv != NULL); if (bo->pitch > UINT16_MAX) { DBG(("%s: pixmap pitch (%d) too large for DRI3 protocol\n", __FUNCTION__, bo->pitch)); return -1; } if (bo->tiling && !sna->kgem.can_fence) { if (!sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { DBG(("%s: unable to discard GPU tiling (%d) for DRI3 protocol\n", __FUNCTION__, bo->tiling)); return -1; } bo = priv->gpu_bo; } fd = kgem_bo_export_to_prime(&sna->kgem, bo); if (fd == -1) { DBG(("%s: exporting handle=%d to fd failed\n", __FUNCTION__, bo->handle)); return -1; } if (bo == priv->gpu_bo) priv->pinned |= PIN_DRI3; list_move(&priv->cow_list, &sna->dri3.pixmaps); mark_dri3_pixmap(sna, priv, bo); *stride = (priv->pinned & PIN_DRI3) ? priv->gpu_bo->pitch : priv->cpu_bo->pitch; *size = kgem_bo_size((priv->pinned & PIN_DRI3) ? priv->gpu_bo : priv->cpu_bo); DBG(("%s: exporting %s pixmap=%ld, handle=%d, stride=%d, size=%d\n", __FUNCTION__, (priv->pinned & PIN_DRI3) ? "GPU" : "CPU", pixmap->drawable.serialNumber, (priv->pinned & PIN_DRI3) ? priv->gpu_bo->handle : priv->cpu_bo->handle, *stride, *size)); return fd; } static dri3_screen_info_rec sna_dri3_info = { .version = DRI3_SCREEN_INFO_VERSION, .open = sna_dri3_open_device, .pixmap_from_fd = sna_dri3_pixmap_from_fd, .fd_from_pixmap = sna_dri3_fd_from_pixmap, }; bool sna_dri3_open(struct sna *sna, ScreenPtr screen) { DBG(("%s()\n", __FUNCTION__)); if (!sna_sync_open(sna, screen)) return false; list_init(&sna->dri3.pixmaps); return dri3_screen_init(screen, &sna_dri3_info); } void sna_dri3_close(struct sna *sna, ScreenPtr screen) { SyncScreenFuncsPtr funcs; DBG(("%s()\n", __FUNCTION__)); funcs = miSyncGetScreenFuncs(screen); if (funcs) funcs->CreateFence = sna->dri3.create_fence; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_driver.c000066400000000000000000001047661267532330400241610ustar00rootroot00000000000000/************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. Copyright © 2002 by David Dawes 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 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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: Jeff Hartmann * Abraham van der Merwe * David Dawes * Alan Hourihane */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "sna.h" #include "sna_module.h" #include "sna_video.h" #include "intel_driver.h" #include "intel_options.h" #include #include #include #include #include #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H) #include #else #define DPMSModeOn 0 #define DPMSModeOff 3 #endif #include #include #include #include "i915_drm.h" #ifdef HAVE_VALGRIND #include #include #endif #if HAVE_DOT_GIT #include "git_version.h" #else #define git_version "not compiled from git" #endif #ifdef TEARFREE #define ENABLE_TEAR_FREE TRUE #else #define ENABLE_TEAR_FREE FALSE #endif DevPrivateKeyRec sna_pixmap_key; DevPrivateKeyRec sna_gc_key; DevPrivateKeyRec sna_window_key; DevPrivateKeyRec sna_glyph_key; DevPrivateKeyRec sna_client_key; static void sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int p, n, i, j; uint16_t lut_r[256], lut_g[256], lut_b[256]; DBG(("%s\n", __FUNCTION__)); for (p = 0; p < xf86_config->num_crtc; p++) { xf86CrtcPtr crtc = xf86_config->crtc[p]; #define C(I,RGB) (colors[I].RGB << 8 | colors[I].RGB) switch (scrn->depth) { case 15: for (n = 0; n < numColors; n++) { i = indices[n]; for (j = 0; j < 8; j++) { lut_r[8*i + j] = C(i, red); lut_g[8*i + j] = C(i, green); lut_b[8*i + j] = C(i, blue); } } break; case 16: for (n = 0; n < numColors; n++) { i = indices[n]; if (i <= 31) { for (j = 0; j < 8; j++) { lut_r[8*i + j] = C(i, red); lut_b[8*i + j] = C(i, blue); } } for (j = 0; j < 4; j++) lut_g[4*i + j] = C(i, green); } break; default: for (n = 0; n < numColors; n++) { i = indices[n]; lut_r[i] = C(i, red); lut_g[i] = C(i, green); lut_b[i] = C(i, blue); } break; } #undef C /* Make the change through RandR */ #ifdef RANDR_12_INTERFACE RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); #else crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); #endif } } static void sna_set_fallback_mode(ScrnInfoPtr scrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86OutputPtr output = NULL; xf86CrtcPtr crtc = NULL; int n; if ((unsigned)config->compat_output < config->num_output) { output = config->output[config->compat_output]; crtc = output->crtc; } for (n = 0; n < config->num_output; n++) config->output[n]->crtc = NULL; for (n = 0; n < config->num_crtc; n++) config->crtc[n]->enabled = FALSE; if (output && crtc) { DisplayModePtr mode; output->crtc = crtc; mode = xf86OutputFindClosestMode(output, scrn->currentMode); if (mode && xf86CrtcSetModeTransform(crtc, mode, RR_Rotate_0, NULL, 0, 0)) { crtc->desiredMode = *mode; crtc->desiredMode.prev = crtc->desiredMode.next = NULL; crtc->desiredMode.name = NULL; crtc->desiredMode.PrivSize = 0; crtc->desiredMode.PrivFlags = 0; crtc->desiredMode.Private = NULL; crtc->desiredRotation = RR_Rotate_0; crtc->desiredTransformPresent = FALSE; crtc->desiredX = 0; crtc->desiredY = 0; crtc->enabled = TRUE; } } xf86DisableUnusedFunctions(scrn); #ifdef RANDR_12_INTERFACE if (get_root_window(xf86ScrnToScreen(scrn))) xf86RandR12TellChanged(xf86ScrnToScreen(scrn)); #endif } static void sna_set_desired_mode(struct sna *sna) { ScrnInfoPtr scrn = sna->scrn; DBG(("%s\n", __FUNCTION__)); if (!xf86SetDesiredModes(scrn)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "failed to restore desired modes on VT switch\n"); sna_set_fallback_mode(scrn); } sna_mode_check(sna); } /** * Adjust the screen pixmap for the current location of the front buffer. * This is done at EnterVT when buffers are bound as long as the resources * have already been created, but the first EnterVT happens before * CreateScreenResources. */ static Bool sna_create_screen_resources(ScreenPtr screen) { struct sna *sna = to_sna_from_screen(screen); PixmapPtr new_front; unsigned hint; DBG(("%s(%dx%d@%d)\n", __FUNCTION__, screen->width, screen->height, screen->rootDepth)); assert(sna->scrn == xf86ScreenToScrn(screen)); assert(to_screen_from_sna(sna) == screen); /* free the data used during miInitScreen */ free(screen->devPrivate); screen->devPrivate = NULL; sna_accel_create(sna); hint = SNA_CREATE_FB; if (sna->flags & SNA_IS_HOSTED) hint = 0; new_front = screen->CreatePixmap(screen, screen->width, screen->height, screen->rootDepth, hint); if (!new_front) { xf86DrvMsg(screen->myNum, X_ERROR, "[intel] Unable to create front buffer %dx%d at depth %d\n", screen->width, screen->height, screen->rootDepth); return FALSE; } /* Prefer to use the GPU for rendering into the eventual scanout * bo so that we do not unduly stall when it is time to attach * it to the CRTCs. */ (void)sna_pixmap_force_to_gpu(new_front, MOVE_READ | __MOVE_SCANOUT); screen->SetScreenPixmap(new_front); assert(screen->GetScreenPixmap(screen) == new_front); assert(sna->front == new_front); screen->DestroyPixmap(new_front); /* transfer ownership to screen */ sna_mode_set_primary(sna); /* Try to become master and copy the current fbcon before the * actual VT switch. If we fail here, we will try to reset the * mode in the eventual VT switch. This can fail if systemd has * already revoked our KMS privileges, so just carry on regardless, * and hope that everything is sorted after the VT switch. */ if (intel_get_master(sna->dev) == 0) { /* Only preserve the fbcon, not any subsequent server regens */ if (serverGeneration == 1 && (sna->flags & SNA_IS_HOSTED) == 0) sna_copy_fbcon(sna); sna_set_desired_mode(sna); } return TRUE; } static void sna_dpms_set(ScrnInfoPtr scrn, int mode, int flags) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); struct sna *sna = to_sna(scrn); bool changed = false; int i; DBG(("%s(mode=%d, flags=%d), vtSema=%d => off?=%d\n", __FUNCTION__, mode, flags, scrn->vtSema, mode!=DPMSModeOn)); if (!scrn->vtSema) return; /* Opencoded version of xf86DPMSSet(). * * The principle difference is to skip calling crtc->dpms() when * turning off the display. This (on recent enough kernels at * least) should be equivalent in power consumption, but require * less work (hence quicker and less likely to fail) when switching * back on. */ if (mode != DPMSModeOn) { if (sna->mode.hidden == 0) { DBG(("%s: hiding %d outputs\n", __FUNCTION__, config->num_output)); for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != NULL) output->funcs->dpms(output, mode); } sna->mode.hidden = sna->mode.front_active + 1; sna->mode.front_active = 0; changed = true; } } else { /* Re-enable CRTC that have been forced off via other means */ if (sna->mode.hidden != 0) { DBG(("%s: unhiding %d crtc, %d outputs\n", __FUNCTION__, config->num_crtc, config->num_output)); sna->mode.front_active = sna->mode.hidden - 1; sna->mode.hidden = 0; for (i = 0; i < config->num_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; if (crtc->enabled) crtc->funcs->dpms(crtc, mode); } for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; if (output->crtc != NULL) output->funcs->dpms(output, mode); } changed = true; } } DBG(("%s: hiding outputs? %d, front active? %d, changed? %d\n", __FUNCTION__, sna->mode.hidden, sna->mode.front_active, changed)); if (changed) sna_crtc_config_notify(xf86ScrnToScreen(scrn)); } static Bool sna_save_screen(ScreenPtr screen, int mode) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); DBG(("%s(mode=%d [unblank=%d])\n", __FUNCTION__, mode, xf86IsUnblank(mode))); /* We have to unroll xf86SaveScreen() here as it is called * by DPMSSet() nullifying our special handling crtc->dpms() * in sna_dpms_set(). */ sna_dpms_set(scrn, xf86IsUnblank(mode) ? DPMSModeOn : DPMSModeOff, 0); return TRUE; } static void sna_selftest(void) { sna_damage_selftest(); } static bool has_vsync(struct sna *sna) { if (sna->flags & SNA_IS_HOSTED) return false; return true; } static void sna_setup_capabilities(ScrnInfoPtr scrn, int fd) { #if HAS_PIXMAP_SHARING && defined(DRM_CAP_PRIME) uint64_t value; scrn->capabilities = 0; if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0) { if (value & DRM_PRIME_CAP_EXPORT) scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; if (value & DRM_PRIME_CAP_IMPORT) scrn->capabilities |= RR_Capability_SinkOutput; } #endif } static Bool fb_supports_depth(int fd, int depth) { struct drm_i915_gem_create create; struct drm_mode_fb_cmd fb; struct drm_mode_card_res res; Bool ret; memset(&res, 0, sizeof(res)); (void)drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res); if (res.count_crtcs == 0) return TRUE; VG_CLEAR(create); create.handle = 0; create.size = 4096; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) return FALSE; VG_CLEAR(fb); fb.width = 64; fb.height = 16; fb.pitch = 256; fb.bpp = depth <= 8 ? 8 : depth <= 16 ? 16 : 32; fb.depth = depth; fb.handle = create.handle; ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &fb) == 0; drmModeRmFB(fd, fb.fb_id); (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &create.handle); return ret; } static void setup_dri(struct sna *sna) { unsigned level; sna->dri2.available = false; sna->dri3.available = false; level = intel_option_cast_to_unsigned(sna->Options, OPTION_DRI, DEFAULT_DRI_LEVEL); #if HAVE_DRI3 if (level >= 3) sna->dri3.available = !!xf86LoadSubModule(sna->scrn, "dri3"); #endif #if HAVE_DRI2 if (level >= 2) sna->dri2.available = !!xf86LoadSubModule(sna->scrn, "dri2"); #endif } static bool enable_tear_free(struct sna *sna) { if (sna->flags & SNA_LINEAR_FB) return false; /* Under certain conditions, we should enable TearFree by default, * for example when the hardware requires pageflipping to run within * its power/performance budget. */ if (sna_mode_wants_tear_free(sna)) return true; return ENABLE_TEAR_FREE; } static bool setup_tear_free(struct sna *sna) { MessageType from; Bool enable; if (sna->flags & SNA_LINEAR_FB) return false; if ((sna->flags & SNA_HAS_FLIP) == 0) { from = X_PROBED; goto done; } if (!xf86GetOptValBool(sna->Options, OPTION_TEAR_FREE, &enable)) { enable = enable_tear_free(sna); from = X_DEFAULT; } else from = X_CONFIG; if (enable) sna->flags |= SNA_TEAR_FREE; done: xf86DrvMsg(sna->scrn->scrnIndex, from, "TearFree %sabled\n", sna->flags & SNA_TEAR_FREE ? "en" : "dis"); return sna->flags & SNA_TEAR_FREE; } /** * This is called before ScreenInit to do any require probing of screen * configuration. * * This code generally covers probing, module loading, option handling * card mapping, and RandR setup. * * Since xf86InitialConfiguration ends up requiring that we set video modes * in order to detect configuration, we end up having to do a lot of driver * setup (talking to the DRM, mapping the device, etc.) in this function. * As a result, we want to set up that server initialization once rather * that doing it per generation. */ static Bool sna_pre_init(ScrnInfoPtr scrn, int probe) { struct sna *sna; char buf[1024]; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; Gamma zeros = { 0.0, 0.0, 0.0 }; int fd; DBG(("%s flags=%x, numEntities=%d\n", __FUNCTION__, probe, scrn->numEntities)); if (scrn->numEntities != 1) return FALSE; pEnt = xf86GetEntityInfo(scrn->entityList[0]); if (pEnt == NULL) { ERR(("%s: no EntityInfo found for scrn\n", __FUNCTION__)); return FALSE; } if (pEnt->location.type != BUS_PCI #ifdef XSERVER_PLATFORM_BUS && pEnt->location.type != BUS_PLATFORM #endif ) { ERR(("%s: invalid EntityInfo found for scrn, location=%d\n", __FUNCTION__, pEnt->location.type)); return FALSE; } if (probe & PROBE_DETECT) return TRUE; sna_selftest(); probe = 0; if (((uintptr_t)scrn->driverPrivate) & 3) { if (posix_memalign((void **)&sna, 4096, sizeof(*sna))) return FALSE; memset(sna, 0, sizeof(*sna)); /* should be unnecessary */ probe = (uintptr_t)scrn->driverPrivate & 1; sna->info = (void *)((uintptr_t)scrn->driverPrivate & ~3); scrn->driverPrivate = sna; sna->cpu_features = sna_cpu_detect(); sna->acpi.fd = sna_acpi_open(); } sna = to_sna(scrn); sna->scrn = scrn; sna->pEnt = pEnt; sna->flags = probe; scrn->displayWidth = 640; /* default it */ scrn->monitor = scrn->confScreen->monitor; scrn->progClock = TRUE; scrn->rgbBits = 8; sna->dev = intel_get_device(scrn, &fd); if (sna->dev == NULL) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to claim DRM device.\n"); goto cleanup; } /* Sanity check */ if (hosted() && (sna->flags & SNA_IS_HOSTED) == 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to setup hosted device.\n"); goto cleanup; } intel_detect_chipset(scrn, sna->dev); xf86DrvMsg(scrn->scrnIndex, X_PROBED, "CPU: %s; using a maximum of %d threads\n", sna_cpu_features_to_string(sna->cpu_features, buf), sna_use_threads(64*1024, 64*1024, 1)); if (!xf86SetDepthBpp(scrn, 24, 0, 0, Support32bppFb | SupportConvert24to32 | PreferConvert24to32)) goto cleanup; switch (scrn->depth) { case 8: case 15: case 16: case 24: case 30: if ((sna->flags & SNA_IS_HOSTED) || fb_supports_depth(fd, scrn->depth)) break; default: xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by the Intel driver and this chipset.\n", scrn->depth); goto cleanup; } xf86PrintDepthBpp(scrn); if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) goto cleanup; if (!xf86SetDefaultVisual(scrn, -1)) goto cleanup; sna->Options = intel_options_get(scrn); if (sna->Options == NULL) goto cleanup; sna_setup_capabilities(scrn, fd); kgem_init(&sna->kgem, fd, xf86GetPciInfoForEntity(pEnt->index), sna->info->gen); if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE)) sna->flags |= SNA_LINEAR_FB; if (!sna->kgem.can_fence) sna->flags |= SNA_LINEAR_FB; if (!xf86ReturnOptValBool(sna->Options, OPTION_SWAPBUFFERS_WAIT, TRUE)) sna->flags |= SNA_NO_WAIT; DBG(("%s: swapbuffer wait? %s\n", __FUNCTION__, sna->flags & SNA_NO_WAIT ? "disabled" : "enabled")); if (!has_vsync(sna) || !xf86ReturnOptValBool(sna->Options, OPTION_VSYNC, TRUE)) sna->flags |= SNA_NO_VSYNC; DBG(("%s: vsync? %s\n", __FUNCTION__, sna->flags & SNA_NO_VSYNC ? "disabled" : "enabled")); if (sna->flags & SNA_IS_HOSTED || !xf86ReturnOptValBool(sna->Options, OPTION_PAGEFLIP, TRUE)) sna->flags |= SNA_NO_FLIP; DBG(("%s: page flips? %s\n", __FUNCTION__, sna->flags & SNA_NO_FLIP ? "disabled" : "enabled")); if ((sna->flags & (SNA_NO_VSYNC | SNA_NO_FLIP | SNA_NO_WAIT)) == 0 && xf86ReturnOptValBool(sna->Options, OPTION_TRIPLE_BUFFER, TRUE)) sna->flags |= SNA_TRIPLE_BUFFER; DBG(("%s: triple buffer? %s\n", __FUNCTION__, sna->flags & SNA_TRIPLE_BUFFER ? "enabled" : "disabled")); if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE)) { xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Forcing per-crtc-pixmaps.\n"); sna->flags |= SNA_FORCE_SHADOW; } if (!sna_mode_pre_init(scrn, sna)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "No outputs and no modes.\n"); goto cleanup; } scrn->currentMode = scrn->modes; if (!setup_tear_free(sna) && sna_mode_wants_tear_free(sna)) sna->kgem.needs_dirtyfb = sna->kgem.has_dirtyfb; xf86SetGamma(scrn, zeros); xf86SetDpi(scrn, 0, 0); setup_dri(sna); sna->present.available = false; if (xf86ReturnOptValBool(sna->Options, OPTION_PRESENT, TRUE)) { #if HAVE_PRESENT sna->present.available = !!xf86LoadSubModule(scrn, "present"); #endif } sna_acpi_init(sna); return TRUE; cleanup: scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); if (sna->dev) intel_put_device(sna->dev); free(sna); return FALSE; } static bool has_shadow(struct sna *sna) { if (!sna->mode.shadow_enabled) return false; assert(sna->mode.shadow_damage); if (RegionNil(DamageRegion(sna->mode.shadow_damage))) return false; return sna->mode.flip_active == 0; } static void sna_block_handler(BLOCKHANDLER_ARGS_DECL) { #ifndef XF86_SCRN_INTERFACE struct sna *sna = to_sna(xf86Screens[arg]); #else struct sna *sna = to_sna_from_screen(arg); #endif struct timeval **tv = timeout; DBG(("%s (tv=%ld.%06ld)\n", __FUNCTION__, *tv ? (*tv)->tv_sec : -1, *tv ? (*tv)->tv_usec : 0)); sna->BlockHandler(BLOCKHANDLER_ARGS); if (*tv == NULL || ((*tv)->tv_usec | (*tv)->tv_sec) || has_shadow(sna)) sna_accel_block(sna, tv); } static void sna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL) { #ifndef XF86_SCRN_INTERFACE struct sna *sna = to_sna(xf86Screens[arg]); #else struct sna *sna = to_sna_from_screen(arg); #endif DBG(("%s\n", __FUNCTION__)); /* despite all appearances, result is just a signed int */ if ((int)result < 0) return; sna_acpi_wakeup(sna, read_mask); sna->WakeupHandler(WAKEUPHANDLER_ARGS); if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask)) { sna_mode_wakeup(sna); /* Clear the flag so that subsequent ZaphodHeads don't block */ FD_CLR(sna->kgem.fd, (fd_set*)read_mask); } } #if HAVE_UDEV #include static void sna_handle_uevents(int fd, void *closure) { struct sna *sna = closure; struct stat s; struct pollfd pfd; bool hotplug = false; DBG(("%s\n", __FUNCTION__)); pfd.fd = udev_monitor_get_fd(sna->uevent_monitor); pfd.events = POLLIN; if (fstat(sna->kgem.fd, &s)) memset(&s, 0, sizeof(s)); while (poll(&pfd, 1, 0) > 0) { struct udev_device *dev; dev_t devnum; dev = udev_monitor_receive_device(sna->uevent_monitor); if (dev == NULL) break; devnum = udev_device_get_devnum(dev); if (memcmp(&s.st_rdev, &devnum, sizeof(dev_t)) == 0) { const char *str; str = udev_device_get_property_value(dev, "HOTPLUG"); if (str && atoi(str) == 1) hotplug = true; } udev_device_unref(dev); } if (hotplug) { DBG(("%s: hotplug event (vtSema?=%d)\n", __FUNCTION__, sna->scrn->vtSema)); if (sna->scrn->vtSema) sna_mode_discover(sna, true); else sna->flags |= SNA_REPROBE; } } static bool has_randr(void) { #if HAS_DIXREGISTERPRIVATEKEY return dixPrivateKeyRegistered(rrPrivKey); #else return *rrPrivKey; #endif } static void sna_uevent_init(struct sna *sna) { struct udev *u; struct udev_monitor *mon; MessageType from = X_CONFIG; if (sna->flags & SNA_IS_HOSTED) return; DBG(("%s\n", __FUNCTION__)); /* RandR will be disabled if Xinerama is active, and so generating * RR hotplug events is then verboten. */ if (!has_randr()) goto out; u = NULL; if (xf86ReturnOptValBool(sna->Options, OPTION_HOTPLUG, TRUE)) u = udev_new(); if (!u) goto out; from = X_DEFAULT; mon = udev_monitor_new_from_netlink(u, "udev"); if (!mon) goto err_dev; if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") < 0) goto err_monitor; if (udev_monitor_enable_receiving(mon) < 0) goto err_monitor; sna->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), sna_handle_uevents, sna); if (!sna->uevent_handler) goto err_monitor; sna->uevent_monitor = mon; out: xf86DrvMsg(sna->scrn->scrnIndex, from, "Display hotplug detection %s\n", sna->uevent_monitor ? "enabled" : "disabled"); return; err_monitor: udev_monitor_unref(mon); err_dev: udev_unref(u); goto out; } static bool sna_uevent_poll(struct sna *sna) { if (sna->uevent_monitor == NULL) return false; sna_handle_uevents(udev_monitor_get_fd(sna->uevent_monitor), sna); return true; } static void sna_uevent_fini(struct sna *sna) { struct udev *u; if (sna->uevent_handler == NULL) return; xf86RemoveGeneralHandler(sna->uevent_handler); u = udev_monitor_get_udev(sna->uevent_monitor); udev_monitor_unref(sna->uevent_monitor); udev_unref(u); sna->uevent_handler = NULL; sna->uevent_monitor = NULL; DBG(("%s: removed uvent handler\n", __FUNCTION__)); } #else static void sna_uevent_init(struct sna *sna) { } static bool sna_uevent_poll(struct sna *sna) { return false; } static void sna_uevent_fini(struct sna *sna) { } #endif /* HAVE_UDEV */ static Bool sna_randr_getinfo(ScreenPtr screen, Rotation *rotations) { struct sna *sna = to_sna_from_screen(screen); DBG(("%s()\n", __FUNCTION__)); if (!sna_uevent_poll(sna)) sna_mode_discover(sna, false); return sna->mode.rrGetInfo(screen, rotations); } static void sna_leave_vt(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); struct sna *sna = to_sna(scrn); DBG(("%s\n", __FUNCTION__)); sna_mode_reset(sna); sna_accel_leave(sna); if (intel_put_master(sna->dev)) xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmDropMaster failed: %s\n", strerror(errno)); } static Bool sna_early_close_screen(CLOSE_SCREEN_ARGS_DECL) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct sna *sna = to_sna(scrn); DBG(("%s\n", __FUNCTION__)); /* XXX Note that we will leak kernel resources if !vtSema */ sna_uevent_fini(sna); sna_mode_close(sna); if (sna->present.open) { sna_present_close(sna, screen); sna->present.open = false; } if (sna->dri3.open) { sna_dri3_close(sna, screen); sna->dri3.open = false; } if (sna->dri2.open) { sna_dri2_close(sna, screen); sna->dri2.open = false; } if (sna->front) { screen->DestroyPixmap(sna->front); sna->front = NULL; } if (scrn->vtSema) { intel_put_master(sna->dev); scrn->vtSema = FALSE; } return sna->CloseScreen(CLOSE_SCREEN_ARGS); } static Bool sna_late_close_screen(CLOSE_SCREEN_ARGS_DECL) { struct sna *sna = to_sna_from_screen(screen); DepthPtr depths; int d; DBG(("%s\n", __FUNCTION__)); sna_accel_close(sna); sna_video_close(sna); depths = screen->allowedDepths; for (d = 0; d < screen->numDepths; d++) free(depths[d].vids); free(depths); free(screen->visuals); return TRUE; } static Bool sna_register_all_privates(void) { #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&sna_pixmap_key, PRIVATE_PIXMAP, 3*sizeof(void *))) return FALSE; if (!dixRegisterPrivateKey(&sna_gc_key, PRIVATE_GC, sizeof(FbGCPrivate))) return FALSE; if (!dixRegisterPrivateKey(&sna_glyph_key, PRIVATE_GLYPH, sizeof(struct sna_glyph))) return FALSE; if (!dixRegisterPrivateKey(&sna_window_key, PRIVATE_WINDOW, 3*sizeof(void *))) return FALSE; if (!dixRegisterPrivateKey(&sna_client_key, PRIVATE_CLIENT, sizeof(struct sna_client))) return FALSE; #else if (!dixRequestPrivate(&sna_pixmap_key, 3*sizeof(void *))) return FALSE; if (!dixRequestPrivate(&sna_gc_key, sizeof(FbGCPrivate))) return FALSE; if (!dixRequestPrivate(&sna_glyph_key, sizeof(struct sna_glyph))) return FALSE; if (!dixRequestPrivate(&sna_window_key, 3*sizeof(void *))) return FALSE; if (!dixRequestPrivate(&sna_client_key, sizeof(struct sna_client))) return FALSE; #endif return TRUE; } static void sna_dri_init(struct sna *sna, ScreenPtr screen) { char str[128] = ""; if (sna->dri2.available) sna->dri2.open = sna_dri2_open(sna, screen); if (sna->dri2.open) strcat(str, "DRI2 "); if (sna->dri3.available) sna->dri3.open = sna_dri3_open(sna, screen); if (sna->dri3.open) strcat(str, "DRI3 "); if (*str) xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "direct rendering: %senabled\n", str); } static Bool sna_mode_init(struct sna *sna, ScreenPtr screen) { rrScrPrivPtr rp; if (!xf86CrtcScreenInit(screen)) return FALSE; xf86RandR12SetRotations(screen, RR_Rotate_All | RR_Reflect_All); xf86RandR12SetTransformSupport(screen, TRUE); /* Wrap RR queries to catch pending MST topology changes */ rp = rrGetScrPriv(screen); if (rp) { sna->mode.rrGetInfo = rp->rrGetInfo; rp->rrGetInfo = sna_randr_getinfo; } return TRUE; } static Bool sna_screen_init(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct sna *sna = to_sna(scrn); VisualPtr visuals; DepthPtr depths; int nvisuals; int ndepths; int rootdepth; VisualID defaultVisual; DBG(("%s\n", __FUNCTION__)); assert(sna->scrn == scrn); assert(to_screen_from_sna(sna) == NULL); /* set afterwards */ assert(sna->freed_pixmap == NULL); if (!sna_register_all_privates()) return FALSE; scrn->videoRam = sna->kgem.aperture_mappable * 4; /* Page to KiB */ miClearVisualTypes(); if (!miSetVisualTypes(scrn->depth, miGetDefaultVisualMask(scrn->depth), scrn->rgbBits, scrn->defaultVisual)) return FALSE; if (!miSetPixmapDepths()) return FALSE; rootdepth = 0; if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth, &defaultVisual, ((unsigned long)1 << (scrn->bitsPerPixel - 1)), 8, -1)) return FALSE; if (!miScreenInit(screen, NULL, scrn->virtualX, scrn->virtualY, scrn->xDpi, scrn->yDpi, 0, rootdepth, ndepths, depths, defaultVisual, nvisuals, visuals)) return FALSE; if (scrn->bitsPerPixel > 8) { /* Fixup RGB ordering */ VisualPtr visual = screen->visuals + screen->numVisuals; while (--visual >= screen->visuals) { if ((visual->class | DynamicClass) == DirectColor) { visual->offsetRed = scrn->offset.red; visual->offsetGreen = scrn->offset.green; visual->offsetBlue = scrn->offset.blue; visual->redMask = scrn->mask.red; visual->greenMask = scrn->mask.green; visual->blueMask = scrn->mask.blue; } } } assert(screen->CloseScreen == NULL); screen->CloseScreen = sna_late_close_screen; if (!sna_accel_init(screen, sna)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Hardware acceleration initialization failed\n"); return FALSE; } xf86SetBlackWhitePixels(screen); xf86SetBackingStore(screen); xf86SetSilkenMouse(screen); if (!miDCInitialize(screen, xf86GetPointerScreenFuncs())) return FALSE; if (sna_cursors_init(screen, sna)) xf86DrvMsg(scrn->scrnIndex, X_INFO, "HW Cursor enabled\n"); /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ scrn->vtSema = TRUE; sna->BlockHandler = screen->BlockHandler; screen->BlockHandler = sna_block_handler; sna->WakeupHandler = screen->WakeupHandler; screen->WakeupHandler = sna_wakeup_handler; screen->SaveScreen = sna_save_screen; screen->CreateScreenResources = sna_create_screen_resources; sna->CloseScreen = screen->CloseScreen; screen->CloseScreen = sna_early_close_screen; if (!sna_mode_init(sna, screen)) return FALSE; if (!miCreateDefColormap(screen)) return FALSE; if (sna->mode.num_real_crtc && !xf86HandleColormaps(screen, 256, 8, sna_load_palette, NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) return FALSE; xf86DPMSInit(screen, sna_dpms_set, 0); sna_uevent_init(sna); sna_video_init(sna, screen); sna_dri_init(sna, screen); if (sna->present.available) sna->present.open = sna_present_open(sna, screen); if (sna->present.open) xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "hardware support for Present enabled\n"); if (serverGeneration == 1) xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); sna->suspended = FALSE; return TRUE; } static void sna_adjust_frame(ADJUST_FRAME_ARGS_DECL) { SCRN_INFO_PTR(arg); DBG(("%s(%d, %d)\n", __FUNCTION__, x, y)); sna_mode_adjust_frame(to_sna(scrn), x, y); } static void sna_free_screen(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); struct sna *sna = to_sna(scrn); DBG(("%s [scrn=%p, sna=%p]\n", __FUNCTION__, scrn, sna)); if (sna == NULL || (uintptr_t)sna & 3) /* beware thieves */ return; scrn->driverPrivate = (void *)((uintptr_t)sna->info | (sna->flags & SNA_IS_SLAVED) | 2); sna_mode_fini(sna); sna_acpi_fini(sna); intel_put_device(sna->dev); free(sna); } static Bool sna_enter_vt(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); struct sna *sna = to_sna(scrn); DBG(("%s\n", __FUNCTION__)); if (intel_get_master(sna->dev)) return FALSE; sna_accel_enter(sna); if (sna->flags & SNA_REPROBE) { DBG(("%s: reporting deferred hotplug event\n", __FUNCTION__)); sna_mode_discover(sna, true); } sna_set_desired_mode(sna); return TRUE; } static Bool sna_switch_mode(SWITCH_MODE_ARGS_DECL) { SCRN_INFO_PTR(arg); DBG(("%s\n", __FUNCTION__)); return xf86SetSingleMode(scrn, mode, RR_Rotate_0); } static ModeStatus sna_valid_mode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { return MODE_OK; } #ifndef SUSPEND_SLEEP #define SUSPEND_SLEEP 0 #endif #ifndef RESUME_SLEEP #define RESUME_SLEEP 0 #endif /* * This function is only required if we need to do anything differently from * DoApmEvent() in common/xf86PM.c, including if we want to see events other * than suspend/resume. */ static Bool sna_pm_event(SCRN_ARG_TYPE arg, pmEvent event, Bool undo) { SCRN_INFO_PTR(arg); struct sna *sna = to_sna(scrn); DBG(("%s\n", __FUNCTION__)); switch (event) { case XF86_APM_SYS_SUSPEND: case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ case XF86_APM_USER_SUSPEND: case XF86_APM_SYS_STANDBY: case XF86_APM_USER_STANDBY: if (!undo && !sna->suspended) { scrn->LeaveVT(VT_FUNC_ARGS(0)); sna->suspended = TRUE; sleep(SUSPEND_SLEEP); } else if (undo && sna->suspended) { sleep(RESUME_SLEEP); scrn->EnterVT(VT_FUNC_ARGS(0)); sna->suspended = FALSE; } break; case XF86_APM_STANDBY_RESUME: case XF86_APM_NORMAL_RESUME: case XF86_APM_CRITICAL_RESUME: if (sna->suspended) { sleep(RESUME_SLEEP); scrn->EnterVT(VT_FUNC_ARGS(0)); sna->suspended = FALSE; /* * Turn the screen saver off when resuming. This seems to be * needed to stop xscreensaver kicking in (when used). * * XXX DoApmEvent() should probably call this just like * xf86VTSwitch() does. Maybe do it here only in 4.2 * compatibility mode. */ SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); } break; /* This is currently used for ACPI */ case XF86_APM_CAPABILITY_CHANGED: SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); break; default: ERR(("sna_pm_event: received APM event %d\n", event)); } return TRUE; } static Bool sna_enter_vt__hosted(VT_FUNC_ARGS_DECL) { return TRUE; } static void sna_leave_vt__hosted(VT_FUNC_ARGS_DECL) { } static void describe_kms(ScrnInfoPtr scrn) { int fd = __intel_peek_fd(scrn); drm_version_t version; char name[128] = ""; char date[128] = ""; memset(&version, 0, sizeof(version)); version.name_len = sizeof(name) - 1; version.name = name; version.date_len = sizeof(date) - 1; version.date = date; if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) return; xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using Kernel Mode Setting driver: %s, version %d.%d.%d %s\n", version.name, version.version_major, version.version_minor, version.version_patchlevel, version.date); } static void describe_sna(ScrnInfoPtr scrn) { #if defined(USE_GIT_DESCRIBE) xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled from %s\n", git_version); #elif defined(BUILDER_DESCRIPTION) xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled: %s\n", BUILDER_DESCRIPTION); #endif #if HAS_DEBUG_FULL ErrorF("SNA compiled with full debug logging; expect to run slowly\n"); #endif #if !NDEBUG xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled with assertions enabled\n"); #endif #if DEBUG_SYNC xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled with synchronous rendering\n"); #endif #if DEBUG_MEMORY xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled with memory allocation reporting enabled\n"); #endif #if DEBUG_PIXMAP xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled with extra pixmap/damage validation\n"); #endif #ifdef HAVE_VALGRIND xf86DrvMsg(scrn->scrnIndex, X_INFO, "SNA compiled for use with valgrind\n"); VALGRIND_PRINTF("SNA compiled for use with valgrind\n"); #endif DBG(("xf86-video-intel version: %s\n", git_version)); DBG(("pixman version: %s\n", pixman_version_string())); } Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num) { DBG(("%s: entity_num=%d\n", __FUNCTION__, entity_num)); describe_kms(scrn); describe_sna(scrn); scrn->PreInit = sna_pre_init; scrn->ScreenInit = sna_screen_init; if (!hosted()) { scrn->SwitchMode = sna_switch_mode; scrn->AdjustFrame = sna_adjust_frame; scrn->EnterVT = sna_enter_vt; scrn->LeaveVT = sna_leave_vt; scrn->ValidMode = sna_valid_mode; scrn->PMEvent = sna_pm_event; } else { scrn->EnterVT = sna_enter_vt__hosted; scrn->LeaveVT = sna_leave_vt__hosted; } scrn->FreeScreen = sna_free_screen; xf86SetEntitySharable(entity_num); xf86SetEntityInstanceForScreen(scrn, entity_num, xf86GetNumEntityInstances(entity_num)-1); sna_threads_init(); return TRUE; } #if HAS_DEBUG_FULL _X_ATTRIBUTE_PRINTF(1, 0) void LogF(const char *f, ...) { va_list ap; /* As we not only may be called from any context, we may also * be called from a thread whilst the main thread is handling * signals, therefore we have to use the signal-safe variants * or else we trip over false positive assertions. */ va_start(ap, f); #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0) LogVMessageVerbSigSafe(X_NONE, 1, f, ap); #else LogVMessageVerb(X_NONE, 1, f, ap); #endif va_end(ap); } #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_glyphs.c000066400000000000000000001705221267532330400241650ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * Partly based on code Copyright © 2008 Red Hat, Inc. * Partly based on code Copyright © 2000 SuSE, Inc. * * 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, and that the name of Intel not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Intel makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INTEL * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * 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, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * 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, and that the name of SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Chris Wilson * Based on code by: Keith Packard and Owen Taylor */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "fb/fbpict.h" #define FALLBACK 0 #define NO_GLYPH_CACHE 0 #define NO_GLYPHS_TO_DST 0 #define FORCE_GLYPHS_TO_DST 0 #define NO_GLYPHS_VIA_MASK 0 #define FORCE_SMALL_MASK 0 /* -1 = never, 1 = always */ #define NO_GLYPHS_SLOW 0 #define DISCARD_MASK 0 /* -1 = never, 1 = always */ #define CACHE_PICTURE_SIZE 1024 #define GLYPH_MIN_SIZE 8 #define GLYPH_MAX_SIZE 64 #define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE)) #define N_STACK_GLYPHS 512 #define NO_ATLAS ((PicturePtr)-1) #define GLYPH_TOLERANCE 3 #define glyph_valid(g) *((uint32_t *)&(g)->info.width) #define glyph_copy_size(r, g) *(uint32_t *)&(r)->width = *(uint32_t *)&g->info.width #if HAS_PIXMAN_GLYPHS static pixman_glyph_cache_t *__global_glyph_cache; #endif #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif extern DevPrivateKeyRec sna_glyph_key; static inline struct sna_glyph *sna_glyph(GlyphPtr glyph) { return __get_private(glyph, sna_glyph_key); } static inline struct sna_glyph *sna_glyph0(GlyphPtr glyph) { return (struct sna_glyph *)glyph->devPrivates; } static inline bool can_use_glyph0(void) { #if HAS_DEVPRIVATEKEYREC return sna_glyph_key.offset == 0; #else return 0; #endif } #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) static bool op_is_bounded(uint8_t op) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: case PictOpXor: return true; default: return false; } } void sna_glyphs_close(struct sna *sna) { struct sna_render *render = &sna->render; unsigned int i; DBG(("%s\n", __FUNCTION__)); for (i = 0; i < ARRAY_SIZE(render->glyph); i++) { struct sna_glyph_cache *cache = &render->glyph[i]; if (cache->picture) FreePicture(cache->picture, 0); free(cache->glyphs); } memset(render->glyph, 0, sizeof(render->glyph)); if (render->white_image) { pixman_image_unref(render->white_image); render->white_image = NULL; } if (render->white_picture) { FreePicture(render->white_picture, 0); render->white_picture = NULL; } } /* All caches for a single format share a single pixmap for glyph storage, * allowing mixing glyphs of different sizes without paying a penalty * for switching between source pixmaps. (Note that for a size of font * right at the border between two sizes, we might be switching for almost * every glyph.) * * This function allocates the storage pixmap, and then fills in the * rest of the allocated structures for all caches with the given format. */ bool sna_glyphs_create(struct sna *sna) { ScreenPtr screen = to_screen_from_sna(sna); pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff }; unsigned int formats[] = { PIXMAN_a8, PIXMAN_a8r8g8b8, }; unsigned int i; int error; DBG(("%s\n", __FUNCTION__)); #if HAS_PIXMAN_GLYPHS if (__global_glyph_cache == NULL) { __global_glyph_cache = pixman_glyph_cache_create(); if (__global_glyph_cache == NULL) goto bail; } #endif sna->render.white_image = pixman_image_create_solid_fill(&white); if (sna->render.white_image == NULL) goto bail; if (!can_render(sna)) { DBG(("%s: no render acceleration, no render glyph caches\n", __FUNCTION__)); return true; } if (xf86IsEntityShared(sna->scrn->entityList[0])) { DBG(("%s: shared GlyphPictures, no render glyph caches\n", __FUNCTION__)); return true; } for (i = 0; i < ARRAY_SIZE(formats); i++) { struct sna_glyph_cache *cache = &sna->render.glyph[i]; struct sna_pixmap *priv; PixmapPtr pixmap; PicturePtr picture = NULL; PictFormatPtr pPictFormat; CARD32 component_alpha; int depth = PIXMAN_FORMAT_DEPTH(formats[i]); pPictFormat = PictureMatchFormat(screen, depth, formats[i]); if (!pPictFormat) goto bail; /* Now allocate the pixmap and picture */ pixmap = screen->CreatePixmap(screen, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, depth, SNA_CREATE_SCRATCH); if (!pixmap) { DBG(("%s: failed to allocate pixmap for Glyph cache\n", __FUNCTION__)); goto bail; } priv = sna_pixmap(pixmap); if (priv != NULL) { /* Prevent the cache from ever being paged out */ assert(priv->gpu_bo); priv->pinned = PIN_SCANOUT; component_alpha = NeedsComponent(pPictFormat->format); picture = CreatePicture(0, &pixmap->drawable, pPictFormat, CPComponentAlpha, &component_alpha, serverClient, &error); } screen->DestroyPixmap(pixmap); if (!picture) goto bail; ValidatePicture(picture); assert(picture->pDrawable == &pixmap->drawable); cache->count = cache->evict = 0; cache->picture = picture; cache->glyphs = calloc(sizeof(struct sna_glyph *), GLYPH_CACHE_SIZE); if (!cache->glyphs) goto bail; cache->evict = rand() % GLYPH_CACHE_SIZE; } sna->render.white_picture = CreateSolidPicture(0, (xRenderColor *)&white, &error); if (sna->render.white_picture == NULL) goto bail; return true; bail: sna_glyphs_close(sna); return false; } static void glyph_cache_upload(struct sna_glyph_cache *cache, GlyphPtr glyph, PicturePtr glyph_picture, int16_t x, int16_t y) { DBG(("%s: upload glyph %p to cache (%d, %d)x(%d, %d)\n", __FUNCTION__, glyph, x, y, glyph_picture->pDrawable->width, glyph_picture->pDrawable->height)); sna_composite(PictOpSrc, glyph_picture, 0, cache->picture, 0, 0, 0, 0, x, y, glyph_picture->pDrawable->width, glyph_picture->pDrawable->height); } static void glyph_extents(int nlist, GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents) { int x1, x2, y1, y2; int x, y; x1 = y1 = MAXSHORT; x2 = y2 = MINSHORT; x = y = 0; while (nlist--) { int n = list->len; x += list->xOff; y += list->yOff; list++; while (n--) { GlyphPtr glyph = *glyphs++; if (glyph_valid(glyph)) { int v; v = x - glyph->info.x; if (v < x1) x1 = v; v += glyph->info.width; if (v > x2) x2 = v; v = y - glyph->info.y; if (v < y1) y1 = v; v += glyph->info.height; if (v > y2) y2 = v; } x += glyph->info.xOff; y += glyph->info.yOff; } } extents->x1 = x1 > MINSHORT ? x1 : MINSHORT; extents->y1 = y1 > MINSHORT ? y1 : MINSHORT; extents->x2 = x2 < MAXSHORT ? x2 : MAXSHORT; extents->y2 = y2 < MAXSHORT ? y2 : MAXSHORT; } #if HAS_DEBUG_FULL static int glyph_count(int nlist, GlyphListPtr list) { int count = 0; while (nlist--) { count += list->len; list++; } return count; } #endif static inline unsigned int glyph_size_to_count(int size) { size /= GLYPH_MIN_SIZE; return size * size; } static inline unsigned int glyph_count_to_mask(int count) { return ~(count - 1); } static inline unsigned int glyph_size_to_mask(int size) { return glyph_count_to_mask(glyph_size_to_count(size)); } static int glyph_cache(ScreenPtr screen, struct sna_render *render, GlyphPtr glyph) { PicturePtr glyph_picture; struct sna_glyph_cache *cache; struct sna_glyph *p; int size, mask, pos, s; assert(glyph_valid(glyph)); glyph_picture = GetGlyphPicture(glyph, screen); if (unlikely(glyph_picture == NULL)) { glyph->info.width = glyph->info.height = 0; return false; } if (NO_GLYPH_CACHE || glyph->info.width > GLYPH_MAX_SIZE || glyph->info.height > GLYPH_MAX_SIZE) { PixmapPtr pixmap = (PixmapPtr)glyph_picture->pDrawable; assert(glyph_picture->pDrawable->type == DRAWABLE_PIXMAP); if (pixmap->drawable.depth >= 8) { pixmap->usage_hint = 0; sna_pixmap_force_to_gpu(pixmap, MOVE_READ); } /* no cache for this glyph */ p = sna_glyph(glyph); p->atlas = glyph_picture; p->coordinate.x = p->coordinate.y = 0; return true; } for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) if (glyph->info.width <= size && glyph->info.height <= size) break; cache = &render->glyph[PICT_FORMAT_RGB(glyph_picture->format) != 0]; s = glyph_size_to_count(size); mask = glyph_count_to_mask(s); pos = (cache->count + s - 1) & mask; if (pos < GLYPH_CACHE_SIZE) { cache->count = pos + s; } else { p = NULL; for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) { int i = cache->evict & glyph_size_to_mask(s); p = cache->glyphs[i]; if (p == NULL) continue; if (p->size >= s) { cache->glyphs[i] = NULL; p->atlas = NULL; pos = i; } else p = NULL; break; } if (p == NULL) { int count = glyph_size_to_count(size); pos = cache->evict & glyph_count_to_mask(count); for (s = 0; s < count; s++) { p = cache->glyphs[pos + s]; if (p != NULL) { p->atlas =NULL; cache->glyphs[pos + s] = NULL; } } } /* And pick a new eviction position */ cache->evict = rand() % GLYPH_CACHE_SIZE; } assert(cache->glyphs[pos] == NULL); p = sna_glyph(glyph); DBG(("%s(%d): adding glyph to cache %d, pos %d\n", __FUNCTION__, screen->myNum, PICT_FORMAT_RGB(glyph_picture->format) != 0, pos)); cache->glyphs[pos] = p; p->atlas = cache->picture; p->size = size; p->pos = pos << 1 | (PICT_FORMAT_RGB(glyph_picture->format) != 0); s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); p->coordinate.x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; p->coordinate.y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) { if (pos & 1) p->coordinate.x += s; if (pos & 2) p->coordinate.y += s; pos >>= 2; } glyph_cache_upload(cache, glyph, glyph_picture, p->coordinate.x, p->coordinate.y); return true; } static void apply_damage(struct sna_composite_op *op, const struct sna_composite_rectangles *r) { BoxRec box; if (op->damage == NULL) return; box.x1 = r->dst.x + op->dst.x; box.y1 = r->dst.y + op->dst.y; box.x2 = box.x1 + r->width; box.y2 = box.y1 + r->height; assert_pixmap_contains_box(op->dst.pixmap, &box); sna_damage_add_box(op->damage, &box); } static void apply_damage_clipped_to_dst(struct sna_composite_op *op, const struct sna_composite_rectangles *r, DrawablePtr dst) { BoxRec box; if (op->damage == NULL) return; box.x1 = r->dst.x + op->dst.x; box.y1 = r->dst.y + op->dst.y; box.x2 = box.x1 + r->width; box.y2 = box.y1 + r->height; if (box.x1 < dst->x) box.x1 = dst->x; if (box.x2 > op->dst.width) box.x2 = op->dst.width; if (box.y1 < dst->y) box.y1 = dst->y; if (box.y2 > op->dst.height) box.y2 = op->dst.height; assert_pixmap_contains_box(op->dst.pixmap, &box); sna_damage_add_box(op->damage, &box); } static inline bool region_matches_pixmap(const RegionRec *r, PixmapPtr pixmap) { return (r->extents.x2 - r->extents.x1 >= pixmap->drawable.width && r->extents.y2 - r->extents.y1 >= pixmap->drawable.height); } static inline bool clipped_glyphs(PicturePtr dst, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { BoxRec box; if (dst->pCompositeClip->data == NULL && region_matches_pixmap(dst->pCompositeClip, get_drawable_pixmap(dst->pDrawable))) { DBG(("%s: no, clip region (%d, %d), (%d, %d) matches drawable pixmap=%ld size=%dx%d\n", __FUNCTION__, dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y1, dst->pCompositeClip->extents.x2, dst->pCompositeClip->extents.y2, get_drawable_pixmap(dst->pDrawable), get_drawable_pixmap(dst->pDrawable)->drawable.width, get_drawable_pixmap(dst->pDrawable)->drawable.height)); return false; } glyph_extents(nlist, list, glyphs, &box); box.x1 += dst->pDrawable->x; box.x2 += dst->pDrawable->x; box.y1 += dst->pDrawable->y; box.y2 += dst->pDrawable->y; DBG(("%s? %d glyph in %d lists extents (%d, %d), (%d, %d), region (%d, %d), (%d, %d): %s\n", __FUNCTION__, glyph_count(nlist, list), nlist, box.x1, box.y1, box.x2, box.y2, dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y1, dst->pCompositeClip->extents.x2, dst->pCompositeClip->extents.y2, pixman_region_contains_rectangle(dst->pCompositeClip, &box) != PIXMAN_REGION_IN ? "yes" : "no")); return pixman_region_contains_rectangle(dst->pCompositeClip, &box) != PIXMAN_REGION_IN; } flatten static bool glyphs_to_dst(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { struct sna_composite_op tmp; ScreenPtr screen = dst->pDrawable->pScreen; PicturePtr glyph_atlas; const BoxRec *rects; int nrect; int16_t x, y; if (NO_GLYPHS_TO_DST) return false; memset(&tmp, 0, sizeof(tmp)); DBG(("%s(op=%d, src=(%d, %d), nlist=%d, dst=(%d, %d)+(%d, %d))\n", __FUNCTION__, op, src_x, src_y, nlist, list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y)); if (clipped_glyphs(dst, nlist, list, glyphs)) { rects = region_rects(dst->pCompositeClip); nrect = region_num_rects(dst->pCompositeClip); } else nrect = 0; x = dst->pDrawable->x; y = dst->pDrawable->y; src_x -= list->xOff + x; src_y -= list->yOff + y; glyph_atlas = NO_ATLAS; while (nlist--) { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr glyph = *glyphs++; struct sna_glyph *p; int i; p = sna_glyph(glyph); if (unlikely(p->atlas != glyph_atlas)) { if (unlikely(!glyph_valid(glyph))) goto next_glyph; if (glyph_atlas != NO_ATLAS) { tmp.done(sna, &tmp); glyph_atlas = NO_ATLAS; } if (p->atlas == NULL && !glyph_cache(screen, &sna->render, glyph)) goto next_glyph; if (!sna->render.composite(sna, op, src, p->atlas, dst, 0, 0, 0, 0, 0, 0, 0, 0, COMPOSITE_PARTIAL, &tmp)) return false; glyph_atlas = p->atlas; } if (nrect) { int xi = x - glyph->info.x; int yi = y - glyph->info.y; if (xi < dst->pCompositeClip->extents.x2 && yi < dst->pCompositeClip->extents.y2 && xi + glyph->info.width > dst->pCompositeClip->extents.x1 && yi + glyph->info.height > dst->pCompositeClip->extents.y1) { for (i = 0; i < nrect; i++) { struct sna_composite_rectangles r; int16_t dx, dy; int16_t x2, y2; r.dst.x = xi; r.dst.y = yi; x2 = xi + glyph->info.width; y2 = yi + glyph->info.height; dx = dy = 0; DBG(("%s: glyph=(%d, %d), (%d, %d), clip=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2, rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2)); if (rects[i].y1 >= y2) break; if (r.dst.x < rects[i].x1) dx = rects[i].x1 - r.dst.x, r.dst.x = rects[i].x1; if (x2 > rects[i].x2) x2 = rects[i].x2; if (r.dst.y < rects[i].y1) dy = rects[i].y1 - r.dst.y, r.dst.y = rects[i].y1; if (y2 > rects[i].y2) y2 = rects[i].y2; assert(dx >= 0 && dy >= 0); if (r.dst.x < x2 && r.dst.y < y2) { DBG(("%s: blt=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2)); r.src.x = r.dst.x + src_x; r.src.y = r.dst.y + src_y; r.mask.x = dx + p->coordinate.x; r.mask.y = dy + p->coordinate.y; r.width = x2 - r.dst.x; r.height = y2 - r.dst.y; tmp.blt(sna, &tmp, &r); apply_damage(&tmp, &r); } } } } else { struct sna_composite_rectangles r; r.dst.x = x - glyph->info.x; r.dst.y = y - glyph->info.y; r.src.x = r.dst.x + src_x; r.src.y = r.dst.y + src_y; r.mask = p->coordinate; glyph_copy_size(&r, glyph); DBG(("%s: glyph=(%d, %d)x(%d, %d), unclipped\n", __FUNCTION__, r.dst.x, r.dst.y, r.width, r.height)); tmp.blt(sna, &tmp, &r); apply_damage_clipped_to_dst(&tmp, &r, dst->pDrawable); } next_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (glyph_atlas != NO_ATLAS) tmp.done(sna, &tmp); return true; } flatten static bool glyphs0_to_dst(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { struct sna_composite_op tmp; ScreenPtr screen = dst->pDrawable->pScreen; PicturePtr glyph_atlas = NO_ATLAS; int x, y; if (NO_GLYPHS_TO_DST) return false; memset(&tmp, 0, sizeof(tmp)); DBG(("%s(op=%d, src=(%d, %d), nlist=%d, dst=(%d, %d)+(%d, %d))\n", __FUNCTION__, op, src_x, src_y, nlist, list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y)); x = dst->pDrawable->x; y = dst->pDrawable->y; src_x -= list->xOff + x; src_y -= list->yOff + y; if (clipped_glyphs(dst, nlist, list, glyphs)) { const BoxRec *rects = region_rects(dst->pCompositeClip); int nrect = region_num_rects(dst->pCompositeClip); if (nrect == 0) return true; while (nlist--) { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr glyph = *glyphs++; struct sna_glyph *p = sna_glyph0(glyph); int i, xi, yi; if (unlikely(p->atlas != glyph_atlas)) { if (unlikely(!glyph_valid(glyph))) goto next_glyph_N; if (glyph_atlas != NO_ATLAS) { tmp.done(sna, &tmp); glyph_atlas = NO_ATLAS; } if (unlikely(p->atlas == NULL)) { if (!glyph_cache(screen, &sna->render, glyph)) goto next_glyph_N; } if (!sna->render.composite(sna, op, src, p->atlas, dst, 0, 0, 0, 0, 0, 0, 0, 0, COMPOSITE_PARTIAL, &tmp)) return false; glyph_atlas = p->atlas; } xi = x - glyph->info.x; yi = y - glyph->info.y; if (xi < dst->pCompositeClip->extents.x2 && yi < dst->pCompositeClip->extents.y2 && xi + glyph->info.width > dst->pCompositeClip->extents.x1 && yi + glyph->info.height > dst->pCompositeClip->extents.y1) { for (i = 0; i < nrect; i++) { struct sna_composite_rectangles r; int16_t dx, dy; int16_t x2, y2; r.dst.x = xi; r.dst.y = yi; x2 = xi + glyph->info.width; y2 = yi + glyph->info.height; dx = dy = 0; DBG(("%s: glyph=(%d, %d), (%d, %d), clip=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2, rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2)); if (rects[i].y1 >= y2) break; if (r.dst.x < rects[i].x1) dx = rects[i].x1 - r.dst.x, r.dst.x = rects[i].x1; if (x2 > rects[i].x2) x2 = rects[i].x2; if (r.dst.y < rects[i].y1) dy = rects[i].y1 - r.dst.y, r.dst.y = rects[i].y1; if (y2 > rects[i].y2) y2 = rects[i].y2; assert(dx >= 0 && dy >= 0); if (r.dst.x < x2 && r.dst.y < y2) { DBG(("%s: blt=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2)); r.src.x = r.dst.x + src_x; r.src.y = r.dst.y + src_y; r.mask.x = dx + p->coordinate.x; r.mask.y = dy + p->coordinate.y; r.width = x2 - r.dst.x; r.height = y2 - r.dst.y; tmp.blt(sna, &tmp, &r); apply_damage(&tmp, &r); } } } next_glyph_N: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } } else while (nlist--) { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr glyph = *glyphs++; struct sna_glyph *p = sna_glyph0(glyph); struct sna_composite_rectangles r; if (unlikely(p->atlas != glyph_atlas)) { if (unlikely(!glyph_valid(glyph))) goto next_glyph_0; if (glyph_atlas != NO_ATLAS) { tmp.done(sna, &tmp); glyph_atlas = NO_ATLAS; } if (unlikely(p->atlas == NULL)) { if (!glyph_cache(screen, &sna->render, glyph)) goto next_glyph_0; } if (!sna->render.composite(sna, op, src, p->atlas, dst, 0, 0, 0, 0, 0, 0, 0, 0, COMPOSITE_PARTIAL, &tmp)) return false; glyph_atlas = p->atlas; } r.dst.x = x - glyph->info.x; r.dst.y = y - glyph->info.y; r.src.x = r.dst.x + src_x; r.src.y = r.dst.y + src_y; r.mask = p->coordinate; glyph_copy_size(&r, glyph); DBG(("%s: glyph=(%d, %d)x(%d, %d), unclipped\n", __FUNCTION__, r.dst.x, r.dst.y, r.width, r.height)); tmp.blt(sna, &tmp, &r); apply_damage_clipped_to_dst(&tmp, &r, dst->pDrawable); next_glyph_0: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (glyph_atlas != NO_ATLAS) tmp.done(sna, &tmp); return true; } static bool glyphs_slow(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { struct sna_composite_op tmp; ScreenPtr screen = dst->pDrawable->pScreen; int16_t x, y; if (NO_GLYPHS_SLOW) return false; DBG(("%s(op=%d, src=(%d, %d), nlist=%d, dst=(%d, %d)+(%d, %d))\n", __FUNCTION__, op, src_x, src_y, nlist, list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y)); x = dst->pDrawable->x; y = dst->pDrawable->y; src_x -= list->xOff + x; src_y -= list->yOff + y; while (nlist--) { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr glyph = *glyphs++; struct sna_glyph *p; const BoxRec *rects; BoxRec box; int nrect; box.x1 = x - glyph->info.x; box.y1 = y - glyph->info.y; box.x2 = bound(box.x1, glyph->info.width); box.y2 = bound(box.y1, glyph->info.height); if (!box_intersect(&box, &dst->pCompositeClip->extents)) goto next_glyph; p = sna_glyph(glyph); if (unlikely(p->atlas == NULL)) { if (unlikely(!glyph_valid(glyph))) goto next_glyph; if (!glyph_cache(screen, &sna->render, glyph)) goto next_glyph; } DBG(("%s: glyph=(%d, %d)x(%d, %d), src=(%d, %d), mask=(%d, %d)\n", __FUNCTION__, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height, src_x + x - glyph->info.x, src_y + y - glyph->info.y, p->coordinate.x, p->coordinate.y)); if (!sna->render.composite(sna, op, src, p->atlas, dst, src_x + x - glyph->info.x, src_y + y - glyph->info.y, p->coordinate.x, p->coordinate.y, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height, COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) return false; rects = region_rects(dst->pCompositeClip); nrect = region_num_rects(dst->pCompositeClip); do { struct sna_composite_rectangles r; int16_t x2, y2; r.dst.x = x - glyph->info.x; r.dst.y = y - glyph->info.y; x2 = r.dst.x + glyph->info.width; y2 = r.dst.y + glyph->info.height; DBG(("%s: glyph=(%d, %d), (%d, %d), clip=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2, rects->x1, rects->y1, rects->x2, rects->y2)); if (rects->y1 >= y2) break; if (r.dst.x < rects->x1) r.dst.x = rects->x1; if (x2 > rects->x2) x2 = rects->x2; if (r.dst.y < rects->y1) r.dst.y = rects->y1; if (y2 > rects->y2) y2 = rects->y2; if (r.dst.x < x2 && r.dst.y < y2) { DBG(("%s: blt=(%d, %d), (%d, %d)\n", __FUNCTION__, r.dst.x, r.dst.y, x2, y2)); r.width = x2 - r.dst.x; r.height = y2 - r.dst.y; r.src = r.mask = r .dst; tmp.blt(sna, &tmp, &r); apply_damage(&tmp, &r); } rects++; } while (--nrect); tmp.done(sna, &tmp); next_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } return true; } static bool clear_pixmap(struct sna *sna, PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); return sna->render.clear(sna, pixmap, priv->gpu_bo); } static bool too_large(struct sna *sna, int width, int height) { return (width > sna->render.max_3d_size || height > sna->render.max_3d_size); } static pixman_image_t * __sna_glyph_get_image(GlyphPtr g, ScreenPtr s) { pixman_image_t *image; PicturePtr p; int dx, dy; DBG(("%s: creating image cache for glyph %p (on screen %d)\n", __FUNCTION__, g, s->myNum)); p = GetGlyphPicture(g, s); if (unlikely(p == NULL)) return NULL; image = image_from_pict(p, FALSE, &dx, &dy); if (!image) return NULL; assert(dx == 0 && dy == 0); return sna_glyph(g)->image = image; } static inline pixman_image_t * sna_glyph_get_image(GlyphPtr g, ScreenPtr s) { pixman_image_t *image; image = sna_glyph(g)->image; if (image == NULL) image = __sna_glyph_get_image(g, s); return image; } static inline bool use_small_mask(struct sna *sna, int16_t width, int16_t height, int depth) { if (depth < 8) return true; if (FORCE_SMALL_MASK) return FORCE_SMALL_MASK > 0; if (depth * width * height < 8 * 4096) return true; return too_large(sna, width, height); } flatten static bool glyphs_via_mask(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr format, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { ScreenPtr screen = dst->pDrawable->pScreen; CARD32 component_alpha; PixmapPtr pixmap; PicturePtr mask; int16_t x, y, width, height; int error; bool ret = false; BoxRec box; if (NO_GLYPHS_VIA_MASK) return false; DBG(("%s(op=%d, src=(%d, %d), nlist=%d, dst=(%d, %d)+(%d, %d))\n", __FUNCTION__, op, src_x, src_y, nlist, list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y)); glyph_extents(nlist, list, glyphs, &box); if (box.x2 <= box.x1 || box.y2 <= box.y1) return true; DBG(("%s: nlist=%d, count=%d, bounds=((%d, %d), (%d, %d))\n", __FUNCTION__, nlist, glyph_count(nlist, list), box.x1, box.y1, box.x2, box.y2)); if (!sna_compute_composite_extents(&box, src, NULL, dst, src_x, src_y, 0, 0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1)) return true; DBG(("%s: extents=((%d, %d), (%d, %d))\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); width = box.x2 - box.x1; height = box.y2 - box.y1; box.x1 -= dst->pDrawable->x; box.y1 -= dst->pDrawable->y; x = -box.x1; y = -box.y1; src_x += box.x1 - list->xOff; src_y += box.y1 - list->yOff; component_alpha = NeedsComponent(format->format); if (use_small_mask(sna, width, height, format->depth)) { pixman_image_t *mask_image; use_small_mask: DBG(("%s: small mask [format=%lx, depth=%d, size=%d], rendering glyphs to upload buffer\n", __FUNCTION__, (unsigned long)format->format, format->depth, (uint32_t)width*height*format->depth)); pixmap = sna_pixmap_create_upload(screen, width, height, format->depth, KGEM_BUFFER_WRITE); if (!pixmap) return false; mask_image = pixman_image_create_bits(pixmap->drawable.bitsPerPixel << 24 | format->format, width, height, pixmap->devPrivate.ptr, pixmap->devKind); if (mask_image == NULL) goto err_pixmap; if (sigtrap_get()) { pixman_image_unref(mask_image); goto err_pixmap; } memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height); #if HAS_PIXMAN_GLYPHS if (__global_glyph_cache) { pixman_glyph_t stack_glyphs[N_STACK_GLYPHS]; pixman_glyph_t *pglyphs = stack_glyphs; int count, n; count = 0; for (n = 0; n < nlist; ++n) count += list[n].len; if (count > N_STACK_GLYPHS) { pglyphs = malloc (count * sizeof(pixman_glyph_t)); if (pglyphs == NULL) goto err_pixmap; } pixman_glyph_cache_freeze(__global_glyph_cache); count = 0; do { n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; const void *ptr; if (!glyph_valid(g)) goto next_pglyph; ptr = pixman_glyph_cache_lookup(__global_glyph_cache, g, NULL); if (ptr == NULL) { pixman_image_t *glyph_image; glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) goto next_pglyph; DBG(("%s: inserting glyph %p into pixman cache\n", __FUNCTION__, g)); ptr = pixman_glyph_cache_insert(__global_glyph_cache, g, NULL, g->info.x, g->info.y, glyph_image); if (ptr == NULL) goto next_pglyph; } assert(sna_glyph_get_image(g, screen) != NULL); pglyphs[count].x = x; pglyphs[count].y = y; pglyphs[count].glyph = ptr; count++; next_pglyph: x += g->info.xOff; y += g->info.yOff; } list++; } while (--nlist); pixman_composite_glyphs_no_mask(PIXMAN_OP_ADD, sna->render.white_image, mask_image, 0, 0, 0, 0, __global_glyph_cache, count, pglyphs); pixman_glyph_cache_thaw(__global_glyph_cache); if (pglyphs != stack_glyphs) free(pglyphs); } else #endif do { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; pixman_image_t *glyph_image; int16_t xi, yi; if (!glyph_valid(g)) goto next_image; /* If the mask has been cropped, it is likely * that some of the glyphs fall outside. */ xi = x - g->info.x; yi = y - g->info.y; if (xi >= width || yi >= height) goto next_image; if (xi + g->info.width <= 0 || yi + g->info.height <= 0) goto next_image; glyph_image = sna_glyph_get_image(g, dst->pDrawable->pScreen); if (glyph_image == NULL) goto next_image; DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", __FUNCTION__, xi, yi, g->info.width, g->info.height)); if (list->format == format) { assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); pixman_image_composite(PictOpAdd, glyph_image, NULL, mask_image, 0, 0, 0, 0, xi, yi, g->info.width, g->info.height); } else { pixman_image_composite(PictOpAdd, sna->render.white_image, glyph_image, mask_image, 0, 0, 0, 0, xi, yi, g->info.width, g->info.height); } next_image: x += g->info.xOff; y += g->info.yOff; } list++; } while (--nlist); pixman_image_unref(mask_image); sigtrap_put(); mask = CreatePicture(0, &pixmap->drawable, format, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) goto err_pixmap; ValidatePicture(mask); } else { struct sna_composite_op tmp; PicturePtr glyph_atlas = NO_ATLAS; pixmap = screen->CreatePixmap(screen, width, height, format->depth, SNA_CREATE_SCRATCH); if (!pixmap) goto use_small_mask; assert(__sna_pixmap_get_bo(pixmap)); mask = CreatePicture(0, &pixmap->drawable, format, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) goto err_pixmap; ValidatePicture(mask); if (!clear_pixmap(sna, pixmap)) goto err_mask; do { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr glyph = *glyphs++; struct sna_glyph *p = sna_glyph(glyph); struct sna_composite_rectangles r; if (unlikely(p->atlas != glyph_atlas)) { bool ok; if (unlikely(!glyph_valid(glyph))) goto next_glyph; if (glyph_atlas != NO_ATLAS) { tmp.done(sna, &tmp); glyph_atlas = NO_ATLAS; } if (unlikely(p->atlas == NULL)) { if (!glyph_cache(screen, &sna->render, glyph)) goto next_glyph; } DBG(("%s: atlas format=%08x, mask format=%08x\n", __FUNCTION__, (int)p->atlas->format, (int)mask->format)); memset(&tmp, 0, sizeof(tmp)); if (p->atlas->format == mask->format || alphaless(p->atlas->format) == mask->format) { ok = sna->render.composite(sna, PictOpAdd, p->atlas, NULL, mask, 0, 0, 0, 0, 0, 0, 0, 0, COMPOSITE_PARTIAL, &tmp); } else { ok = sna->render.composite(sna, PictOpAdd, sna->render.white_picture, p->atlas, mask, 0, 0, 0, 0, 0, 0, 0, 0, COMPOSITE_PARTIAL, &tmp); } if (!ok) { DBG(("%s: fallback -- can not handle PictOpAdd of glyph onto mask!\n", __FUNCTION__)); goto err_mask; } glyph_atlas = p->atlas; } DBG(("%s: blt glyph origin (%d, %d), offset (%d, %d), src (%d, %d), size (%d, %d)\n", __FUNCTION__, x, y, glyph->info.x, glyph->info.y, p->coordinate.x, p->coordinate.y, glyph->info.width, glyph->info.height)); r.mask = r.src = p->coordinate; r.dst.x = x - glyph->info.x; r.dst.y = y - glyph->info.y; glyph_copy_size(&r, glyph); tmp.blt(sna, &tmp, &r); next_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } while (--nlist); if (glyph_atlas != NO_ATLAS) tmp.done(sna, &tmp); } sna_composite(op, src, mask, dst, src_x, src_y, 0, 0, box.x1, box.y1, width, height); ret = true; err_mask: FreePicture(mask, 0); err_pixmap: sna_pixmap_destroy(pixmap); return ret; } static PictFormatPtr glyphs_format(int nlist, GlyphListPtr list, GlyphPtr * glyphs) { PictFormatPtr format = list[0].format; int16_t x1, x2, y1, y2; int16_t x, y; BoxRec stack_extents[64], *list_extents = stack_extents; int i, j; if (nlist > ARRAY_SIZE(stack_extents)) { list_extents = malloc(sizeof(BoxRec) * nlist); if (list_extents == NULL) return NULL; } x = y = 0; i = 0; while (nlist--) { BoxRec extents; bool first = true; int n = list->len; /* Check the intersection of each glyph within the list and * then each list against the previous lists. * * If we overlap then we cannot substitute a mask as the * rendering will be altered. */ if (format->format != list->format->format) { DBG(("%s: switching formats from %x to %x\n", __FUNCTION__, (unsigned)format->format, (unsigned)list->format->format)); format = NULL; goto out; } x += list->xOff; y += list->yOff; list++; while (n--) { GlyphPtr glyph = *glyphs++; if (!glyph_valid(glyph)) goto skip_glyph; x1 = x - glyph->info.x; y1 = y - glyph->info.y; x2 = x1 + glyph->info.width; y2 = y1 + glyph->info.height; if (first) { extents.x1 = x1; extents.y1 = y1; extents.x2 = x2; extents.y2 = y2; first = false; } else { /* Potential overlap? * We cheat and ignore the boundary pixels, as * the likelihood of an actual overlap of * inkedk pixels being noticeable in the * boundary is small, yet glyphs frequently * overlap on the boundaries. */ if (x1 < extents.x2-GLYPH_TOLERANCE && x2 > extents.x1+GLYPH_TOLERANCE && y1 < extents.y2-GLYPH_TOLERANCE && y2 > extents.y1+GLYPH_TOLERANCE) { DBG(("%s: overlapping glyph inside line, current bbox (%d, %d), (%d, %d), glyph (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, x1, y1, x2, y2)); format = NULL; goto out; } if (x1 < extents.x1) extents.x1 = x1; if (x2 > extents.x2) extents.x2 = x2; if (y1 < extents.y1) extents.y1 = y1; if (y2 > extents.y2) extents.y2 = y2; } skip_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } /* Incrementally building a region is expensive. We expect * the number of lists to be small, so just keep a list * of the previous boxes and walk those. */ if (!first) { for (j = 0; j < i; j++) { if (extents.x1 < list_extents[j].x2-GLYPH_TOLERANCE && extents.x2 > list_extents[j].x1+GLYPH_TOLERANCE && extents.y1 < list_extents[j].y2-GLYPH_TOLERANCE && extents.y2 > list_extents[j].y1+GLYPH_TOLERANCE) { DBG(("%s: overlapping lines, current bbox (%d, %d), (%d, %d), previous line (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, list_extents[j].x1, list_extents[j].y1, list_extents[j].x2, list_extents[j].y2)); format = NULL; goto out; } } list_extents[i++] = extents; } } assert(format); DBG(("%s: format=%08d, depth=%d\n", __FUNCTION__, format->format, format->depth)); out: if (list_extents != stack_extents) free(list_extents); return format; } static bool can_discard_mask(uint8_t op, PicturePtr src, PictFormatPtr mask, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { PictFormatPtr g; uint32_t color; if (DISCARD_MASK) return DISCARD_MASK > 0; DBG(("%s: nlist=%d, mask=%08x, depth %d, op=%d (bounded? %d)\n", __FUNCTION__, nlist, mask ? (unsigned)mask->format : 0, mask ? mask->depth : 0, op, op_is_bounded(op))); if (nlist == 1 && list->len == 1) { if (mask == list->format) return true; g = list->format; goto skip; } if (!op_is_bounded(op)) { DBG(("%s: unbounded op, not discarding\n", __FUNCTION__)); return false; } /* No glyphs overlap and we are not performing a mask conversion. */ g = glyphs_format(nlist, list, glyphs); if (mask == g) { DBG(("%s: mask matches glyphs format, no conversion, so discard mask\n", __FUNCTION__)); return true; } DBG(("%s: preferred mask format %08x, depth %d\n", __FUNCTION__, g ? (unsigned)g->format : 0, g ? g->depth : 0)); /* Otherwise if the glyphs are all bitmaps and we have an * opaque source we can also render directly to the dst. */ if (g == NULL) { while (nlist--) { if (list->format->depth != 1) return false; list++; } if (!sna_picture_is_solid(src, &color)) return false; return color >> 24 == 0xff; } else { skip: if (mask->format == g->format) return true; if (mask->format == alphaless(g->format)) return true; if (PICT_FORMAT_TYPE(g->format) == PICT_TYPE_A && PICT_FORMAT_TYPE(mask->format) != PICT_TYPE_A) return true; return false; } } static uint32_t pixman_format(PictFormatPtr short_format) { uint32_t bpp; bpp = short_format->depth; if (bpp <= 1) bpp = 1; else if (bpp <= 8) bpp = 8; else if (bpp <= 16) bpp = 16; else bpp = 32; return bpp << 24 | short_format->format; } static void glyphs_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, int src_x, int src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { struct sna *sna = to_sna_from_drawable(dst->pDrawable); pixman_image_t *src_image, *dst_image; int src_dx, src_dy; ScreenPtr screen = dst->pDrawable->pScreen; RegionRec region; int x, y, n; glyph_extents(nlist, list, glyphs, ®ion.extents); DBG(("%s: nlist=%d, count=%d, extents (%d, %d), (%d, %d)\n", __FUNCTION__, nlist, glyph_count(nlist, list), region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (region.extents.x2 <= region.extents.x1 || region.extents.y2 <= region.extents.y1) return; region.data = NULL; RegionTranslate(®ion, dst->pDrawable->x, dst->pDrawable->y); RegionIntersect(®ion, ®ion, dst->pCompositeClip); DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, RegionExtents(®ion)->x1, RegionExtents(®ion)->y1, RegionExtents(®ion)->x2, RegionExtents(®ion)->y2)); if (RegionNil(®ion)) return; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, MOVE_READ | MOVE_WRITE)) return; if (dst->alphaMap && !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, MOVE_READ | MOVE_WRITE)) return; if (src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) return; if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) return; } RegionTranslate(®ion, -dst->pDrawable->x, -dst->pDrawable->y); if (mask_format && can_discard_mask(op, src, mask_format, nlist, list, glyphs)) { DBG(("%s: discarding mask\n", __FUNCTION__)); mask_format = NULL; } #if HAS_PIXMAN_GLYPHS if (__global_glyph_cache) { pixman_glyph_t stack_glyphs[N_STACK_GLYPHS]; pixman_glyph_t *pglyphs = stack_glyphs; int dst_x = list->xOff, dst_y = list->yOff; int dst_dx, dst_dy, count; pixman_glyph_cache_freeze(__global_glyph_cache); count = 0; for (n = 0; n < nlist; ++n) count += list[n].len; if (count > N_STACK_GLYPHS) { pglyphs = malloc(count * sizeof(pixman_glyph_t)); if (pglyphs == NULL) goto out; } count = 0; x = y = 0; while (nlist--) { n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; const void *ptr; if (!glyph_valid(g)) goto next; ptr = pixman_glyph_cache_lookup(__global_glyph_cache, g, NULL); if (ptr == NULL) { pixman_image_t *glyph_image; glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) goto next; DBG(("%s: inserting glyph %p into pixman cache\n", __FUNCTION__, g)); ptr = pixman_glyph_cache_insert(__global_glyph_cache, g, NULL, g->info.x, g->info.y, glyph_image); if (ptr == NULL) goto next; } assert(sna_glyph_get_image(g, screen) != NULL); pglyphs[count].x = x; pglyphs[count].y = y; pglyphs[count].glyph = ptr; count++; next: x += g->info.xOff; y += g->info.yOff; } list++; } if (count == 0) goto out; src_image = image_from_pict(src, FALSE, &src_dx, &src_dy); if (src_image == NULL) goto out; dst_image = image_from_pict(dst, TRUE, &dst_dx, &dst_dy); if (dst_image == NULL) goto out_free_src; if (sigtrap_get() == 0) { if (mask_format) { pixman_composite_glyphs(op, src_image, dst_image, pixman_format(mask_format), src_x + src_dx + region.extents.x1 - dst_x, src_y + src_dy + region.extents.y1 - dst_y, region.extents.x1, region.extents.y1, region.extents.x1 + dst_dx, region.extents.y1 + dst_dy, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, __global_glyph_cache, count, pglyphs); } else { pixman_composite_glyphs_no_mask(op, src_image, dst_image, src_x + src_dx - dst_x, src_y + src_dy - dst_y, dst_dx, dst_dy, __global_glyph_cache, count, pglyphs); } sigtrap_put(); } free_pixman_pict(dst, dst_image); out_free_src: free_pixman_pict(src, src_image); out: pixman_glyph_cache_thaw(__global_glyph_cache); if (pglyphs != stack_glyphs) free(pglyphs); } else #endif { pixman_image_t *mask_image; dst_image = image_from_pict(dst, TRUE, &x, &y); if (dst_image == NULL) goto cleanup_region; DBG(("%s: dst offset (%d, %d)\n", __FUNCTION__, x, y)); if (x | y) { region.extents.x1 += x; region.extents.x2 += x; region.extents.y1 += y; region.extents.y2 += y; } src_image = image_from_pict(src, FALSE, &src_dx, &src_dy); if (src_image == NULL) goto cleanup_dst; DBG(("%s: src offset (%d, %d)\n", __FUNCTION__, src_dx, src_dy)); src_x += src_dx - list->xOff; src_y += src_dy - list->yOff; if (mask_format) { DBG(("%s: create mask (%d, %d)x(%d,%d) + (%d,%d) + (%d,%d), depth=%d, format=%lx [%lx], ca? %d\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, dst->pDrawable->x, dst->pDrawable->y, x, y, mask_format->depth, (long)mask_format->format, (long)pixman_format(mask_format), NeedsComponent(mask_format->format))); mask_image = pixman_image_create_bits(pixman_format(mask_format), region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, NULL, 0); if (mask_image == NULL) goto cleanup_src; if (NeedsComponent(mask_format->format)) pixman_image_set_component_alpha(mask_image, TRUE); x -= region.extents.x1; y -= region.extents.y1; } else { mask_image = dst_image; src_x -= x - dst->pDrawable->x; src_y -= y - dst->pDrawable->y; } if (sigtrap_get() == 0) { do { n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; pixman_image_t *glyph_image; if (!glyph_valid(g)) goto next_glyph; glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) goto next_glyph; if (mask_format) { DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", __FUNCTION__, x - g->info.x, y - g->info.y, g->info.width, g->info.height)); if (list->format == mask_format) { assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); pixman_image_composite(PictOpAdd, glyph_image, NULL, mask_image, 0, 0, 0, 0, x - g->info.x, y - g->info.y, g->info.width, g->info.height); } else { pixman_image_composite(PictOpAdd, sna->render.white_image, glyph_image, mask_image, 0, 0, 0, 0, x - g->info.x, y - g->info.y, g->info.width, g->info.height); } } else { int xi = x - g->info.x; int yi = y - g->info.y; DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n", __FUNCTION__, xi, yi, g->info.width, g->info.height, dst->pDrawable->x, dst->pDrawable->y, dst->pDrawable->width, dst->pDrawable->height, src_x + xi, src_y + yi, op)); pixman_image_composite(op, src_image, glyph_image, dst_image, src_x + xi, src_y + yi, 0, 0, xi, yi, g->info.width, g->info.height); } next_glyph: x += g->info.xOff; y += g->info.yOff; } list++; } while (--nlist); sigtrap_put(); } if (mask_format) { DBG(("%s: glyph mask composite src=(%d+%d,%d+%d) dst=(%d, %d)x(%d, %d)\n", __FUNCTION__, src_x, region.extents.x1, src_y, region.extents.y1, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)); pixman_image_composite(op, src_image, mask_image, dst_image, src_x, src_y, 0, 0, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1); pixman_image_unref(mask_image); } cleanup_src: free_pixman_pict(src, src_image); cleanup_dst: free_pixman_pict(dst, dst_image); } cleanup_region: RegionUninit(®ion); } void sna_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; DBG(("%s(op=%d, nlist=%d, src=(%d, %d))\n", __FUNCTION__, op, nlist, src_x, src_y)); if (RegionNil(dst->pCompositeClip)) return; if (FALLBACK) goto fallback; if (!can_render(sna)) { DBG(("%s: wedged\n", __FUNCTION__)); goto fallback; } if (!can_render_to_picture(dst)) { DBG(("%s: fallback -- dst incompatible picture\n", __FUNCTION__)); goto fallback; } priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: fallback -- destination unattached\n", __FUNCTION__)); goto fallback; } if (!is_gpu_dst(priv) && !picture_is_gpu(sna, src, 0)) { DBG(("%s: fallback -- too small (%dx%d)\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); goto fallback; } /* Try to discard the mask for non-overlapping glyphs */ if (FORCE_GLYPHS_TO_DST || mask == NULL || (dst->pCompositeClip->data == NULL && can_discard_mask(op, src, mask, nlist, list, glyphs))) { DBG(("%s: discarding mask\n", __FUNCTION__)); if (can_use_glyph0()) { if (glyphs0_to_dst(sna, op, src, dst, src_x, src_y, nlist, list, glyphs)) return; } else { if (glyphs_to_dst(sna, op, src, dst, src_x, src_y, nlist, list, glyphs)) return; } } /* Otherwise see if we can substitute a mask */ if (!mask) { mask = glyphs_format(nlist, list, glyphs); DBG(("%s: substituting mask? %d\n", __FUNCTION__, mask!=NULL)); } if (mask) { if (glyphs_via_mask(sna, op, src, dst, mask, src_x, src_y, nlist, list, glyphs)) return; } else { if (glyphs_slow(sna, op, src, dst, src_x, src_y, nlist, list, glyphs)) return; } fallback: glyphs_fallback(op, src, dst, mask, src_x, src_y, nlist, list, glyphs); } static bool glyphs_via_image(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr format, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { ScreenPtr screen = dst->pDrawable->pScreen; CARD32 component_alpha; PixmapPtr pixmap; PicturePtr mask; int16_t x, y, width, height; pixman_image_t *mask_image; int error; bool ret = false; BoxRec box; if (NO_GLYPHS_VIA_MASK) return false; DBG(("%s(op=%d, src=(%d, %d), nlist=%d, dst=(%d, %d)+(%d, %d))\n", __FUNCTION__, op, src_x, src_y, nlist, list->xOff, list->yOff, dst->pDrawable->x, dst->pDrawable->y)); glyph_extents(nlist, list, glyphs, &box); if (box.x2 <= box.x1 || box.y2 <= box.y1) return true; DBG(("%s: nlist=%d, count=%d, bounds=((%d, %d), (%d, %d))\n", __FUNCTION__, nlist, glyph_count(nlist, list), box.x1, box.y1, box.x2, box.y2)); if (!sna_compute_composite_extents(&box, src, NULL, dst, src_x, src_y, 0, 0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1)) return true; DBG(("%s: extents=((%d, %d), (%d, %d))\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); width = box.x2 - box.x1; height = box.y2 - box.y1; box.x1 -= dst->pDrawable->x; box.y1 -= dst->pDrawable->y; x = -box.x1; y = -box.y1; src_x += box.x1 - list->xOff; src_y += box.y1 - list->yOff; DBG(("%s: small mask [format=%lx, depth=%d, size=%d], rendering glyphs to upload buffer\n", __FUNCTION__, (unsigned long)format->format, format->depth, (uint32_t)width*height*format->depth)); pixmap = sna_pixmap_create_upload(screen, width, height, format->depth, KGEM_BUFFER_WRITE); if (!pixmap) return false; mask_image = pixman_image_create_bits(pixmap->drawable.bitsPerPixel << 24 | format->format, width, height, pixmap->devPrivate.ptr, pixmap->devKind); if (mask_image == NULL) goto err_pixmap; if (sigtrap_get()) { pixman_image_unref(mask_image); goto err_pixmap; } memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height); #if HAS_PIXMAN_GLYPHS if (__global_glyph_cache) { pixman_glyph_t stack_glyphs[N_STACK_GLYPHS]; pixman_glyph_t *pglyphs = stack_glyphs; int count, n; count = 0; for (n = 0; n < nlist; ++n) count += list[n].len; if (count > N_STACK_GLYPHS) { pglyphs = malloc(count * sizeof(pixman_glyph_t)); if (pglyphs == NULL) goto err_pixmap; } pixman_glyph_cache_freeze(__global_glyph_cache); count = 0; do { n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; const void *ptr; if (!glyph_valid(g)) goto next_pglyph; ptr = pixman_glyph_cache_lookup(__global_glyph_cache, g, NULL); if (ptr == NULL) { pixman_image_t *glyph_image; glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) goto next_pglyph; DBG(("%s: inserting glyph %p into pixman cache\n", __FUNCTION__, g)); ptr = pixman_glyph_cache_insert(__global_glyph_cache, g, NULL, g->info.x, g->info.y, glyph_image); if (ptr == NULL) goto next_pglyph; } assert(sna_glyph_get_image(g, screen) != NULL); pglyphs[count].x = x; pglyphs[count].y = y; pglyphs[count].glyph = ptr; count++; next_pglyph: x += g->info.xOff; y += g->info.yOff; } list++; } while (--nlist); pixman_composite_glyphs_no_mask(PIXMAN_OP_ADD, sna->render.white_image, mask_image, 0, 0, 0, 0, __global_glyph_cache, count, pglyphs); pixman_glyph_cache_thaw(__global_glyph_cache); if (pglyphs != stack_glyphs) free(pglyphs); } else #endif do { int n = list->len; x += list->xOff; y += list->yOff; while (n--) { GlyphPtr g = *glyphs++; pixman_image_t *glyph_image; int16_t xi, yi; if (!glyph_valid(g)) goto next_image; /* If the mask has been cropped, it is likely * that some of the glyphs fall outside. */ xi = x - g->info.x; yi = y - g->info.y; if (xi >= width || yi >= height) goto next_image; if (xi + g->info.width <= 0 || yi + g->info.height <= 0) goto next_image; glyph_image = sna_glyph_get_image(g, screen); if (glyph_image == NULL) goto next_image; DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", __FUNCTION__, xi, yi, g->info.width, g->info.height)); if (list->format == format) { assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); pixman_image_composite(PictOpAdd, glyph_image, NULL, mask_image, 0, 0, 0, 0, xi, yi, g->info.width, g->info.height); } else { pixman_image_composite(PictOpAdd, sna->render.white_image, glyph_image, mask_image, 0, 0, 0, 0, xi, yi, g->info.width, g->info.height); } next_image: x += g->info.xOff; y += g->info.yOff; } list++; } while (--nlist); pixman_image_unref(mask_image); sigtrap_put(); component_alpha = NeedsComponent(format->format); mask = CreatePicture(0, &pixmap->drawable, format, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) goto err_pixmap; ValidatePicture(mask); sna_composite(op, src, mask, dst, src_x, src_y, 0, 0, box.x1, box.y1, width, height); FreePicture(mask, 0); ret = true; err_pixmap: sna_pixmap_destroy(pixmap); return ret; } void sna_glyphs__shared(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, INT16 src_x, INT16 src_y, int nlist, GlyphListPtr list, GlyphPtr *glyphs) { PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; DBG(("%s(op=%d, nlist=%d, src=(%d, %d))\n", __FUNCTION__, op, nlist, src_x, src_y)); if (RegionNil(dst->pCompositeClip)) return; if (FALLBACK) goto fallback; if (!can_render(sna)) { DBG(("%s: wedged\n", __FUNCTION__)); goto fallback; } if (!can_render_to_picture(dst)) { DBG(("%s: fallback -- incompatible picture\n", __FUNCTION__)); goto fallback; } priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: fallback -- destination unattached\n", __FUNCTION__)); goto fallback; } if (!is_gpu_dst(priv) && !picture_is_gpu(sna, src, 0)) { DBG(("%s: fallback -- too small (%dx%d)\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height)); goto fallback; } if (!mask) { mask = glyphs_format(nlist, list, glyphs); DBG(("%s: substituting mask? %d\n", __FUNCTION__, mask!=NULL)); } if (mask) { if (glyphs_via_image(sna, op, src, dst, mask, src_x, src_y, nlist, list, glyphs)) return; } fallback: glyphs_fallback(op, src, dst, mask, src_x, src_y, nlist, list, glyphs); } void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) { struct sna_glyph *p = sna_glyph(glyph); DBG(("%s: screen=%d, glyph=%p (image?=%d, atlas?=%d)\n", __FUNCTION__, screen->myNum, glyph, !!p->image, p->atlas && p->atlas != GetGlyphPicture(glyph, screen))); if (p->image) { #if HAS_PIXMAN_GLYPHS if (__global_glyph_cache) { DBG(("%s: removing glyph %p from pixman cache\n", __FUNCTION__, glyph)); pixman_glyph_cache_remove(__global_glyph_cache, glyph, NULL); } #endif pixman_image_unref(p->image); p->image = NULL; } if (p->atlas && p->atlas != GetGlyphPicture(glyph, screen)) { struct sna *sna = to_sna_from_screen(screen); struct sna_glyph_cache *cache = &sna->render.glyph[p->pos&1]; DBG(("%s: releasing glyph pos %d from cache %d\n", __FUNCTION__, p->pos >> 1, p->pos & 1)); assert(cache->glyphs[p->pos >> 1] == p); cache->glyphs[p->pos >> 1] = NULL; p->atlas = NULL; } #if HAS_PIXMAN_GLYPHS assert(__global_glyph_cache == NULL || pixman_glyph_cache_lookup(__global_glyph_cache, glyph, NULL) == NULL); #endif } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_gradient.c000066400000000000000000000300331267532330400244440ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #define xFixedToDouble(f) pixman_fixed_to_double(f) bool sna_gradient_is_opaque(const PictGradient *gradient) { int n; for (n = 0; n < gradient->nstops; n++) { if (gradient->stops[n].color.alpha < 0xff00) return false; } return true; } static int sna_gradient_sample_width(PictGradient *gradient) { int n, width; width = 0; for (n = 1; n < gradient->nstops; n++) { xFixed dx = gradient->stops[n].x - gradient->stops[n-1].x; int delta, max, ramp; if (dx == 0) return 1024; max = gradient->stops[n].color.red - gradient->stops[n-1].color.red; if (max < 0) max = -max; delta = gradient->stops[n].color.green - gradient->stops[n-1].color.green; if (delta < 0) delta = -delta; if (delta > max) max = delta; delta = gradient->stops[n].color.blue - gradient->stops[n-1].color.blue; if (delta < 0) delta = -delta; if (delta > max) max = delta; delta = gradient->stops[n].color.alpha - gradient->stops[n-1].color.alpha; if (delta < 0) delta = -delta; if (delta > max) max = delta; ramp = 256 * max / dx; if (ramp > width) width = ramp; } if (width == 0) return 1; width = (width + 7) & -8; return min(width, 1024); } static bool _gradient_color_stops_equal(PictGradient *pattern, struct sna_gradient_cache *cache) { if (cache->nstops != pattern->nstops) return false; return memcmp(cache->stops, pattern->stops, sizeof(PictGradientStop)*cache->nstops) == 0; } struct kgem_bo * sna_render_get_gradient(struct sna *sna, PictGradient *pattern) { struct sna_render *render = &sna->render; struct sna_gradient_cache *cache; pixman_image_t *gradient, *image; pixman_point_fixed_t p1, p2; int i, width; struct kgem_bo *bo; DBG(("%s: %dx[%f:%x ... %f:%x ... %f:%x]\n", __FUNCTION__, pattern->nstops, pattern->stops[0].x / 65536., pattern->stops[0].color.alpha >> 8 << 24 | pattern->stops[0].color.red >> 8 << 16 | pattern->stops[0].color.green >> 8 << 8 | pattern->stops[0].color.blue >> 8 << 0, pattern->stops[pattern->nstops/2].x / 65536., pattern->stops[pattern->nstops/2].color.alpha >> 8 << 24 | pattern->stops[pattern->nstops/2].color.red >> 8 << 16 | pattern->stops[pattern->nstops/2].color.green >> 8 << 8 | pattern->stops[pattern->nstops/2].color.blue >> 8 << 0, pattern->stops[pattern->nstops-1].x / 65536., pattern->stops[pattern->nstops-1].color.alpha >> 8 << 24 | pattern->stops[pattern->nstops-1].color.red >> 8 << 16 | pattern->stops[pattern->nstops-1].color.green >> 8 << 8 | pattern->stops[pattern->nstops-1].color.blue >> 8 << 0)); for (i = 0; i < render->gradient_cache.size; i++) { cache = &render->gradient_cache.cache[i]; if (_gradient_color_stops_equal(pattern, cache)) { DBG(("%s: old --> %d\n", __FUNCTION__, i)); return kgem_bo_reference(cache->bo); } } width = sna_gradient_sample_width(pattern); DBG(("%s: sample width = %d\n", __FUNCTION__, width)); if (width == 0) return NULL; p1.x = 0; p1.y = 0; p2.x = width << 16; p2.y = 0; gradient = pixman_image_create_linear_gradient(&p1, &p2, (pixman_gradient_stop_t *)pattern->stops, pattern->nstops); if (gradient == NULL) return NULL; pixman_image_set_filter(gradient, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_set_repeat(gradient, PIXMAN_REPEAT_PAD); image = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, 1, NULL, 0); if (image == NULL) { pixman_image_unref(gradient); return NULL; } pixman_image_composite(PIXMAN_OP_SRC, gradient, NULL, image, 0, 0, 0, 0, 0, 0, width, 1); pixman_image_unref(gradient); DBG(("%s: [0]=%x, [%d]=%x [%d]=%x\n", __FUNCTION__, pixman_image_get_data(image)[0], width/2, pixman_image_get_data(image)[width/2], width-1, pixman_image_get_data(image)[width-1])); bo = kgem_create_linear(&sna->kgem, width*4, 0); if (!bo) { pixman_image_unref(image); return NULL; } bo->pitch = 4*width; kgem_bo_write(&sna->kgem, bo, pixman_image_get_data(image), 4*width); pixman_image_unref(image); if (render->gradient_cache.size < GRADIENT_CACHE_SIZE) i = render->gradient_cache.size++; else i = rand () % GRADIENT_CACHE_SIZE; cache = &render->gradient_cache.cache[i]; if (cache->nstops < pattern->nstops) { PictGradientStop *newstops; newstops = malloc(sizeof(PictGradientStop) * pattern->nstops); if (newstops == NULL) return bo; free(cache->stops); cache->stops = newstops; } memcpy(cache->stops, pattern->stops, sizeof(PictGradientStop) * pattern->nstops); cache->nstops = pattern->nstops; if (cache->bo) kgem_bo_destroy(&sna->kgem, cache->bo); cache->bo = kgem_bo_reference(bo); return bo; } void sna_render_flush_solid(struct sna *sna) { struct sna_solid_cache *cache = &sna->render.solid_cache; DBG(("sna_render_flush_solid(size=%d)\n", cache->size)); assert(cache->dirty); assert(cache->size); assert(cache->size <= 1024); kgem_bo_write(&sna->kgem, cache->cache_bo, cache->color, cache->size*sizeof(uint32_t)); cache->dirty = 0; } static void sna_render_finish_solid(struct sna *sna, bool force) { struct sna_solid_cache *cache = &sna->render.solid_cache; struct kgem_bo *old; int i; DBG(("sna_render_finish_solid(force=%d, domain=%d, busy=%d, dirty=%d, size=%d)\n", force, cache->cache_bo->domain, cache->cache_bo->rq != NULL, cache->dirty, cache->size)); if (!force && cache->cache_bo->domain != DOMAIN_GPU) return; if (cache->dirty) sna_render_flush_solid(sna); for (i = 0; i < cache->size; i++) { if (cache->bo[i] == NULL) continue; kgem_bo_destroy(&sna->kgem, cache->bo[i]); cache->bo[i] = NULL; } DBG(("sna_render_finish_solid reset\n")); old = cache->cache_bo; cache->cache_bo = kgem_create_linear(&sna->kgem, sizeof(cache->color), 0); if (cache->cache_bo == NULL) { cache->cache_bo = old; old = NULL; } if (force) cache->size = 0; if (cache->last < cache->size) { cache->bo[cache->last] = kgem_create_proxy(&sna->kgem, cache->cache_bo, cache->last*sizeof(uint32_t), sizeof(uint32_t)); if (cache->bo[cache->last]) cache->bo[cache->last]->pitch = 4; else cache->last = 1024; } if (old) kgem_bo_destroy(&sna->kgem, old); } struct kgem_bo * sna_render_get_solid(struct sna *sna, uint32_t color) { struct sna_solid_cache *cache = &sna->render.solid_cache; int i; DBG(("%s: %08x\n", __FUNCTION__, color)); if ((color & 0xffffff) == 0) /* alpha only */ return kgem_bo_reference(sna->render.alpha_cache.bo[color>>24]); if (color == 0xffffffff) { DBG(("%s(white)\n", __FUNCTION__)); return kgem_bo_reference(sna->render.alpha_cache.bo[255+7]); } if ((color >> 24) == 0xff) { int v = 0; if (((color >> 16) & 0xff) == 0) v |= 0; else if (((color >> 16) & 0xff) == 0xff) v |= 1 << 2; else v = -1; if (((color >> 8) & 0xff) == 0) v |= 0; else if (((color >> 8) & 0xff) == 0xff) v |= 1 << 1; else v = -1; if (((color >> 0) & 0xff) == 0) v |= 0; else if (((color >> 0) & 0xff) == 0xff) v |= 1 << 0; else v = -1; if (v >= 0) { DBG(("%s(primary (%d,%d,%d): %d)\n", __FUNCTION__, v & 4, v & 2, v & 1, v)); return kgem_bo_reference(sna->render.alpha_cache.bo[255+v]); } } if (cache->color[cache->last] == color) { DBG(("sna_render_get_solid(%d) = %x (last)\n", cache->last, color)); return kgem_bo_reference(cache->bo[cache->last]); } for (i = 0; i < cache->size; i++) { if (cache->color[i] == color) { if (cache->bo[i] == NULL) { DBG(("sna_render_get_solid(%d) = %x (recreate)\n", i, color)); goto create; } else { DBG(("sna_render_get_solid(%d) = %x (old)\n", i, color)); goto done; } } } sna_render_finish_solid(sna, i == ARRAY_SIZE(cache->color)); i = cache->size++; assert(i < ARRAY_SIZE(cache->color)); cache->color[i] = color; cache->dirty = 1; DBG(("sna_render_get_solid(%d) = %x (new)\n", i, color)); create: cache->bo[i] = kgem_create_proxy(&sna->kgem, cache->cache_bo, i*sizeof(uint32_t), sizeof(uint32_t)); cache->bo[i]->pitch = 4; done: cache->last = i; return kgem_bo_reference(cache->bo[i]); } static bool sna_alpha_cache_init(struct sna *sna) { struct sna_alpha_cache *cache = &sna->render.alpha_cache; uint32_t color[256 + 7]; int i; DBG(("%s\n", __FUNCTION__)); cache->cache_bo = kgem_create_linear(&sna->kgem, sizeof(color), 0); if (!cache->cache_bo) return false; for (i = 0; i < 256; i++) { color[i] = i << 24; cache->bo[i] = kgem_create_proxy(&sna->kgem, cache->cache_bo, sizeof(uint32_t)*i, sizeof(uint32_t)); if (cache->bo[i] == NULL) return false; cache->bo[i]->pitch = 4; } /* primary */ for (i = 1; i < 8; i++) { int j = 255+i; color[j] = 0xff << 24; if (i & 1) color[j] |= 0xff << 0; if (i & 2) color[j] |= 0xff << 8; if (i & 4) color[j] |= 0xff << 16; cache->bo[j] = kgem_create_proxy(&sna->kgem, cache->cache_bo, sizeof(uint32_t)*j, sizeof(uint32_t)); if (cache->bo[j] == NULL) return false; cache->bo[j]->pitch = 4; } return kgem_bo_write(&sna->kgem, cache->cache_bo, color, sizeof(color)); } static bool sna_solid_cache_init(struct sna *sna) { struct sna_solid_cache *cache = &sna->render.solid_cache; DBG(("%s\n", __FUNCTION__)); cache->cache_bo = kgem_create_linear(&sna->kgem, 4096, 0); if (!cache->cache_bo) return false; cache->last = 0; cache->color[cache->last] = 0; cache->dirty = 0; cache->size = 0; return true; } bool sna_gradients_create(struct sna *sna) { DBG(("%s\n", __FUNCTION__)); if (unlikely(sna->kgem.wedged)) return true; if (!sna_alpha_cache_init(sna)) return false; if (!sna_solid_cache_init(sna)) return false; return true; } void sna_gradients_close(struct sna *sna) { int i; DBG(("%s\n", __FUNCTION__)); for (i = 0; i < 256; i++) { if (sna->render.alpha_cache.bo[i]) { kgem_bo_destroy(&sna->kgem, sna->render.alpha_cache.bo[i]); sna->render.alpha_cache.bo[i] = NULL; } } if (sna->render.alpha_cache.cache_bo) { kgem_bo_destroy(&sna->kgem, sna->render.alpha_cache.cache_bo); sna->render.alpha_cache.cache_bo = NULL; } if (sna->render.solid_cache.cache_bo) kgem_bo_destroy(&sna->kgem, sna->render.solid_cache.cache_bo); for (i = 0; i < sna->render.solid_cache.size; i++) { if (sna->render.solid_cache.bo[i]) kgem_bo_destroy(&sna->kgem, sna->render.solid_cache.bo[i]); } sna->render.solid_cache.cache_bo = 0; sna->render.solid_cache.size = 0; sna->render.solid_cache.dirty = 0; for (i = 0; i < sna->render.gradient_cache.size; i++) { struct sna_gradient_cache *cache = &sna->render.gradient_cache.cache[i]; if (cache->bo) kgem_bo_destroy(&sna->kgem, cache->bo); free(cache->stops); cache->stops = NULL; cache->nstops = 0; } sna->render.gradient_cache.size = 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_io.c000066400000000000000000001446611267532330400232730ustar00rootroot00000000000000/* * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_reg.h" #include #define PITCH(x, y) ALIGN((x)*(y), 4) #define FORCE_INPLACE 0 /* 1 upload directly, -1 force indirect */ /* XXX Need to avoid using GTT fenced access for I915_TILING_Y on 855GM */ static inline bool upload_too_large(struct sna *sna, int width, int height) { return width * height * 4 > sna->kgem.max_upload_tile_size; } static inline bool must_tile(struct sna *sna, int width, int height) { return (width > sna->render.max_3d_size || height > sna->render.max_3d_size || upload_too_large(sna, width, height)); } static bool download_inplace__cpu(struct kgem *kgem, PixmapPtr p, struct kgem_bo *bo, const BoxRec *box, int nbox) { BoxRec extents; switch (bo->tiling) { case I915_TILING_X: if (!kgem->memcpy_from_tiled_x) return false; case I915_TILING_NONE: break; default: return false; } if (!kgem_bo_can_map__cpu(kgem, bo, false)) return false; if (kgem->has_llc) return true; extents = *box; while (--nbox) { ++box; if (box->x1 < extents.x1) extents.x1 = box->x1; if (box->x2 > extents.x2) extents.x2 = box->x2; extents.y2 = box->y2; } if (extents.x2 - extents.x1 == p->drawable.width && extents.y2 - extents.y1 == p->drawable.height) return true; return __kgem_bo_size(bo) <= PAGE_SIZE; } static bool read_boxes_inplace__cpu(struct kgem *kgem, PixmapPtr pixmap, struct kgem_bo *bo, const BoxRec *box, int n) { int bpp = pixmap->drawable.bitsPerPixel; void *src, *dst = pixmap->devPrivate.ptr; int src_pitch = bo->pitch; int dst_pitch = pixmap->devKind; if (!download_inplace__cpu(kgem, dst, bo, box, n)) return false; if (bo->tiling == I915_TILING_Y) return false; assert(kgem_bo_can_map__cpu(kgem, bo, false)); src = kgem_bo_map__cpu(kgem, bo); if (src == NULL) return false; kgem_bo_sync__cpu_full(kgem, bo, 0); if (sigtrap_get()) return false; DBG(("%s x %d\n", __FUNCTION__, n)); if (bo->tiling == I915_TILING_X) { do { memcpy_from_tiled_x(kgem, src, dst, bpp, src_pitch, dst_pitch, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { do { memcpy_blt(src, dst, bpp, src_pitch, dst_pitch, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } sigtrap_put(); return true; } static void read_boxes_inplace(struct kgem *kgem, PixmapPtr pixmap, struct kgem_bo *bo, const BoxRec *box, int n) { int bpp = pixmap->drawable.bitsPerPixel; void *src, *dst = pixmap->devPrivate.ptr; int src_pitch = bo->pitch; int dst_pitch = pixmap->devKind; if (read_boxes_inplace__cpu(kgem, pixmap, bo, box, n)) return; DBG(("%s x %d, tiling=%d\n", __FUNCTION__, n, bo->tiling)); if (!kgem_bo_can_map(kgem, bo)) return; kgem_bo_submit(kgem, bo); src = kgem_bo_map(kgem, bo); if (src == NULL) return; if (sigtrap_get()) return; assert(src != dst); do { DBG(("%s: copying box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); memcpy_blt(src, dst, bpp, src_pitch, dst_pitch, box->x1, box->y1, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); } static bool download_inplace(struct kgem *kgem, PixmapPtr p, struct kgem_bo *bo, const BoxRec *box, int nbox) { bool cpu; if (unlikely(kgem->wedged)) return true; cpu = download_inplace__cpu(kgem, p, bo, box, nbox); if (!cpu && !kgem_bo_can_map(kgem, bo)) return false; if (FORCE_INPLACE) return FORCE_INPLACE > 0; if (cpu) return true; if (kgem->can_blt_cpu && kgem->max_cpu_size) return false; return !__kgem_bo_is_busy(kgem, bo); } void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; struct kgem_bo *dst_bo; BoxRec extents; const BoxRec *tmp_box; int tmp_nbox; void *ptr; int src_pitch, cpp, offset; int n, cmd, br13; bool can_blt; DBG(("%s x %d, src=(handle=%d), dst=(size=(%d, %d)\n", __FUNCTION__, nbox, src_bo->handle, dst->drawable.width, dst->drawable.height)); #ifndef NDEBUG for (n = 0; n < nbox; n++) { if (box[n].x1 < 0 || box[n].y1 < 0 || box[n].x2 * dst->drawable.bitsPerPixel/8 > src_bo->pitch || box[n].y2 * src_bo->pitch > kgem_bo_size(src_bo)) { FatalError("source out-of-bounds box[%d]=(%d, %d), (%d, %d), pitch=%d, size=%d\n", n, box[n].x1, box[n].y1, box[n].x2, box[n].y2, src_bo->pitch, kgem_bo_size(src_bo)); } } #endif /* XXX The gpu is faster to perform detiling in bulk, but takes * longer to setup and retrieve the results, with an additional * copy. The long term solution is to use snoopable bo and avoid * this path. */ if (download_inplace(kgem, dst, src_bo, box, nbox)) { fallback: read_boxes_inplace(kgem, dst, src_bo, box, nbox); return; } can_blt = kgem_bo_can_blt(kgem, src_bo) && (box[0].x2 - box[0].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); extents = box[0]; for (n = 1; n < nbox; n++) { if (box[n].x1 < extents.x1) extents.x1 = box[n].x1; if (box[n].x2 > extents.x2) extents.x2 = box[n].x2; if (can_blt) can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); if (box[n].y1 < extents.y1) extents.y1 = box[n].y1; if (box[n].y2 > extents.y2) extents.y2 = box[n].y2; } if (!can_blt && sna->render.max_3d_size == 0) goto fallback; if (kgem_bo_can_map(kgem, src_bo)) { /* Is it worth detiling? */ if ((extents.y2 - extents.y1 - 1) * src_bo->pitch < 4096) goto fallback; } /* Try to avoid switching rings... */ if (!can_blt || kgem->ring == KGEM_RENDER || upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DrawableRec tmp; tmp.width = extents.x2 - extents.x1; tmp.height = extents.y2 - extents.y1; tmp.depth = dst->drawable.depth; tmp.bitsPerPixel = dst->drawable.bitsPerPixel; assert(tmp.width); assert(tmp.height); if (must_tile(sna, tmp.width, tmp.height)) { BoxRec tile, stack[64], *clipped, *c; int step; if (n > ARRAY_SIZE(stack)) { clipped = malloc(sizeof(BoxRec) * n); if (clipped == NULL) goto fallback; } else clipped = stack; step = MIN(sna->render.max_3d_size, 8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel); while (step * step * 4 > sna->kgem.max_upload_tile_size) step /= 2; DBG(("%s: tiling download, using %dx%d tiles\n", __FUNCTION__, step, step)); assert(step); for (tile.y1 = extents.y1; tile.y1 < extents.y2; tile.y1 = tile.y2) { int y2 = tile.y1 + step; if (y2 > extents.y2) y2 = extents.y2; tile.y2 = y2; for (tile.x1 = extents.x1; tile.x1 < extents.x2; tile.x1 = tile.x2) { int x2 = tile.x1 + step; if (x2 > extents.x2) x2 = extents.x2; tile.x2 = x2; tmp.width = tile.x2 - tile.x1; tmp.height = tile.y2 - tile.y1; c = clipped; for (n = 0; n < nbox; n++) { *c = box[n]; if (!box_intersect(c, &tile)) continue; DBG(("%s: box(%d, %d), (%d, %d),, dst=(%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2, c->x1 - tile.x1, c->y1 - tile.y1)); c++; } if (c == clipped) continue; dst_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_LAST, &ptr); if (!dst_bo) { if (clipped != stack) free(clipped); goto fallback; } if (!sna->render.copy_boxes(sna, GXcopy, &dst->drawable, src_bo, 0, 0, &tmp, dst_bo, -tile.x1, -tile.y1, clipped, c-clipped, COPY_LAST)) { kgem_bo_destroy(&sna->kgem, dst_bo); if (clipped != stack) free(clipped); goto fallback; } kgem_bo_submit(&sna->kgem, dst_bo); kgem_buffer_read_sync(kgem, dst_bo); if (sigtrap_get() == 0) { while (c-- != clipped) { memcpy_blt(ptr, dst->devPrivate.ptr, tmp.bitsPerPixel, dst_bo->pitch, dst->devKind, c->x1 - tile.x1, c->y1 - tile.y1, c->x1, c->y1, c->x2 - c->x1, c->y2 - c->y1); } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, dst_bo); } } if (clipped != stack) free(clipped); } else { dst_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_LAST, &ptr); if (!dst_bo) goto fallback; if (!sna->render.copy_boxes(sna, GXcopy, &dst->drawable, src_bo, 0, 0, &tmp, dst_bo, -extents.x1, -extents.y1, box, nbox, COPY_LAST)) { kgem_bo_destroy(&sna->kgem, dst_bo); goto fallback; } kgem_bo_submit(&sna->kgem, dst_bo); kgem_buffer_read_sync(kgem, dst_bo); if (sigtrap_get() == 0) { for (n = 0; n < nbox; n++) { memcpy_blt(ptr, dst->devPrivate.ptr, tmp.bitsPerPixel, dst_bo->pitch, dst->devKind, box[n].x1 - extents.x1, box[n].y1 - extents.y1, box[n].x1, box[n].y1, box[n].x2 - box[n].x1, box[n].y2 - box[n].y1); } sigtrap_put(); } kgem_bo_destroy(&sna->kgem, dst_bo); } return; } /* count the total number of bytes to be read and allocate a bo */ cpp = dst->drawable.bitsPerPixel / 8; offset = 0; for (n = 0; n < nbox; n++) { int height = box[n].y2 - box[n].y1; int width = box[n].x2 - box[n].x1; offset += PITCH(width, cpp) * height; } DBG((" read buffer size=%d\n", offset)); dst_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_LAST, &ptr); if (!dst_bo) { read_boxes_inplace(kgem, dst, src_bo, box, nbox); return; } cmd = XY_SRC_COPY_BLT_CMD; src_pitch = src_bo->pitch; if (kgem->gen >= 040 && src_bo->tiling) { cmd |= BLT_SRC_TILED; src_pitch >>= 2; } br13 = 0xcc << 16; switch (cpp) { default: case 4: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; br13 |= 1 << 25; /* RGB8888 */ case 2: br13 |= 1 << 24; /* RGB565 */ case 1: break; } kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) { kgem_submit(kgem); if (!kgem_check_many_bo_fenced(kgem, dst_bo, src_bo, NULL)) goto fallback; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL); tmp_nbox = nbox; tmp_box = box; offset = 0; if (sna->kgem.gen >= 0100) { cmd |= 8; do { int nbox_this_time, rem; nbox_this_time = tmp_nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); tmp_nbox -= nbox_this_time; assert(kgem->mode == KGEM_BLT); for (n = 0; n < nbox_this_time; n++) { int height = tmp_box[n].y2 - tmp_box[n].y1; int width = tmp_box[n].x2 - tmp_box[n].x1; int pitch = PITCH(width, cpp); uint32_t *b = kgem->batch + kgem->nbatch; DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n", offset, tmp_box[n].x1, tmp_box[n].y1, width, height, pitch)); assert(tmp_box[n].x1 >= 0); assert(tmp_box[n].x2 * dst->drawable.bitsPerPixel/8 <= src_bo->pitch); assert(tmp_box[n].y1 >= 0); assert(tmp_box[n].y2 * src_bo->pitch <= kgem_bo_size(src_bo)); b[0] = cmd; b[1] = br13 | pitch; b[2] = 0; b[3] = height << 16 | width; *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, offset); b[6] = tmp_box[n].y1 << 16 | tmp_box[n].x1; b[7] = src_pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 10; offset += pitch * height; } _kgem_submit(kgem); if (!tmp_nbox) break; _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL); tmp_box += nbox_this_time; } while (1); } else { cmd |= 6; do { int nbox_this_time, rem; nbox_this_time = tmp_nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); tmp_nbox -= nbox_this_time; assert(kgem->mode == KGEM_BLT); for (n = 0; n < nbox_this_time; n++) { int height = tmp_box[n].y2 - tmp_box[n].y1; int width = tmp_box[n].x2 - tmp_box[n].x1; int pitch = PITCH(width, cpp); uint32_t *b = kgem->batch + kgem->nbatch; DBG((" blt offset %x: (%d, %d) x (%d, %d), pitch=%d\n", offset, tmp_box[n].x1, tmp_box[n].y1, width, height, pitch)); assert(tmp_box[n].x1 >= 0); assert(tmp_box[n].x2 * dst->drawable.bitsPerPixel/8 <= src_bo->pitch); assert(tmp_box[n].y1 >= 0); assert(tmp_box[n].y2 * src_bo->pitch <= kgem_bo_size(src_bo)); b[0] = cmd; b[1] = br13 | pitch; b[2] = 0; b[3] = height << 16 | width; b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, offset); b[5] = tmp_box[n].y1 << 16 | tmp_box[n].x1; b[6] = src_pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, 0); kgem->nbatch += 8; offset += pitch * height; } _kgem_submit(kgem); if (!tmp_nbox) break; _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL); tmp_box += nbox_this_time; } while (1); } assert(offset == __kgem_buffer_size(dst_bo)); kgem_buffer_read_sync(kgem, dst_bo); if (sigtrap_get() == 0) { char *src = ptr; do { int height = box->y2 - box->y1; int width = box->x2 - box->x1; int pitch = PITCH(width, cpp); DBG((" copy offset %lx [%08x...%08x...%08x]: (%d, %d) x (%d, %d), src pitch=%d, dst pitch=%d, bpp=%d\n", (long)((char *)src - (char *)ptr), *(uint32_t*)src, *(uint32_t*)(src+pitch*height/2 + pitch/2 - 4), *(uint32_t*)(src+pitch*height - 4), box->x1, box->y1, width, height, pitch, dst->devKind, cpp*8)); assert(box->x1 >= 0); assert(box->x2 <= dst->drawable.width); assert(box->y1 >= 0); assert(box->y2 <= dst->drawable.height); memcpy_blt(src, dst->devPrivate.ptr, cpp*8, pitch, dst->devKind, 0, 0, box->x1, box->y1, width, height); box++; src += pitch * height; } while (--nbox); assert(src - (char *)ptr == __kgem_buffer_size(dst_bo)); sigtrap_put(); } kgem_bo_destroy(kgem, dst_bo); sna->blt_state.fill_bo = 0; } static bool upload_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: tiling=%d\n", __FUNCTION__, bo->tiling)); switch (bo->tiling) { case I915_TILING_Y: return false; case I915_TILING_X: if (!kgem->memcpy_to_tiled_x) return false; default: break; } if (kgem->has_wc_mmap) return true; return kgem_bo_can_map__cpu(kgem, bo, true); } static bool write_boxes_inplace__tiled(struct kgem *kgem, const uint8_t *src, int stride, int bpp, int16_t src_dx, int16_t src_dy, struct kgem_bo *bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n) { uint8_t *dst; if (bo->tiling == I915_TILING_Y) return false; assert(kgem->has_wc_mmap || kgem_bo_can_map__cpu(kgem, bo, true)); if (kgem_bo_can_map__cpu(kgem, bo, true)) { dst = kgem_bo_map__cpu(kgem, bo); if (dst == NULL) return false; kgem_bo_sync__cpu(kgem, bo); } else { dst = kgem_bo_map__wc(kgem, bo); if (dst == NULL) return false; kgem_bo_sync__gtt(kgem, bo); } if (sigtrap_get()) return false; if (bo->tiling) { do { memcpy_to_tiled_x(kgem, src, dst, bpp, stride, bo->pitch, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } else { do { memcpy_blt(src, dst, bpp, stride, bo->pitch, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); } sigtrap_put(); return true; } static bool write_boxes_inplace(struct kgem *kgem, const void *src, int stride, int bpp, int16_t src_dx, int16_t src_dy, struct kgem_bo *bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n) { void *dst; DBG(("%s x %d, handle=%d, tiling=%d\n", __FUNCTION__, n, bo->handle, bo->tiling)); if (upload_inplace__tiled(kgem, bo) && write_boxes_inplace__tiled(kgem, src, stride, bpp, src_dx, src_dy, bo, dst_dx, dst_dy, box, n)) return true; if (!kgem_bo_can_map(kgem, bo)) return false; kgem_bo_submit(kgem, bo); dst = kgem_bo_map(kgem, bo); if (dst == NULL) return false; assert(dst != src); if (sigtrap_get()) return false; do { DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d) [bpp=%d, src_pitch=%d, dst_pitch=%d]\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1, bpp, stride, bo->pitch)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 + dst_dx >= 0); assert((box->x2 + dst_dx)*bpp <= 8*bo->pitch); assert(box->y1 + dst_dy >= 0); assert((box->y2 + dst_dy)*bo->pitch <= kgem_bo_size(bo)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*bpp <= 8*stride); assert(box->y1 + src_dy >= 0); memcpy_blt(src, dst, bpp, stride, bo->pitch, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); return true; } static bool __upload_inplace(struct kgem *kgem, struct kgem_bo *bo, const BoxRec *box, int n, int bpp) { unsigned int bytes; if (FORCE_INPLACE) return FORCE_INPLACE > 0; if (bo->exec) return false; if (bo->flush) return true; if (kgem_bo_can_map__cpu(kgem, bo, true)) return true; /* If we are writing through the GTT, check first if we might be * able to almagamate a series of small writes into a single * operation. */ bytes = 0; while (n--) { bytes += (box->x2 - box->x1) * (box->y2 - box->y1); box++; } if (__kgem_bo_is_busy(kgem, bo)) return bytes * bpp >> 12 >= kgem->half_cpu_cache_pages; else return bytes * bpp >> 12; } static bool upload_inplace(struct kgem *kgem, struct kgem_bo *bo, const BoxRec *box, int n, int bpp) { if (unlikely(kgem->wedged)) return true; if (!kgem_bo_can_map(kgem, bo) && !upload_inplace__tiled(kgem, bo)) return false; return __upload_inplace(kgem, bo, box, n,bpp); } bool sna_write_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo * const dst_bo, int16_t const dst_dx, int16_t const dst_dy, const void * const src, int const stride, int16_t const src_dx, int16_t const src_dy, const BoxRec *box, int nbox) { struct kgem *kgem = &sna->kgem; struct kgem_bo *src_bo; BoxRec extents; void *ptr; int offset; int n, cmd, br13; bool can_blt; DBG(("%s x %d, src stride=%d, src dx=(%d, %d)\n", __FUNCTION__, nbox, stride, src_dx, src_dy)); if (upload_inplace(kgem, dst_bo, box, nbox, dst->drawable.bitsPerPixel) && write_boxes_inplace(kgem, src, stride, dst->drawable.bitsPerPixel, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, nbox)) return true; if (wedged(sna)) return false; can_blt = kgem_bo_can_blt(kgem, dst_bo) && (box[0].x2 - box[0].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); extents = box[0]; for (n = 1; n < nbox; n++) { if (box[n].x1 < extents.x1) extents.x1 = box[n].x1; if (box[n].x2 > extents.x2) extents.x2 = box[n].x2; if (can_blt) can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); if (box[n].y1 < extents.y1) extents.y1 = box[n].y1; if (box[n].y2 > extents.y2) extents.y2 = box[n].y2; } if (!can_blt && sna->render.max_3d_size == 0) goto fallback; /* Try to avoid switching rings... */ if (!can_blt || kgem->ring == KGEM_RENDER || upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DrawableRec tmp; tmp.width = extents.x2 - extents.x1; tmp.height = extents.y2 - extents.y1; tmp.depth = dst->drawable.depth; tmp.bitsPerPixel = dst->drawable.bitsPerPixel; assert(tmp.width); assert(tmp.height); DBG(("%s: upload (%d, %d)x(%d, %d), max %dx%d\n", __FUNCTION__, extents.x1, extents.y1, tmp.width, tmp.height, sna->render.max_3d_size, sna->render.max_3d_size)); if (must_tile(sna, tmp.width, tmp.height)) { BoxRec tile, stack[64], *clipped; int cpp, step; tile: cpp = dst->drawable.bitsPerPixel / 8; step = MIN(sna->render.max_3d_size, (MAXSHORT&~63) / cpp); while (step * step * cpp > sna->kgem.max_upload_tile_size) step /= 2; if (step * cpp > 4096) step = 4096 / cpp; assert(step); DBG(("%s: tiling upload, using %dx%d tiles\n", __FUNCTION__, step, step)); if (n > ARRAY_SIZE(stack)) { clipped = malloc(sizeof(BoxRec) * n); if (clipped == NULL) goto fallback; } else clipped = stack; for (tile.y1 = extents.y1; tile.y1 < extents.y2; tile.y1 = tile.y2) { int y2 = tile.y1 + step; if (y2 > extents.y2) y2 = extents.y2; tile.y2 = y2; for (tile.x1 = extents.x1; tile.x1 < extents.x2; tile.x1 = tile.x2) { int x2 = tile.x1 + step; if (x2 > extents.x2) x2 = extents.x2; tile.x2 = x2; tmp.width = tile.x2 - tile.x1; tmp.height = tile.y2 - tile.y1; src_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!src_bo) { if (clipped != stack) free(clipped); goto fallback; } if (sigtrap_get() == 0) { BoxRec *c = clipped; for (n = 0; n < nbox; n++) { *c = box[n]; if (!box_intersect(c, &tile)) continue; DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2, src_dx, src_dy, c->x1 - tile.x1, c->y1 - tile.y1)); memcpy_blt(src, ptr, tmp.bitsPerPixel, stride, src_bo->pitch, c->x1 + src_dx, c->y1 + src_dy, c->x1 - tile.x1, c->y1 - tile.y1, c->x2 - c->x1, c->y2 - c->y1); c++; } if (c != clipped) n = sna->render.copy_boxes(sna, GXcopy, &tmp, src_bo, -tile.x1, -tile.y1, &dst->drawable, dst_bo, dst_dx, dst_dy, clipped, c - clipped, 0); else n = 1; sigtrap_put(); } else n = 0; kgem_bo_destroy(&sna->kgem, src_bo); if (!n) { if (clipped != stack) free(clipped); goto fallback; } } } if (clipped != stack) free(clipped); } else { src_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!src_bo) goto fallback; if (sigtrap_get() == 0) { for (n = 0; n < nbox; n++) { DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, box[n].x1, box[n].y1, box[n].x2, box[n].y2, src_dx, src_dy, box[n].x1 - extents.x1, box[n].y1 - extents.y1)); memcpy_blt(src, ptr, tmp.bitsPerPixel, stride, src_bo->pitch, box[n].x1 + src_dx, box[n].y1 + src_dy, box[n].x1 - extents.x1, box[n].y1 - extents.y1, box[n].x2 - box[n].x1, box[n].y2 - box[n].y1); } n = sna->render.copy_boxes(sna, GXcopy, &tmp, src_bo, -extents.x1, -extents.y1, &dst->drawable, dst_bo, dst_dx, dst_dy, box, nbox, 0); sigtrap_put(); } else n = 0; kgem_bo_destroy(&sna->kgem, src_bo); if (!n) goto tile; } return true; } cmd = XY_SRC_COPY_BLT_CMD; br13 = dst_bo->pitch; if (kgem->gen >= 040 && dst_bo->tiling) { cmd |= BLT_DST_TILED; br13 >>= 2; } br13 |= 0xcc << 16; switch (dst->drawable.bitsPerPixel) { default: case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_bo_fenced(kgem, dst_bo)) { kgem_submit(kgem); if (!kgem_check_bo_fenced(kgem, dst_bo)) goto fallback; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); if (kgem->gen >= 0100) { cmd |= 8; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); nbox -= nbox_this_time; /* Count the total number of bytes to be read and allocate a * single buffer large enough. Or if it is very small, combine * with other allocations. */ offset = 0; for (n = 0; n < nbox_this_time; n++) { int height = box[n].y2 - box[n].y1; int width = box[n].x2 - box[n].x1; offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height; } src_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) break; if (sigtrap_get() == 0) { offset = 0; do { int height = box->y2 - box->y1; int width = box->x2 - box->x1; int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); uint32_t *b; DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, width, height, offset, pitch)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); memcpy_blt(src, (char *)ptr + offset, dst->drawable.bitsPerPixel, stride, pitch, box->x1 + src_dx, box->y1 + src_dy, 0, 0, width, height); assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = 0; b[7] = pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, offset); kgem->nbatch += 10; box++; offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); sigtrap_put(); } if (nbox) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); } kgem_bo_destroy(kgem, src_bo); } while (nbox); } else { cmd |= 6; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); nbox -= nbox_this_time; /* Count the total number of bytes to be read and allocate a * single buffer large enough. Or if it is very small, combine * with other allocations. */ offset = 0; for (n = 0; n < nbox_this_time; n++) { int height = box[n].y2 - box[n].y1; int width = box[n].x2 - box[n].x1; offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height; } src_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) break; if (sigtrap_get()) { kgem_bo_destroy(kgem, src_bo); goto fallback; } offset = 0; do { int height = box->y2 - box->y1; int width = box->x2 - box->x1; int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); uint32_t *b; DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, width, height, offset, pitch)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); memcpy_blt(src, (char *)ptr + offset, dst->drawable.bitsPerPixel, stride, pitch, box->x1 + src_dx, box->y1 + src_dy, 0, 0, width, height); assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = 0; b[6] = pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, offset); kgem->nbatch += 8; box++; offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); sigtrap_put(); if (nbox) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); } kgem_bo_destroy(kgem, src_bo); } while (nbox); } sna->blt_state.fill_bo = 0; return true; fallback: return write_boxes_inplace(kgem, src, stride, dst->drawable.bitsPerPixel, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, nbox); } static bool write_boxes_inplace__xor(struct kgem *kgem, const void *src, int stride, int bpp, int16_t src_dx, int16_t src_dy, struct kgem_bo *bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, uint32_t and, uint32_t or) { void *dst; DBG(("%s x %d, tiling=%d\n", __FUNCTION__, n, bo->tiling)); if (!kgem_bo_can_map(kgem, bo)) return false; kgem_bo_submit(kgem, bo); dst = kgem_bo_map(kgem, bo); if (dst == NULL) return false; if (sigtrap_get()) return false; do { DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d) [bpp=%d, src_pitch=%d, dst_pitch=%d]\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1, bpp, stride, bo->pitch)); assert(box->x2 > box->x1); assert(box->y2 > box->y1); assert(box->x1 + dst_dx >= 0); assert((box->x2 + dst_dx)*bpp <= 8*bo->pitch); assert(box->y1 + dst_dy >= 0); assert((box->y2 + dst_dy)*bo->pitch <= kgem_bo_size(bo)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*bpp <= 8*stride); assert(box->y1 + src_dy >= 0); memcpy_xor(src, dst, bpp, stride, bo->pitch, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, box->x2 - box->x1, box->y2 - box->y1, and, or); box++; } while (--n); sigtrap_put(); return true; } static bool upload_inplace__xor(struct kgem *kgem, struct kgem_bo *bo, const BoxRec *box, int n, int bpp) { if (unlikely(kgem->wedged)) return true; if (!kgem_bo_can_map(kgem, bo)) return false; return __upload_inplace(kgem, bo, box, n, bpp); } bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const void *src, int stride, int16_t src_dx, int16_t src_dy, const BoxRec *box, int nbox, uint32_t and, uint32_t or) { struct kgem *kgem = &sna->kgem; struct kgem_bo *src_bo; BoxRec extents; bool can_blt; void *ptr; int offset; int n, cmd, br13; DBG(("%s x %d\n", __FUNCTION__, nbox)); if (upload_inplace__xor(kgem, dst_bo, box, nbox, dst->drawable.bitsPerPixel) && write_boxes_inplace__xor(kgem, src, stride, dst->drawable.bitsPerPixel, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, nbox, and, or)) return true; if (wedged(sna)) return false; can_blt = kgem_bo_can_blt(kgem, dst_bo) && (box[0].x2 - box[0].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); extents = box[0]; for (n = 1; n < nbox; n++) { if (box[n].x1 < extents.x1) extents.x1 = box[n].x1; if (box[n].x2 > extents.x2) extents.x2 = box[n].x2; if (can_blt) can_blt = (box[n].x2 - box[n].x1) * dst->drawable.bitsPerPixel < 8 * (MAXSHORT - 4); if (box[n].y1 < extents.y1) extents.y1 = box[n].y1; if (box[n].y2 > extents.y2) extents.y2 = box[n].y2; } /* Try to avoid switching rings... */ if (!can_blt || kgem->ring == KGEM_RENDER || upload_too_large(sna, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DrawableRec tmp; tmp.width = extents.x2 - extents.x1; tmp.height = extents.y2 - extents.y1; tmp.depth = dst->drawable.depth; tmp.bitsPerPixel = dst->drawable.bitsPerPixel; assert(tmp.width); assert(tmp.height); DBG(("%s: upload (%d, %d)x(%d, %d), max %dx%d\n", __FUNCTION__, extents.x1, extents.y1, tmp.width, tmp.height, sna->render.max_3d_size, sna->render.max_3d_size)); if (must_tile(sna, tmp.width, tmp.height)) { BoxRec tile, stack[64], *clipped; int step; tile: step = MIN(sna->render.max_3d_size - 4096 / dst->drawable.bitsPerPixel, 8*(MAXSHORT&~63) / dst->drawable.bitsPerPixel); while (step * step * 4 > sna->kgem.max_upload_tile_size) step /= 2; DBG(("%s: tiling upload, using %dx%d tiles\n", __FUNCTION__, step, step)); assert(step); if (n > ARRAY_SIZE(stack)) { clipped = malloc(sizeof(BoxRec) * n); if (clipped == NULL) goto fallback; } else clipped = stack; for (tile.y1 = extents.y1; tile.y1 < extents.y2; tile.y1 = tile.y2) { int y2 = tile.y1 + step; if (y2 > extents.y2) y2 = extents.y2; tile.y2 = y2; for (tile.x1 = extents.x1; tile.x1 < extents.x2; tile.x1 = tile.x2) { int x2 = tile.x1 + step; if (x2 > extents.x2) x2 = extents.x2; tile.x2 = x2; tmp.width = tile.x2 - tile.x1; tmp.height = tile.y2 - tile.y1; src_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!src_bo) { if (clipped != stack) free(clipped); goto fallback; } if (sigtrap_get() == 0) { BoxRec *c = clipped; for (n = 0; n < nbox; n++) { *c = box[n]; if (!box_intersect(c, &tile)) continue; DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2, src_dx, src_dy, c->x1 - tile.x1, c->y1 - tile.y1)); memcpy_xor(src, ptr, tmp.bitsPerPixel, stride, src_bo->pitch, c->x1 + src_dx, c->y1 + src_dy, c->x1 - tile.x1, c->y1 - tile.y1, c->x2 - c->x1, c->y2 - c->y1, and, or); c++; } if (c != clipped) n = sna->render.copy_boxes(sna, GXcopy, &tmp, src_bo, -tile.x1, -tile.y1, &dst->drawable, dst_bo, dst_dx, dst_dy, clipped, c - clipped, 0); else n = 1; sigtrap_put(); } else n = 0; kgem_bo_destroy(&sna->kgem, src_bo); if (!n) { if (clipped != stack) free(clipped); goto fallback; } } } if (clipped != stack) free(clipped); } else { src_bo = kgem_create_buffer_2d(kgem, tmp.width, tmp.height, tmp.bitsPerPixel, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!src_bo) goto fallback; if (sigtrap_get() == 0) { for (n = 0; n < nbox; n++) { DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, box[n].x1, box[n].y1, box[n].x2, box[n].y2, src_dx, src_dy, box[n].x1 - extents.x1, box[n].y1 - extents.y1)); memcpy_xor(src, ptr, tmp.bitsPerPixel, stride, src_bo->pitch, box[n].x1 + src_dx, box[n].y1 + src_dy, box[n].x1 - extents.x1, box[n].y1 - extents.y1, box[n].x2 - box[n].x1, box[n].y2 - box[n].y1, and, or); } n = sna->render.copy_boxes(sna, GXcopy, &tmp, src_bo, -extents.x1, -extents.y1, &dst->drawable, dst_bo, dst_dx, dst_dy, box, nbox, 0); sigtrap_put(); } else n = 0; kgem_bo_destroy(&sna->kgem, src_bo); if (!n) goto tile; } return true; } cmd = XY_SRC_COPY_BLT_CMD; br13 = dst_bo->pitch; if (kgem->gen >= 040 && dst_bo->tiling) { cmd |= BLT_DST_TILED; br13 >>= 2; } br13 |= 0xcc << 16; switch (dst->drawable.bitsPerPixel) { default: case 32: cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB; br13 |= 1 << 25; /* RGB8888 */ case 16: br13 |= 1 << 24; /* RGB565 */ case 8: break; } kgem_set_mode(kgem, KGEM_BLT, dst_bo); if (!kgem_check_batch(kgem, 10) || !kgem_check_reloc_and_exec(kgem, 2) || !kgem_check_bo_fenced(kgem, dst_bo)) { kgem_submit(kgem); if (!kgem_check_bo_fenced(kgem, dst_bo)) goto fallback; _kgem_set_mode(kgem, KGEM_BLT); } kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); if (sna->kgem.gen >= 0100) { cmd |= 8; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (10*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); nbox -= nbox_this_time; /* Count the total number of bytes to be read and allocate a * single buffer large enough. Or if it is very small, combine * with other allocations. */ offset = 0; for (n = 0; n < nbox_this_time; n++) { int height = box[n].y2 - box[n].y1; int width = box[n].x2 - box[n].x1; offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height; } src_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) goto fallback; if (sigtrap_get()) { kgem_bo_destroy(kgem, src_bo); goto fallback; } offset = 0; do { int height = box->y2 - box->y1; int width = box->x2 - box->x1; int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); uint32_t *b; DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, width, height, offset, pitch)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); memcpy_xor(src, (char *)ptr + offset, dst->drawable.bitsPerPixel, stride, pitch, box->x1 + src_dx, box->y1 + src_dy, 0, 0, width, height, and, or); assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); *(uint64_t *)(b+4) = kgem_add_reloc64(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[6] = 0; b[7] = pitch; *(uint64_t *)(b+8) = kgem_add_reloc64(kgem, kgem->nbatch + 8, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, offset); kgem->nbatch += 10; box++; offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); sigtrap_put(); if (nbox) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); } kgem_bo_destroy(kgem, src_bo); } while (nbox); } else { cmd |= 6; do { int nbox_this_time, rem; nbox_this_time = nbox; rem = kgem_batch_space(kgem); if (8*nbox_this_time > rem) nbox_this_time = rem / 8; if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc) nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2; assert(nbox_this_time); nbox -= nbox_this_time; /* Count the total number of bytes to be read and allocate a * single buffer large enough. Or if it is very small, combine * with other allocations. */ offset = 0; for (n = 0; n < nbox_this_time; n++) { int height = box[n].y2 - box[n].y1; int width = box[n].x2 - box[n].x1; offset += PITCH(width, dst->drawable.bitsPerPixel >> 3) * height; } src_bo = kgem_create_buffer(kgem, offset, KGEM_BUFFER_WRITE_INPLACE | (nbox ? KGEM_BUFFER_LAST : 0), &ptr); if (!src_bo) goto fallback; if (sigtrap_get()) { kgem_bo_destroy(kgem, src_bo); goto fallback; } offset = 0; do { int height = box->y2 - box->y1; int width = box->x2 - box->x1; int pitch = PITCH(width, dst->drawable.bitsPerPixel >> 3); uint32_t *b; DBG((" %s: box src=(%d, %d), dst=(%d, %d) size=(%d, %d), dst offset=%d, dst pitch=%d\n", __FUNCTION__, box->x1 + src_dx, box->y1 + src_dy, box->x1 + dst_dx, box->y1 + dst_dy, width, height, offset, pitch)); assert(box->x1 + src_dx >= 0); assert((box->x2 + src_dx)*dst->drawable.bitsPerPixel <= 8*stride); assert(box->y1 + src_dy >= 0); assert(box->x1 + dst_dx >= 0); assert(box->y1 + dst_dy >= 0); memcpy_xor(src, (char *)ptr + offset, dst->drawable.bitsPerPixel, stride, pitch, box->x1 + src_dx, box->y1 + src_dy, 0, 0, width, height, and, or); assert(kgem->mode == KGEM_BLT); b = kgem->batch + kgem->nbatch; b[0] = cmd; b[1] = br13; b[2] = (box->y1 + dst_dy) << 16 | (box->x1 + dst_dx); b[3] = (box->y2 + dst_dy) << 16 | (box->x2 + dst_dx); b[4] = kgem_add_reloc(kgem, kgem->nbatch + 4, dst_bo, I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER | KGEM_RELOC_FENCED, 0); b[5] = 0; b[6] = pitch; b[7] = kgem_add_reloc(kgem, kgem->nbatch + 7, src_bo, I915_GEM_DOMAIN_RENDER << 16 | KGEM_RELOC_FENCED, offset); kgem->nbatch += 8; box++; offset += pitch * height; } while (--nbox_this_time); assert(offset == __kgem_buffer_size(src_bo)); sigtrap_put(); if (nbox) { _kgem_submit(kgem); _kgem_set_mode(kgem, KGEM_BLT); kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo); } kgem_bo_destroy(kgem, src_bo); } while (nbox); } sna->blt_state.fill_bo = 0; return true; fallback: return write_boxes_inplace__xor(kgem, src, stride, dst->drawable.bitsPerPixel, src_dx, src_dy, dst_bo, dst_dx, dst_dy, box, nbox, and, or); } static bool indirect_replace(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo, const void *src, int stride) { struct kgem *kgem = &sna->kgem; struct kgem_bo *src_bo; BoxRec box; void *ptr; bool ret; DBG(("%s: size=%d vs %d\n", __FUNCTION__, stride * pixmap->drawable.height >> 12, kgem->half_cpu_cache_pages)); if (stride * pixmap->drawable.height >> 12 > kgem->half_cpu_cache_pages) return false; if (!kgem_bo_can_blt(kgem, bo) && must_tile(sna, pixmap->drawable.width, pixmap->drawable.height)) return false; src_bo = kgem_create_buffer_2d(kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!src_bo) return false; ret = false; if (sigtrap_get() == 0) { memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel, stride, src_bo->pitch, 0, 0, 0, 0, pixmap->drawable.width, pixmap->drawable.height); box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; ret = sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, src_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0); sigtrap_put(); } kgem_bo_destroy(kgem, src_bo); return ret; } bool sna_replace(struct sna *sna, PixmapPtr pixmap, const void *src, int stride) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct kgem_bo *bo = priv->gpu_bo; void *dst; assert(bo); DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d) busy?=%d\n", __FUNCTION__, bo->handle, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, bo->tiling, __kgem_bo_is_busy(&sna->kgem, bo))); assert(!priv->pinned); kgem_bo_undo(&sna->kgem, bo); if (__kgem_bo_is_busy(&sna->kgem, bo)) { struct kgem_bo *new_bo; if (indirect_replace(sna, pixmap, bo, src, stride)) return true; new_bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, bo->tiling, CREATE_GTT_MAP | CREATE_INACTIVE); if (new_bo) bo = new_bo; } if (bo->tiling == I915_TILING_NONE && bo->pitch == stride && kgem_bo_write(&sna->kgem, bo, src, (pixmap->drawable.height-1)*stride + pixmap->drawable.width*pixmap->drawable.bitsPerPixel/8)) goto done; if (upload_inplace__tiled(&sna->kgem, bo)) { BoxRec box; box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (write_boxes_inplace__tiled(&sna->kgem, src, stride, pixmap->drawable.bitsPerPixel, 0, 0, bo, 0, 0, &box, 1)) goto done; } if (kgem_bo_can_map(&sna->kgem, bo) && (dst = kgem_bo_map(&sna->kgem, bo)) != NULL && sigtrap_get() == 0) { memcpy_blt(src, dst, pixmap->drawable.bitsPerPixel, stride, bo->pitch, 0, 0, 0, 0, pixmap->drawable.width, pixmap->drawable.height); sigtrap_put(); } else { BoxRec box; if (bo != priv->gpu_bo) { kgem_bo_destroy(&sna->kgem, bo); bo = priv->gpu_bo; } box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (!sna_write_boxes(sna, pixmap, bo, 0, 0, src, stride, 0, 0, &box, 1)) return false; } done: if (bo != priv->gpu_bo) { sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; } return true; } bool sna_replace__xor(struct sna *sna, PixmapPtr pixmap, const void *src, int stride, uint32_t and, uint32_t or) { struct sna_pixmap *priv = sna_pixmap(pixmap); struct kgem_bo *bo = priv->gpu_bo; void *dst; DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d)\n", __FUNCTION__, bo->handle, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, bo->tiling)); assert(!priv->pinned); kgem_bo_undo(&sna->kgem, bo); if (!kgem_bo_can_map(&sna->kgem, bo) || __kgem_bo_is_busy(&sna->kgem, bo)) { struct kgem_bo *new_bo; new_bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, bo->tiling, CREATE_GTT_MAP | CREATE_INACTIVE); if (new_bo) bo = new_bo; } if (kgem_bo_can_map(&sna->kgem, bo) && (dst = kgem_bo_map(&sna->kgem, bo)) != NULL && sigtrap_get() == 0) { memcpy_xor(src, dst, pixmap->drawable.bitsPerPixel, stride, bo->pitch, 0, 0, 0, 0, pixmap->drawable.width, pixmap->drawable.height, and, or); sigtrap_put(); } else { BoxRec box; if (bo != priv->gpu_bo) { kgem_bo_destroy(&sna->kgem, bo); bo = priv->gpu_bo; } box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (!sna_write_boxes__xor(sna, pixmap, bo, 0, 0, src, stride, 0, 0, &box, 1, and, or)) return false; } if (bo != priv->gpu_bo) { sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; } return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_module.h000066400000000000000000000000661267532330400241440ustar00rootroot00000000000000Bool sna_init_scrn(ScrnInfoPtr scrn, int entity_num); xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_present.c000066400000000000000000000567651267532330400243530ustar00rootroot00000000000000/* * Copyright © 2014 Intel Corporation * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "sna.h" #include #include static present_screen_info_rec present_info; struct sna_present_event { xf86CrtcPtr crtc; struct sna *sna; struct list link; uint64_t *event_id; uint64_t target_msc; int n_event_id; }; static void sna_present_unflip(ScreenPtr screen, uint64_t event_id); static bool sna_present_queue(struct sna_present_event *info, uint64_t last_msc); static inline struct sna_present_event * to_present_event(uintptr_t data) { return (struct sna_present_event *)(data & ~3); } #define MARK_PRESENT(x) ((void *)((uintptr_t)(x) | 2)) static inline xf86CrtcPtr unmask_crtc(xf86CrtcPtr crtc) { return (xf86CrtcPtr)((uintptr_t)crtc & ~1); } static inline xf86CrtcPtr mark_crtc(xf86CrtcPtr crtc) { return (xf86CrtcPtr)((uintptr_t)crtc | 1); } static inline bool has_vblank(xf86CrtcPtr crtc) { return (uintptr_t)crtc & 1; } static inline int pipe_from_crtc(RRCrtcPtr crtc) { return crtc ? sna_crtc_pipe(crtc->devPrivate) : -1; } static uint32_t pipe_select(int pipe) { if (pipe > 1) return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT; else if (pipe > 0) return DRM_VBLANK_SECONDARY; else return 0; } static inline int sna_wait_vblank(struct sna *sna, union drm_wait_vblank *vbl, int pipe) { DBG(("%s(pipe=%d, waiting until seq=%u%s)\n", __FUNCTION__, pipe, vbl->request.sequence, vbl->request.type & DRM_VBLANK_RELATIVE ? " [relative]" : "")); vbl->request.type |= pipe_select(pipe); return drmIoctl(sna->kgem.fd, DRM_IOCTL_WAIT_VBLANK, vbl); } static uint64_t gettime_ust64(void) { struct timespec tv; if (clock_gettime(CLOCK_MONOTONIC, &tv)) return GetTimeInMicros(); return ust64(tv.tv_sec, tv.tv_nsec / 1000); } static void vblank_complete(struct sna_present_event *info, uint64_t ust, uint64_t msc) { int n; if (msc < info->target_msc) { DBG(("%s: event=%d too early, now %lld, expected %lld\n", __FUNCTION__, info->event_id[0], (long long)msc, (long long)info->target_msc)); if (sna_present_queue(info, msc)) return; } DBG(("%s: %d events complete\n", __FUNCTION__, info->n_event_id)); for (n = 0; n < info->n_event_id; n++) { DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete%s\n", __FUNCTION__, sna_crtc_pipe(unmask_crtc(info->crtc)), (int)(ust / 1000000), (int)(ust % 1000000), (long long)msc, (long long)info->target_msc, (long long)info->event_id[n], info->target_msc && msc == (uint32_t)info->target_msc ? "" : ": MISS")); present_event_notify(info->event_id[n], ust, msc); } if (info->n_event_id > 1) free(info->event_id); list_del(&info->link); free(info); } static uint32_t msc_to_delay(xf86CrtcPtr crtc, uint64_t target) { const DisplayModeRec *mode = &crtc->desiredMode; const struct ust_msc *swap = sna_crtc_last_swap(crtc); int64_t delay, subframe; delay = (target - swap->msc) * mode->VTotal * mode->HTotal / mode->Clock; subframe = gettime_ust64() - swap_ust(swap); subframe /= 1000; if (subframe < delay) delay -= subframe; else delay = 0; DBG(("%s: sleep %d frames, %llu ms\n", __FUNCTION__, (int)(target - swap->msc), (long long)delay)); assert(delay >= 0); return delay; } static CARD32 sna_fake_vblank_handler(OsTimerPtr timer, CARD32 now, void *data) { struct sna_present_event *info = data; union drm_wait_vblank vbl; uint64_t msc, ust; DBG(("%s(event=%lldx%d, now=%d)\n", __FUNCTION__, (long long)info->event_id[0], info->n_event_id, now)); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); msc = sna_crtc_record_vblank(info->crtc, &vbl); DBG(("%s: event=%lld, target msc=%lld, now %lld\n", __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc)); if (msc < info->target_msc) { uint32_t delay; DBG(("%s: too early, requeuing\n", __FUNCTION__)); vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = info->target_msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(info); if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)) == 0) { DBG(("%s: scheduled new vblank event for %lld\n", __FUNCTION__, (long long)info->target_msc)); free(timer); return 0; } delay = msc_to_delay(info->crtc, info->target_msc); if (delay) { DBG(("%s: requeueing timer for %dms delay\n", __FUNCTION__, delay)); return delay; } /* As a last resort use a blocking wait. * Less than a millisecond for a rare case. */ DBG(("%s: blocking wait!\n", __FUNCTION__)); vbl.request.type = DRM_VBLANK_ABSOLUTE; vbl.request.sequence = info->target_msc; (void)sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc)); } } else { ust = gettime_ust64(); msc = info->target_msc; DBG(("%s: event=%lld, CRTC OFF, target msc=%lld, was %lld (off)\n", __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)sna_crtc_last_swap(info->crtc)->msc)); } vblank_complete(info, ust, msc); free(timer); return 0; } static bool sna_fake_vblank(struct sna_present_event *info) { uint64_t msc = sna_crtc_last_swap(info->crtc)->msc; uint32_t delay; assert(info->n_event_id == 1); if (msc < info->target_msc) delay = msc_to_delay(info->crtc, info->target_msc); else delay = 0; DBG(("%s(event=%lld, target_msc=%lld, msc=%lld, delay=%ums)\n", __FUNCTION__, (long long)info->event_id[0], (long long)info->target_msc, (long long)msc, delay)); if (delay == 0) { const struct ust_msc *swap = sna_crtc_last_swap(info->crtc); present_event_notify(info->event_id[0], swap_ust(swap), swap->msc); list_del(&info->link); free(info); return true; } return TimerSet(NULL, 0, delay, sna_fake_vblank_handler, info); } static bool sna_present_queue(struct sna_present_event *info, uint64_t last_msc) { union drm_wait_vblank vbl; DBG(("%s: target msc=%llu, seq=%u (last_msc=%llu)\n", __FUNCTION__, (long long)info->target_msc, (unsigned)info->target_msc, (long long)last_msc)); assert(info->target_msc - last_msc < 1ull<<31); VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; vbl.request.sequence = info->target_msc; vbl.request.signal = (uintptr_t)MARK_PRESENT(info); if (sna_wait_vblank(info->sna, &vbl, sna_crtc_pipe(info->crtc))) { DBG(("%s: vblank enqueue failed, faking\n", __FUNCTION__)); if (!sna_fake_vblank(info)) return false; } else { if (info->target_msc - last_msc == 1) { sna_crtc_set_vblank(info->crtc); info->crtc = mark_crtc(info->crtc); } } return true; } static RRCrtcPtr sna_present_get_crtc(WindowPtr window) { struct sna *sna = to_sna_from_drawable(&window->drawable); BoxRec box; xf86CrtcPtr crtc; DBG(("%s: window=%ld (pixmap=%ld), box=(%d, %d)x(%d, %d)\n", __FUNCTION__, window->drawable.id, get_window_pixmap(window)->drawable.serialNumber, window->drawable.x, window->drawable.y, window->drawable.width, window->drawable.height)); box.x1 = window->drawable.x; box.y1 = window->drawable.y; box.x2 = box.x1 + window->drawable.width; box.y2 = box.y1 + window->drawable.height; crtc = sna_covering_crtc(sna, &box, NULL); if (crtc) return crtc->randr_crtc; return NULL; } static int sna_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); union drm_wait_vblank vbl; DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate))); if (sna_crtc_has_vblank(crtc->devPrivate)) { DBG(("%s: vblank active, reusing last swap msc/ust\n", __FUNCTION__)); goto last; } VG_CLEAR(vbl); vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; if (sna_wait_vblank(sna, &vbl, sna_crtc_pipe(crtc->devPrivate)) == 0) { *ust = ust64(vbl.reply.tval_sec, vbl.reply.tval_usec); *msc = sna_crtc_record_vblank(crtc->devPrivate, &vbl); } else { const struct ust_msc *swap; last: swap = sna_crtc_last_swap(crtc->devPrivate); *ust = swap_ust(swap); *msc = swap->msc; } DBG(("%s: pipe=%d, tv=%d.%06d seq=%d msc=%lld\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate), (int)(*ust / 1000000), (int)(*ust % 1000000), vbl.reply.sequence, (long long)*msc)); return Success; } void sna_present_vblank_handler(struct drm_event_vblank *event) { struct sna_present_event *info = to_present_event(event->user_data); xf86CrtcPtr crtc = info->crtc; vblank_complete(info, ust64(event->tv_sec, event->tv_usec), sna_crtc_record_event(unmask_crtc(crtc), event)); if (has_vblank(crtc)) sna_crtc_clear_vblank(unmask_crtc(crtc)); } static int sna_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { struct sna *sna = to_sna_from_screen(crtc->pScreen); struct sna_present_event *info, *tmp; const struct ust_msc *swap; swap = sna_crtc_last_swap(crtc->devPrivate); DBG(("%s(pipe=%d, event=%lld, msc=%lld, last swap=%lld)\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate), (long long)event_id, (long long)msc, (long long)swap->msc)); if (warn_unless((int64_t)(msc - swap->msc) >= 0)) { DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__, sna_crtc_pipe(crtc->devPrivate), swap->tv_sec, swap->tv_usec, (long long)swap->msc, (long long)msc, (long long)event_id)); present_event_notify(event_id, swap_ust(swap), swap->msc); return Success; } if (warn_unless(msc - swap->msc < 1ull<<31)) return BadValue; list_for_each_entry(tmp, &sna->present.vblank_queue, link) { if (tmp->target_msc == msc && unmask_crtc(tmp->crtc) == crtc->devPrivate) { uint64_t *events = tmp->event_id; if (is_power_of_two(tmp->n_event_id)) { events = malloc(2*sizeof(uint64_t)*tmp->n_event_id); if (events == NULL) return BadAlloc; memcpy(events, tmp->event_id, tmp->n_event_id*sizeof(uint64_t)); if (tmp->n_event_id != 1) free(tmp->event_id); tmp->event_id = events; } DBG(("%s: appending event=%lld to vblank %lld x %d\n", __FUNCTION__, (long long)event_id, (long long)msc, tmp->n_event_id+1)); events[tmp->n_event_id++] = event_id; return Success; } if ((int64_t)(tmp->target_msc - msc) > 0) { DBG(("%s: previous target_msc=%lld invalid for coalescing\n", __FUNCTION__, (long long)tmp->target_msc)); break; } } info = malloc(sizeof(struct sna_present_event) + sizeof(uint64_t)); if (info == NULL) return BadAlloc; info->crtc = crtc->devPrivate; info->sna = sna; info->target_msc = msc; info->event_id = (uint64_t *)(info + 1); info->event_id[0] = event_id; info->n_event_id = 1; list_add_tail(&info->link, &tmp->link); if (!sna_present_queue(info, swap->msc)) { list_del(&info->link); free(info); return BadAlloc; } return Success; } static void sna_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { DBG(("%s(pipe=%d, event=%lld, msc=%lld)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, (long long)msc)); } static void sna_present_flush(WindowPtr window) { } static bool check_flip__crtc(struct sna *sna, RRCrtcPtr crtc) { if (!sna_crtc_is_on(crtc->devPrivate)) { DBG(("%s: CRTC off\n", __FUNCTION__)); return false; } assert(sna->scrn->vtSema); if (!sna->mode.front_active) { DBG(("%s: DPMS off, no flips\n", __FUNCTION__)); return FALSE; } if (sna->mode.rr_active) { DBG(("%s: RandR transformation active\n", __FUNCTION__)); return false; } return true; } static Bool sna_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *flip; DBG(("%s(pipe=%d, pixmap=%ld, sync_flip=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), pixmap->drawable.serialNumber, sync_flip)); if (!sna->scrn->vtSema) { DBG(("%s: VT switched away, no flips\n", __FUNCTION__)); return FALSE; } if (sna->flags & SNA_NO_FLIP) { DBG(("%s: flips not suported\n", __FUNCTION__)); return FALSE; } if (sync_flip) { if ((sna->flags & SNA_HAS_FLIP) == 0) { DBG(("%s: sync flips not suported\n", __FUNCTION__)); return FALSE; } } else { if ((sna->flags & SNA_HAS_ASYNC_FLIP) == 0) { DBG(("%s: async flips not suported\n", __FUNCTION__)); return FALSE; } } if (!check_flip__crtc(sna, crtc)) { DBG(("%s: flip invalid for CRTC\n", __FUNCTION__)); return FALSE; } flip = sna_pixmap(pixmap); if (flip == NULL) { DBG(("%s: unattached pixmap\n", __FUNCTION__)); return FALSE; } if (flip->cpu_bo && IS_STATIC_PTR(flip->ptr)) { DBG(("%s: SHM pixmap\n", __FUNCTION__)); return FALSE; } if (flip->pinned) { assert(flip->gpu_bo); if (sna->flags & SNA_LINEAR_FB) { if (flip->gpu_bo->tiling != I915_TILING_NONE) { DBG(("%s: pined bo, tilng=%d needs NONE\n", __FUNCTION__, flip->gpu_bo->tiling)); return FALSE; } } else { if (!sna->kgem.can_scanout_y && flip->gpu_bo->tiling == I915_TILING_Y) { DBG(("%s: pined bo, tilng=%d and can't scanout Y\n", __FUNCTION__, flip->gpu_bo->tiling)); return FALSE; } } if (flip->gpu_bo->pitch & 63) { DBG(("%s: pined bo, bad pitch=%d\n", __FUNCTION__, flip->gpu_bo->pitch)); return FALSE; } } return TRUE; } static Bool flip__async(struct sna *sna, RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, struct kgem_bo *bo) { DBG(("%s(pipe=%d, event=%lld, handle=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, bo->handle)); if (!sna_page_flip(sna, bo, NULL, NULL)) { DBG(("%s: async pageflip failed\n", __FUNCTION__)); present_info.capabilities &= ~PresentCapabilityAsync; return FALSE; } DBG(("%s: pipe=%d tv=%ld.%06d msc=%lld (target=%lld), event=%lld complete\n", __FUNCTION__, pipe_from_crtc(crtc), (long)(gettime_ust64() / 1000000), (int)(gettime_ust64() % 1000000), crtc ? (long long)sna_crtc_last_swap(crtc->devPrivate)->msc : 0LL, (long long)target_msc, (long long)event_id)); present_event_notify(event_id, gettime_ust64(), target_msc); return TRUE; } static void present_flip_handler(struct drm_event_vblank *event, void *data) { struct sna_present_event *info = data; struct ust_msc swap; DBG(("%s(sequence=%d): event=%lld\n", __FUNCTION__, event->sequence, (long long)info->event_id[0])); assert(info->n_event_id == 1); if (info->crtc == NULL) { swap.tv_sec = event->tv_sec; swap.tv_usec = event->tv_usec; swap.msc = event->sequence; } else swap = *sna_crtc_last_swap(info->crtc); DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld (target %lld), event=%lld complete%s\n", __FUNCTION__, info->crtc ? sna_crtc_pipe(info->crtc) : -1, swap.tv_sec, swap.tv_usec, (long long)swap.msc, (long long)info->target_msc, (long long)info->event_id[0], info->target_msc && info->target_msc == swap.msc ? "" : ": MISS")); present_event_notify(info->event_id[0], swap_ust(&swap), swap.msc); if (info->crtc) sna_crtc_clear_vblank(info->crtc); if (info->sna->present.unflip) { DBG(("%s: executing queued unflip (event=%lld)\n", __FUNCTION__, (long long)info->sna->present.unflip)); sna_present_unflip(xf86ScrnToScreen(info->sna->scrn), info->sna->present.unflip); info->sna->present.unflip = 0; } free(info); } static Bool flip(struct sna *sna, RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, struct kgem_bo *bo) { struct sna_present_event *info; DBG(("%s(pipe=%d, event=%lld, handle=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, bo->handle)); info = malloc(sizeof(struct sna_present_event)+sizeof(uint64_t)); if (info == NULL) return FALSE; info->crtc = crtc ? crtc->devPrivate : NULL; info->sna = sna; info->event_id = (uint64_t *)(info + 1); info->event_id[0] = event_id; info->n_event_id = 1; info->target_msc = target_msc; if (!sna_page_flip(sna, bo, present_flip_handler, info)) { DBG(("%s: pageflip failed\n", __FUNCTION__)); free(info); return FALSE; } if (info->crtc) sna_crtc_set_vblank(info->crtc); return TRUE; } static struct kgem_bo * get_flip_bo(PixmapPtr pixmap) { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber)); priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT | __MOVE_FORCE); if (priv == NULL) { DBG(("%s: cannot force pixmap to the GPU\n", __FUNCTION__)); return NULL; } if (priv->gpu_bo->scanout) return priv->gpu_bo; if (sna->kgem.has_llc && !wedged(sna) && !priv->pinned) { struct kgem_bo *bo; uint32_t tiling; tiling = I915_TILING_NONE; if ((sna->flags & SNA_LINEAR_FB) == 0) tiling = I915_TILING_X; bo = kgem_create_2d(&sna->kgem, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel, tiling, CREATE_SCANOUT | CREATE_CACHED); if (bo) { BoxRec box; box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; if (sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, priv->gpu_bo, 0, 0, &pixmap->drawable, bo, 0, 0, &box, 1, 0)) { sna_pixmap_unmap(pixmap, priv); kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = bo; } else kgem_bo_destroy(&sna->kgem, bo); } } if (sna->flags & SNA_LINEAR_FB && priv->gpu_bo->tiling && !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) { DBG(("%s: invalid tiling for scanout, user requires linear\n", __FUNCTION__)); return NULL; } if (priv->gpu_bo->tiling == I915_TILING_Y && !sna->kgem.can_scanout_y && !sna_pixmap_change_tiling(pixmap, I915_TILING_X)) { DBG(("%s: invalid Y-tiling, cannot convert\n", __FUNCTION__)); return NULL; } if (priv->gpu_bo->pitch & 63) { DBG(("%s: invalid pitch, no conversion\n", __FUNCTION__)); return NULL; } return priv->gpu_bo; } static Bool sna_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, PixmapPtr pixmap, Bool sync_flip) { struct sna *sna = to_sna_from_pixmap(pixmap); struct kgem_bo *bo; DBG(("%s(pipe=%d, event=%lld, msc=%lld, pixmap=%ld, sync?=%d)\n", __FUNCTION__, pipe_from_crtc(crtc), (long long)event_id, (long long)target_msc, pixmap->drawable.serialNumber, sync_flip)); if (!check_flip__crtc(sna, crtc)) { DBG(("%s: flip invalid for CRTC\n", __FUNCTION__)); return FALSE; } assert(sna->present.unflip == 0); if (sna->flags & SNA_TEAR_FREE) { DBG(("%s: disabling TearFree (was %s) in favour of Present flips\n", __FUNCTION__, sna->mode.shadow_enabled ? "enabled" : "disabled")); sna->mode.shadow_enabled = false; } assert(!sna->mode.shadow_enabled); if (sna->mode.flip_active) { struct pollfd pfd; DBG(("%s: flips still pending, stalling\n", __FUNCTION__)); pfd.fd = sna->kgem.fd; pfd.events = POLLIN; do { if (poll(&pfd, 1, -1) != 1) return FALSE; sna_mode_wakeup(sna); } while (sna->mode.flip_active); } bo = get_flip_bo(pixmap); if (bo == NULL) { DBG(("%s: flip invalid bo\n", __FUNCTION__)); return FALSE; } if (sync_flip) return flip(sna, crtc, event_id, target_msc, bo); else return flip__async(sna, crtc, event_id, target_msc, bo); } static void sna_present_unflip(ScreenPtr screen, uint64_t event_id) { struct sna *sna = to_sna_from_screen(screen); struct kgem_bo *bo; DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id)); if (sna->mode.front_active == 0 || sna->mode.rr_active) { const struct ust_msc *swap; DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__)); notify: swap = sna_crtc_last_swap(sna_primary_crtc(sna)); DBG(("%s: pipe=%d, tv=%d.%06d msc=%lld, event=%lld complete\n", __FUNCTION__, -1, swap->tv_sec, swap->tv_usec, (long long)swap->msc, (long long)event_id)); present_event_notify(event_id, swap_ust(swap), swap->msc); return; } assert(!sna->mode.shadow_enabled); if (sna->mode.flip_active) { DBG(("%s: %d outstanding flips, queueing unflip\n", __FUNCTION__, sna->mode.flip_active)); assert(sna->present.unflip == 0); sna->present.unflip = event_id; return; } if (sna->flags & SNA_TEAR_FREE) { DBG(("%s: %s TearFree after Present flips\n", __FUNCTION__, sna->mode.shadow_damage != NULL ? "enabling" : "disabling")); sna->mode.shadow_enabled = sna->mode.shadow_damage != NULL; } bo = get_flip_bo(screen->GetScreenPixmap(screen)); if (bo == NULL) { reset_mode: DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__)); xf86SetDesiredModes(sna->scrn); goto notify; } assert(sna_pixmap(screen->GetScreenPixmap(screen))->pinned & PIN_SCANOUT); if (sna->flags & SNA_HAS_ASYNC_FLIP) { DBG(("%s: trying async flip restore\n", __FUNCTION__)); if (flip__async(sna, NULL, event_id, 0, bo)) return; } if (!flip(sna, NULL, event_id, 0, bo)) goto reset_mode; } void sna_present_cancel_flip(struct sna *sna) { if (sna->present.unflip) { const struct ust_msc *swap; swap = sna_crtc_last_swap(sna_primary_crtc(sna)); present_event_notify(sna->present.unflip, swap_ust(swap), swap->msc); sna->present.unflip = 0; } } static present_screen_info_rec present_info = { .version = PRESENT_SCREEN_INFO_VERSION, .get_crtc = sna_present_get_crtc, .get_ust_msc = sna_present_get_ust_msc, .queue_vblank = sna_present_queue_vblank, .abort_vblank = sna_present_abort_vblank, .flush = sna_present_flush, .capabilities = PresentCapabilityNone, .check_flip = sna_present_check_flip, .flip = sna_present_flip, .unflip = sna_present_unflip, }; bool sna_present_open(struct sna *sna, ScreenPtr screen) { DBG(("%s(num_crtc=%d)\n", __FUNCTION__, sna->mode.num_real_crtc)); if (sna->mode.num_real_crtc == 0) return false; sna_present_update(sna); list_init(&sna->present.vblank_queue); return present_screen_init(screen, &present_info); } void sna_present_update(struct sna *sna) { if (sna->flags & SNA_HAS_ASYNC_FLIP) present_info.capabilities |= PresentCapabilityAsync; else present_info.capabilities &= ~PresentCapabilityAsync; DBG(("%s: has_async_flip? %d\n", __FUNCTION__, !!(present_info.capabilities & PresentCapabilityAsync))); } void sna_present_close(struct sna *sna, ScreenPtr screen) { DBG(("%s()\n", __FUNCTION__)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_reg.h000066400000000000000000000054221267532330400234350ustar00rootroot00000000000000#ifndef SNA_REG_H #define SNA_REG_H /* Flush */ #define MI_FLUSH (0x04<<23) #define MI_FLUSH_DW (0x26<<23) #define MI_WRITE_DIRTY_STATE (1<<4) #define MI_END_SCENE (1<<3) #define MI_GLOBAL_SNAPSHOT_COUNT_RESET (1<<3) #define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2) #define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1) #define MI_INVALIDATE_MAP_CACHE (1<<0) /* broadwater flush bits */ #define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3) #define MI_BATCH_BUFFER_END (0xA << 23) /* Noop */ #define MI_NOOP 0x00 #define MI_NOOP_WRITE_ID (1<<22) #define MI_NOOP_ID_MASK (1<<22 - 1) /* Wait for Events */ #define MI_WAIT_FOR_EVENT (0x03<<23) #define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18) #define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17) #define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) #define MI_WAIT_FOR_PIPEB_VBLANK (1<<7) #define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5) #define MI_WAIT_FOR_PIPEA_VBLANK (1<<3) #define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<1) /* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */ #define MI_LOAD_SCAN_LINES_INCL (0x12<<23) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20) /* BLT commands */ #define BLT_WRITE_ALPHA (1<<21) #define BLT_WRITE_RGB (1<<20) #define BLT_SRC_TILED (1<<15) #define BLT_DST_TILED (1<<11) #define COLOR_BLT_CMD (2<<29|0x40<<22|(0x3)) #define XY_COLOR_BLT (2<<29|0x50<<22|(0x4)) #define XY_SETUP_BLT (2<<29|0x01<<22) #define XY_SETUP_MONO_PATTERN_SL_BLT (2<<29|0x11<<22) #define XY_SETUP_CLIP (2<<29|0x03<<22|1) #define XY_PIXEL_BLT (2<<29|0x24<<22) #define XY_SCANLINE_BLT (2<<29|0x25<<22|1) #define XY_TEXT_IMMEDIATE_BLT (2<<29|0x31<<22|(1<<16)) #define XY_SRC_COPY_BLT_CMD (2<<29|0x53<<22) #define SRC_COPY_BLT_CMD (2<<29|0x43<<22|0x4) #define XY_PAT_BLT (2<<29|0x51<<22) #define XY_PAT_BLT_IMMEDIATE (2<<29|0x72<<22) #define XY_MONO_PAT (2<<29|0x52<<22) #define XY_MONO_SRC_COPY (2<<29|0x54<<22) #define XY_MONO_SRC_COPY_IMM (2<<29|0x71<<22) #define XY_FULL_MONO_PATTERN_BLT (2<<29|0x57<<22) #define XY_FULL_MONO_PATTERN_MONO_SRC_BLT (2<<29|0x58<<22) /* FLUSH commands */ #define BRW_3D(Pipeline,Opcode,Subopcode) \ ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define PIPE_CONTROL BRW_3D(3, 2, 0) #define PIPE_CONTROL_NOWRITE (0 << 14) #define PIPE_CONTROL_WRITE_QWORD (1 << 14) #define PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define PIPE_CONTROL_WRITE_TIME (3 << 14) #define PIPE_CONTROL_DEPTH_STALL (1 << 13) #define PIPE_CONTROL_WC_FLUSH (1 << 12) #define PIPE_CONTROL_IS_FLUSH (1 << 11) #define PIPE_CONTROL_TC_FLUSH (1 << 10) #define PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_render.c000066400000000000000000001725521267532330400241430ustar00rootroot00000000000000/* * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "fb/fbpict.h" #define NO_REDIRECT 0 #define NO_CONVERT 0 #define NO_FIXUP 0 #define NO_EXTRACT 0 #define DBG_FORCE_UPLOAD 0 #define DBG_NO_CPU_BO 0 #define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \ PICT_FORMAT_TYPE(format), \ 0, \ PICT_FORMAT_R(format), \ PICT_FORMAT_G(format), \ PICT_FORMAT_B(format)) CARD32 sna_format_for_depth(int depth) { switch (depth) { case 1: return PICT_a1; case 4: return PICT_x4a4; case 8: return PICT_a8; case 15: return PICT_x1r5g5b5; case 16: return PICT_r5g6b5; default: assert(0); case 24: return PICT_x8r8g8b8; #ifdef PICT_x2r10g10b10 case 30: return PICT_x2r10g10b10; #endif case 32: return PICT_a8r8g8b8; } } CARD32 sna_render_format_for_depth(int depth) { switch (depth) { case 1: return PIXMAN_a1; case 4: return PIXMAN_a4; case 8: return PIXMAN_a8; case 15: return PIXMAN_a1r5g5b5; case 16: return PIXMAN_r5g6b5; case 30: return PIXMAN_a2r10g10b10; default: assert(0); case 24: case 32: return PIXMAN_a8r8g8b8; } } static bool no_render_composite(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp) { DBG(("%s (op=%d, mask? %d)\n", __FUNCTION__, op, mask != NULL)); if (mask) return false; if (!is_gpu(sna, dst->pDrawable, PREFER_GPU_BLT) && (src->pDrawable == NULL || !is_gpu(sna, src->pDrawable, PREFER_GPU_BLT))) return false; return sna_blt_composite(sna, op, src, dst, src_x, src_y, dst_x, dst_y, width, height, flags | COMPOSITE_FALLBACK, tmp); (void)mask_x; (void)mask_y; } static bool no_render_check_composite_spans(struct sna *sna, uint8_t op, PicturePtr src, PicturePtr dst, int16_t width, int16_t height, unsigned flags) { return false; } static bool no_render_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags) { DBG(("%s (n=%d)\n", __FUNCTION__, n)); if (!sna_blt_compare_depth(src, dst)) return false; return sna_blt_copy_boxes(sna, alu, src_bo, src_dx, src_dy, dst_bo, dst_dx, dst_dy, dst->bitsPerPixel, box, n); } static bool no_render_copy(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *tmp) { DBG(("%s ()\n", __FUNCTION__)); if (sna_blt_compare_depth(&src->drawable, &dst->drawable) && sna_blt_copy(sna, alu, src_bo, dst_bo, dst->drawable.bitsPerPixel, tmp)) return true; return false; } static bool no_render_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { uint8_t alu = GXcopy; uint32_t pixel; DBG(("%s (op=%d, color=(%04x,%04x,%04x, %04x))\n", __FUNCTION__, op, color->red, color->green, color->blue, color->alpha)); if (op == PictOpClear) { pixel = 0; alu = GXclear; op = PictOpSrc; } if (op == PictOpOver) { if ((color->alpha >= 0xff00)) op = PictOpSrc; } if (op != PictOpSrc) return false; if (alu == GXcopy && !sna_get_pixel_from_rgba(&pixel, color->red, color->green, color->blue, color->alpha, format)) return false; return sna_blt_fill_boxes(sna, alu, dst_bo, dst->bitsPerPixel, pixel, box, n); } static bool no_render_fill(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *tmp) { DBG(("%s (alu=%d, color=%08x)\n", __FUNCTION__, alu, color)); return sna_blt_fill(sna, alu, dst_bo, dst->drawable.bitsPerPixel, color, tmp); } static bool no_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu) { BoxRec box; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; DBG(("%s (alu=%d, color=%08x) (%d,%d), (%d, %d)\n", __FUNCTION__, alu, color, x1, y1, x2, y2)); return sna_blt_fill_boxes(sna, alu, bo, dst->drawable.bitsPerPixel, color, &box, 1); } static bool no_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) { DBG(("%s: pixmap=%ld %dx%d\n", __FUNCTION__, dst->drawable.serialNumber, dst->drawable.width, dst->drawable.height)); return sna->render.fill_one(sna, dst, bo, 0, 0, 0, dst->drawable.width, dst->drawable.height, GXclear); } static void no_render_reset(struct sna *sna) { (void)sna; } static void no_render_flush(struct sna *sna) { (void)sna; } static void no_render_context_switch(struct kgem *kgem, int new_mode) { if (!kgem->nbatch) return; if (kgem_ring_is_idle(kgem, kgem->ring)) { DBG(("%s: GPU idle, flushing\n", __FUNCTION__)); _kgem_submit(kgem); } (void)new_mode; } static void no_render_fini(struct sna *sna) { (void)sna; } const char *no_render_init(struct sna *sna) { struct sna_render *render = &sna->render; memset (render, 0, sizeof (*render)); render->prefer_gpu = PREFER_GPU_BLT; render->vertices = render->vertex_data; render->vertex_size = ARRAY_SIZE(render->vertex_data); render->composite = no_render_composite; render->check_composite_spans = no_render_check_composite_spans; render->copy_boxes = no_render_copy_boxes; render->copy = no_render_copy; render->fill_boxes = no_render_fill_boxes; render->fill = no_render_fill; render->fill_one = no_render_fill_one; render->clear = no_render_clear; render->reset = no_render_reset; render->flush = no_render_flush; render->fini = no_render_fini; sna->kgem.context_switch = no_render_context_switch; if (sna->kgem.has_blt) sna->kgem.ring = KGEM_BLT; sna_vertex_init(sna); return "generic"; } static struct kgem_bo * use_cpu_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt) { struct sna_pixmap *priv; if (DBG_NO_CPU_BO) return NULL; priv = sna_pixmap(pixmap); if (priv == NULL || priv->cpu_bo == NULL) { DBG(("%s: no cpu bo\n", __FUNCTION__)); return NULL; } if (!blt && priv->cpu_bo->snoop && priv->source_count > SOURCE_BIAS) { DBG(("%s: promoting snooped CPU bo due to reuse\n", __FUNCTION__)); return NULL; } if (priv->gpu_bo) { switch (sna_damage_contains_box(&priv->cpu_damage, box)) { case PIXMAN_REGION_OUT: DBG(("%s: has GPU bo and no damage to upload\n", __FUNCTION__)); return NULL; case PIXMAN_REGION_IN: DBG(("%s: has GPU bo but box is completely on CPU\n", __FUNCTION__)); break; default: if (kgem_bo_is_busy(priv->gpu_bo)){ DBG(("%s: box is partially damaged on the CPU, and the GPU is busy\n", __FUNCTION__)); return NULL; } if (sna_damage_contains_box(&priv->gpu_damage, box) != PIXMAN_REGION_OUT) { DBG(("%s: box is damaged on the GPU\n", __FUNCTION__)); return NULL; } break; } } if (!blt) { int w = box->x2 - box->x1; int h = box->y2 - box->y1; if (w < pixmap->drawable.width || h < pixmap->drawable.height || priv->source_count != SOURCE_BIAS) { bool want_tiling; if (priv->cpu_bo->pitch >= 4096) { DBG(("%s: size=%dx%d, promoting reused (%d) CPU bo due to TLB miss (%dx%d, pitch=%d)\n", __FUNCTION__, w, h, priv->source_count, pixmap->drawable.width, pixmap->drawable.height, priv->cpu_bo->pitch)); return NULL; } if (priv->gpu_bo) want_tiling = priv->gpu_bo->tiling != I915_TILING_NONE; else want_tiling = kgem_choose_tiling(&sna->kgem, I915_TILING_Y, pixmap->drawable.width, pixmap->drawable.height, pixmap->drawable.bitsPerPixel) != I915_TILING_NONE; if (want_tiling && priv->source_count*w*h >= (int)pixmap->drawable.width * pixmap->drawable.height) { DBG(("%s: pitch (%d) requires tiling\n", __FUNCTION__, priv->cpu_bo->pitch)); return NULL; } } } if (priv->shm) { assert(!priv->flush); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); } DBG(("%s for box=(%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); ++priv->source_count; return priv->cpu_bo; } static struct kgem_bo * move_to_gpu(PixmapPtr pixmap, const BoxRec *box, bool blt) { struct sna_pixmap *priv; int count, w, h; bool migrate = false; if (DBG_FORCE_UPLOAD > 0) return NULL; priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: not migrating unattached pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); return NULL; } if (priv->shm) blt = true; if (priv->gpu_bo) { if (priv->cpu_damage && sna_damage_contains_box(&priv->cpu_damage, box) != PIXMAN_REGION_OUT) goto upload; return priv->gpu_bo; } if (priv->cpu_damage == NULL) { DBG(("%s: not migrating uninitialised pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); return NULL; } if (pixmap->usage_hint) { DBG(("%s: not migrating pixmap=%ld due to usage_hint=%d\n", __FUNCTION__, pixmap->drawable.serialNumber, pixmap->usage_hint)); return NULL; } if (DBG_FORCE_UPLOAD < 0) { if (!sna_pixmap_force_to_gpu(pixmap, blt ? MOVE_READ : MOVE_SOURCE_HINT | MOVE_ASYNC_HINT | MOVE_READ)) return NULL; return priv->gpu_bo; } w = box->x2 - box->x1; h = box->y2 - box->y1; if (priv->cpu_bo && !priv->cpu_bo->flush) { migrate = true; } else if (w == pixmap->drawable.width && h == pixmap->drawable.height) { migrate = priv->source_count++ > SOURCE_BIAS; DBG(("%s: migrating whole pixmap (%dx%d) for source (%d,%d),(%d,%d), count %d? %d\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height, box->x1, box->y1, box->x2, box->y2, priv->source_count, migrate)); } else if (kgem_choose_tiling(&to_sna_from_pixmap(pixmap)->kgem, blt ? I915_TILING_X : I915_TILING_Y, w, h, pixmap->drawable.bitsPerPixel) != I915_TILING_NONE) { count = priv->source_count++; if ((priv->create & KGEM_CAN_CREATE_GPU) == 0) count -= SOURCE_BIAS; DBG(("%s: migrate box (%d, %d), (%d, %d)? source count=%d, fraction=%d/%d [%d]\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, count, w*h, pixmap->drawable.width * pixmap->drawable.height, pixmap->drawable.width * pixmap->drawable.height / (w*h))); migrate = count*w*h > pixmap->drawable.width * pixmap->drawable.height; } if (!migrate) return NULL; upload: if (blt) { if (!sna_pixmap_move_area_to_gpu(pixmap, box, __MOVE_FORCE | MOVE_READ)) return NULL; } else { if (!sna_pixmap_move_to_gpu(pixmap, __MOVE_FORCE | MOVE_ASYNC_HINT | MOVE_SOURCE_HINT | MOVE_READ)) return NULL; } return priv->gpu_bo; } static struct kgem_bo *upload(struct sna *sna, struct sna_composite_channel *channel, PixmapPtr pixmap, const BoxRec *box) { struct sna_pixmap *priv; struct kgem_bo *bo; DBG(("%s: box=(%d, %d), (%d, %d), pixmap=%dx%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height)); assert(box->x1 >= 0); assert(box->y1 >= 0); assert(box->x2 <= pixmap->drawable.width); assert(box->y2 <= pixmap->drawable.height); priv = sna_pixmap(pixmap); if (priv) { RegionRec region; if (priv->cpu_damage == NULL) return NULL; /* uninitialised */ region.extents = *box; region.data = NULL; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, MOVE_READ)) return NULL; assert(!priv->mapped); if (pixmap->devPrivate.ptr == NULL) return NULL; /* uninitialised */ } bo = kgem_upload_source_image(&sna->kgem, pixmap->devPrivate.ptr, box, pixmap->devKind, pixmap->drawable.bitsPerPixel); if (channel && bo) { channel->width = box->x2 - box->x1; channel->height = box->y2 - box->y1; channel->offset[0] -= box->x1; channel->offset[1] -= box->y1; if (priv && pixmap->usage_hint == 0 && channel->width == pixmap->drawable.width && channel->height == pixmap->drawable.height) { DBG(("%s: adding upload cache to pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(priv->gpu_damage == NULL); assert(priv->gpu_bo == NULL); assert(bo->proxy != NULL); sna_damage_all(&priv->cpu_damage, pixmap); kgem_proxy_bo_attach(bo, &priv->gpu_bo); } } return bo; } struct kgem_bo * __sna_render_pixmap_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt) { struct kgem_bo *bo; bo = use_cpu_bo(sna, pixmap, box, blt); if (bo == NULL) { bo = move_to_gpu(pixmap, box, blt); if (bo == NULL) return NULL; } return bo; } int sna_render_pixmap_bo(struct sna *sna, struct sna_composite_channel *channel, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { struct sna_pixmap *priv; BoxRec box; DBG(("%s pixmap=%ld, (%d, %d)x(%d, %d)/(%d, %d)\n", __FUNCTION__, pixmap->drawable.serialNumber, x, y, w,h, pixmap->drawable.width, pixmap->drawable.height)); channel->width = pixmap->drawable.width; channel->height = pixmap->drawable.height; channel->offset[0] = x - dst_x; channel->offset[1] = y - dst_y; priv = sna_pixmap(pixmap); if (priv) { if (priv->gpu_bo && (DAMAGE_IS_ALL(priv->gpu_damage) || !priv->cpu_damage || priv->gpu_bo->proxy)) { DBG(("%s: GPU all damaged\n", __FUNCTION__)); channel->bo = priv->gpu_bo; goto done; } if (priv->cpu_bo && (DAMAGE_IS_ALL(priv->cpu_damage) || !priv->gpu_damage) && !priv->cpu_bo->snoop && priv->cpu_bo->pitch < 4096) { DBG(("%s: CPU all damaged\n", __FUNCTION__)); channel->bo = priv->cpu_bo; if (priv->shm) { assert(!priv->flush); sna_add_flush_pixmap(sna, priv, priv->cpu_bo); } goto done; } } /* XXX handle transformed repeat */ if (w == 0 || h == 0 || channel->transform) { box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; } else { box.x1 = x; box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); if (channel->repeat == RepeatNone || channel->repeat == RepeatPad) { if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; } else { if (box.x1 < 0 || box.x2 > pixmap->drawable.width) box.x1 = 0, box.x2 = pixmap->drawable.width; if (box.y1 < 0 || box.y2 > pixmap->drawable.height) box.y1 = 0, box.y2 = pixmap->drawable.height; } } w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, pixmap->drawable.width, pixmap->drawable.height)); if (w <= 0 || h <= 0) { DBG(("%s: sample extents outside of texture -> clear\n", __FUNCTION__)); return 0; } DBG(("%s: offset=(%d, %d), size=(%d, %d)\n", __FUNCTION__, channel->offset[0], channel->offset[1], pixmap->drawable.width, pixmap->drawable.height)); channel->bo = __sna_render_pixmap_bo(sna, pixmap, &box, false); if (channel->bo == NULL) { DBG(("%s: uploading CPU box (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); channel->bo = upload(sna, channel, pixmap, &box); if (channel->bo == NULL) return 0; } else { done: kgem_bo_reference(channel->bo); } channel->scale[0] = 1.f / channel->width; channel->scale[1] = 1.f / channel->height; return 1; } static int sna_render_picture_downsample(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, const int16_t x, const int16_t y, const int16_t w, const int16_t h, const int16_t dst_x, const int16_t dst_y) { PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); ScreenPtr screen = pixmap->drawable.pScreen; PicturePtr tmp_src, tmp_dst; PictFormatPtr format; struct sna_pixmap *priv; pixman_transform_t t; PixmapPtr tmp; int width, height, size, max_size; int sx, sy, sw, sh; int error, ret = 0; BoxRec box, b; box.x1 = x; box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); if (channel->transform) { pixman_vector_t v; pixman_transform_bounds(channel->transform, &box); v.vector[0] = x << 16; v.vector[1] = y << 16; v.vector[2] = 1 << 16; pixman_transform_point(channel->transform, &v); } if (channel->repeat == RepeatNone || channel->repeat == RepeatPad) { if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; } else { /* XXX tiled repeats? */ if (box.x1 < 0 || box.x2 > pixmap->drawable.width) box.x1 = 0, box.x2 = pixmap->drawable.width; if (box.y1 < 0 || box.y2 > pixmap->drawable.height) box.y1 = 0, box.y2 = pixmap->drawable.height; } sw = box.x2 - box.x1; sh = box.y2 - box.y1; DBG(("%s: sample (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); sx = (sw + sna->render.max_3d_size - 1) / sna->render.max_3d_size; sy = (sh + sna->render.max_3d_size - 1) / sna->render.max_3d_size; DBG(("%s: scaling (%d, %d) down by %dx%d\n", __FUNCTION__, sw, sh, sx, sy)); width = sw / sx; height = sh / sy; DBG(("%s: creating temporary GPU bo %dx%d\n", __FUNCTION__, width, height)); tmp = screen->CreatePixmap(screen, width, height, pixmap->drawable.depth, SNA_CREATE_SCRATCH); if (tmp == NULL) goto fixup; priv = sna_pixmap(tmp); assert(priv && priv->gpu_bo); if (!sna_pixmap_move_to_gpu(pixmap, MOVE_ASYNC_HINT | MOVE_SOURCE_HINT | MOVE_READ)) { fixup: DBG(("%s: unable to create GPU bo for target or temporary pixmaps\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, w, h, dst_x, dst_y); } format = PictureMatchFormat(screen, pixmap->drawable.depth, picture->format); if (format == NULL) { DBG(("%s: invalid depth=%d, format=%08x\n", __FUNCTION__, pixmap->drawable.depth, picture->format)); goto fixup; } tmp_dst = CreatePicture(0, &tmp->drawable, format, 0, NULL, serverClient, &error); if (!tmp_dst) goto cleanup_tmp; tmp_src = CreatePicture(0, &pixmap->drawable, format, 0, NULL, serverClient, &error); if (!tmp_src) goto cleanup_dst; tmp_src->repeat = 1; tmp_src->repeatType = RepeatPad; /* Prefer to use nearest as it helps reduce artefacts from * interpolating and filtering twice. */ tmp_src->filter = PictFilterNearest; memset(&t, 0, sizeof(t)); t.matrix[0][0] = (sw << 16) / width; t.matrix[0][2] = box.x1 << 16; t.matrix[1][1] = (sh << 16) / height; t.matrix[1][2] = box.y1 << 16; t.matrix[2][2] = 1 << 16; tmp_src->transform = &t; ValidatePicture(tmp_dst); ValidatePicture(tmp_src); /* Use a small size to accommodate enlargement through tile alignment */ max_size = sna_max_tile_copy_size(sna, sna_pixmap(pixmap)->gpu_bo, priv->gpu_bo); if (max_size == 0) goto cleanup_dst; size = sna->render.max_3d_size - 4096 / pixmap->drawable.bitsPerPixel; while (size * size * 4 > max_size) size /= 2; DBG(("%s: size=%d (max=%d), scale %dx%d\n", __FUNCTION__, size, max_size, sx, sy)); sw = size / sx - 2 * sx; if (sw < 1) sw = 1; sh = size / sy - 2 * sy; if (sh < 1) sh = 1; DBG(("%s %d:%d downsampling using %dx%d GPU tiles\n", __FUNCTION__, (width + sw-1)/sw, (height + sh-1)/sh, sw, sh)); for (b.y1 = 0; b.y1 < height; b.y1 = b.y2) { b.y2 = b.y1 + sh; if (b.y2 > height) b.y2 = height; for (b.x1 = 0; b.x1 < width; b.x1 = b.x2) { struct sna_composite_op op; b.x2 = b.x1 + sw; if (b.x2 > width) b.x2 = width; DBG(("%s: tile (%d, %d), (%d, %d)\n", __FUNCTION__, b.x1, b.y1, b.x2, b.y2)); memset(&op, 0, sizeof(op)); if (!sna->render.composite(sna, PictOpSrc, tmp_src, NULL, tmp_dst, b.x1, b.y1, 0, 0, b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1, 0, &op)) goto cleanup_src; op.box(sna, &op, &b); op.done(sna, &op); } } pixman_transform_invert(&channel->embedded_transform, &t); if (channel->transform) pixman_transform_multiply(&channel->embedded_transform, &channel->embedded_transform, channel->transform); channel->transform = &channel->embedded_transform; channel->offset[0] = x - dst_x; channel->offset[1] = y - dst_y; channel->scale[0] = 1.f/width; channel->scale[1] = 1.f/height; channel->width = width; channel->height = height; channel->bo = kgem_bo_reference(priv->gpu_bo); ret = 1; cleanup_src: tmp_src->transform = NULL; FreePicture(tmp_src, 0); cleanup_dst: FreePicture(tmp_dst, 0); cleanup_tmp: screen->DestroyPixmap(tmp); return ret; } bool sna_render_pixmap_partial(struct sna *sna, const DrawableRec *draw, struct kgem_bo *bo, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h) { BoxRec box; int offset; DBG(("%s (%d, %d)x(%d, %d), pitch %d, max %d\n", __FUNCTION__, x, y, w, h, bo->pitch, sna->render.max_3d_pitch)); if (bo->pitch > sna->render.max_3d_pitch) { DBG(("%s: pitch too great %d > %d\n", __FUNCTION__, bo->pitch, sna->render.max_3d_pitch)); return false; } box.x1 = x; box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); DBG(("%s: unaligned box (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2)); if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (bo->tiling) { int tile_width, tile_height, tile_size; kgem_get_tile_size(&sna->kgem, bo->tiling, bo->pitch, &tile_width, &tile_height, &tile_size); DBG(("%s: tile size for tiling %d: %dx%d, size=%d\n", __FUNCTION__, bo->tiling, tile_width, tile_height, tile_size)); /* Ensure we align to an even tile row */ box.y1 = box.y1 & ~(2*tile_height - 1); box.y2 = ALIGN(box.y2, 2*tile_height); assert(tile_width * 8 >= draw->bitsPerPixel); box.x1 = box.x1 & ~(tile_width * 8 / draw->bitsPerPixel - 1); box.x2 = ALIGN(box.x2, tile_width * 8 / draw->bitsPerPixel); offset = box.x1 * draw->bitsPerPixel / 8 / tile_width * tile_size; } else { box.y1 = box.y1 & ~1; box.y2 = ALIGN(box.y2, 2); box.x1 = box.x1 & ~1; box.x2 = ALIGN(box.x2, 2); offset = box.x1 * draw->bitsPerPixel / 8; } if (box.x2 > draw->width) box.x2 = draw->width; if (box.y2 > draw->height) box.y2 = draw->height; w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, draw->width, draw->height)); if (w <= 0 || h <= 0 || w > sna->render.max_3d_size || h > sna->render.max_3d_size) { DBG(("%s: box too large (%dx%d) for 3D pipeline (max %d)\n", __FUNCTION__, w, h, sna->render.max_3d_size)); return false; } /* How many tiles across are we? */ channel->bo = kgem_create_proxy(&sna->kgem, bo, box.y1 * bo->pitch + offset, h * bo->pitch); if (channel->bo == NULL) { DBG(("%s: failed to create proxy for partial (offset=%d, size=%d)\n", __FUNCTION__, box.y1 * bo->pitch + offset, h * bo->pitch)); return false; } channel->bo->pitch = bo->pitch; channel->offset[0] = -box.x1; channel->offset[1] = -box.y1; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->width = w; channel->height = h; return true; } static bool sna_render_picture_partial(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { struct kgem_bo *bo = NULL; PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); BoxRec box; int offset; DBG(("%s (%d, %d)x(%d, %d) [dst=(%d, %d)]\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); box.x1 = x; box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); if (channel->transform) pixman_transform_bounds(channel->transform, &box); DBG(("%s sample=(%d, %d), (%d, %d): (%d, %d)/(%d, %d), repeat=%d\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, pixmap->drawable.width, pixmap->drawable.height, channel->repeat)); if (channel->repeat == RepeatNone || channel->repeat == RepeatPad) { if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; } else { if (box.x1 < 0 || box.x2 > pixmap->drawable.width) box.x1 = 0, box.x2 = pixmap->drawable.width; if (box.y1 < 0 || box.y2 > pixmap->drawable.height) box.y1 = 0, box.y2 = pixmap->drawable.height; } if (use_cpu_bo(sna, pixmap, &box, false)) { bo = sna_pixmap(pixmap)->cpu_bo; } else { struct sna_pixmap *priv; priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT | MOVE_SOURCE_HINT); if (priv == NULL) return false; bo = priv->gpu_bo; } if (bo->pitch > sna->render.max_3d_pitch) { DBG(("%s: pitch too great %d > %d\n", __FUNCTION__, bo->pitch, sna->render.max_3d_pitch)); return false; } if (bo->tiling) { int tile_width, tile_height, tile_size; kgem_get_tile_size(&sna->kgem, bo->tiling, bo->pitch, &tile_width, &tile_height, &tile_size); DBG(("%s: tiling=%d, size=%dx%d, chunk=%d\n", __FUNCTION__, bo->tiling, tile_width, tile_height, tile_size)); /* Ensure we align to an even tile row */ box.y1 = box.y1 & ~(2*tile_height - 1); box.y2 = ALIGN(box.y2, 2*tile_height); if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; box.x1 = box.x1 & ~(tile_width * 8 / pixmap->drawable.bitsPerPixel - 1); box.x2 = ALIGN(box.x2, tile_width * 8 / pixmap->drawable.bitsPerPixel); if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; offset = box.x1 * pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size; } else offset = box.x1 * pixmap->drawable.bitsPerPixel / 8; w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, pixmap->drawable.width, pixmap->drawable.height)); if (w <= 0 || h <= 0 || w > sna->render.max_3d_size || h > sna->render.max_3d_size) return false; /* How many tiles across are we? */ channel->bo = kgem_create_proxy(&sna->kgem, bo, box.y1 * bo->pitch + offset, h * bo->pitch); if (channel->bo == NULL) return false; if (channel->transform) { memset(&channel->embedded_transform, 0, sizeof(channel->embedded_transform)); channel->embedded_transform.matrix[0][0] = 1 << 16; channel->embedded_transform.matrix[0][2] = -box.x1 << 16; channel->embedded_transform.matrix[1][1] = 1 << 16; channel->embedded_transform.matrix[1][2] = -box.y1 << 16; channel->embedded_transform.matrix[2][2] = 1 << 16; pixman_transform_multiply(&channel->embedded_transform, &channel->embedded_transform, channel->transform); channel->transform = &channel->embedded_transform; } else { x -= box.x1; y -= box.y1; } channel->offset[0] = x - dst_x; channel->offset[1] = y - dst_y; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->width = w; channel->height = h; return true; } int sna_render_picture_extract(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { struct kgem_bo *bo = NULL, *src_bo; PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); int16_t ox, oy, ow, oh; BoxRec box; #if NO_EXTRACT return -1; #endif DBG(("%s (%d, %d)x(%d, %d) [dst=(%d, %d)]\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); if (w == 0 || h == 0) { DBG(("%s: fallback -- unknown bounds\n", __FUNCTION__)); return -1; } if (sna_render_picture_partial(sna, picture, channel, x, y, w, h, dst_x, dst_y)) return 1; ow = w; oh = h; ox = box.x1 = x; oy = box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); if (channel->transform) { pixman_vector_t v; pixman_transform_bounds(channel->transform, &box); v.vector[0] = ox << 16; v.vector[1] = oy << 16; v.vector[2] = 1 << 16; pixman_transform_point(channel->transform, &v); ox = v.vector[0] / v.vector[2]; oy = v.vector[1] / v.vector[2]; } DBG(("%s sample=(%d, %d), (%d, %d): (%d, %d)/(%d, %d), repeat=%d\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, pixmap->drawable.width, pixmap->drawable.height, channel->repeat)); if (channel->repeat == RepeatNone || channel->repeat == RepeatPad) { if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; } else { /* XXX tiled repeats? */ if (box.x1 < 0 || box.x2 > pixmap->drawable.width) box.x1 = 0, box.x2 = pixmap->drawable.width; if (box.y1 < 0 || box.y2 > pixmap->drawable.height) box.y1 = 0, box.y2 = pixmap->drawable.height; } w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, pixmap->drawable.width, pixmap->drawable.height)); if (w <= 0 || h <= 0) { DBG(("%s: sample extents outside of texture -> clear\n", __FUNCTION__)); return 0; } if (w > sna->render.max_3d_size || h > sna->render.max_3d_size) { DBG(("%s: fallback -- sample too large for texture (%d, %d)x(%d, %d)\n", __FUNCTION__, box.x1, box.y1, w, h)); return sna_render_picture_downsample(sna, picture, channel, x, y, ow, oh, dst_x, dst_y); } src_bo = use_cpu_bo(sna, pixmap, &box, true); if (src_bo == NULL) src_bo = move_to_gpu(pixmap, &box, false); if (src_bo) { bo = kgem_create_2d(&sna->kgem, w, h, pixmap->drawable.bitsPerPixel, kgem_choose_tiling(&sna->kgem, I915_TILING_X, w, h, pixmap->drawable.bitsPerPixel), CREATE_TEMPORARY); if (bo) { DrawableRec tmp; tmp.width = w; tmp.height = h; tmp.depth = pixmap->drawable.depth; tmp.bitsPerPixel = pixmap->drawable.bitsPerPixel; assert(tmp.width); assert(tmp.height); if (!sna->render.copy_boxes(sna, GXcopy, &pixmap->drawable, src_bo, 0, 0, &tmp, bo, -box.x1, -box.y1, &box, 1, 0)) { kgem_bo_destroy(&sna->kgem, bo); bo = NULL; } } } else { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv) { RegionRec region; region.extents = box; region.data = NULL; if (!sna_drawable_move_region_to_cpu(&pixmap->drawable, ®ion, MOVE_READ)) return 0; assert(!priv->mapped); if (pixmap->devPrivate.ptr == NULL) return 0; /* uninitialised */ } bo = kgem_upload_source_image(&sna->kgem, pixmap->devPrivate.ptr, &box, pixmap->devKind, pixmap->drawable.bitsPerPixel); if (priv != NULL && bo != NULL && box.x2 - box.x1 == pixmap->drawable.width && box.y2 - box.y1 == pixmap->drawable.height) { DBG(("%s: adding upload cache to pixmap=%ld\n", __FUNCTION__, pixmap->drawable.serialNumber)); assert(priv->gpu_damage == NULL); assert(priv->gpu_bo == NULL); assert(bo->proxy != NULL); sna_damage_all(&priv->cpu_damage, pixmap); kgem_proxy_bo_attach(bo, &priv->gpu_bo); } } if (bo == NULL) { DBG(("%s: falback -- pixmap is not on the GPU\n", __FUNCTION__)); return sna_render_picture_fixup(sna, picture, channel, x, y, ow, oh, dst_x, dst_y); } if (ox == x && oy == y) { x = y = 0; } else if (channel->transform) { pixman_vector_t v; pixman_transform_t m; v.vector[0] = (ox - box.x1) << 16; v.vector[1] = (oy - box.y1) << 16; v.vector[2] = 1 << 16; pixman_transform_invert(&m, channel->transform); pixman_transform_point(&m, &v); x = v.vector[0] / v.vector[2]; y = v.vector[1] / v.vector[2]; } else { x = ox - box.x1; y = oy - box.y1; } channel->offset[0] = x - dst_x; channel->offset[1] = y - dst_y; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->width = w; channel->height = h; channel->bo = bo; return 1; } static int sna_render_picture_convolve(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { ScreenPtr screen = picture->pDrawable->pScreen; PixmapPtr pixmap; PicturePtr tmp; pixman_fixed_t *params = picture->filter_params; int x_off = -pixman_fixed_to_int((params[0] - pixman_fixed_1) >> 1); int y_off = -pixman_fixed_to_int((params[1] - pixman_fixed_1) >> 1); int cw = pixman_fixed_to_int(params[0]); int ch = pixman_fixed_to_int(params[1]); int i, j, error, depth; struct kgem_bo *bo; /* Lame multi-pass accumulation implementation of a general convolution * that works everywhere. */ DBG(("%s: origin=(%d,%d) kernel=%dx%d, size=%dx%d\n", __FUNCTION__, x_off, y_off, cw, ch, w, h)); assert(picture->pDrawable); assert(picture->filter == PictFilterConvolution); assert(w <= sna->render.max_3d_size && h <= sna->render.max_3d_size); if (PICT_FORMAT_RGB(picture->format) == 0) { channel->pict_format = PIXMAN_a8; depth = 8; } else { channel->pict_format = PIXMAN_a8r8g8b8; depth = 32; } pixmap = screen->CreatePixmap(screen, w, h, depth, SNA_CREATE_SCRATCH); if (pixmap == NullPixmap) { DBG(("%s: pixmap allocation failed\n", __FUNCTION__)); return -1; } tmp = NULL; bo = __sna_pixmap_get_bo(pixmap); assert(bo); if (sna->render.clear(sna, pixmap, bo)) tmp = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, depth, channel->pict_format), 0, NULL, serverClient, &error); screen->DestroyPixmap(pixmap); if (tmp == NULL) return -1; ValidatePicture(tmp); picture->filter = PictFilterBilinear; params += 2; for (j = 0; j < ch; j++) { for (i = 0; i < cw; i++) { xRenderColor color; PicturePtr alpha; color.alpha = *params++; color.red = color.green = color.blue = 0; DBG(("%s: (%d, %d), alpha=%x\n", __FUNCTION__, i,j, color.alpha)); if (color.alpha <= 0x00ff) continue; alpha = CreateSolidPicture(0, &color, &error); if (alpha) { sna_composite(PictOpAdd, picture, alpha, tmp, x, y, 0, 0, x_off+i, y_off+j, w, h); FreePicture(alpha, 0); } } } picture->filter = PictFilterConvolution; channel->height = h; channel->width = w; channel->filter = PictFilterNearest; channel->repeat = RepeatNone; channel->is_affine = true; channel->transform = NULL; channel->scale[0] = 1.f / w; channel->scale[1] = 1.f / h; channel->offset[0] = -dst_x; channel->offset[1] = -dst_y; channel->bo = kgem_bo_reference(bo); /* transfer ownership */ FreePicture(tmp, 0); return 1; } static bool sna_render_picture_flatten(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { ScreenPtr screen = picture->pDrawable->pScreen; PixmapPtr pixmap; PicturePtr tmp, alpha; int old_format, error; assert(picture->pDrawable); assert(picture->alphaMap); assert(w <= sna->render.max_3d_size && h <= sna->render.max_3d_size); /* XXX shortcut a8? */ DBG(("%s: %dx%d\n", __FUNCTION__, w, h)); pixmap = screen->CreatePixmap(screen, w, h, 32, SNA_CREATE_SCRATCH); if (pixmap == NullPixmap) { DBG(("%s: pixmap allocation failed\n", __FUNCTION__)); return false; } assert(__sna_pixmap_get_bo(pixmap)); tmp = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, 32, PICT_a8r8g8b8), 0, NULL, serverClient, &error); screen->DestroyPixmap(pixmap); if (tmp == NULL) return false; ValidatePicture(tmp); old_format = picture->format; picture->format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format), PICT_FORMAT_TYPE(picture->format), 0, PICT_FORMAT_R(picture->format), PICT_FORMAT_G(picture->format), PICT_FORMAT_B(picture->format)); alpha = picture->alphaMap; picture->alphaMap = NULL; sna_composite(PictOpSrc, picture, alpha, tmp, x, y, x + picture->alphaOrigin.x, y + picture->alphaOrigin.y, 0, 0, w, h); picture->format = old_format; picture->alphaMap = alpha; channel->height = h; channel->width = w; channel->filter = PictFilterNearest; channel->repeat = RepeatNone; channel->pict_format = PIXMAN_a8r8g8b8; channel->is_affine = true; channel->transform = NULL; channel->scale[0] = 1.f / w; channel->scale[1] = 1.f / h; channel->offset[0] = -dst_x; channel->offset[1] = -dst_y; channel->bo = kgem_bo_reference(__sna_pixmap_get_bo(pixmap)); FreePicture(tmp, 0); return true; } int sna_render_picture_approximate_gradient(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { pixman_image_t *dst, *src; pixman_transform_t t; int w2 = w/2, h2 = h/2; int dx, dy; void *ptr; #if NO_FIXUP return -1; #endif DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); if (w2 == 0 || h2 == 0) { DBG(("%s: fallback - unknown bounds\n", __FUNCTION__)); return -1; } if (w2 > sna->render.max_3d_size || h2 > sna->render.max_3d_size) { DBG(("%s: fallback - too large (%dx%d)\n", __FUNCTION__, w, h)); return -1; } channel->is_opaque = sna_gradient_is_opaque((PictGradient*)picture->pSourcePict); channel->pict_format = channel->is_opaque ? PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8; DBG(("%s: gradient is opaque? %d, selecting format %08x\n", __FUNCTION__, channel->is_opaque, channel->pict_format)); assert(channel->card_format == -1); channel->bo = kgem_create_buffer_2d(&sna->kgem, w2, h2, 32, KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!channel->bo) { DBG(("%s: failed to create upload buffer, using clear\n", __FUNCTION__)); return 0; } dst = pixman_image_create_bits(channel->pict_format, w2, h2, ptr, channel->bo->pitch); if (!dst) { kgem_bo_destroy(&sna->kgem, channel->bo); channel->bo = NULL; return 0; } src = image_from_pict(picture, false, &dx, &dy); if (src == NULL) { pixman_image_unref(dst); kgem_bo_destroy(&sna->kgem, channel->bo); channel->bo = NULL; return 0; } DBG(("%s: source offset (%d, %d)\n", __FUNCTION__, dx, dy)); memset(&t, 0, sizeof(t)); t.matrix[0][0] = (w << 16) / w2; t.matrix[0][2] = (x + dx) << 16; t.matrix[1][1] = (h << 16) / h2; t.matrix[1][2] = (y + dy) << 16; t.matrix[2][2] = 1 << 16; if (picture->transform) pixman_transform_multiply(&t, picture->transform, &t); DBG(("%s: applying transform [(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)]\n", __FUNCTION__, pixman_fixed_to_double(t.matrix[0][0]), pixman_fixed_to_double(t.matrix[0][1]), pixman_fixed_to_double(t.matrix[0][2]), pixman_fixed_to_double(t.matrix[1][0]), pixman_fixed_to_double(t.matrix[1][1]), pixman_fixed_to_double(t.matrix[1][2]), pixman_fixed_to_double(t.matrix[2][0]), pixman_fixed_to_double(t.matrix[2][1]), pixman_fixed_to_double(t.matrix[2][2]))); pixman_image_set_transform(src, &t); sna_image_composite(PictOpSrc, src, NULL, dst, 0, 0, 0, 0, 0, 0, w2, h2); free_pixman_pict(picture, src); pixman_image_unref(dst); channel->width = w2; channel->height = h2; channel->filter = PictFilterNearest; channel->repeat = RepeatNone; channel->is_affine = true; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->offset[0] = -dst_x; channel->offset[1] = -dst_y; channel->transform = NULL; return 1; } int sna_render_picture_fixup(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y) { pixman_image_t *dst, *src; int dx, dy; void *ptr; #if NO_FIXUP return -1; #endif DBG(("%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h)); if (w == 0 || h == 0) { DBG(("%s: fallback - unknown bounds\n", __FUNCTION__)); return -1; } if (w > sna->render.max_3d_size || h > sna->render.max_3d_size) { DBG(("%s: fallback - too large (%dx%d)\n", __FUNCTION__, w, h)); return -1; } if (picture->alphaMap) { DBG(("%s: alphamap\n", __FUNCTION__)); if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER) || is_gpu(sna, picture->alphaMap->pDrawable, PREFER_GPU_RENDER)) { if (sna_render_picture_flatten(sna, picture, channel, x, y, w, h, dst_x, dst_y)) return 1; } goto do_fixup; } if (picture->filter == PictFilterConvolution) { DBG(("%s: convolution\n", __FUNCTION__)); if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER)) { return sna_render_picture_convolve(sna, picture, channel, x, y, w, h, dst_x, dst_y); } goto do_fixup; } do_fixup: if (PICT_FORMAT_RGB(picture->format) == 0) channel->pict_format = PIXMAN_a8; else channel->pict_format = PIXMAN_a8r8g8b8; if (picture->pDrawable && !sna_drawable_move_to_cpu(picture->pDrawable, MOVE_READ)) return 0; channel->bo = kgem_create_buffer_2d(&sna->kgem, w, h, PIXMAN_FORMAT_BPP(channel->pict_format), KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!channel->bo) { DBG(("%s: failed to create upload buffer, using clear\n", __FUNCTION__)); return 0; } /* Composite in the original format to preserve idiosyncracies */ if (!kgem_buffer_is_inplace(channel->bo) && (picture->pDrawable == NULL || alphaless(picture->format) == alphaless(channel->pict_format))) dst = pixman_image_create_bits(channel->pict_format, w, h, ptr, channel->bo->pitch); else dst = pixman_image_create_bits((pixman_format_code_t)picture->format, w, h, NULL, 0); if (!dst) { kgem_bo_destroy(&sna->kgem, channel->bo); return 0; } src = image_from_pict(picture, false, &dx, &dy); if (src == NULL) { pixman_image_unref(dst); kgem_bo_destroy(&sna->kgem, channel->bo); return 0; } DBG(("%s: compositing tmp=(%d+%d, %d+%d)x(%d, %d)\n", __FUNCTION__, x, dx, y, dy, w, h)); sna_image_composite(PictOpSrc, src, NULL, dst, x + dx, y + dy, 0, 0, 0, 0, w, h); free_pixman_pict(picture, src); /* Then convert to card format */ if (pixman_image_get_data(dst) != ptr) { DBG(("%s: performing post-conversion %08x->%08x (%d, %d)\n", __FUNCTION__, picture->format, channel->pict_format, w, h)); src = dst; dst = pixman_image_create_bits(channel->pict_format, w, h, ptr, channel->bo->pitch); if (dst) { sna_image_composite(PictOpSrc, src, NULL, dst, 0, 0, 0, 0, 0, 0, w, h); pixman_image_unref(src); } else { memset(ptr, 0, __kgem_buffer_size(channel->bo)); dst = src; } } pixman_image_unref(dst); channel->width = w; channel->height = h; channel->filter = PictFilterNearest; channel->repeat = RepeatNone; channel->is_affine = true; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->offset[0] = -dst_x; channel->offset[1] = -dst_y; channel->transform = NULL; return 1; } int sna_render_picture_convert(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y, bool fixup_alpha) { BoxRec box; #if NO_CONVERT return -1; #endif if (w != 0 && h != 0) { box.x1 = x; box.y1 = y; box.x2 = bound(x, w); box.y2 = bound(y, h); if (channel->transform) { DBG(("%s: has transform, converting whole surface\n", __FUNCTION__)); box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; } if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; if (box.x2 > pixmap->drawable.width) box.x2 = pixmap->drawable.width; if (box.y2 > pixmap->drawable.height) box.y2 = pixmap->drawable.height; } else { DBG(("%s: op no bounds, converting whole surface\n", __FUNCTION__)); box.x1 = box.y1 = 0; box.x2 = pixmap->drawable.width; box.y2 = pixmap->drawable.height; } w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s: convert (%d, %d)x(%d, %d), source size %dx%d\n", __FUNCTION__, box.x1, box.y1, w, h, pixmap->drawable.width, pixmap->drawable.height)); if (w <= 0 || h <= 0) { DBG(("%s: sample extents lie outside of source, using clear\n", __FUNCTION__)); return 0; } if (fixup_alpha && is_gpu(sna, &pixmap->drawable, PREFER_GPU_RENDER)) { ScreenPtr screen = pixmap->drawable.pScreen; PixmapPtr tmp; PicturePtr src, dst; int error; assert(PICT_FORMAT_BPP(picture->format) == pixmap->drawable.bitsPerPixel); channel->pict_format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format), PICT_FORMAT_TYPE(picture->format), PICT_FORMAT_BPP(picture->format) - PIXMAN_FORMAT_DEPTH(picture->format), PICT_FORMAT_R(picture->format), PICT_FORMAT_G(picture->format), PICT_FORMAT_B(picture->format)); DBG(("%s: converting to %08x from %08x using composite alpha-fixup\n", __FUNCTION__, (unsigned)channel->pict_format, (unsigned)picture->format)); tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, SNA_CREATE_SCRATCH); if (tmp == NULL) return -1; assert(__sna_pixmap_get_bo(tmp)); dst = CreatePicture(0, &tmp->drawable, PictureMatchFormat(screen, pixmap->drawable.bitsPerPixel, channel->pict_format), 0, NULL, serverClient, &error); if (dst == NULL) { screen->DestroyPixmap(tmp); return 0; } src = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, pixmap->drawable.depth, picture->format), 0, NULL, serverClient, &error); if (src == NULL) { FreePicture(dst, 0); screen->DestroyPixmap(tmp); return 0; } ValidatePicture(src); ValidatePicture(dst); sna_composite(PictOpSrc, src, NULL, dst, box.x1, box.y1, 0, 0, 0, 0, w, h); FreePicture(dst, 0); FreePicture(src, 0); channel->bo = __sna_pixmap_get_bo(tmp); kgem_bo_reference(channel->bo); screen->DestroyPixmap(tmp); } else { pixman_image_t *src, *dst; void *ptr; if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) return 0; src = pixman_image_create_bits((pixman_format_code_t)picture->format, pixmap->drawable.width, pixmap->drawable.height, pixmap->devPrivate.ptr, pixmap->devKind); if (!src) return 0; if (PICT_FORMAT_RGB(picture->format) == 0) { channel->pict_format = PIXMAN_a8; DBG(("%s: converting to a8 from %08x\n", __FUNCTION__, picture->format)); } else { channel->pict_format = PIXMAN_a8r8g8b8; DBG(("%s: converting to a8r8g8b8 from %08x\n", __FUNCTION__, picture->format)); } channel->bo = kgem_create_buffer_2d(&sna->kgem, w, h, PIXMAN_FORMAT_BPP(channel->pict_format), KGEM_BUFFER_WRITE_INPLACE, &ptr); if (!channel->bo) { pixman_image_unref(src); return 0; } dst = pixman_image_create_bits(channel->pict_format, w, h, ptr, channel->bo->pitch); if (!dst) { kgem_bo_destroy(&sna->kgem, channel->bo); pixman_image_unref(src); return 0; } if (sigtrap_get() == 0) { sna_image_composite(PictOpSrc, src, NULL, dst, box.x1, box.y1, 0, 0, 0, 0, w, h); sigtrap_put(); } pixman_image_unref(dst); pixman_image_unref(src); } channel->width = w; channel->height = h; channel->scale[0] = 1.f/w; channel->scale[1] = 1.f/h; channel->offset[0] = x - dst_x - box.x1; channel->offset[1] = y - dst_y - box.y1; DBG(("%s: offset=(%d, %d), size=(%d, %d)\n", __FUNCTION__, channel->offset[0], channel->offset[1], channel->width, channel->height)); return 1; } bool sna_render_composite_redirect(struct sna *sna, struct sna_composite_op *op, int x, int y, int width, int height, bool partial) { struct sna_composite_redirect *t = &op->redirect; int bpp = op->dst.pixmap->drawable.bitsPerPixel; struct kgem_bo *bo; assert(t->real_bo == NULL); #if NO_REDIRECT return false; #endif DBG(("%s: target too large (%dx%d), copying to temporary %dx%d, max %d / %d\n", __FUNCTION__, op->dst.width, op->dst.height, width, height, sna->render.max_3d_size, sna->render.max_3d_pitch)); if (!width || !height) return false; if (width > sna->render.max_3d_size || height > sna->render.max_3d_size) return false; if (op->dst.bo->pitch <= sna->render.max_3d_pitch) { BoxRec box; int w, h, offset; DBG(("%s: dst pitch (%d) fits within render pipeline (%d)\n", __FUNCTION__, op->dst.bo->pitch, sna->render.max_3d_pitch)); box.x1 = x + op->dst.x; box.x2 = bound(box.x1, width); box.y1 = y + op->dst.y; box.y2 = bound(box.y1, height); if (box.x1 < 0) box.x1 = 0; if (box.y1 < 0) box.y1 = 0; /* Ensure we align to an even tile row */ if (op->dst.bo->tiling) { int tile_width, tile_height, tile_size; kgem_get_tile_size(&sna->kgem, op->dst.bo->tiling, op->dst.bo->pitch, &tile_width, &tile_height, &tile_size); box.y1 = box.y1 & ~(2*tile_height - 1); box.y2 = ALIGN(box.y2, 2*tile_height); box.x1 = box.x1 & ~(tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel - 1); box.x2 = ALIGN(box.x2, tile_width * 8 / op->dst.pixmap->drawable.bitsPerPixel); if (box.x1 > sna->render.max_3d_size && box.x2 <= 2*sna->render.max_3d_size) box.x1 = sna->render.max_3d_size; if (box.y1 > sna->render.max_3d_size && box.y2 <= 2*sna->render.max_3d_size) box.y1 = sna->render.max_3d_size; offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size; } else { if (sna->kgem.gen < 040) { box.y1 = box.y1 & ~3; box.y2 = ALIGN(box.y2, 4); box.x1 = box.x1 & ~3; box.x2 = ALIGN(box.x2, 4); } else { box.y1 = box.y1 & ~1; box.y2 = ALIGN(box.y2, 2); box.x1 = box.x1 & ~1; box.x2 = ALIGN(box.x2, 2); } if (box.x1 > sna->render.max_3d_size && box.x2 <= 2*sna->render.max_3d_size) box.x1 = sna->render.max_3d_size; if (box.y1 > sna->render.max_3d_size && box.y2 <= 2*sna->render.max_3d_size) box.y1 = sna->render.max_3d_size; offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8; } if (box.y2 > op->dst.pixmap->drawable.height) box.y2 = op->dst.pixmap->drawable.height; if (box.x2 > op->dst.pixmap->drawable.width) box.x2 = op->dst.pixmap->drawable.width; w = box.x2 - box.x1; h = box.y2 - box.y1; DBG(("%s box=(%d, %d), (%d, %d): (%d, %d)/(%d, %d), max %d\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, w, h, op->dst.pixmap->drawable.width, op->dst.pixmap->drawable.height, sna->render.max_3d_size)); if (w <= sna->render.max_3d_size && h <= sna->render.max_3d_size) { t->box.x2 = t->box.x1 = op->dst.x; t->box.y2 = t->box.y1 = op->dst.y; t->real_bo = op->dst.bo; t->real_damage = op->damage; if (op->damage) { assert(!DAMAGE_IS_ALL(op->damage)); t->damage = sna_damage_create(); op->damage = &t->damage; } /* How many tiles across are we? */ op->dst.bo = kgem_create_proxy(&sna->kgem, op->dst.bo, box.y1 * op->dst.bo->pitch + offset, h * op->dst.bo->pitch); if (!op->dst.bo) { t->real_bo = NULL; if (t->damage) __sna_damage_destroy(t->damage); return false; } assert(op->dst.bo != t->real_bo); op->dst.bo->pitch = t->real_bo->pitch; op->dst.x -= box.x1; op->dst.y -= box.y1; op->dst.width = w; op->dst.height = h; return true; } } /* We can process the operation in a single pass, * but the target is too large for the 3D pipeline. * Copy into a smaller surface and replace afterwards. */ bo = kgem_create_2d(&sna->kgem, width, height, bpp, kgem_choose_tiling(&sna->kgem, I915_TILING_X, width, height, bpp), CREATE_TEMPORARY); if (!bo) return false; t->box.x1 = x + op->dst.x; t->box.y1 = y + op->dst.y; t->box.x2 = bound(t->box.x1, width); t->box.y2 = bound(t->box.y1, height); DBG(("%s: original box (%d, %d), (%d, %d)\n", __FUNCTION__, t->box.x1, t->box.y1, t->box.x2, t->box.y2)); if (partial && !sna_blt_copy_boxes(sna, GXcopy, op->dst.bo, 0, 0, bo, -t->box.x1, -t->box.y1, bpp, &t->box, 1)) { kgem_bo_destroy(&sna->kgem, bo); return false; } t->real_bo = op->dst.bo; t->real_damage = op->damage; if (op->damage) { assert(!DAMAGE_IS_ALL(op->damage)); t->damage = sna_damage_create(); op->damage = &t->damage; } op->dst.bo = bo; op->dst.x = -x; op->dst.y = -y; op->dst.width = width; op->dst.height = height; return true; } void sna_render_composite_redirect_done(struct sna *sna, const struct sna_composite_op *op) { const struct sna_composite_redirect *t = &op->redirect; if (t->real_bo) { assert(op->dst.bo != t->real_bo); if (t->box.x2 > t->box.x1) { bool ok; DBG(("%s: copying temporary to dst\n", __FUNCTION__)); ok = sna_blt_copy_boxes(sna, GXcopy, op->dst.bo, -t->box.x1, -t->box.y1, t->real_bo, 0, 0, op->dst.pixmap->drawable.bitsPerPixel, &t->box, 1); assert(ok); (void)ok; } if (t->damage) { DBG(("%s: combining damage (all? %d), offset=(%d, %d)\n", __FUNCTION__, (int)DAMAGE_IS_ALL(t->damage), t->box.x1, t->box.y1)); sna_damage_combine(t->real_damage, DAMAGE_PTR(t->damage), t->box.x1, t->box.y1); __sna_damage_destroy(DAMAGE_PTR(t->damage)); } kgem_bo_destroy(&sna->kgem, op->dst.bo); } } static bool copy_overlap(struct sna *sna, uint8_t alu, const DrawableRec *draw, struct kgem_bo *bo, int16_t src_dx, int16_t src_dy, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, const BoxRec *extents) { ScreenPtr screen = draw->pScreen; struct kgem_bo *tmp_bo; PixmapPtr tmp; bool ret = false; if (n == 0) return true; DBG(("%s: %d x %dx%d src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, n, extents->x2 - extents->x1, extents->y2 - extents->y1, src_dx, src_dy, dst_dx, dst_dy)); tmp = screen->CreatePixmap(screen, extents->x2 - extents->x1, extents->y2 - extents->y1, draw->depth, SNA_CREATE_SCRATCH); if (tmp == NULL) return false; tmp_bo = __sna_pixmap_get_bo(tmp); assert(tmp_bo); ret = (sna->render.copy_boxes(sna, GXcopy, draw, bo, src_dx, src_dy, &tmp->drawable, tmp_bo, -extents->x1, -extents->y1, box, n, 0) && sna->render.copy_boxes(sna, alu, &tmp->drawable, tmp_bo, -extents->x1, -extents->y1, draw, bo, dst_dx, dst_dy, box, n, 0)); screen->DestroyPixmap(tmp); return ret; } bool sna_render_copy_boxes__overlap(struct sna *sna, uint8_t alu, const DrawableRec *draw, struct kgem_bo *bo, int16_t src_dx, int16_t src_dy, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, const BoxRec *extents) { bool ret = false; RegionRec overlap, non_overlap; pixman_region16_t region; pixman_box16_t stack_boxes[64], *boxes = stack_boxes; int num_boxes, i; DBG(("%s: pixmap=%ld, handle=%d, %d x [(%d, %d), (%d, %d)], dst=(%d, %d), src=(%d, %d)\n", __FUNCTION__, draw->serialNumber, bo->handle, n, extents->x1, extents->y1, extents->x2, extents->y2, src_dx, src_dy, dst_dx, dst_dy)); if ((dst_dx - src_dx < 4 && src_dx - dst_dx < 4) && (dst_dy - src_dy < 4 && src_dy - dst_dy < 4)) return copy_overlap(sna, alu, draw, bo, src_dx, src_dy, dst_dx, dst_dy, box, n, extents); if (n > ARRAY_SIZE(stack_boxes)) { boxes = malloc(sizeof(pixman_box16_t) * n); if (boxes == NULL) return copy_overlap(sna, alu, draw, bo, src_dx, src_dy, dst_dx, dst_dy, box, n, extents); } region.extents.x1 = extents->x1 + dst_dx; region.extents.x2 = extents->x2 + dst_dx; region.extents.y1 = extents->y1 + dst_dy; region.extents.y2 = extents->y2 + dst_dy; for (i = num_boxes = 0; i < n; i++) { boxes[num_boxes].x1 = box[i].x1 + dst_dx; if (boxes[num_boxes].x1 < region.extents.x1) boxes[num_boxes].x1 = region.extents.x1; boxes[num_boxes].y1 = box[i].y1 + dst_dy; if (boxes[num_boxes].y1 < region.extents.y1) boxes[num_boxes].y1 = region.extents.y1; boxes[num_boxes].x2 = box[i].x2 + dst_dx; if (boxes[num_boxes].x2 > region.extents.x2) boxes[num_boxes].x2 = region.extents.x2; boxes[num_boxes].y2 = box[i].y2 + dst_dy; if (boxes[num_boxes].y2 > region.extents.y2) boxes[num_boxes].y2 = region.extents.y2; if (boxes[num_boxes].x2 > boxes[num_boxes].x1 && boxes[num_boxes].y2 > boxes[num_boxes].y1) num_boxes++; } if (num_boxes == 0) { ret = true; goto cleanup_boxes; } if (!pixman_region_init_rects(®ion, boxes, num_boxes)) goto cleanup_boxes; overlap.extents.x1 = extents->x1 + src_dx; overlap.extents.x2 = extents->x2 + src_dx; overlap.extents.y1 = extents->y1 + src_dy; overlap.extents.y2 = extents->y2 + src_dy; overlap.data = NULL; RegionIntersect(&overlap, &overlap, ®ion); DBG(("%s: overlapping extents: (%d, %d), (%d, %d) x %d\n", __FUNCTION__, overlap.extents.x1, overlap.extents.y1, overlap.extents.x2, overlap.extents.y2, region_num_rects(&overlap))); RegionNull(&non_overlap); RegionSubtract(&non_overlap, ®ion, &overlap); DBG(("%s: non-overlapping extents: (%d, %d), (%d, %d) x %d\n", __FUNCTION__, non_overlap.extents.x1, non_overlap.extents.y1, non_overlap.extents.x2, non_overlap.extents.y2, region_num_rects(&non_overlap))); n = region_num_rects(&non_overlap); box = region_rects(&non_overlap); if (n && !sna->render.copy_boxes(sna, alu, draw, bo, -dst_dx + src_dx, -dst_dy + src_dy, draw, bo, 0, 0, box, n , COPY_NO_OVERLAP)) goto cleanup_boxes; n = region_num_rects(&overlap); box = region_rects(&overlap); ret = copy_overlap(sna, alu, draw, bo, -dst_dx + src_dx, -dst_dy + src_dy, 0, 0, box, n, &overlap.extents); cleanup_boxes: if (boxes != stack_boxes) free(boxes); return ret; } static bool can_copy_cpu(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst) { if (src->tiling != dst->tiling) return false; if (src->pitch != dst->pitch) return false; if (!kgem_bo_can_map__cpu(&sna->kgem, src, false)) return false; if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true)) return false; DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle)); return true; } bool memcpy_copy_boxes(struct sna *sna, uint8_t op, const DrawableRec *src_draw, struct kgem_bo *src_bo, int16_t sx, int16_t sy, const DrawableRec *dst_draw, struct kgem_bo *dst_bo, int16_t dx, int16_t dy, const BoxRec *box, int n, unsigned flags) { void *dst, *src; bool clipped; if (op != GXcopy) return false; if (src_draw->depth != dst_draw->depth) return false; clipped = (n > 1 || box->x1 + dx > 0 || box->y1 + dy > 0 || box->x2 + dx < dst_draw->width || box->y2 + dy < dst_draw->height); dst = src = NULL; if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) { dst = kgem_bo_map__cpu(&sna->kgem, dst_bo); src = kgem_bo_map__cpu(&sna->kgem, src_bo); } if (dst == NULL || src == NULL) { dst = kgem_bo_map__gtt(&sna->kgem, dst_bo); src = kgem_bo_map__gtt(&sna->kgem, src_bo); if (dst == NULL || src == NULL) return false; } else { kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true); kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false); } DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n", __FUNCTION__, sx, sy, dx, dy, n)); if (sigtrap_get() == 0) { do { memcpy_blt(src, dst, dst_draw->bitsPerPixel, src_bo->pitch, dst_bo->pitch, box->x1 + sx, box->y1 + sy, box->x1 + dx, box->y1 + dy, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--n); sigtrap_put(); } return true; } void sna_render_mark_wedged(struct sna *sna) { sna->render.copy_boxes = memcpy_copy_boxes; sna->render.prefer_gpu = 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_render.h000066400000000000000000000517321267532330400241440ustar00rootroot00000000000000#ifndef SNA_RENDER_H #define SNA_RENDER_H #include "compiler.h" #include #include #include #include #include "atomic.h" #define GRADIENT_CACHE_SIZE 16 #define GXinvalid 0xff struct sna; struct sna_glyph; struct sna_video; struct sna_video_frame; struct brw_compile; struct sna_composite_rectangles { struct sna_coordinate { int16_t x, y; } src, mask, dst; int16_t width, height; }; struct sna_composite_op { fastcall void (*blt)(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r); fastcall void (*box)(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box); void (*boxes)(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox); void (*thread_boxes)(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox); void (*done)(struct sna *sna, const struct sna_composite_op *op); struct sna_damage **damage; uint32_t op; struct { PixmapPtr pixmap; /* XXX */ CARD32 format; struct kgem_bo *bo; int16_t x, y; uint16_t width, height; } dst; struct sna_composite_channel { struct kgem_bo *bo; PictTransform *transform; uint16_t width; uint16_t height; uint32_t pict_format; uint32_t card_format; uint32_t filter; uint32_t repeat; uint32_t is_affine : 1; uint32_t is_solid : 1; uint32_t is_linear : 1; uint32_t is_opaque : 1; uint32_t alpha_fixup : 1; uint32_t rb_reversed : 1; int16_t offset[2]; float scale[2]; pixman_transform_t embedded_transform; union { struct { float dx, dy, offset; } linear; struct { uint32_t pixel; } gen2; struct gen3_shader_channel { int type; uint32_t mode; uint32_t constants; } gen3; } u; } src, mask; uint32_t is_affine : 1; uint32_t has_component_alpha : 1; uint32_t need_magic_ca_pass : 1; uint32_t rb_reversed : 1; int16_t floats_per_vertex; int16_t floats_per_rect; fastcall void (*prim_emit)(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r); fastcall void (*emit_boxes)(const struct sna_composite_op *op, const BoxRec *box, int nbox, float *v); struct sna_composite_redirect { struct kgem_bo *real_bo; struct sna_damage **real_damage, *damage; BoxRec box; } redirect; union { struct sna_blt_state { PixmapPtr src_pixmap; int16_t sx, sy; uint32_t inplace :1; uint32_t overwrites:1; uint32_t bpp : 6; uint32_t alu : 4; uint32_t cmd; uint32_t br13; uint32_t pitch[2]; uint32_t pixel; struct kgem_bo *bo[2]; } blt; struct { float constants[8]; uint32_t num_constants; } gen3; struct { int wm_kernel; int ve_id; } gen4; struct { int16_t wm_kernel; int16_t ve_id; } gen5; struct { uint32_t flags; } gen6; struct { uint32_t flags; } gen7; struct { uint32_t flags; } gen8; } u; void *priv; }; struct sna_opacity_box { BoxRec box; float alpha; } tightly_packed; struct sna_composite_spans_op { struct sna_composite_op base; fastcall void (*box)(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity); void (*boxes)(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity); fastcall void (*thread_boxes)(struct sna *sna, const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox); fastcall void (*done)(struct sna *sna, const struct sna_composite_spans_op *op); fastcall void (*prim_emit)(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity); fastcall void (*emit_boxes)(const struct sna_composite_spans_op *op, const struct sna_opacity_box *box, int nbox, float *v); }; struct sna_fill_op { struct sna_composite_op base; void (*blt)(struct sna *sna, const struct sna_fill_op *op, int16_t x, int16_t y, int16_t w, int16_t h); fastcall void (*box)(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box); fastcall void (*boxes)(struct sna *sna, const struct sna_fill_op *op, const BoxRec *box, int count); fastcall void (*points)(struct sna *sna, const struct sna_fill_op *op, int16_t dx, int16_t dy, const DDXPointRec *points, int count); void (*done)(struct sna *sna, const struct sna_fill_op *op); }; struct sna_copy_op { struct sna_composite_op base; void (*blt)(struct sna *sna, const struct sna_copy_op *op, int16_t sx, int16_t sy, int16_t w, int16_t h, int16_t dx, int16_t dy); void (*done)(struct sna *sna, const struct sna_copy_op *op); }; struct sna_render { pthread_mutex_t lock; pthread_cond_t wait; int active; int max_3d_size; int max_3d_pitch; unsigned prefer_gpu; #define PREFER_GPU_BLT 0x1 #define PREFER_GPU_RENDER 0x2 #define PREFER_GPU_SPANS 0x4 bool (*composite)(struct sna *sna, uint8_t op, PicturePtr dst, PicturePtr src, PicturePtr mask, int16_t src_x, int16_t src_y, int16_t msk_x, int16_t msk_y, int16_t dst_x, int16_t dst_y, int16_t w, int16_t h, unsigned flags, struct sna_composite_op *tmp); #define COMPOSITE_PARTIAL 0x1 #define COMPOSITE_UPLOAD 0x40000000 #define COMPOSITE_FALLBACK 0x80000000 bool (*check_composite_spans)(struct sna *sna, uint8_t op, PicturePtr dst, PicturePtr src, int16_t w, int16_t h, unsigned flags); bool (*composite_spans)(struct sna *sna, uint8_t op, PicturePtr dst, PicturePtr src, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t w, int16_t h, unsigned flags, struct sna_composite_spans_op *tmp); #define COMPOSITE_SPANS_RECTILINEAR 0x1 #define COMPOSITE_SPANS_INPLACE_HINT 0x2 bool (*video)(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, PixmapPtr pixmap); bool (*fill_boxes)(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n); bool (*fill)(struct sna *sna, uint8_t alu, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, unsigned flags, struct sna_fill_op *tmp); #define FILL_BOXES 0x1 #define FILL_POINTS 0x2 #define FILL_SPANS 0x4 bool (*fill_one)(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo, uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu); bool (*clear)(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo); bool (*copy_boxes)(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags); #define COPY_LAST 0x1 #define COPY_SYNC 0x2 #define COPY_NO_OVERLAP 0x4 #define COPY_SMALL 0x8 #define COPY_DRI 0x10 bool (*copy)(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, PixmapPtr dst, struct kgem_bo *dst_bo, struct sna_copy_op *op); void (*flush)(struct sna *sna); void (*reset)(struct sna *sna); void (*fini)(struct sna *sna); struct sna_alpha_cache { struct kgem_bo *cache_bo; struct kgem_bo *bo[256+7]; } alpha_cache; struct sna_solid_cache { struct kgem_bo *cache_bo; struct kgem_bo *bo[1024]; uint32_t color[1024]; int last; int size; int dirty; } solid_cache; struct { struct sna_gradient_cache { struct kgem_bo *bo; int nstops; PictGradientStop *stops; } cache[GRADIENT_CACHE_SIZE]; int size; } gradient_cache; struct sna_glyph_cache{ PicturePtr picture; struct sna_glyph **glyphs; uint16_t count; uint16_t evict; } glyph[2]; pixman_image_t *white_image; PicturePtr white_picture; uint16_t vb_id; uint16_t vertex_offset; uint16_t vertex_start; uint16_t vertex_index; uint16_t vertex_used; uint16_t vertex_size; uint16_t vertex_reloc[16]; int nvertex_reloc; struct kgem_bo *vbo; float *vertices; float vertex_data[1024]; }; struct gen2_render_state { uint32_t target; bool need_invariant; uint32_t logic_op_enabled; uint32_t ls1, ls2, vft; uint32_t diffuse; uint32_t specular; }; struct gen3_render_state { uint32_t current_dst; bool need_invariant; uint32_t tex_count; uint32_t last_drawrect_limit; uint32_t last_target; uint32_t last_blend; uint32_t last_constants; uint32_t last_sampler; uint32_t last_shader; uint32_t last_diffuse; uint32_t last_specular; uint16_t last_vertex_offset; uint16_t floats_per_vertex; uint16_t last_floats_per_vertex; uint32_t tex_map[4]; uint32_t tex_handle[2]; uint32_t tex_delta[2]; }; struct gen4_render_state { struct kgem_bo *general_bo; uint32_t vs; uint32_t sf; uint32_t wm; uint32_t cc; int ve_id; uint32_t drawrect_offset; uint32_t drawrect_limit; uint32_t last_pipelined_pointers; uint16_t last_primitive; int16_t floats_per_vertex; uint16_t surface_table; bool needs_invariant; bool needs_urb; }; struct gen5_render_state { struct kgem_bo *general_bo; uint32_t vs; uint32_t sf[2]; uint32_t wm; uint32_t cc; int ve_id; uint32_t drawrect_offset; uint32_t drawrect_limit; uint32_t last_pipelined_pointers; uint16_t last_primitive; int16_t floats_per_vertex; uint16_t surface_table; bool needs_invariant; }; enum { GEN6_WM_KERNEL_NOMASK = 0, GEN6_WM_KERNEL_NOMASK_P, GEN6_WM_KERNEL_MASK, GEN6_WM_KERNEL_MASK_P, GEN6_WM_KERNEL_MASKCA, GEN6_WM_KERNEL_MASKCA_P, GEN6_WM_KERNEL_MASKSA, GEN6_WM_KERNEL_MASKSA_P, GEN6_WM_KERNEL_OPACITY, GEN6_WM_KERNEL_OPACITY_P, GEN6_WM_KERNEL_VIDEO_PLANAR, GEN6_WM_KERNEL_VIDEO_PACKED, GEN6_KERNEL_COUNT }; struct gen6_render_state { unsigned gt; const struct gt_info *info; struct kgem_bo *general_bo; uint32_t vs_state; uint32_t sf_state; uint32_t sf_mask_state; uint32_t wm_state; uint32_t wm_kernel[GEN6_KERNEL_COUNT][3]; uint32_t cc_blend; uint32_t drawrect_offset; uint32_t drawrect_limit; uint32_t blend; uint32_t samplers; uint32_t kernel; uint16_t num_sf_outputs; uint16_t ve_id; uint16_t last_primitive; int16_t floats_per_vertex; uint16_t surface_table; bool needs_invariant; bool first_state_packet; }; enum { GEN7_WM_KERNEL_NOMASK = 0, GEN7_WM_KERNEL_NOMASK_P, GEN7_WM_KERNEL_MASK, GEN7_WM_KERNEL_MASK_P, GEN7_WM_KERNEL_MASKCA, GEN7_WM_KERNEL_MASKCA_P, GEN7_WM_KERNEL_MASKSA, GEN7_WM_KERNEL_MASKSA_P, GEN7_WM_KERNEL_OPACITY, GEN7_WM_KERNEL_OPACITY_P, GEN7_WM_KERNEL_VIDEO_PLANAR, GEN7_WM_KERNEL_VIDEO_PACKED, GEN7_WM_KERNEL_COUNT }; struct gen7_render_state { unsigned gt; const struct gt_info *info; struct kgem_bo *general_bo; uint32_t vs_state; uint32_t sf_state; uint32_t sf_mask_state; uint32_t wm_state; uint32_t wm_kernel[GEN7_WM_KERNEL_COUNT][3]; uint32_t cc_blend; uint32_t drawrect_offset; uint32_t drawrect_limit; uint32_t blend; uint32_t samplers; uint32_t kernel; uint16_t num_sf_outputs; uint16_t ve_id; uint16_t last_primitive; int16_t floats_per_vertex; uint16_t surface_table; uint16_t pipe_controls_since_stall; bool needs_invariant; bool emit_flush; }; enum { GEN8_WM_KERNEL_NOMASK = 0, GEN8_WM_KERNEL_NOMASK_P, GEN8_WM_KERNEL_MASK, GEN8_WM_KERNEL_MASK_P, GEN8_WM_KERNEL_MASKCA, GEN8_WM_KERNEL_MASKCA_P, GEN8_WM_KERNEL_MASKSA, GEN8_WM_KERNEL_MASKSA_P, GEN8_WM_KERNEL_OPACITY, GEN8_WM_KERNEL_OPACITY_P, GEN8_WM_KERNEL_VIDEO_PLANAR, GEN8_WM_KERNEL_VIDEO_PACKED, GEN8_WM_KERNEL_COUNT }; struct gen8_render_state { unsigned gt; const struct gt_info *info; struct kgem_bo *general_bo; uint32_t vs_state; uint32_t sf_state; uint32_t sf_mask_state; uint32_t wm_state; uint32_t wm_kernel[GEN8_WM_KERNEL_COUNT][3]; uint32_t cc_blend; uint32_t drawrect_offset; uint32_t drawrect_limit; uint32_t blend; uint32_t samplers; uint32_t kernel; uint16_t num_sf_outputs; uint16_t ve_id; uint16_t last_primitive; int16_t floats_per_vertex; uint16_t surface_table; bool needs_invariant; bool emit_flush; }; struct sna_static_stream { uint32_t size, used; uint8_t *data; }; int sna_static_stream_init(struct sna_static_stream *stream); uint32_t sna_static_stream_add(struct sna_static_stream *stream, const void *data, uint32_t len, uint32_t align); void *sna_static_stream_map(struct sna_static_stream *stream, uint32_t len, uint32_t align); uint32_t sna_static_stream_offsetof(struct sna_static_stream *stream, void *ptr); unsigned sna_static_stream_compile_sf(struct sna *sna, struct sna_static_stream *stream, bool (*compile)(struct brw_compile *)); unsigned sna_static_stream_compile_wm(struct sna *sna, struct sna_static_stream *stream, bool (*compile)(struct brw_compile *, int), int width); struct kgem_bo *sna_static_stream_fini(struct sna *sna, struct sna_static_stream *stream); struct kgem_bo * sna_render_get_solid(struct sna *sna, uint32_t color); void sna_render_flush_solid(struct sna *sna); struct kgem_bo * sna_render_get_gradient(struct sna *sna, PictGradient *pattern); bool sna_gradient_is_opaque(const PictGradient *gradient); uint32_t sna_rgba_for_color(uint32_t color, int depth); uint32_t sna_rgba_to_color(uint32_t rgba, uint32_t format); bool sna_get_rgba_from_pixel(uint32_t pixel, uint16_t *red, uint16_t *green, uint16_t *blue, uint16_t *alpha, uint32_t format); bool sna_picture_is_solid(PicturePtr picture, uint32_t *color); const char *no_render_init(struct sna *sna); const char *gen2_render_init(struct sna *sna, const char *backend); const char *gen3_render_init(struct sna *sna, const char *backend); const char *gen4_render_init(struct sna *sna, const char *backend); const char *gen5_render_init(struct sna *sna, const char *backend); const char *gen6_render_init(struct sna *sna, const char *backend); const char *gen7_render_init(struct sna *sna, const char *backend); const char *gen8_render_init(struct sna *sna, const char *backend); void sna_render_mark_wedged(struct sna *sna); bool sna_tiling_composite(uint32_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, struct sna_composite_op *tmp); bool sna_tiling_composite_spans(uint32_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp); bool sna_tiling_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n); bool sna_tiling_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n); bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, const BoxRec *box, int nbox); bool sna_tiling_blt_composite(struct sna *sna, struct sna_composite_op *op, struct kgem_bo *bo, int bpp, uint32_t alpha_fixup); bool sna_blt_composite(struct sna *sna, uint32_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_op *tmp); bool sna_blt_composite__convert(struct sna *sna, int x, int y, int width, int height, struct sna_composite_op *tmp); bool sna_blt_fill(struct sna *sna, uint8_t alu, struct kgem_bo *bo, int bpp, uint32_t pixel, struct sna_fill_op *fill); bool sna_blt_copy(struct sna *sna, uint8_t alu, struct kgem_bo *src, struct kgem_bo *dst, int bpp, struct sna_copy_op *copy); bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *bo, int bpp, uint32_t pixel, const BoxRec *box, int n); bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, const BoxRec *box, int n); bool sna_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, int alpha_fixup, const BoxRec *box, int nbox); bool sna_blt_copy_boxes_fallback(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int nbox); bool memcpy_copy_boxes(struct sna *sna, uint8_t op, const DrawableRec *src_draw, struct kgem_bo *src_bo, int16_t sx, int16_t sy, const DrawableRec *dst_draw, struct kgem_bo *dst_bo, int16_t dx, int16_t dy, const BoxRec *box, int n, unsigned flags); bool _sna_get_pixel_from_rgba(uint32_t *pixel, uint16_t red, uint16_t green, uint16_t blue, uint16_t alpha, uint32_t format); static inline bool sna_get_pixel_from_rgba(uint32_t * pixel, uint16_t red, uint16_t green, uint16_t blue, uint16_t alpha, uint32_t format) { switch (format) { case PICT_x8r8g8b8: alpha = 0xffff; /* fall through to re-use a8r8g8b8 expansion */ case PICT_a8r8g8b8: *pixel = ((alpha >> 8 << 24) | (red >> 8 << 16) | (green & 0xff00) | (blue >> 8)); return TRUE; case PICT_a8: *pixel = alpha >> 8; return TRUE; } return _sna_get_pixel_from_rgba(pixel, red, green, blue, alpha, format); } struct kgem_bo * __sna_render_pixmap_bo(struct sna *sna, PixmapPtr pixmap, const BoxRec *box, bool blt); int sna_render_pixmap_bo(struct sna *sna, struct sna_composite_channel *channel, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y); bool sna_render_pixmap_partial(struct sna *sna, const DrawableRec *draw, struct kgem_bo *bo, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h); int sna_render_picture_extract(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y); int sna_render_picture_approximate_gradient(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y); int sna_render_picture_fixup(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y); int sna_render_picture_convert(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, int16_t dst_x, int16_t dst_y, bool fixup_alpha); inline static void sna_render_composite_redirect_init(struct sna_composite_op *op) { struct sna_composite_redirect *t = &op->redirect; t->real_bo = NULL; t->damage = NULL; } bool sna_render_composite_redirect(struct sna *sna, struct sna_composite_op *op, int x, int y, int width, int height, bool partial); void sna_render_composite_redirect_done(struct sna *sna, const struct sna_composite_op *op); bool sna_render_copy_boxes__overlap(struct sna *sna, uint8_t alu, const DrawableRec *draw, struct kgem_bo *bo, int16_t src_dx, int16_t src_dy, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, const BoxRec *extents); bool sna_composite_mask_is_opaque(PicturePtr mask); void sna_vertex_init(struct sna *sna); static inline void sna_vertex_lock(struct sna_render *r) { pthread_mutex_lock(&r->lock); } static inline void sna_vertex_acquire__locked(struct sna_render *r) { r->active++; } static inline void sna_vertex_unlock(struct sna_render *r) { pthread_mutex_unlock(&r->lock); } static inline void sna_vertex_release__locked(struct sna_render *r) { assert(r->active > 0); if (--r->active == 0) pthread_cond_signal(&r->wait); } static inline bool sna_vertex_wait__locked(struct sna_render *r) { bool was_active = r->active; while (r->active) pthread_cond_wait(&r->wait, &r->lock); return was_active; } #define alphaless(format) PICT_FORMAT(PICT_FORMAT_BPP(format), \ PICT_FORMAT_TYPE(format), \ 0, \ PICT_FORMAT_R(format), \ PICT_FORMAT_G(format), \ PICT_FORMAT_B(format)) #endif /* SNA_RENDER_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_render_inline.h000066400000000000000000000217111267532330400254740ustar00rootroot00000000000000#ifndef SNA_RENDER_INLINE_H #define SNA_RENDER_INLINE_H static inline bool need_tiling(struct sna *sna, int16_t width, int16_t height) { /* Is the damage area too large to fit in 3D pipeline, * and so do we need to split the operation up into tiles? */ return (width > sna->render.max_3d_size || height > sna->render.max_3d_size); } static inline bool need_redirect(struct sna *sna, PixmapPtr dst) { /* Is the pixmap too large to render to? */ return (dst->drawable.width > sna->render.max_3d_size || dst->drawable.height > sna->render.max_3d_size); } static force_inline float pack_2s(int16_t x, int16_t y) { union { struct sna_coordinate p; float f; } u; u.p.x = x; u.p.y = y; return u.f; } static force_inline int vertex_space(struct sna *sna) { return sna->render.vertex_size - sna->render.vertex_used; } static force_inline void vertex_emit(struct sna *sna, float v) { assert(sna->render.vertex_used < sna->render.vertex_size); sna->render.vertices[sna->render.vertex_used++] = v; } static force_inline void vertex_emit_2s(struct sna *sna, int16_t x, int16_t y) { vertex_emit(sna, pack_2s(x, y)); } static force_inline int batch_space(struct sna *sna) { assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem)); assert(sna->kgem.nbatch + KGEM_BATCH_RESERVED <= sna->kgem.surface); return sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED; } static force_inline void batch_emit(struct sna *sna, uint32_t dword) { assert(sna->kgem.mode != KGEM_NONE); assert(sna->kgem.nbatch + KGEM_BATCH_RESERVED < sna->kgem.surface); sna->kgem.batch[sna->kgem.nbatch++] = dword; } static force_inline void batch_emit64(struct sna *sna, uint64_t qword) { assert(sna->kgem.mode != KGEM_NONE); assert(sna->kgem.nbatch + 2 + KGEM_BATCH_RESERVED < sna->kgem.surface); *(uint64_t *)(sna->kgem.batch+sna->kgem.nbatch) = qword; sna->kgem.nbatch += 2; } static force_inline void batch_emit_float(struct sna *sna, float f) { union { uint32_t dw; float f; } u; u.f = f; batch_emit(sna, u.dw); } static inline bool is_gpu(struct sna *sna, DrawablePtr drawable, unsigned prefer) { struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); if (priv == NULL || priv->clear || priv->cpu) return false; if (priv->cpu_damage == NULL) return true; if (priv->gpu_damage && !priv->gpu_bo->proxy && (sna->render.prefer_gpu & prefer)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; if (DAMAGE_IS_ALL(priv->cpu_damage)) return false; return priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo); } static inline bool too_small(struct sna_pixmap *priv) { assert(priv); if (priv->gpu_bo) return false; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return false; return (priv->create & KGEM_CAN_CREATE_GPU) == 0; } static inline bool can_render_to_picture(PicturePtr dst) { if (dst->alphaMap) { DBG(("%s(pixmap=%ld) -- no, has alphamap\n", __FUNCTION__, get_drawable_pixmap(dst->pDrawable)->drawable.serialNumber)); return false; } switch (PICT_FORMAT_TYPE(dst->format)) { case PICT_TYPE_COLOR: case PICT_TYPE_GRAY: case PICT_TYPE_OTHER: DBG(("%s(pixmap=%ld) -- no, has palette\n", __FUNCTION__, get_drawable_pixmap(dst->pDrawable)->drawable.serialNumber)); return false; default: break; } return true; } static inline bool is_gpu_dst(struct sna_pixmap *priv) { assert(priv); if (too_small(priv)) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; if (DAMAGE_IS_ALL(priv->cpu_damage)) return false; return priv->gpu_damage != NULL || !priv->cpu; } static inline bool unattached(DrawablePtr drawable) { struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable); return priv == NULL || (priv->gpu_damage == NULL && priv->cpu_damage && !priv->cpu_bo); } static inline bool picture_is_gpu(struct sna *sna, PicturePtr picture, unsigned flags) { if (!picture) return false; if (!picture->pDrawable) { switch (flags) { case PREFER_GPU_RENDER: switch (picture->pSourcePict->type) { case SourcePictTypeSolidFill: case SourcePictTypeLinear: return false; default: return true; } case PREFER_GPU_SPANS: return true; default: return false; } } else { if (picture->repeat && (picture->pDrawable->width | picture->pDrawable->height) == 1) return flags == PREFER_GPU_SPANS; } return is_gpu(sna, picture->pDrawable, flags); } static inline bool picture_is_cpu(struct sna *sna, PicturePtr picture) { if (!picture->pDrawable) return false; return !is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER); } static inline bool sna_blt_compare_depth(const DrawableRec *src, const DrawableRec *dst) { if (src->depth == dst->depth) return true; /* Also allow for the alpha to be discarded on a copy */ if (src->bitsPerPixel != dst->bitsPerPixel) return false; if (dst->depth == 24 && src->depth == 32) return true; /* Note that a depth-16 pixmap is r5g6b5, not x1r5g5b5. */ return false; } static inline struct kgem_bo * sna_render_get_alpha_gradient(struct sna *sna) { return kgem_bo_reference(sna->render.alpha_cache.cache_bo); } static inline void sna_render_picture_extents(PicturePtr p, BoxRec *box) { box->x1 = p->pDrawable->x; box->y1 = p->pDrawable->y; box->x2 = bound(box->x1, p->pDrawable->width); box->y2 = bound(box->y1, p->pDrawable->height); if (box->x1 < p->pCompositeClip->extents.x1) box->x1 = p->pCompositeClip->extents.x1; if (box->y1 < p->pCompositeClip->extents.y1) box->y1 = p->pCompositeClip->extents.y1; if (box->x2 > p->pCompositeClip->extents.x2) box->x2 = p->pCompositeClip->extents.x2; if (box->y2 > p->pCompositeClip->extents.y2) box->y2 = p->pCompositeClip->extents.y2; assert(box->x2 > box->x1 && box->y2 > box->y1); } static inline void sna_render_reduce_damage(struct sna_composite_op *op, int dst_x, int dst_y, int width, int height) { BoxRec r; if (op->damage == NULL || *op->damage == NULL) return; if (DAMAGE_IS_ALL(*op->damage)) { DBG(("%s: damage-all, dicarding damage\n", __FUNCTION__)); op->damage = NULL; return; } if (width == 0 || height == 0) return; r.x1 = dst_x + op->dst.x; r.x2 = r.x1 + width; r.y1 = dst_y + op->dst.y; r.y2 = r.y1 + height; if (sna_damage_contains_box__no_reduce(*op->damage, &r)) { DBG(("%s: damage contains render extents, dicarding damage\n", __FUNCTION__)); op->damage = NULL; } } inline static uint32_t color_convert(uint32_t pixel, uint32_t src_format, uint32_t dst_format) { DBG(("%s: src=%08x [%08x]\n", __FUNCTION__, pixel, src_format)); if (src_format != dst_format) { uint16_t red, green, blue, alpha; if (!sna_get_rgba_from_pixel(pixel, &red, &green, &blue, &alpha, src_format)) return 0; if (!sna_get_pixel_from_rgba(&pixel, red, green, blue, alpha, dst_format)) return 0; } DBG(("%s: dst=%08x [%08x]\n", __FUNCTION__, pixel, dst_format)); return pixel; } inline static uint32_t solid_color(uint32_t format, uint32_t pixel) { return color_convert(pixel, format, PICT_a8r8g8b8); } inline static bool dst_use_gpu(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL) return false; if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) return true; if (priv->clear) return false; if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) return true; return priv->gpu_damage && (!priv->cpu || !priv->cpu_damage); } inline static bool dst_use_cpu(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv == NULL || priv->shm) return true; return priv->cpu_damage && priv->cpu; } inline static bool dst_is_cpu(PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); return priv == NULL || DAMAGE_IS_ALL(priv->cpu_damage); } inline static bool untransformed(PicturePtr p) { return !p->transform || pixman_transform_is_int_translate(p->transform); } inline static void boxes_extents(const BoxRec *box, int n, BoxRec *extents) { *extents = box[0]; while (--n) { box++; if (box->x1 < extents->x1) extents->x1 = box->x1; if (box->x2 > extents->x2) extents->x2 = box->x2; if (box->y1 < extents->y1) extents->y1 = box->y1; if (box->y2 > extents->y2) extents->y2 = box->y2; } } inline static bool overlaps(struct sna *sna, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n, unsigned flags, BoxRec *extents) { if (src_bo != dst_bo) return false; if (flags & COPY_NO_OVERLAP) return false; boxes_extents(box, n, extents); return (extents->x2 + src_dx > extents->x1 + dst_dx && extents->x1 + src_dx < extents->x2 + dst_dx && extents->y2 + src_dy > extents->y1 + dst_dy && extents->y1 + src_dy < extents->y2 + dst_dy); } static inline long get_picture_id(PicturePtr picture) { return picture && picture->pDrawable ? get_drawable_pixmap(picture->pDrawable)->drawable.serialNumber : 0; } #endif /* SNA_RENDER_INLINE_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_stream.c000066400000000000000000000077531267532330400241570ustar00rootroot00000000000000/* * Copyright © 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "brw/brw.h" int sna_static_stream_init(struct sna_static_stream *stream) { stream->used = 0; stream->size = 64*1024; stream->data = malloc(stream->size); return stream->data != NULL; } static uint32_t sna_static_stream_alloc(struct sna_static_stream *stream, uint32_t len, uint32_t align) { uint32_t offset = ALIGN(stream->used, align); uint32_t size = offset + len; if (size > stream->size) { do stream->size *= 2; while (stream->size < size); stream->data = realloc(stream->data, stream->size); } stream->used = size; return offset; } uint32_t sna_static_stream_add(struct sna_static_stream *stream, const void *data, uint32_t len, uint32_t align) { uint32_t offset = sna_static_stream_alloc(stream, len, align); memcpy(stream->data + offset, data, len); return offset; } void *sna_static_stream_map(struct sna_static_stream *stream, uint32_t len, uint32_t align) { uint32_t offset = sna_static_stream_alloc(stream, len, align); return memset(stream->data + offset, 0, len); } uint32_t sna_static_stream_offsetof(struct sna_static_stream *stream, void *ptr) { return (uint8_t *)ptr - stream->data; } struct kgem_bo *sna_static_stream_fini(struct sna *sna, struct sna_static_stream *stream) { struct kgem_bo *bo; DBG(("uploaded %d bytes of static state\n", stream->used)); bo = kgem_create_linear(&sna->kgem, stream->used, 0); if (bo && !kgem_bo_write(&sna->kgem, bo, stream->data, stream->used)) { kgem_bo_destroy(&sna->kgem, bo); return NULL; } free(stream->data); return bo; } unsigned sna_static_stream_compile_sf(struct sna *sna, struct sna_static_stream *stream, bool (*compile)(struct brw_compile *)) { struct brw_compile p; brw_compile_init(&p, sna->kgem.gen, sna_static_stream_map(stream, 64*sizeof(uint32_t), 64)); if (!compile(&p)) { stream->used -= 64*sizeof(uint32_t); return 0; } assert(p.nr_insn*sizeof(struct brw_instruction) <= 64*sizeof(uint32_t)); stream->used -= 64*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction); return sna_static_stream_offsetof(stream, p.store); } unsigned sna_static_stream_compile_wm(struct sna *sna, struct sna_static_stream *stream, bool (*compile)(struct brw_compile *, int), int dispatch_width) { struct brw_compile p; brw_compile_init(&p, sna->kgem.gen, sna_static_stream_map(stream, 256*sizeof(uint32_t), 64)); if (!compile(&p, dispatch_width)) { stream->used -= 256*sizeof(uint32_t); return 0; } assert(p.nr_insn*sizeof(struct brw_instruction) <= 256*sizeof(uint32_t)); stream->used -= 256*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction); return sna_static_stream_offsetof(stream, p.store); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_threads.c000066400000000000000000000202661267532330400243100ustar00rootroot00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include #include #include #ifdef HAVE_VALGRIND #include static inline bool valgrind_active(void) { return RUNNING_ON_VALGRIND; } #else static inline bool valgrind_active(void) { return false; } #endif static int max_threads = -1; static struct thread { pthread_t thread; pthread_mutex_t mutex; pthread_cond_t cond; void (*func)(void *arg); void *arg; } *threads; static void *__run__(void *arg) { struct thread *t = arg; sigset_t signals; /* Disable all signals in the slave threads as X uses them for IO */ sigfillset(&signals); sigdelset(&signals, SIGBUS); sigdelset(&signals, SIGSEGV); pthread_sigmask(SIG_SETMASK, &signals, NULL); pthread_mutex_lock(&t->mutex); while (1) { while (t->func == NULL) pthread_cond_wait(&t->cond, &t->mutex); pthread_mutex_unlock(&t->mutex); assert(t->func); t->func(t->arg); pthread_mutex_lock(&t->mutex); t->arg = NULL; t->func = NULL; pthread_cond_signal(&t->cond); } pthread_mutex_unlock(&t->mutex); return NULL; } #if defined(__GNUC__) #define popcount(x) __builtin_popcount(x) #else static int popcount(unsigned int x) { int count = 0; while (x) { count += x&1; x >>= 1; } return count; } #endif static int num_cores(void) { FILE *file = fopen("/proc/cpuinfo", "r"); int count = 0; if (file) { size_t len = 0; char *line = NULL; uint32_t processors = 0, cores = 0; while (getline(&line, &len, file) != -1) { int id; if (sscanf(line, "physical id : %d", &id) == 1) { if (id >= 32) continue; processors |= 1 << id; } else if (sscanf(line, "core id : %d", &id) == 1) { if (id >= 32) continue; cores |= 1 << id; } } free(line); fclose(file); DBG(("%s: processors=0x%08x, cores=0x%08x\n", __FUNCTION__, processors, cores)); count = popcount(processors) * popcount(cores); } return count; } void sna_threads_init(void) { int n; if (max_threads != -1) return; if (valgrind_active()) goto bail; max_threads = num_cores(); if (max_threads == 0) max_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; if (max_threads <= 1) goto bail; DBG(("%s: creating a thread pool of %d threads\n", __func__, max_threads)); threads = malloc (sizeof(threads[0])*max_threads); if (threads == NULL) goto bail; for (n = 1; n < max_threads; n++) { pthread_mutex_init(&threads[n].mutex, NULL); pthread_cond_init(&threads[n].cond, NULL); threads[n].func = NULL; threads[n].arg = NULL; if (pthread_create(&threads[n].thread, NULL, __run__, &threads[n])) goto bail; } threads[0].thread = pthread_self(); return; bail: max_threads = 0; } void sna_threads_run(int id, void (*func)(void *arg), void *arg) { assert(max_threads > 0); assert(pthread_self() == threads[0].thread); assert(id > 0 && id < max_threads); assert(threads[id].func == NULL); pthread_mutex_lock(&threads[id].mutex); threads[id].func = func; threads[id].arg = arg; pthread_cond_signal(&threads[id].cond); pthread_mutex_unlock(&threads[id].mutex); } void sna_threads_trap(int sig) { pthread_t t = pthread_self(); int n; if (max_threads == 0) return; if (t == threads[0].thread) return; for (n = 1; threads[n].thread != t; n++) ; ERR(("%s: thread[%d] caught signal %d\n", __func__, n, sig)); pthread_mutex_lock(&threads[n].mutex); threads[n].arg = (void *)(intptr_t)sig; threads[n].func = NULL; pthread_cond_signal(&threads[n].cond); pthread_mutex_unlock(&threads[n].mutex); pthread_exit(&sig); } void sna_threads_wait(void) { int n; assert(max_threads > 0); assert(pthread_self() == threads[0].thread); for (n = 1; n < max_threads; n++) { if (threads[n].func != NULL) { pthread_mutex_lock(&threads[n].mutex); while (threads[n].func) pthread_cond_wait(&threads[n].cond, &threads[n].mutex); pthread_mutex_unlock(&threads[n].mutex); } if (threads[n].arg != NULL) { DBG(("%s: thread[%d] died from signal %d\n", __func__, n, (int)(intptr_t)threads[n].arg)); sna_threads_kill(); return; } } } void sna_threads_kill(void) { int n; ERR(("%s: kill %d threads\n", __func__, max_threads)); assert(max_threads > 0); assert(pthread_self() == threads[0].thread); for (n = 1; n < max_threads; n++) pthread_cancel(threads[n].thread); for (n = 1; n < max_threads; n++) pthread_join(threads[n].thread, NULL); max_threads = 0; } int sna_use_threads(int width, int height, int threshold) { int num_threads; if (max_threads <= 0) return 1; if (height <= 1) return 1; if (width < 128) height /= 128/width; num_threads = height * max_threads / threshold - 1; if (num_threads <= 0) return 1; if (num_threads > max_threads) num_threads = max_threads; if (num_threads > height) num_threads = height; return num_threads; } struct thread_composite { pixman_image_t *src, *mask, *dst; pixman_op_t op; int16_t src_x, src_y; int16_t mask_x, mask_y; int16_t dst_x, dst_y; uint16_t width, height; }; static void thread_composite(void *arg) { struct thread_composite *t = arg; pixman_image_composite(t->op, t->src, t->mask, t->dst, t->src_x, t->src_y, t->mask_x, t->mask_y, t->dst_x, t->dst_y, t->width, t->height); } void sna_image_composite(pixman_op_t op, pixman_image_t *src, pixman_image_t *mask, pixman_image_t *dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height) { int num_threads; num_threads = sna_use_threads(width, height, 32); if (num_threads <= 1) { if (sigtrap_get() == 0) { pixman_image_composite(op, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); sigtrap_put(); } } else { struct thread_composite data[num_threads]; int y, dy, n; DBG(("%s: using %d threads for compositing %dx%d\n", __FUNCTION__, num_threads, width, height)); y = dst_y; dy = (height + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * dy >= height; data[0].op = op; data[0].src = src; data[0].mask = mask; data[0].dst = dst; data[0].src_x = src_x; data[0].src_y = src_y; data[0].mask_x = mask_x; data[0].mask_y = mask_y; data[0].dst_x = dst_x; data[0].dst_y = y; data[0].width = width; data[0].height = dy; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { data[n] = data[0]; data[n].src_y += y - dst_y; data[n].mask_y += y - dst_y; data[n].dst_y = y; y += dy; sna_threads_run(n, thread_composite, &data[n]); } assert(y < dst_y + height); if (y + dy > dst_y + height) dy = dst_y + height - y; data[0].src_y += y - dst_y; data[0].mask_y += y - dst_y; data[0].dst_y = y; data[0].height = dy; thread_composite(&data[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_tiling.c000066400000000000000000000766131267532330400241530ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "fb/fbpict.h" struct sna_tile_span { BoxRec box; float opacity; }; struct sna_tile_state { int op; PicturePtr src, mask, dst; PixmapPtr dst_pixmap; uint32_t dst_format; int16_t src_x, src_y; int16_t mask_x, mask_y; int16_t dst_x, dst_y; int16_t width, height; unsigned flags; int rect_count; int rect_size; struct sna_composite_rectangles rects_embedded[16], *rects; }; static void sna_tiling_composite_add_rect(struct sna_tile_state *tile, const struct sna_composite_rectangles *r) { if (tile->rect_count == tile->rect_size) { struct sna_composite_rectangles *a; int newsize = tile->rect_size * 2; if (tile->rects == tile->rects_embedded) { a = malloc (sizeof(struct sna_composite_rectangles) * newsize); if (a == NULL) return; memcpy(a, tile->rects_embedded, sizeof(struct sna_composite_rectangles) * tile->rect_count); } else { a = realloc(tile->rects, sizeof(struct sna_composite_rectangles) * newsize); if (a == NULL) return; } tile->rects = a; tile->rect_size = newsize; } tile->rects[tile->rect_count++] = *r; } fastcall static void sna_tiling_composite_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { sna_tiling_composite_add_rect(op->priv, r); (void)sna; } fastcall static void sna_tiling_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct sna_composite_rectangles r; r.dst.x = box->x1; r.dst.y = box->y1; r.mask = r.src = r.dst; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; sna_tiling_composite_add_rect(op->priv, &r); (void)sna; } static void sna_tiling_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { while (nbox--) { struct sna_composite_rectangles r; r.dst.x = box->x1; r.dst.y = box->y1; r.mask = r.src = r.dst; r.width = box->x2 - box->x1; r.height = box->y2 - box->y1; sna_tiling_composite_add_rect(op->priv, &r); box++; } (void)sna; } static void sna_tiling_composite_done(struct sna *sna, const struct sna_composite_op *op) { struct sna_tile_state *tile = op->priv; struct sna_composite_op tmp; int x, y, n, step, max_size; /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) || tile->dst_y & 63) step /= 2; max_size = sna_max_tile_copy_size(sna, op->dst.bo, op->dst.bo); if (max_size == 0) goto done; while (step * step * 4 > max_size) step /= 2; DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__, tile->width, tile->height, tile->rect_count, step)); if (tile->rect_count == 0) goto done; for (y = 0; y < tile->height; y += step) { int height = step; if (y + height > tile->height) height = tile->height - y; for (x = 0; x < tile->width; x += step) { int width = step; if (x + width > tile->width) width = tile->width - x; if (sna->render.composite(sna, tile->op, tile->src, tile->mask, tile->dst, tile->src_x + x, tile->src_y + y, tile->mask_x + x, tile->mask_y + y, tile->dst_x + x, tile->dst_y + y, width, height, COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) { for (n = 0; n < tile->rect_count; n++) { const struct sna_composite_rectangles *r = &tile->rects[n]; int x1, x2, dx, y1, y2, dy; x1 = r->dst.x - tile->dst_x, dx = 0; if (x1 < x) dx = x - x1, x1 = x; y1 = r->dst.y - tile->dst_y, dy = 0; if (y1 < y) dy = y - y1, y1 = y; x2 = r->dst.x + r->width - tile->dst_x; if (x2 > x + width) x2 = x + width; y2 = r->dst.y + r->height - tile->dst_y; if (y2 > y + height) y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d), delta=(%d,%d)\n", __FUNCTION__, n, r->dst.x, r->dst.y, r->width, r->height, x, y, width, height, x1, y1, x2, y2, dx, dy)); if (y2 > y1 && x2 > x1) { struct sna_composite_rectangles rr; rr.src.x = dx + r->src.x; rr.src.y = dy + r->src.y; rr.mask.x = dx + r->mask.x; rr.mask.y = dy + r->mask.y; rr.dst.x = dx + r->dst.x; rr.dst.y = dy + r->dst.y; rr.width = x2 - x1; rr.height = y2 - y1; tmp.blt(sna, &tmp, &rr); } } tmp.done(sna, &tmp); } else { unsigned int flags; DBG(("%s -- falback\n", __FUNCTION__)); if (tile->op <= PictOpSrc) flags = MOVE_WRITE; else flags = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_to_cpu(tile->dst->pDrawable, flags)) goto done; if (tile->dst->alphaMap && !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable, flags)) goto done; if (tile->src->pDrawable && !sna_drawable_move_to_cpu(tile->src->pDrawable, MOVE_READ)) goto done; if (tile->src->alphaMap && !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable, MOVE_READ)) goto done; if (tile->mask && tile->mask->pDrawable && !sna_drawable_move_to_cpu(tile->mask->pDrawable, MOVE_READ)) goto done; if (tile->mask && tile->mask->alphaMap && !sna_drawable_move_to_cpu(tile->mask->alphaMap->pDrawable, MOVE_READ)) goto done; if (sigtrap_get() == 0) { fbComposite(tile->op, tile->src, tile->mask, tile->dst, tile->src_x + x, tile->src_y + y, tile->mask_x + x, tile->mask_y + y, tile->dst_x + x, tile->dst_y + y, width, height); sigtrap_put(); } } } } done: if (tile->rects != tile->rects_embedded) free(tile->rects); free(tile); } bool sna_tiling_composite(uint32_t op, PicturePtr src, PicturePtr mask, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t mask_x, int16_t mask_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, struct sna_composite_op *tmp) { struct sna_tile_state *tile; struct sna_pixmap *priv; DBG(("%s size=(%d, %d), tile=%d\n", __FUNCTION__, width, height, to_sna_from_drawable(dst->pDrawable)->render.max_3d_size)); priv = sna_pixmap(get_drawable_pixmap(dst->pDrawable)); if (priv == NULL || priv->gpu_bo == NULL) return false; tile = malloc(sizeof(*tile)); if (!tile) return false; tile->op = op; tile->src = src; tile->mask = mask; tile->dst = dst; tile->src_x = src_x; tile->src_y = src_y; tile->mask_x = mask_x; tile->mask_y = mask_y; tile->dst_x = dst_x; tile->dst_y = dst_y; tile->width = width; tile->height = height; tile->rects = tile->rects_embedded; tile->rect_count = 0; tile->rect_size = ARRAY_SIZE(tile->rects_embedded); tmp->blt = sna_tiling_composite_blt; tmp->box = sna_tiling_composite_box; tmp->boxes = sna_tiling_composite_boxes; tmp->done = sna_tiling_composite_done; tmp->priv = tile; tmp->dst.bo = priv->gpu_bo; return true; } fastcall static void sna_tiling_composite_spans_box(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, float opacity) { struct sna_tile_state *tile = op->base.priv; struct sna_tile_span *a; if (tile->rect_count == tile->rect_size) { int newsize = tile->rect_size * 2; if (tile->rects == tile->rects_embedded) { a = malloc (sizeof(struct sna_tile_span) * newsize); if (a == NULL) return; memcpy(a, tile->rects_embedded, sizeof(struct sna_tile_span) * tile->rect_count); } else { a = realloc(tile->rects, sizeof(struct sna_tile_span) * newsize); if (a == NULL) return; } tile->rects = (void *)a; tile->rect_size = newsize; } else a = (void *)tile->rects; a[tile->rect_count].box = *box; a[tile->rect_count].opacity = opacity; tile->rect_count++; (void)sna; } static void sna_tiling_composite_spans_boxes(struct sna *sna, const struct sna_composite_spans_op *op, const BoxRec *box, int nbox, float opacity) { while (nbox--) sna_tiling_composite_spans_box(sna, op, box++, opacity); } fastcall static void sna_tiling_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { struct sna_tile_state *tile = op->base.priv; struct sna_composite_spans_op tmp; int x, y, n, step, max_size; bool force_fallback = false; /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) || tile->dst_y & 63) step /= 2; max_size = sna_max_tile_copy_size(sna, op->base.dst.bo, op->base.dst.bo); if (max_size == 0) goto done; while (step * step * 4 > max_size) step /= 2; DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__, tile->width, tile->height, tile->rect_count, step)); if (tile->rect_count == 0) goto done; for (y = 0; y < tile->height; y += step) { int height = step; if (y + height > tile->height) height = tile->height - y; for (x = 0; x < tile->width; x += step) { const struct sna_tile_span *r = (void *)tile->rects; int width = step; if (x + width > tile->width) width = tile->width - x; if (!force_fallback && sna->render.composite_spans(sna, tile->op, tile->src, tile->dst, tile->src_x + x, tile->src_y + y, tile->dst_x + x, tile->dst_y + y, width, height, tile->flags, memset(&tmp, 0, sizeof(tmp)))) { for (n = 0; n < tile->rect_count; n++) { BoxRec b; b.x1 = r->box.x1 - tile->dst_x; if (b.x1 < x) b.x1 = x; b.y1 = r->box.y1 - tile->dst_y; if (b.y1 < y) b.y1 = y; b.x2 = r->box.x2 - tile->dst_x; if (b.x2 > x + width) b.x2 = x + width; b.y2 = r->box.y2 - tile->dst_y; if (b.y2 > y + height) b.y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n", __FUNCTION__, n, r->box.x1, r->box.y1, r->box.x2-r->box.x1, r->box.y2-r->box.y1, x, y, width, height, b.x1, b.y1, b.x2, b.y2)); if (b.y2 > b.y1 && b.x2 > b.x1) tmp.box(sna, &tmp, &b, r->opacity); r++; } tmp.done(sna, &tmp); } else { unsigned int flags; DBG(("%s -- falback\n", __FUNCTION__)); if (tile->op <= PictOpSrc) flags = MOVE_WRITE; else flags = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_to_cpu(tile->dst->pDrawable, flags)) goto done; if (tile->dst->alphaMap && !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable, flags)) goto done; if (tile->src->pDrawable && !sna_drawable_move_to_cpu(tile->src->pDrawable, MOVE_READ)) goto done; if (tile->src->alphaMap && !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable, MOVE_READ)) goto done; for (n = 0; n < tile->rect_count; n++) { BoxRec b; b.x1 = r->box.x1 - tile->dst_x; if (b.x1 < x) b.x1 = x; b.y1 = r->box.y1 - tile->dst_y; if (b.y1 < y) b.y1 = y; b.x2 = r->box.x2 - tile->dst_x; if (b.x2 > x + width) b.x2 = x + width; b.y2 = r->box.y2 - tile->dst_y; if (b.y2 > y + height) b.y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n", __FUNCTION__, n, r->box.x1, r->box.y1, r->box.x2-r->box.x1, r->box.y2-r->box.y1, x, y, width, height, b.x1, b.y1, b.x2, b.y2)); if (b.y2 > b.y1 && b.x2 > b.x1) { xRenderColor alpha; PicturePtr mask; int error; alpha.red = alpha.green = alpha.blue = 0; alpha.alpha = r->opacity * 0xffff; mask = CreateSolidPicture(0, &alpha, &error); if (!mask) goto done; if (sigtrap_get() == 0) { fbComposite(tile->op, tile->src, mask, tile->dst, tile->src_x + x, tile->src_y + y, 0, 0, tile->dst_x + x, tile->dst_y + y, width, height); sigtrap_put(); } FreePicture(mask, 0); } r++; } force_fallback = true; } } } done: if (tile->rects != tile->rects_embedded) free(tile->rects); free(tile); } bool sna_tiling_composite_spans(uint32_t op, PicturePtr src, PicturePtr dst, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, int16_t width, int16_t height, unsigned flags, struct sna_composite_spans_op *tmp) { struct sna_tile_state *tile; struct sna_pixmap *priv; DBG(("%s size=(%d, %d), tile=%d\n", __FUNCTION__, width, height, to_sna_from_drawable(dst->pDrawable)->render.max_3d_size)); priv = sna_pixmap(get_drawable_pixmap(dst->pDrawable)); if (priv == NULL || priv->gpu_bo == NULL) return false; tile = malloc(sizeof(*tile)); if (!tile) return false; tile->op = op; tile->flags = flags; tile->src = src; tile->mask = NULL; tile->dst = dst; tile->src_x = src_x; tile->src_y = src_y; tile->mask_x = 0; tile->mask_y = 0; tile->dst_x = dst_x; tile->dst_y = dst_y; tile->width = width; tile->height = height; tile->rects = tile->rects_embedded; tile->rect_count = 0; tile->rect_size = ARRAY_SIZE(tile->rects_embedded); COMPILE_TIME_ASSERT(sizeof(tile->rects_embedded[0]) >= sizeof(struct sna_tile_span)); tmp->box = sna_tiling_composite_spans_box; tmp->boxes = sna_tiling_composite_spans_boxes; tmp->done = sna_tiling_composite_spans_done; tmp->base.priv = tile; tmp->base.dst.bo = priv->gpu_bo; return true; } bool sna_tiling_fill_boxes(struct sna *sna, CARD8 op, PictFormat format, const xRenderColor *color, const DrawableRec *dst, struct kgem_bo *dst_bo, const BoxRec *box, int n) { RegionRec region, tile, this; struct kgem_bo *bo; int step, max_size; bool ret = false; pixman_region_init_rects(®ion, box, n); /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (region.extents.x1 & (8*512 / dst->bitsPerPixel - 1) || region.extents.y1 & 63) step /= 2; max_size = sna_max_tile_copy_size(sna, dst_bo, dst_bo); if (max_size == 0) goto done; while (step * step * 4 > max_size) step /= 2; DBG(("%s (op=%d, format=%x, color=(%04x,%04x,%04x, %04x), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n", __FUNCTION__, op, (int)format, color->red, color->green, color->blue, color->alpha, step, n, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); for (tile.extents.y1 = tile.extents.y2 = region.extents.y1; tile.extents.y2 < region.extents.y2; tile.extents.y1 = tile.extents.y2) { int y2 = tile.extents.y1 + step; if (y2 > region.extents.y2) y2 = region.extents.y2; tile.extents.y2 = y2; for (tile.extents.x1 = tile.extents.x2 = region.extents.x1; tile.extents.x2 < region.extents.x2; tile.extents.x1 = tile.extents.x2) { DrawableRec tmp; int x2 = tile.extents.x1 + step; if (x2 > region.extents.x2) x2 = region.extents.x2; tile.extents.x2 = x2; tile.data = NULL; RegionNull(&this); RegionIntersect(&this, ®ion, &tile); if (RegionNil(&this)) continue; tmp.width = this.extents.x2 - this.extents.x1; tmp.height = this.extents.y2 - this.extents.y1; tmp.depth = dst->depth; tmp.bitsPerPixel = dst->bitsPerPixel; bo = kgem_create_2d(&sna->kgem, tmp.width, tmp.height, dst->bitsPerPixel, kgem_choose_tiling(&sna->kgem, I915_TILING_X, tmp.width, tmp.height, dst->bitsPerPixel), CREATE_TEMPORARY); if (bo) { int16_t dx = this.extents.x1; int16_t dy = this.extents.y1; assert(kgem_bo_can_blt(&sna->kgem, bo)); if (op > PictOpSrc && !sna->render.copy_boxes(sna, GXcopy, dst, dst_bo, 0, 0, &tmp, bo, -dx, -dy, region_rects(&this), region_num_rects(&this), 0)) goto err; RegionTranslate(&this, -dx, -dy); if (!sna->render.fill_boxes(sna, op, format, color, &tmp, bo, region_rects(&this), region_num_rects(&this))) goto err; if (!sna->render.copy_boxes(sna, GXcopy, &tmp, bo, 0, 0, dst, dst_bo, dx, dy, region_rects(&this), region_num_rects(&this), 0)) goto err; kgem_bo_destroy(&sna->kgem, bo); } RegionUninit(&this); } } ret = true; goto done; err: kgem_bo_destroy(&sna->kgem, bo); RegionUninit(&this); done: pixman_region_fini(®ion); return ret; } fastcall static void tiling_blt(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; int src_x, src_y; BoxRec box; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, r->dst.x, r->dst.y, r->width, r->height)); /* XXX higher layer should have clipped? */ x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; src_x = r->src.x - x1 + op->u.blt.sx; src_y = r->src.y - y1 + op->u.blt.sy; /* clip against dst */ if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; DBG(("%s: box=(%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 <= x1 || y2 <= y1) return; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; sna_tiling_blt_copy_boxes(sna, GXcopy, op->src.bo, src_x, src_y, op->dst.bo, 0, 0, op->u.blt.bpp, &box, 1); } fastcall static void tiling_blt_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_tiling_blt_copy_boxes(sna, GXcopy, op->src.bo, op->u.blt.sx, op->u.blt.sy, op->dst.bo, op->dst.x, op->dst.y, op->u.blt.bpp, box, 1); } static void tiling_blt_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_tiling_blt_copy_boxes(sna, GXcopy, op->src.bo, op->u.blt.sx, op->u.blt.sy, op->dst.bo, op->dst.x, op->dst.y, op->u.blt.bpp, box, nbox); } static bool sna_tiling_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, int alpha_fixup, const BoxRec *box, int nbox) { RegionRec region, tile, this; struct kgem_bo *bo; int max_size, step; bool ret = false; if (wedged(sna) || !kgem_bo_can_blt(&sna->kgem, src_bo) || !kgem_bo_can_blt(&sna->kgem, dst_bo)) { /* XXX */ DBG(("%s: tiling blt fail: src?=%d, dst?=%d\n", __FUNCTION__, kgem_bo_can_blt(&sna->kgem, src_bo), kgem_bo_can_blt(&sna->kgem, dst_bo))); return false; } max_size = sna_max_tile_copy_size(sna, src_bo, dst_bo); if (max_size == 0) return false; pixman_region_init_rects(®ion, box, nbox); /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (region.extents.x1 & (8*512 / bpp - 1) || region.extents.y1 & 63) step /= 2; while (step * step * 4 > max_size) step /= 2; if (sna->kgem.gen < 033) step /= 2; /* accommodate severe fence restrictions */ if (step == 0) { DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__)); return false; } DBG(("%s (alu=%d), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n", __FUNCTION__, alu, step, nbox, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); for (tile.extents.y1 = tile.extents.y2 = region.extents.y1; tile.extents.y2 < region.extents.y2; tile.extents.y1 = tile.extents.y2) { int y2 = tile.extents.y1 + step; if (y2 > region.extents.y2) y2 = region.extents.y2; tile.extents.y2 = y2; for (tile.extents.x1 = tile.extents.x2 = region.extents.x1; tile.extents.x2 < region.extents.x2; tile.extents.x1 = tile.extents.x2) { int w, h; int x2 = tile.extents.x1 + step; if (x2 > region.extents.x2) x2 = region.extents.x2; tile.extents.x2 = x2; tile.data = NULL; RegionNull(&this); RegionIntersect(&this, ®ion, &tile); if (RegionNil(&this)) continue; w = this.extents.x2 - this.extents.x1; h = this.extents.y2 - this.extents.y1; bo = kgem_create_2d(&sna->kgem, w, h, bpp, kgem_choose_tiling(&sna->kgem, I915_TILING_X, w, h, bpp), CREATE_TEMPORARY); if (bo) { int16_t dx = this.extents.x1; int16_t dy = this.extents.y1; assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!sna_blt_copy_boxes(sna, GXcopy, src_bo, src_dx, src_dy, bo, -dx, -dy, bpp, region_rects(&this), region_num_rects(&this))) goto err; if (!sna_blt_copy_boxes__with_alpha(sna, alu, bo, -dx, -dy, dst_bo, dst_dx, dst_dy, bpp, alpha_fixup, region_rects(&this), region_num_rects(&this))) goto err; kgem_bo_destroy(&sna->kgem, bo); } RegionUninit(&this); } } ret = true; goto done; err: kgem_bo_destroy(&sna->kgem, bo); RegionUninit(&this); done: pixman_region_fini(®ion); return ret; } fastcall static void tiling_blt__with_alpha(struct sna *sna, const struct sna_composite_op *op, const struct sna_composite_rectangles *r) { int x1, x2, y1, y2; int src_x, src_y; BoxRec box; DBG(("%s: src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n", __FUNCTION__, r->src.x, r->src.y, r->dst.x, r->dst.y, r->width, r->height)); /* XXX higher layer should have clipped? */ x1 = r->dst.x + op->dst.x; y1 = r->dst.y + op->dst.y; x2 = x1 + r->width; y2 = y1 + r->height; src_x = r->src.x - x1 + op->u.blt.sx; src_y = r->src.y - y1 + op->u.blt.sy; /* clip against dst */ if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > op->dst.width) x2 = op->dst.width; if (y2 > op->dst.height) y2 = op->dst.height; DBG(("%s: box=(%d, %d), (%d, %d)\n", __FUNCTION__, x1, y1, x2, y2)); if (x2 <= x1 || y2 <= y1) return; box.x1 = x1; box.y1 = y1; box.x2 = x2; box.y2 = y2; sna_tiling_blt_copy_boxes__with_alpha(sna, GXcopy, op->src.bo, src_x, src_y, op->dst.bo, 0, 0, op->u.blt.bpp, op->u.blt.pixel, &box, 1); } fastcall static void tiling_blt_box__with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { DBG(("%s: box (%d, %d), (%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2)); sna_tiling_blt_copy_boxes__with_alpha(sna, GXcopy, op->src.bo, op->u.blt.sx, op->u.blt.sy, op->dst.bo, op->dst.x, op->dst.y, op->u.blt.bpp, op->u.blt.pixel, box, 1); } static void tiling_blt_boxes__with_alpha(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { DBG(("%s: nbox=%d\n", __FUNCTION__, nbox)); sna_tiling_blt_copy_boxes__with_alpha(sna, GXcopy, op->src.bo, op->u.blt.sx, op->u.blt.sy, op->dst.bo, op->dst.x, op->dst.y, op->u.blt.bpp, op->u.blt.pixel, box, nbox); } static void nop_done(struct sna *sna, const struct sna_composite_op *op) { assert(sna->kgem.nbatch <= KGEM_BATCH_SIZE(&sna->kgem)); (void)op; } bool sna_tiling_blt_composite(struct sna *sna, struct sna_composite_op *op, struct kgem_bo *bo, int bpp, uint32_t alpha_fixup) { assert(op->dst.bo); assert(kgem_bo_can_blt(&sna->kgem, op->dst.bo)); assert(kgem_bo_can_blt(&sna->kgem, bo)); op->src.bo = bo; op->u.blt.bpp = bpp; op->u.blt.pixel = alpha_fixup; if (alpha_fixup) { op->blt = tiling_blt__with_alpha; op->box = tiling_blt_box__with_alpha; op->boxes = tiling_blt_boxes__with_alpha; } else { op->blt = tiling_blt; op->box = tiling_blt_box; op->boxes = tiling_blt_boxes; } op->done = nop_done; return true; } bool sna_tiling_blt_copy_boxes(struct sna *sna, uint8_t alu, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, int bpp, const BoxRec *box, int nbox) { RegionRec region, tile, this; struct kgem_bo *bo; int max_size, step; bool ret = false; DBG(("%s: alu=%d, src size=%d, dst size=%d\n", __FUNCTION__, alu, kgem_bo_size(src_bo), kgem_bo_size(dst_bo))); if (wedged(sna) || !kgem_bo_can_blt(&sna->kgem, src_bo) || !kgem_bo_can_blt(&sna->kgem, dst_bo)) { /* XXX */ DBG(("%s: tiling blt fail: src?=%d, dst?=%d\n", __FUNCTION__, kgem_bo_can_blt(&sna->kgem, src_bo), kgem_bo_can_blt(&sna->kgem, dst_bo))); return false; } max_size = sna_max_tile_copy_size(sna, src_bo, dst_bo); if (max_size == 0) return false; pixman_region_init_rects(®ion, box, nbox); /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (region.extents.x1 & (8*512 / bpp - 1) || region.extents.y1 & 63) step /= 2; while (step * step * 4 > max_size) step /= 2; if (sna->kgem.gen < 033) step /= 2; /* accommodate severe fence restrictions */ if (step == 0) { DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__)); return false; } DBG(("%s (alu=%d), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n", __FUNCTION__, alu, step, nbox, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); for (tile.extents.y1 = tile.extents.y2 = region.extents.y1; tile.extents.y2 < region.extents.y2; tile.extents.y1 = tile.extents.y2) { int y2 = tile.extents.y1 + step; if (y2 > region.extents.y2) y2 = region.extents.y2; tile.extents.y2 = y2; for (tile.extents.x1 = tile.extents.x2 = region.extents.x1; tile.extents.x2 < region.extents.x2; tile.extents.x1 = tile.extents.x2) { int w, h; int x2 = tile.extents.x1 + step; if (x2 > region.extents.x2) x2 = region.extents.x2; tile.extents.x2 = x2; tile.data = NULL; RegionNull(&this); RegionIntersect(&this, ®ion, &tile); if (RegionNil(&this)) continue; w = this.extents.x2 - this.extents.x1; h = this.extents.y2 - this.extents.y1; bo = kgem_create_2d(&sna->kgem, w, h, bpp, kgem_choose_tiling(&sna->kgem, I915_TILING_X, w, h, bpp), CREATE_TEMPORARY); if (bo) { int16_t dx = this.extents.x1; int16_t dy = this.extents.y1; assert(kgem_bo_can_blt(&sna->kgem, bo)); if (!sna_blt_copy_boxes(sna, GXcopy, src_bo, src_dx, src_dy, bo, -dx, -dy, bpp, region_rects(&this), region_num_rects(&this))) goto err; if (!sna_blt_copy_boxes(sna, alu, bo, -dx, -dy, dst_bo, dst_dx, dst_dy, bpp, region_rects(&this), region_num_rects(&this))) goto err; kgem_bo_destroy(&sna->kgem, bo); } RegionUninit(&this); } } ret = true; goto done; err: kgem_bo_destroy(&sna->kgem, bo); RegionUninit(&this); done: pixman_region_fini(®ion); return ret; } bool sna_tiling_copy_boxes(struct sna *sna, uint8_t alu, const DrawableRec *src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, const DrawableRec *dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, const BoxRec *box, int n) { BoxRec extents, tile, stack[64], *clipped, *c; DrawableRec p; int i, step, tiling; bool create = true; bool ret = false; extents = box[0]; for (i = 1; i < n; i++) { if (box[i].x1 < extents.x1) extents.x1 = box[i].x1; if (box[i].y1 < extents.y1) extents.y1 = box[i].y1; if (box[i].x2 > extents.x2) extents.x2 = box[i].x2; if (box[i].y2 > extents.y2) extents.y2 = box[i].y2; } tiling = I915_TILING_X; if (!kgem_bo_can_blt(&sna->kgem, src_bo) || !kgem_bo_can_blt(&sna->kgem, dst_bo)) tiling = I915_TILING_Y; create = (src_bo->pitch > sna->render.max_3d_pitch || dst_bo->pitch > sna->render.max_3d_pitch); step = sna->render.max_3d_size / 2; if (create) { while (step * step * 4 > sna->kgem.max_upload_tile_size) step /= 2; } DBG(("%s: tiling copy %dx%d, %s %dx%d %c tiles\n", __FUNCTION__, extents.x2-extents.x1, extents.y2-extents.y1, create ? "creating" : "using", step, step, tiling == I915_TILING_X ? 'X' : 'Y')); if (n > ARRAY_SIZE(stack)) { clipped = malloc(sizeof(BoxRec) * n); if (clipped == NULL) goto tiled_error; } else clipped = stack; p.depth = src->depth; p.bitsPerPixel = src->bitsPerPixel; for (tile.y1 = extents.y1; tile.y1 < extents.y2; tile.y1 = tile.y2) { int y2 = tile.y1 + step; if (y2 > extents.y2) y2 = extents.y2; tile.y2 = y2; for (tile.x1 = extents.x1; tile.x1 < extents.x2; tile.x1 = tile.x2) { struct kgem_bo *tmp_bo; int x2 = tile.x1 + step; if (x2 > extents.x2) x2 = extents.x2; tile.x2 = x2; c = clipped; for (i = 0; i < n; i++) { *c = box[i]; if (!box_intersect(c, &tile)) continue; DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, c->x1, c->y1, c->x2, c->y2, src_dx, src_dy, c->x1 - tile.x1, c->y1 - tile.y1)); c++; } if (c == clipped) continue; p.width = tile.x2 - tile.x1; p.height = tile.y2 - tile.y1; DBG(("%s: tile (%d, %d), (%d, %d)\n", __FUNCTION__, tile.x1, tile.y1, tile.x2, tile.y2)); if (create) { tmp_bo = kgem_create_2d(&sna->kgem, p.width, p.height, p.bitsPerPixel, tiling, CREATE_TEMPORARY); if (!tmp_bo) goto tiled_error; i = (sna->render.copy_boxes(sna, GXcopy, src, src_bo, src_dx, src_dy, &p, tmp_bo, -tile.x1, -tile.y1, clipped, c - clipped, 0) && sna->render.copy_boxes(sna, alu, &p, tmp_bo, -tile.x1, -tile.y1, dst, dst_bo, dst_dx, dst_dy, clipped, c - clipped, 0)); kgem_bo_destroy(&sna->kgem, tmp_bo); } else { i = sna->render.copy_boxes(sna, GXcopy, src, src_bo, src_dx, src_dy, dst, dst_bo, dst_dx, dst_dy, clipped, c - clipped, 0); } if (!i) goto tiled_error; } } ret = true; tiled_error: if (clipped != stack) free(clipped); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_transform.c000066400000000000000000000125671267532330400246760ustar00rootroot00000000000000/* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. All Rights Reserved. * Copyright (c) 2005 Jesse Barnes * Copyright © 2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Jesse Barns * Chris Wilson */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" /** * Returns whether the provided transform is affine. * * transform may be null. */ bool sna_transform_is_affine(const PictTransform *t) { if (t == NULL) return true; return t->matrix[2][0] == 0 && t->matrix[2][1] == 0; } bool sna_transform_is_translation(const PictTransform *t, pixman_fixed_t *tx, pixman_fixed_t *ty) { if (t == NULL) { *tx = *ty = 0; return true; } if (t->matrix[0][0] != IntToxFixed(1) || t->matrix[0][1] != 0 || t->matrix[1][0] != 0 || t->matrix[1][1] != IntToxFixed(1) || t->matrix[2][0] != 0 || t->matrix[2][1] != 0 || t->matrix[2][2] != IntToxFixed(1)) return false; *tx = t->matrix[0][2]; *ty = t->matrix[1][2]; return true; } bool sna_transform_is_integer_translation(const PictTransform *t, int16_t *tx, int16_t *ty) { if (t == NULL) { *tx = *ty = 0; return true; } if (t->matrix[0][0] != IntToxFixed(1) || t->matrix[0][1] != 0 || t->matrix[1][0] != 0 || t->matrix[1][1] != IntToxFixed(1) || t->matrix[2][0] != 0 || t->matrix[2][1] != 0 || t->matrix[2][2] != IntToxFixed(1)) return false; if (pixman_fixed_fraction(t->matrix[0][2]) || pixman_fixed_fraction(t->matrix[1][2])) return false; *tx = pixman_fixed_to_int(t->matrix[0][2]); *ty = pixman_fixed_to_int(t->matrix[1][2]); return true; } bool sna_transform_is_imprecise_integer_translation(const PictTransform *t, int filter, bool precise, int16_t *tx, int16_t *ty) { if (t == NULL) { DBG(("%s: no transform\n", __FUNCTION__)); *tx = *ty = 0; return true; } DBG(("%s: FilterNearest?=%d, precise?=%d, transform=[%f %f %f, %f %f %f, %f %f %f]\n", __FUNCTION__, filter==PictFilterNearest, precise, t->matrix[0][0]/65536., t->matrix[0][1]/65536., t->matrix[0][2]/65536., t->matrix[1][0]/65536., t->matrix[1][1]/65536., t->matrix[1][2]/65536., t->matrix[2][0]/65536., t->matrix[2][1]/65536., t->matrix[2][2]/65536.)); if (t->matrix[0][0] != IntToxFixed(1) || t->matrix[0][1] != 0 || t->matrix[1][0] != 0 || t->matrix[1][1] != IntToxFixed(1) || t->matrix[2][0] != 0 || t->matrix[2][1] != 0 || t->matrix[2][2] != IntToxFixed(1)) { DBG(("%s: not unity scaling\n", __FUNCTION__)); return false; } if (filter != PictFilterNearest) { if (precise) { if (pixman_fixed_fraction(t->matrix[0][2]) || pixman_fixed_fraction(t->matrix[1][2])) { DBG(("%s: precise, fractional translation\n", __FUNCTION__)); return false; } } else { int f; f = pixman_fixed_fraction(t->matrix[0][2]); if (f > IntToxFixed(1)/4 && f < IntToxFixed(3)/4) { DBG(("%s: imprecise, fractional translation X: %x\n", __FUNCTION__, f)); return false; } f = pixman_fixed_fraction(t->matrix[1][2]); if (f > IntToxFixed(1)/4 && f < IntToxFixed(3)/4) { DBG(("%s: imprecise, fractional translation Y: %x\n", __FUNCTION__, f)); return false; } } } *tx = pixman_fixed_to_int(t->matrix[0][2] + IntToxFixed(1)/2); *ty = pixman_fixed_to_int(t->matrix[1][2] + IntToxFixed(1)/2); return true; } /** * Returns the floating-point coordinates transformed by the given transform. */ void sna_get_transformed_coordinates(int x, int y, const PictTransform *transform, float *x_out, float *y_out) { if (transform == NULL) { *x_out = x; *y_out = y; } else _sna_get_transformed_coordinates(x, y, transform, x_out, y_out); } /** * Returns the un-normalized floating-point coordinates transformed by the given transform. */ void sna_get_transformed_coordinates_3d(int x, int y, const PictTransform *transform, float *x_out, float *y_out, float *w_out) { if (transform == NULL) { *x_out = x; *y_out = y; *w_out = 1; } else { int64_t result[3]; if (_sna_transform_point(transform, x, y, result)) { *x_out = result[0] / 65536.; *y_out = result[1] / 65536.; *w_out = result[2] / 65536.; } else { *x_out = *y_out = 0; *w_out = 1.; } } } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids.c000066400000000000000000000777061267532330400250550ustar00rootroot00000000000000/* * Copyright (c) 2007 David Turner * Copyright (c) 2008 M Joonas Pihlaja * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_trapezoids.h" #include "fb/fbpict.h" #include /* TODO: Emit unantialiased and MSAA triangles. */ #ifndef MAX #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif #ifndef MIN #define MIN(x,y) ((x) <= (y) ? (x) : (y)) #endif #define region_count(r) ((r)->data ? (r)->data->numRects : 1) #define region_boxes(r) ((r)->data ? (BoxPtr)((r)->data + 1) : &(r)->extents) inline static xFixed line_x_for_y(const xLineFixed *l, xFixed y, bool ceil) { xFixed_32_32 ex = (xFixed_32_32)(y - l->p1.y) * (l->p2.x - l->p1.x); xFixed d = l->p2.y - l->p1.y; if (ceil) ex += (d - 1); return l->p1.x + (xFixed) (ex / d); } bool trapezoids_bounds(int n, const xTrapezoid *t, BoxPtr box) { xFixed x1, y1, x2, y2; /* XXX need 33 bits... */ x1 = y1 = INT_MAX / 2; x2 = y2 = INT_MIN / 2; do { xFixed fx1, fx2, v; if (!xTrapezoidValid(t)) { __DBG(("%s: skipping invalid trapezoid: top=%d, bottom=%d, left=(%d, %d), (%d, %d), right=(%d, %d), (%d, %d)\n", __FUNCTION__, t->top, t->bottom, t->left.p1.x, t->left.p1.y, t->left.p2.x, t->left.p2.y, t->right.p1.x, t->right.p1.y, t->right.p2.x, t->right.p2.y)); continue; } if (t->top < y1) y1 = t->top; if (t->bottom > y2) y2 = t->bottom; if (((t->left.p1.x - x1) | (t->left.p2.x - x1)) < 0) { if (pixman_fixed_floor(t->left.p1.x) == pixman_fixed_floor(t->left.p2.x)) { x1 = pixman_fixed_floor(t->left.p1.x); } else { if (t->left.p1.y == t->top) fx1 = t->left.p1.x; else fx1 = line_x_for_y(&t->left, t->top, false); if (t->left.p2.y == t->bottom) fx2 = t->left.p2.x; else fx2 = line_x_for_y(&t->left, t->bottom, false); v = min(fx1, fx2); if (v < x1) x1 = pixman_fixed_floor(v); } } if (((x2 - t->right.p1.x) | (x2 - t->right.p2.x)) < 0) { if (pixman_fixed_ceil(t->right.p1.x) == pixman_fixed_ceil(t->right.p2.x)) { x2 = pixman_fixed_ceil(t->right.p1.x); } else { if (t->right.p1.y == t->top) fx1 = t->right.p1.x; else fx1 = line_x_for_y(&t->right, t->top, true); if (t->right.p2.y == t->bottom) fx2 = t->right.p2.x; else fx2 = line_x_for_y(&t->right, t->bottom, true); v = max(fx1, fx2); if (v > x2) x2 = pixman_fixed_ceil(v); } } } while (t++, --n); box->x1 = pixman_fixed_to_int(x1); box->x2 = pixman_fixed_to_int(x2); box->y1 = pixman_fixed_integer_floor(y1); box->y2 = pixman_fixed_integer_ceil(y2); return box->x2 > box->x1 && box->y2 > box->y1; } static bool trapezoids_inplace_fallback(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask, int ntrap, xTrapezoid *traps) { pixman_image_t *image; BoxRec box; uint32_t color; int dx, dy; if (op != PictOpAdd) return false; if (is_mono(dst, mask)) { if (dst->format != PICT_a1) return false; } else { if (dst->format != PICT_a8) return false; } if (!sna_picture_is_solid(src, &color) || (color >> 24) != 0xff) { DBG(("%s: not an opaque solid source\n", __FUNCTION__)); return false; } box.x1 = dst->pDrawable->x; box.y1 = dst->pDrawable->y; box.x2 = dst->pDrawable->width; box.y2 = dst->pDrawable->height; if (pixman_region_contains_rectangle(dst->pCompositeClip, &box) != PIXMAN_REGION_IN) { DBG(("%s: requires clipping, drawable (%d,%d), (%d, %d), clip (%d, %d), (%d, %d)\n", __FUNCTION__, box.x1, box.y1, box.x2, box.y2, dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y1, dst->pCompositeClip->extents.x2, dst->pCompositeClip->extents.y2)); return false; } if (is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: not performing inplace as dst is already on the GPU\n", __FUNCTION__)); return false; } DBG(("%s\n", __FUNCTION__)); image = NULL; if (sna_drawable_move_to_cpu(dst->pDrawable, MOVE_READ | MOVE_WRITE)) image = image_from_pict(dst, false, &dx, &dy); if (image) { dx += dst->pDrawable->x; dy += dst->pDrawable->y; if (sigtrap_get() == 0) { for (; ntrap; ntrap--, traps++) if (xTrapezoidValid(traps)) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *)traps, dx, dy); sigtrap_put(); } pixman_image_unref(image); } return true; } struct rasterize_traps_thread { xTrapezoid *traps; char *ptr; int stride; BoxRec bounds; pixman_format_code_t format; int ntrap; }; static void rasterize_traps_thread(void *arg) { struct rasterize_traps_thread *thread = arg; pixman_image_t *image; int width, height, n; width = thread->bounds.x2 - thread->bounds.x1; height = thread->bounds.y2 - thread->bounds.y1; memset(thread->ptr, 0, thread->stride*height); if (PIXMAN_FORMAT_DEPTH(thread->format) < 8) image = pixman_image_create_bits(thread->format, width, height, NULL, 0); else image = pixman_image_create_bits(thread->format, width, height, (uint32_t *)thread->ptr, thread->stride); if (image == NULL) return; for (n = 0; n < thread->ntrap; n++) if (xTrapezoidValid(&thread->traps[n])) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *)&thread->traps[n], -thread->bounds.x1, -thread->bounds.y1); if (PIXMAN_FORMAT_DEPTH(thread->format) < 8) { pixman_image_t *a8; a8 = pixman_image_create_bits(PIXMAN_a8, width, height, (uint32_t *)thread->ptr, thread->stride); if (a8) { pixman_image_composite(PIXMAN_OP_SRC, image, NULL, a8, 0, 0, 0, 0, 0, 0, width, height); pixman_image_unref(a8); } } pixman_image_unref(image); } static void trapezoids_fallback(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) { ScreenPtr screen = dst->pDrawable->pScreen; if (maskFormat) { PixmapPtr scratch; PicturePtr mask; INT16 dst_x, dst_y; BoxRec bounds; int width, height, depth; pixman_image_t *image; pixman_format_code_t format; int error; trapezoid_origin(&traps[0].left, &dst_x, &dst_y); if (!trapezoids_bounds(ntrap, traps, &bounds)) return; DBG(("%s: bounds (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); if (!sna_compute_composite_extents(&bounds, src, NULL, dst, xSrc, ySrc, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1)) return; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; bounds.x1 -= dst->pDrawable->x; bounds.y1 -= dst->pDrawable->y; bounds.x2 -= dst->pDrawable->x; bounds.y2 -= dst->pDrawable->y; depth = maskFormat->depth; if (depth == 1) { format = PIXMAN_a1; } else if (depth <= 4) { format = PIXMAN_a4; depth = 4; } else format = PIXMAN_a8; DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n", __FUNCTION__, width, height, depth, format)); if (is_gpu(sna, dst->pDrawable, PREFER_GPU_RENDER) || picture_is_gpu(sna, src, PREFER_GPU_RENDER)) { int num_threads; scratch = sna_pixmap_create_upload(screen, width, height, 8, KGEM_BUFFER_WRITE); if (!scratch) return; num_threads = sna_use_threads(width, height, 8); if (num_threads == 1) { if (depth < 8) { image = pixman_image_create_bits(format, width, height, NULL, 0); } else { memset(scratch->devPrivate.ptr, 0, scratch->devKind*height); image = pixman_image_create_bits(format, width, height, scratch->devPrivate.ptr, scratch->devKind); } if (image) { for (; ntrap; ntrap--, traps++) if (xTrapezoidValid(traps)) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *)traps, -bounds.x1, -bounds.y1); if (depth < 8) { pixman_image_t *a8; a8 = pixman_image_create_bits(PIXMAN_a8, width, height, scratch->devPrivate.ptr, scratch->devKind); if (a8) { pixman_image_composite(PIXMAN_OP_SRC, image, NULL, a8, 0, 0, 0, 0, 0, 0, width, height); format = PIXMAN_a8; depth = 8; pixman_image_unref(a8); } } pixman_image_unref(image); } if (format != PIXMAN_a8) { sna_pixmap_destroy(scratch); return; } } else { struct rasterize_traps_thread threads[num_threads]; int y, dy, n; threads[0].ptr = scratch->devPrivate.ptr; threads[0].stride = scratch->devKind; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].bounds = bounds; threads[0].format = format; y = bounds.y1; dy = (height + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * dy >= bounds.y2 - bounds.y1; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].ptr += (y - bounds.y1) * threads[n].stride; threads[n].bounds.y1 = y; threads[n].bounds.y2 = y += dy; sna_threads_run(n, rasterize_traps_thread, &threads[n]); } assert(y < threads[0].bounds.y2); threads[0].ptr += (y - bounds.y1) * threads[0].stride; threads[0].bounds.y1 = y; rasterize_traps_thread(&threads[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); format = PIXMAN_a8; depth = 8; } } else { scratch = sna_pixmap_create_unattached(screen, width, height, depth); if (!scratch) return; memset(scratch->devPrivate.ptr, 0, scratch->devKind*height); image = pixman_image_create_bits(format, width, height, scratch->devPrivate.ptr, scratch->devKind); if (image) { for (; ntrap; ntrap--, traps++) if (xTrapezoidValid(traps)) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *)traps, -bounds.x1, -bounds.y1); pixman_image_unref(image); } } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, depth, format), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, xSrc + bounds.x1 - dst_x, ySrc + bounds.y1 - dst_y, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); } else { if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) trapezoids_fallback(sna, op, src, dst, maskFormat, xSrc, ySrc, 1, traps); } } static bool trapezoid_spans_maybe_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat) { struct sna_pixmap *priv; if (NO_SCAN_CONVERTER) return false; if (dst->alphaMap) return false; if (is_mono(dst, maskFormat)) goto out; switch ((int)dst->format) { case PICT_a8: if (!sna_picture_is_solid(src, NULL)) return false; switch (op) { case PictOpIn: case PictOpAdd: case PictOpSrc: break; default: return false; } break; case PICT_x8r8g8b8: case PICT_a8r8g8b8: if (picture_is_gpu(sna, src, 0)) return false; switch (op) { case PictOpOver: case PictOpAdd: case PictOpOutReverse: break; case PictOpSrc: if (sna_picture_is_solid(src, NULL)) break; if (!sna_drawable_is_clear(dst->pDrawable)) return false; break; default: return false; } break; default: return false; } out: priv = sna_pixmap_from_drawable(dst->pDrawable); if (priv == NULL) { DBG(("%s? yes -- unattached\n", __FUNCTION__)); return true; } if (priv->cpu_bo && kgem_bo_is_busy(priv->cpu_bo)) { DBG(("%s? no -- CPU bo is busy\n", __FUNCTION__)); return false; } if (DAMAGE_IS_ALL(priv->cpu_damage) || priv->gpu_damage == NULL) { DBG(("%s? yes -- damaged on CPU only (all? %d)\n", __FUNCTION__, DAMAGE_IS_ALL(priv->cpu_damage))); return true; } if (priv->clear) { DBG(("%s? clear, %s\n", __FUNCTION__, dst->pDrawable->width <= TOR_INPLACE_SIZE ? "yes" : "no")); return dst->pDrawable->width <= TOR_INPLACE_SIZE; } if (kgem_bo_is_busy(priv->gpu_bo)) { DBG(("%s? no, GPU bo is busy\n", __FUNCTION__)); return false; } if (priv->cpu_damage) { DBG(("%s? yes, idle GPU bo and damage on idle CPU\n", __FUNCTION__)); return true; } DBG(("%s? small enough? %s\n", __FUNCTION__, dst->pDrawable->width <= TOR_INPLACE_SIZE ? "yes" : "no")); return dst->pDrawable->width <= TOR_INPLACE_SIZE; } void sna_composite_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps) { PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv; bool force_fallback = false; bool rectilinear, pixel_aligned; unsigned flags; int n; DBG(("%s(op=%d, src=(%d, %d), mask=%08x, ntrap=%d)\n", __FUNCTION__, op, xSrc, ySrc, maskFormat ? (int)maskFormat->format : 0, ntrap)); if (ntrap == 0) return; if (NO_ACCEL) goto force_fallback; if (FORCE_FALLBACK > 0) goto force_fallback; if (wedged(sna)) { DBG(("%s: fallback -- wedged\n", __FUNCTION__)); goto force_fallback; } if (dst->alphaMap) { DBG(("%s: fallback -- dst alpha map\n", __FUNCTION__)); goto force_fallback; } priv = sna_pixmap(pixmap); if (priv == NULL) { DBG(("%s: fallback -- dst is unattached\n", __FUNCTION__)); goto force_fallback; } if (FORCE_FALLBACK == 0 && !is_gpu_dst(priv) && !picture_is_gpu(sna, src, 0) && untransformed(src)) { DBG(("%s: force fallbacks -- (!gpu dst, %dx%d? %d) && (src-is-cpu? %d && untransformed? %d)\n", __FUNCTION__, dst->pDrawable->width, dst->pDrawable->height, !is_gpu_dst(priv), !picture_is_gpu(sna, src, 0), untransformed(src))); force_fallback: force_fallback = true; } /* scan through for fast rectangles */ rectilinear = pixel_aligned = true; if (is_mono(dst, maskFormat)) { for (n = 0; n < ntrap && rectilinear; n++) { int lx1 = pixman_fixed_to_int(traps[n].left.p1.x + pixman_fixed_1_minus_e/2); int lx2 = pixman_fixed_to_int(traps[n].left.p2.x + pixman_fixed_1_minus_e/2); int rx1 = pixman_fixed_to_int(traps[n].right.p1.x + pixman_fixed_1_minus_e/2); int rx2 = pixman_fixed_to_int(traps[n].right.p2.x + pixman_fixed_1_minus_e/2); rectilinear &= lx1 == lx2 && rx1 == rx2; } } else if (dst->polyMode != PolyModePrecise) { for (n = 0; n < ntrap && rectilinear; n++) { int lx1 = pixman_fixed_to_fast(traps[n].left.p1.x); int lx2 = pixman_fixed_to_fast(traps[n].left.p2.x); int rx1 = pixman_fixed_to_fast(traps[n].right.p1.x); int rx2 = pixman_fixed_to_fast(traps[n].right.p2.x); int top = pixman_fixed_to_fast(traps[n].top); int bot = pixman_fixed_to_fast(traps[n].bottom); rectilinear &= lx1 == lx2 && rx1 == rx2; pixel_aligned &= ((top | bot | lx1 | lx2 | rx1 | rx2) & FAST_SAMPLES_mask) == 0; } } else { for (n = 0; n < ntrap && rectilinear; n++) { rectilinear &= traps[n].left.p1.x == traps[n].left.p2.x && traps[n].right.p1.x == traps[n].right.p2.x; pixel_aligned &= ((traps[n].top | traps[n].bottom | traps[n].left.p1.x | traps[n].left.p2.x | traps[n].right.p1.x | traps[n].right.p2.x) & pixman_fixed_1_minus_e) == 0; } } DBG(("%s: rectilinear? %d, pixel-aligned? %d, mono? %d precise? %d\n", __FUNCTION__, rectilinear, pixel_aligned, is_mono(dst, maskFormat), is_precise(dst, maskFormat))); flags = 0; if (rectilinear) { if (pixel_aligned) { if (composite_aligned_boxes(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps, force_fallback)) return; } else { if (composite_unaligned_boxes(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps, force_fallback)) return; } flags |= COMPOSITE_SPANS_RECTILINEAR; } if (force_fallback) goto fallback; if (is_mono(dst, maskFormat) && mono_trapezoids_span_converter(sna, op, src, dst, xSrc, ySrc, ntrap, traps)) return; if (trapezoid_spans_maybe_inplace(sna, op, src, dst, maskFormat)) { flags |= COMPOSITE_SPANS_INPLACE_HINT; if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps, false)) return; } if (trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps)) return; if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps, false)) return; if (trapezoid_mask_converter(op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps)) return; fallback: if (trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps, true)) return; if (trapezoid_span_fallback(op, src, dst, maskFormat, flags, xSrc, ySrc, ntrap, traps)) return; if (trapezoids_inplace_fallback(sna, op, src, dst, maskFormat, ntrap, traps)) return; DBG(("%s: fallback mask=%08x, ntrap=%d\n", __FUNCTION__, maskFormat ? (unsigned)maskFormat->format : 0, ntrap)); trapezoids_fallback(sna, op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps); } static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv, BoxPtr box, int16_t x, int16_t y) { box->x1 += x; box->x2 += x; box->y1 += y; box->y2 += y; if (box->x1 <= 0 && box->y1 <= 0 && box->x2 >= pixmap->drawable.width && box->y2 >= pixmap->drawable.height) { sna_damage_destroy(&priv->cpu_damage); sna_damage_all(&priv->gpu_damage, pixmap); list_del(&priv->flush_list); } else { sna_damage_add_box(&priv->gpu_damage, box); sna_damage_subtract_box(&priv->cpu_damage, box); } } static bool trap_upload(PicturePtr picture, INT16 x, INT16 y, int ntrap, xTrap *trap) { ScreenPtr screen = picture->pDrawable->pScreen; struct sna *sna = to_sna_from_screen(screen); PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); PixmapPtr scratch; struct sna_pixmap *priv; BoxRec extents; pixman_image_t *image; int width, height, depth; int n; priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE); if (priv == NULL) return false; extents = *RegionExtents(picture->pCompositeClip); for (n = 0; n < ntrap; n++) { int v; v = x + pixman_fixed_integer_floor (MIN(trap[n].top.l, trap[n].bot.l)); if (v < extents.x1) extents.x1 = v; v = x + pixman_fixed_integer_ceil (MAX(trap[n].top.r, trap[n].bot.r)); if (v > extents.x2) extents.x2 = v; v = y + pixman_fixed_integer_floor (trap[n].top.y); if (v < extents.y1) extents.y1 = v; v = y + pixman_fixed_integer_ceil (trap[n].bot.y); if (v > extents.y2) extents.y2 = v; } DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); width = extents.x2 - extents.x1; height = extents.y2 - extents.y1; depth = picture->pDrawable->depth; DBG(("%s: tmp (%dx%d) depth=%d\n", __FUNCTION__, width, height, depth)); scratch = sna_pixmap_create_upload(screen, width, height, depth, KGEM_BUFFER_WRITE); if (!scratch) return true; memset(scratch->devPrivate.ptr, 0, scratch->devKind*height); image = pixman_image_create_bits((pixman_format_code_t)picture->format, width, height, scratch->devPrivate.ptr, scratch->devKind); if (image) { pixman_add_traps (image, -extents.x1, -extents.y1, ntrap, (pixman_trap_t *)trap); pixman_image_unref(image); } /* XXX clip boxes */ get_drawable_deltas(picture->pDrawable, pixmap, &x, &y); sna->render.copy_boxes(sna, GXcopy, &scratch->drawable, __sna_pixmap_get_bo(scratch), -extents.x1, -extents.x1, &pixmap->drawable, priv->gpu_bo, x, y, &extents, 1, 0); mark_damaged(pixmap, priv, &extents, x, y); sna_pixmap_destroy(scratch); return true; } void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t) { PixmapPtr pixmap = get_drawable_pixmap(picture->pDrawable); struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); DBG(("%s (%d, %d) x %d\n", __FUNCTION__, x, y, n)); if (priv && is_gpu_dst(priv)) { if (trap_span_converter(sna, picture, x, y, n, t)) return; } if (is_gpu(sna, picture->pDrawable, PREFER_GPU_RENDER)) { if (trap_mask_converter(sna, picture, x, y, n, t)) return; if (trap_upload(picture, x, y, n, t)) return; } DBG(("%s -- fallback\n", __FUNCTION__)); if (sna_pixmap_move_to_cpu(pixmap, MOVE_READ | MOVE_WRITE)) { pixman_image_t *image; int dx, dy; if (!(image = image_from_pict(picture, false, &dx, &dy))) return; if (sigtrap_get() == 0) { pixman_add_traps(image, x + dx, y + dy, n, (pixman_trap_t *)t); sigtrap_put(); } free_pixman_pict(picture, image); } } #if HAS_PIXMAN_TRIANGLES static void triangles_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xTriangle *tri) { ScreenPtr screen = dst->pDrawable->pScreen; DBG(("%s op=%d, count=%d\n", __FUNCTION__, op, n)); if (maskFormat) { PixmapPtr scratch; PicturePtr mask; INT16 dst_x, dst_y; BoxRec bounds; int width, height, depth; pixman_image_t *image; pixman_format_code_t format; int error; dst_x = pixman_fixed_to_int(tri[0].p1.x); dst_y = pixman_fixed_to_int(tri[0].p1.y); miTriangleBounds(n, tri, &bounds); DBG(("%s: bounds (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; if (!sna_compute_composite_extents(&bounds, src, NULL, dst, xSrc, ySrc, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1)) return; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; bounds.x1 -= dst->pDrawable->x; bounds.y1 -= dst->pDrawable->y; depth = maskFormat->depth; format = maskFormat->format | (BitsPerPixel(depth) << 24); DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n", __FUNCTION__, width, height, depth, format)); scratch = sna_pixmap_create_upload(screen, width, height, depth, KGEM_BUFFER_WRITE); if (!scratch) return; memset(scratch->devPrivate.ptr, 0, (size_t)scratch->devKind*height); image = pixman_image_create_bits(format, width, height, scratch->devPrivate.ptr, scratch->devKind); if (image) { pixman_add_triangles(image, -bounds.x1, -bounds.y1, n, (pixman_triangle_t *)tri); pixman_image_unref(image); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, depth, format), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, xSrc + bounds.x1 - dst_x, ySrc + bounds.y1 - dst_y, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); } else { if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; n--; tri++) triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, 1, tri); } } void sna_composite_triangles(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xTriangle *tri) { struct sna *sna = to_sna_from_drawable(dst->pDrawable); if (triangles_span_converter(sna, op, src, dst, maskFormat, xSrc, ySrc, n, tri)) return; if (triangles_mask_converter(op, src, dst, maskFormat, xSrc, ySrc, n, tri)) return; triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, n, tri); } static void tristrip_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xPointFixed *points) { ScreenPtr screen = dst->pDrawable->pScreen; if (maskFormat) { PixmapPtr scratch; PicturePtr mask; INT16 dst_x, dst_y; BoxRec bounds; int width, height, depth; pixman_image_t *image; pixman_format_code_t format; int error; dst_x = pixman_fixed_to_int(points->x); dst_y = pixman_fixed_to_int(points->y); miPointFixedBounds(n, points, &bounds); DBG(("%s: bounds (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; if (!sna_compute_composite_extents(&bounds, src, NULL, dst, xSrc, ySrc, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1)) return; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; bounds.x1 -= dst->pDrawable->x; bounds.y1 -= dst->pDrawable->y; depth = maskFormat->depth; format = maskFormat->format | (BitsPerPixel(depth) << 24); DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n", __FUNCTION__, width, height, depth, format)); scratch = sna_pixmap_create_upload(screen, width, height, depth, KGEM_BUFFER_WRITE); if (!scratch) return; memset(scratch->devPrivate.ptr, 0, scratch->devKind*height); image = pixman_image_create_bits(format, width, height, scratch->devPrivate.ptr, scratch->devKind); if (image) { xTriangle tri; xPointFixed *p[3] = { &tri.p1, &tri.p2, &tri.p3 }; int i; *p[0] = points[0]; *p[1] = points[1]; *p[2] = points[2]; pixman_add_triangles(image, -bounds.x1, -bounds.y1, 1, (pixman_triangle_t *)&tri); for (i = 3; i < n; i++) { *p[i%3] = points[i]; pixman_add_triangles(image, -bounds.x1, -bounds.y1, 1, (pixman_triangle_t *)&tri); } pixman_image_unref(image); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, depth, format), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, xSrc + bounds.x1 - dst_x, ySrc + bounds.y1 - dst_y, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); } else { xTriangle tri; xPointFixed *p[3] = { &tri.p1, &tri.p2, &tri.p3 }; int i; if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); *p[0] = points[0]; *p[1] = points[1]; *p[2] = points[2]; triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, 1, &tri); for (i = 3; i < n; i++) { *p[i%3] = points[i]; /* Should xSrc,ySrc be updated? */ triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, 1, &tri); } } } void sna_composite_tristrip(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xPointFixed *points) { struct sna *sna = to_sna_from_drawable(dst->pDrawable); if (tristrip_span_converter(sna, op, src, dst, maskFormat, xSrc, ySrc, n, points)) return; tristrip_fallback(op, src, dst, maskFormat, xSrc, ySrc, n, points); } static void trifan_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xPointFixed *points) { ScreenPtr screen = dst->pDrawable->pScreen; if (maskFormat) { PixmapPtr scratch; PicturePtr mask; INT16 dst_x, dst_y; BoxRec bounds; int width, height, depth; pixman_image_t *image; pixman_format_code_t format; int error; dst_x = pixman_fixed_to_int(points->x); dst_y = pixman_fixed_to_int(points->y); miPointFixedBounds(n, points, &bounds); DBG(("%s: bounds (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; if (!sna_compute_composite_extents(&bounds, src, NULL, dst, xSrc, ySrc, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1)) return; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, bounds.x1, bounds.y1, bounds.x2, bounds.y2)); width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; bounds.x1 -= dst->pDrawable->x; bounds.y1 -= dst->pDrawable->y; depth = maskFormat->depth; format = maskFormat->format | (BitsPerPixel(depth) << 24); DBG(("%s: mask (%dx%d) depth=%d, format=%08x\n", __FUNCTION__, width, height, depth, format)); scratch = sna_pixmap_create_upload(screen, width, height, depth, KGEM_BUFFER_WRITE); if (!scratch) return; memset(scratch->devPrivate.ptr, 0, scratch->devKind*height); image = pixman_image_create_bits(format, width, height, scratch->devPrivate.ptr, scratch->devKind); if (image) { xTriangle tri; xPointFixed *p[3] = { &tri.p1, &tri.p2, &tri.p3 }; int i; *p[0] = points[0]; *p[1] = points[1]; *p[2] = points[2]; pixman_add_triangles(image, -bounds.x1, -bounds.y1, 1, (pixman_triangle_t *)&tri); for (i = 3; i < n; i++) { *p[2 - (i&1)] = points[i]; pixman_add_triangles(image, -bounds.x1, -bounds.y1, 1, (pixman_triangle_t *)&tri); } pixman_image_unref(image); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, depth, format), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, xSrc + bounds.x1 - dst_x, ySrc + bounds.y1 - dst_y, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); } else { xTriangle tri; xPointFixed *p[3] = { &tri.p1, &tri.p2, &tri.p3 }; int i; if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); *p[0] = points[0]; *p[1] = points[1]; *p[2] = points[2]; triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, 1, &tri); for (i = 3; i < n; i++) { *p[2 - (i&1)] = points[i]; /* Should xSrc,ySrc be updated? */ triangles_fallback(op, src, dst, maskFormat, xSrc, ySrc, 1, &tri); } } } void sna_composite_trifan(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int n, xPointFixed *points) { trifan_fallback(op, src, dst, maskFormat, xSrc, ySrc, n, points); } #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids.h000066400000000000000000000254561267532330400250550ustar00rootroot00000000000000#include #ifndef SNA_TRAPEZOIDS_H #define SNA_TRAPEZOIDS_H #define NO_ACCEL 0 #define FORCE_FALLBACK 0 #define NO_ALIGNED_BOXES 0 #define NO_UNALIGNED_BOXES 0 #define NO_SCAN_CONVERTER 0 #define NO_GPU_THREADS 0 #define NO_IMPRECISE 0 #define NO_PRECISE 0 #if 0 #define __DBG DBG #else #define __DBG(x) #endif bool composite_aligned_boxes(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int ntrap, const xTrapezoid *traps, bool force_fallback); bool composite_unaligned_boxes(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int ntrap, const xTrapezoid *traps, bool force_fallback); bool mono_trapezoids_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool mono_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool mono_triangles_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int count, xTriangle *tri); bool imprecise_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback); bool imprecise_trapezoid_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool imprecise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool imprecise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool precise_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback); bool precise_trapezoid_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); bool precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps); static inline bool is_mono(PicturePtr dst, PictFormatPtr mask) { return mask ? mask->depth < 8 : dst->polyEdge==PolyEdgeSharp; } static inline bool is_precise(PicturePtr dst, PictFormatPtr mask) { return dst->polyMode == PolyModePrecise && !is_mono(dst, mask); } static inline bool trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback) { if (NO_SCAN_CONVERTER) return false; if (dst->alphaMap) { DBG(("%s: fallback -- dst alphamap\n", __FUNCTION__)); return false; } if (!fallback && is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback -- can not perform operation in place, destination busy\n", __FUNCTION__)); return false; } if (is_mono(dst, maskFormat)) return mono_trapezoid_span_inplace(sna, op, src, dst, src_x, src_y, ntrap, traps); else if (is_precise(dst, maskFormat)) return precise_trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps, fallback); else return imprecise_trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps, fallback); } static inline bool trapezoid_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { if (NO_SCAN_CONVERTER) return false; if (is_mono(dst, maskFormat)) return mono_trapezoids_span_converter(sna, op, src, dst, src_x, src_y, ntrap, traps); else if (is_precise(dst, maskFormat)) return precise_trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); else return imprecise_trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); } static inline bool trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { if (NO_SCAN_CONVERTER) return false; if (is_precise(dst, maskFormat)) return precise_trapezoid_mask_converter(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); else return imprecise_trapezoid_mask_converter(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); } static inline bool trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { if (NO_SCAN_CONVERTER) return false; if (is_precise(dst, maskFormat)) return precise_trapezoid_span_fallback(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); else return imprecise_trapezoid_span_fallback(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); } bool mono_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 x, INT16 y, int ntrap, xTrap *traps); bool precise_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap); bool imprecise_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap); static inline bool trap_span_converter(struct sna *sna, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap) { if (NO_SCAN_CONVERTER) return false; if (dst->polyEdge == PolyEdgeSharp || dst->pDrawable->depth < 8) return mono_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); else if (dst->polyMode == PolyModePrecise) return precise_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); else return imprecise_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); } bool trap_mask_converter(struct sna *sna, PicturePtr picture, INT16 x, INT16 y, int ntrap, xTrap *trap); bool triangles_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xTriangle *tri); bool triangles_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xTriangle *tri); bool mono_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int count, xPointFixed *points); bool imprecise_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points); bool precise_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points); static inline bool tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points) { if (NO_SCAN_CONVERTER) return false; if (is_mono(dst, maskFormat)) return mono_tristrip_span_converter(sna, op, src, dst, src_x, src_y, count, points); else if (is_precise(dst, maskFormat)) return precise_tristrip_span_converter(sna, op, src, dst, maskFormat, src_x, src_y, count, points); else return imprecise_tristrip_span_converter(sna, op, src, dst, maskFormat, src_x, src_y, count, points); } inline static void trapezoid_origin(const xLineFixed *l, int16_t *x, int16_t *y) { if (l->p1.y < l->p2.y) { *x = pixman_fixed_to_int(l->p1.x); *y = pixman_fixed_to_int(l->p1.y); } else { *x = pixman_fixed_to_int(l->p2.x); *y = pixman_fixed_to_int(l->p2.y); } } #define ONE_HALF 0x7f #define RB_MASK 0x00ff00ff #define RB_ONE_HALF 0x007f007f #define RB_MASK_PLUS_ONE 0x01000100 #define G_SHIFT 8 static force_inline uint32_t mul8x2_8 (uint32_t a, uint8_t b) { uint32_t t = (a & RB_MASK) * b + RB_ONE_HALF; return ((t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT) & RB_MASK; } static force_inline uint32_t add8x2_8x2(uint32_t a, uint32_t b) { uint32_t t = a + b; t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); return t & RB_MASK; } static force_inline uint32_t lerp8x4(uint32_t src, uint8_t a, uint32_t dst) { return (add8x2_8x2(mul8x2_8(src, a), mul8x2_8(dst, ~a)) | add8x2_8x2(mul8x2_8(src >> G_SHIFT, a), mul8x2_8(dst >> G_SHIFT, ~a)) << G_SHIFT); } static force_inline uint8_t mul_8_8(uint8_t a, uint8_t b) { uint16_t t = a * (uint16_t)b + 0x7f; return ((t >> 8) + t) >> 8; } static inline uint32_t multa(uint32_t s, uint8_t a, int shift) { return mul_8_8((s >> shift) & 0xff, a) << shift; } static inline uint32_t mul_4x8_8(uint32_t color, uint8_t alpha) { uint32_t v; v = 0; v |= multa(color, alpha, 24); v |= multa(color, alpha, 16); v |= multa(color, alpha, 8); v |= multa(color, alpha, 0); return v; } static inline bool xTriangleValid(const xTriangle *t) { xPointFixed v1, v2; v1.x = t->p2.x - t->p1.x; v1.y = t->p2.y - t->p1.y; v2.x = t->p3.x - t->p1.x; v2.y = t->p3.y - t->p1.y; /* if the length of any edge is zero, the area must be zero */ if (v1.x == 0 && v1.y == 0) return false; if (v2.x == 0 && v2.y == 0) return false; /* if the cross-product is zero, so it the size */ return v2.y * v1.x != v1.y * v2.x; } #define SAMPLES_X 17 #define SAMPLES_Y 15 #define FAST_SAMPLES_shift 2 #define FAST_SAMPLES_X (1<> (16 - FAST_SAMPLES_shift); } bool trapezoids_bounds(int n, const xTrapezoid *t, BoxPtr box); #define TOR_INPLACE_SIZE 128 #endif /* SNA_TRAPEZOIDS_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids_boxes.c000066400000000000000000001147461267532330400262510ustar00rootroot00000000000000/* * Copyright (c) 2007 David Turner * Copyright (c) 2008 M Joonas Pihlaja * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_trapezoids.h" #include "fb/fbpict.h" #include /* TODO: Emit unantialiased and MSAA triangles. */ #ifndef MAX #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif #ifndef MIN #define MIN(x,y) ((x) <= (y) ? (x) : (y)) #endif #define region_count(r) ((r)->data ? (r)->data->numRects : 1) #define region_boxes(r) ((r)->data ? (BoxPtr)((r)->data + 1) : &(r)->extents) #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif static void apply_damage(struct sna_composite_op *op, RegionPtr region) { DBG(("%s: damage=%p, region=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, op->damage, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (op->damage == NULL) return; RegionTranslate(region, op->dst.x, op->dst.y); assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region)); if (sna_damage_add_to_pixmap(op->damage, region, op->dst.pixmap)) op->damage = NULL; } static void _apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { BoxRec r; r.x1 = box->x1 + op->dst.x; r.x2 = box->x2 + op->dst.x; r.y1 = box->y1 + op->dst.y; r.y2 = box->y2 + op->dst.y; assert_pixmap_contains_box(op->dst.pixmap, &r); sna_damage_add_box(op->damage, &r); } inline static void apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { if (op->damage) _apply_damage_box(op, box); } bool composite_aligned_boxes(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int ntrap, const xTrapezoid *traps, bool force_fallback) { BoxRec stack_boxes[64], *boxes; pixman_region16_t region, clip; struct sna_composite_op tmp; int16_t dst_x, dst_y; bool ret = true; int dx, dy, n, num_boxes; if (NO_ALIGNED_BOXES) return false; DBG(("%s: pixmap=%ld, nboxes=%d, dx=(%d, %d)\n", __FUNCTION__, get_drawable_pixmap(dst->pDrawable)->drawable.serialNumber, ntrap, dst->pDrawable->x, dst->pDrawable->y)); boxes = stack_boxes; if (ntrap > (int)ARRAY_SIZE(stack_boxes)) { boxes = malloc(sizeof(BoxRec)*ntrap); if (boxes == NULL) return false; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; region.extents.x1 = region.extents.y1 = 32767; region.extents.x2 = region.extents.y2 = -32767; num_boxes = 0; for (n = 0; n < ntrap; n++) { boxes[num_boxes].x1 = dx + pixman_fixed_to_int(traps[n].left.p1.x + pixman_fixed_1_minus_e/2); boxes[num_boxes].y1 = dy + pixman_fixed_to_int(traps[n].top + pixman_fixed_1_minus_e/2); boxes[num_boxes].x2 = dx + pixman_fixed_to_int(traps[n].right.p2.x + pixman_fixed_1_minus_e/2); boxes[num_boxes].y2 = dy + pixman_fixed_to_int(traps[n].bottom + pixman_fixed_1_minus_e/2); if (boxes[num_boxes].x1 >= boxes[num_boxes].x2) continue; if (boxes[num_boxes].y1 >= boxes[num_boxes].y2) continue; if (boxes[num_boxes].x1 < region.extents.x1) region.extents.x1 = boxes[num_boxes].x1; if (boxes[num_boxes].x2 > region.extents.x2) region.extents.x2 = boxes[num_boxes].x2; if (boxes[num_boxes].y1 < region.extents.y1) region.extents.y1 = boxes[num_boxes].y1; if (boxes[num_boxes].y2 > region.extents.y2) region.extents.y2 = boxes[num_boxes].y2; num_boxes++; } if (num_boxes == 0) goto free_boxes; trapezoid_origin(&traps[0].left, &dst_x, &dst_y); DBG(("%s: extents (%d, %d), (%d, %d) offset of (%d, %d), origin (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, region.extents.x1 - boxes[0].x1, region.extents.y1 - boxes[0].y1, dst_x, dst_y)); if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + region.extents.x1 - dst_x - dx, src_y + region.extents.y1 - dst_y - dy, 0, 0, region.extents.x1 - dx, region.extents.y1 - dy, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; goto done; } if (op == PictOpClear && sna->clear) src = sna->clear; DBG(("%s: clipped extents (%d, %d), (%d, %d); now offset by (%d, %d), origin (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, clip.extents.x1 - boxes[0].x1, clip.extents.y1 - boxes[0].y1, dst_x, dst_y)); if (force_fallback || !sna->render.composite(sna, op, src, NULL, dst, src_x + clip.extents.x1 - dst_x, src_y + clip.extents.y1 - dst_y, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, (clip.data || num_boxes > 1) ? COMPOSITE_PARTIAL : 0, memset(&tmp, 0, sizeof(tmp)))) { unsigned int flags; const pixman_box16_t *b; int i, count; DBG(("%s: composite render op not supported\n", __FUNCTION__)); flags = MOVE_READ | MOVE_WRITE; if (op <= PictOpSrc) { flags |= MOVE_INPLACE_HINT; if (n == 1) flags &= ~MOVE_READ; } if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &clip, flags)) goto done; if (dst->alphaMap && !sna_drawable_move_to_cpu(dst->alphaMap->pDrawable, MOVE_READ | MOVE_WRITE)) goto done; if (src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) goto done; if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) goto done; } DBG(("%s: fbComposite()\n", __FUNCTION__)); src_x -= dst_x - dx; src_y -= dst_y - dy; if (maskFormat) { pixman_region_init_rects(®ion, boxes, num_boxes); RegionIntersect(®ion, ®ion, &clip); if (sigtrap_get() == 0) { b = region_rects(®ion); count = region_num_rects(®ion); for (i = 0; i < count; i++) { fbComposite(op, src, NULL, dst, src_x + b[i].x1, src_y + b[i].y1, 0, 0, b[i].x1, b[i].y1, b[i].x2 - b[i].x1, b[i].y2 - b[i].y1); } sigtrap_put(); } pixman_region_fini(®ion); } else { for (n = 0; n < num_boxes; n++) { pixman_region_init_rects(®ion, &boxes[n], 1); RegionIntersect(®ion, ®ion, &clip); b = region_rects(®ion); count = region_num_rects(®ion); if (sigtrap_get() == 0) { for (i = 0; i < count; i++) { fbComposite(op, src, NULL, dst, src_x + b[i].x1, src_y + b[i].y1, 0, 0, b[i].x1, b[i].y1, b[i].x2 - b[i].x1, b[i].y2 - b[i].y1); } sigtrap_put(); } pixman_region_fini(®ion); pixman_region_fini(®ion); } } ret = true; goto done; } if (maskFormat || (op == PictOpSrc || op == PictOpClear) || num_boxes == 1) { pixman_region_init_rects(®ion, boxes, num_boxes); RegionIntersect(®ion, ®ion, &clip); if (region_num_rects(®ion)) { tmp.boxes(sna, &tmp, region_rects(®ion), region_num_rects(®ion)); apply_damage(&tmp, ®ion); } pixman_region_fini(®ion); } else { for (n = 0; n < num_boxes; n++) { pixman_region_init_rects(®ion, &boxes[n], 1); RegionIntersect(®ion, ®ion, &clip); if (region_num_rects(®ion)) { tmp.boxes(sna, &tmp, region_rects(®ion), region_num_rects(®ion)); apply_damage(&tmp, ®ion); } pixman_region_fini(®ion); } } tmp.done(sna, &tmp); done: REGION_UNINIT(NULL, &clip); free_boxes: if (boxes != stack_boxes) free(boxes); return ret; } static inline int grid_coverage(int samples, pixman_fixed_t f) { return (samples * pixman_fixed_frac(f) + pixman_fixed_1/2) / pixman_fixed_1; } inline static void composite_unaligned_box(struct sna *sna, struct sna_composite_spans_op *tmp, const BoxRec *box, float opacity, pixman_region16_t *clip) { assert(opacity != 0.); if (clip) { pixman_region16_t region; pixman_region_init_rects(®ion, box, 1); RegionIntersect(®ion, ®ion, clip); if (region_num_rects(®ion)) tmp->boxes(sna, tmp, region_rects(®ion), region_num_rects(®ion), opacity); pixman_region_fini(®ion); } else tmp->box(sna, tmp, box, opacity); } inline static void composite_unaligned_trap_row(struct sna *sna, struct sna_composite_spans_op *tmp, const xTrapezoid *trap, int dx, int y1, int y2, int covered, pixman_region16_t *clip) { BoxRec box; int opacity; int x1, x2; #define u8_to_float(x) ((x) * (1.f/255)) if (covered == 0) return; x1 = dx + pixman_fixed_to_int(trap->left.p1.x); x2 = dx + pixman_fixed_to_int(trap->right.p1.x); if (clip) { if (y2 > clip->extents.y2) y2 = clip->extents.y2; if (y1 < clip->extents.y1) y1 = clip->extents.y1; if (y1 >= y2) return; if (x2 < clip->extents.x1 || x1 > clip->extents.x2) return; } box.y1 = y1; box.y2 = y2; if (x1 == x2) { box.x1 = x1; box.x2 = x2 + 1; opacity = covered; opacity *= grid_coverage(SAMPLES_X, trap->right.p1.x) - grid_coverage(SAMPLES_X, trap->left.p1.x); if (opacity) composite_unaligned_box(sna, tmp, &box, u8_to_float(opacity), clip); } else { if (pixman_fixed_frac(trap->left.p1.x)) { box.x1 = x1; box.x2 = ++x1; opacity = covered; opacity *= SAMPLES_X - grid_coverage(SAMPLES_X, trap->left.p1.x); if (opacity) composite_unaligned_box(sna, tmp, &box, u8_to_float(opacity), clip); } if (x2 > x1) { box.x1 = x1; box.x2 = x2; composite_unaligned_box(sna, tmp, &box, covered == SAMPLES_Y ? 1. : u8_to_float(covered*SAMPLES_X), clip); } if (pixman_fixed_frac(trap->right.p1.x)) { box.x1 = x2; box.x2 = x2 + 1; opacity = covered; opacity *= grid_coverage(SAMPLES_X, trap->right.p1.x); if (opacity) composite_unaligned_box(sna, tmp, &box, u8_to_float(opacity), clip); } } } flatten static void composite_unaligned_trap(struct sna *sna, struct sna_composite_spans_op *tmp, const xTrapezoid *trap, int dx, int dy, pixman_region16_t *clip) { int y1, y2; y1 = dy + pixman_fixed_to_int(trap->top); y2 = dy + pixman_fixed_to_int(trap->bottom); DBG(("%s: y1=%d, y2=%d\n", __FUNCTION__, y1, y2)); if (y1 == y2) { composite_unaligned_trap_row(sna, tmp, trap, dx, y1, y1 + 1, grid_coverage(SAMPLES_Y, trap->bottom) - grid_coverage(SAMPLES_Y, trap->top), clip); } else { if (pixman_fixed_frac(trap->top)) { composite_unaligned_trap_row(sna, tmp, trap, dx, y1, y1 + 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, trap->top), clip); y1++; } if (y2 > y1) composite_unaligned_trap_row(sna, tmp, trap, dx, y1, y2, SAMPLES_Y, clip); if (pixman_fixed_frac(trap->bottom)) composite_unaligned_trap_row(sna, tmp, trap, dx, y2, y2 + 1, grid_coverage(SAMPLES_Y, trap->bottom), clip); } if (tmp->base.damage) { BoxRec box; box.x1 = dx + pixman_fixed_to_int(trap->left.p1.x); box.x2 = dx + pixman_fixed_to_int(trap->right.p1.x + pixman_fixed_1_minus_e); box.y1 = dy + pixman_fixed_to_int(trap->top); box.y2 = dy + pixman_fixed_to_int(trap->bottom + pixman_fixed_1_minus_e); if (clip) { pixman_region16_t region; pixman_region_init_rects(®ion, &box, 1); RegionIntersect(®ion, ®ion, clip); if (region_num_rects(®ion)) apply_damage(&tmp->base, ®ion); RegionUninit(®ion); } else apply_damage_box(&tmp->base, &box); } } inline static void blt_opacity(PixmapPtr scratch, int x1, int x2, int y, int h, uint8_t opacity) { uint8_t *ptr; if (opacity == 0xff) return; if (x1 < 0) x1 = 0; if (x2 > scratch->drawable.width) x2 = scratch->drawable.width; if (x1 >= x2) return; x2 -= x1; ptr = scratch->devPrivate.ptr; ptr += scratch->devKind * y; ptr += x1; do { if (x2 == 1) *ptr = opacity; else memset(ptr, opacity, x2); ptr += scratch->devKind; } while (--h); } static void blt_unaligned_box_row(PixmapPtr scratch, BoxPtr extents, const xTrapezoid *trap, int y1, int y2, int covered) { int x1, x2; if (y2 > scratch->drawable.height) y2 = scratch->drawable.height; if (y1 < 0) y1 = 0; if (y1 >= y2) return; y2 -= y1; x1 = pixman_fixed_to_int(trap->left.p1.x); x2 = pixman_fixed_to_int(trap->right.p1.x); x1 -= extents->x1; x2 -= extents->x1; if (x1 == x2) { blt_opacity(scratch, x1, x1+1, y1, y2, covered * (grid_coverage(SAMPLES_X, trap->right.p1.x) - grid_coverage(SAMPLES_X, trap->left.p1.x))); } else { if (pixman_fixed_frac(trap->left.p1.x)) { blt_opacity(scratch, x1, x1 + 1, y1, y2, covered * (SAMPLES_X - grid_coverage(SAMPLES_X, trap->left.p1.x))); x1++; } if (x2 > x1) { blt_opacity(scratch, x1, x2, y1, y2, covered*SAMPLES_X); } if (pixman_fixed_frac(trap->right.p1.x)) blt_opacity(scratch, x2, x2 + 1, y1, y2, covered * grid_coverage(SAMPLES_X, trap->right.p1.x)); } } inline static void lerp32_opacity(PixmapPtr scratch, uint32_t color, int16_t x, int16_t w, int16_t y, int16_t h, uint8_t opacity) { uint32_t *ptr; int stride, i; sigtrap_assert_active(); ptr = (uint32_t*)((uint8_t *)scratch->devPrivate.ptr + scratch->devKind * y); ptr += x; stride = scratch->devKind / 4; if (opacity == 0xff) { if ((w | h) == 1) { *ptr = color; } else { if (w < 16) { do { for (i = 0; i < w; i++) ptr[i] = color; ptr += stride; } while (--h); } else { pixman_fill(ptr, stride, 32, 0, 0, w, h, color); } } } else { if ((w | h) == 1) { *ptr = lerp8x4(color, opacity, *ptr); } else if (w == 1) { do { *ptr = lerp8x4(color, opacity, *ptr); ptr += stride; } while (--h); } else{ do { for (i = 0; i < w; i++) ptr[i] = lerp8x4(color, opacity, ptr[i]); ptr += stride; } while (--h); } } } static void lerp32_unaligned_box_row(PixmapPtr scratch, uint32_t color, const BoxRec *extents, const xTrapezoid *trap, int16_t dx, int16_t y, int16_t h, uint8_t covered) { int16_t x1 = pixman_fixed_to_int(trap->left.p1.x) + dx; uint16_t fx1 = grid_coverage(SAMPLES_X, trap->left.p1.x); int16_t x2 = pixman_fixed_to_int(trap->right.p2.x) + dx; uint16_t fx2 = grid_coverage(SAMPLES_X, trap->right.p2.x); if (x1 < extents->x1) x1 = extents->x1, fx1 = 0; if (x2 >= extents->x2) x2 = extents->x2, fx2 = 0; DBG(("%s: x=(%d.%d, %d.%d), y=%dx%d, covered=%d\n", __FUNCTION__, x1, fx1, x2, fx2, y, h, covered)); if (x1 < x2) { if (fx1) { lerp32_opacity(scratch, color, x1, 1, y, h, covered * (SAMPLES_X - fx1)); x1++; } if (x2 > x1) { lerp32_opacity(scratch, color, x1, x2-x1, y, h, covered*SAMPLES_X); } if (fx2) { lerp32_opacity(scratch, color, x2, 1, y, h, covered * fx2); } } else if (x1 == x2 && fx2 > fx1) { lerp32_opacity(scratch, color, x1, 1, y, h, covered * (fx2 - fx1)); } } struct pixman_inplace { pixman_image_t *image, *source, *mask; uint32_t color; uint32_t *bits; int dx, dy; int sx, sy; uint8_t op; }; inline static void pixsolid_opacity(struct pixman_inplace *pi, int16_t x, int16_t w, int16_t y, int16_t h, uint8_t opacity) { if (opacity == 0xff) *pi->bits = pi->color; else *pi->bits = mul_4x8_8(pi->color, opacity); sna_image_composite(pi->op, pi->source, NULL, pi->image, 0, 0, 0, 0, pi->dx + x, pi->dy + y, w, h); } static void pixsolid_unaligned_box_row(struct pixman_inplace *pi, const BoxRec *extents, const xTrapezoid *trap, int16_t y, int16_t h, uint8_t covered) { int16_t x1 = pixman_fixed_to_int(trap->left.p1.x); uint16_t fx1 = grid_coverage(SAMPLES_X, trap->left.p1.x); int16_t x2 = pixman_fixed_to_int(trap->right.p1.x); uint16_t fx2 = grid_coverage(SAMPLES_X, trap->right.p1.x); if (x1 < extents->x1) x1 = extents->x1, fx1 = 0; if (x2 >= extents->x2) x2 = extents->x2, fx2 = 0; if (x1 < x2) { if (fx1) { pixsolid_opacity(pi, x1, 1, y, h, covered * (SAMPLES_X - fx1)); x1++; } if (x2 > x1) pixsolid_opacity(pi, x1, x2-x1, y, h, covered*SAMPLES_X); if (fx2) pixsolid_opacity(pi, x2, 1, y, h, covered * fx2); } else if (x1 == x2 && fx2 > fx1) { pixsolid_opacity(pi, x1, 1, y, h, covered * (fx2 - fx1)); } } static bool composite_unaligned_boxes_inplace__solid(struct sna *sna, CARD8 op, uint32_t color, PicturePtr dst, int n, const xTrapezoid *t, bool force_fallback) { PixmapPtr pixmap; int16_t dx, dy; DBG(("%s: force=%d, is_gpu=%d, op=%d, color=%x\n", __FUNCTION__, force_fallback, is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS), op, color)); if (!force_fallback && is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { DBG(("%s: fallback -- can not perform operation in place, destination busy\n", __FUNCTION__)); return false; } /* XXX a8 boxes */ if (!(dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8)) { DBG(("%s: fallback -- can not perform operation in place, unhanbled format %08lx\n", __FUNCTION__, (long)dst->format)); goto pixman; } pixmap = get_drawable_pixmap(dst->pDrawable); get_drawable_deltas(dst->pDrawable, pixmap, &dx, &dy); if (op == PictOpOver && (color >> 24) == 0xff) op = PictOpSrc; if (op == PictOpOver || op == PictOpAdd) { struct sna_pixmap *priv = sna_pixmap(pixmap); if (priv && priv->clear && priv->clear_color == 0) op = PictOpSrc; } switch (op) { case PictOpSrc: break; default: DBG(("%s: fallback -- can not perform op [%d] in place\n", __FUNCTION__, op)); goto pixman; } DBG(("%s: inplace operation on argb32 destination x %d\n", __FUNCTION__, n)); do { RegionRec clip; const BoxRec *extents; int count; clip.extents.x1 = pixman_fixed_to_int(t->left.p1.x); clip.extents.x2 = pixman_fixed_to_int(t->right.p1.x + pixman_fixed_1_minus_e); clip.extents.y1 = pixman_fixed_to_int(t->top); clip.extents.y2 = pixman_fixed_to_int(t->bottom + pixman_fixed_1_minus_e); clip.data = NULL; if (!sna_compute_composite_region(&clip, NULL, NULL, dst, 0, 0, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)) continue; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &clip, MOVE_WRITE | MOVE_READ)) { RegionUninit(&clip); continue; } if (sigtrap_get() == 0) { RegionTranslate(&clip, dx, dy); count = region_num_rects(&clip); extents = region_rects(&clip); while (count--) { int16_t y1 = dy + pixman_fixed_to_int(t->top); uint16_t fy1 = pixman_fixed_frac(t->top); int16_t y2 = dy + pixman_fixed_to_int(t->bottom); uint16_t fy2 = pixman_fixed_frac(t->bottom); DBG(("%s: t=(%d, %d), (%d, %d), extents (%d, %d), (%d, %d)\n", __FUNCTION__, pixman_fixed_to_int(t->left.p1.x), pixman_fixed_to_int(t->top), pixman_fixed_to_int(t->right.p2.x), pixman_fixed_to_int(t->bottom), extents->x1, extents->y1, extents->x2, extents->y2)); if (y1 < extents->y1) y1 = extents->y1, fy1 = 0; if (y2 >= extents->y2) y2 = extents->y2, fy2 = 0; if (y1 < y2) { if (fy1) { lerp32_unaligned_box_row(pixmap, color, extents, t, dx, y1, 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, fy1)); y1++; } if (y2 > y1) lerp32_unaligned_box_row(pixmap, color, extents, t, dx, y1, y2 - y1, SAMPLES_Y); if (fy2) lerp32_unaligned_box_row(pixmap, color, extents, t, dx, y2, 1, grid_coverage(SAMPLES_Y, fy2)); } else if (y1 == y2 && fy2 > fy1) { lerp32_unaligned_box_row(pixmap, color, extents, t, dx, y1, 1, grid_coverage(SAMPLES_Y, fy2) - grid_coverage(SAMPLES_Y, fy1)); } extents++; } sigtrap_put(); } RegionUninit(&clip); } while (--n && t++); return true; pixman: do { struct pixman_inplace pi; RegionRec clip; const BoxRec *extents; int count; clip.extents.x1 = pixman_fixed_to_int(t->left.p1.x); clip.extents.x2 = pixman_fixed_to_int(t->right.p1.x + pixman_fixed_1_minus_e); clip.extents.y1 = pixman_fixed_to_int(t->top); clip.extents.y2 = pixman_fixed_to_int(t->bottom + pixman_fixed_1_minus_e); clip.data = NULL; if (!sna_compute_composite_region(&clip, NULL, NULL, dst, 0, 0, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)) continue; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &clip, MOVE_WRITE | MOVE_READ)) { RegionUninit(&clip); continue; } pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.source = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, NULL, 0); pixman_image_set_repeat(pi.source, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.source); pi.color = color; pi.op = op; if (sigtrap_get() == 0) { count = region_num_rects(&clip); extents = region_rects(&clip); while (count--) { int16_t y1 = pixman_fixed_to_int(t->top); uint16_t fy1 = pixman_fixed_frac(t->top); int16_t y2 = pixman_fixed_to_int(t->bottom); uint16_t fy2 = pixman_fixed_frac(t->bottom); if (y1 < extents->y1) y1 = extents->y1, fy1 = 0; if (y2 >= extents->y2) y2 = extents->y2, fy2 = 0; if (y1 < y2) { if (fy1) { pixsolid_unaligned_box_row(&pi, extents, t, y1, 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, fy1)); y1++; } if (y2 > y1) pixsolid_unaligned_box_row(&pi, extents, t, y1, y2 - y1, SAMPLES_Y); if (fy2) pixsolid_unaligned_box_row(&pi, extents, t, y2, 1, grid_coverage(SAMPLES_Y, fy2)); } else if (y1 == y2 && fy2 > fy1) { pixsolid_unaligned_box_row(&pi, extents, t, y1, 1, grid_coverage(SAMPLES_Y, fy2) - grid_coverage(SAMPLES_Y, fy1)); } extents++; } sigtrap_put(); } RegionUninit(&clip); pixman_image_unref(pi.image); pixman_image_unref(pi.source); } while (--n && t++); return true; } inline static void pixmask_opacity(struct pixman_inplace *pi, int16_t x, int16_t w, int16_t y, int16_t h, uint8_t opacity) { if (opacity == 0xff) { pixman_image_composite(pi->op, pi->source, NULL, pi->image, pi->sx + x, pi->sy + y, 0, 0, pi->dx + x, pi->dy + y, w, h); } else { *pi->bits = opacity; pixman_image_composite(pi->op, pi->source, pi->mask, pi->image, pi->sx + x, pi->sy + y, 0, 0, pi->dx + x, pi->dy + y, w, h); } } static void pixmask_unaligned_box_row(struct pixman_inplace *pi, const BoxRec *extents, const xTrapezoid *trap, int16_t y, int16_t h, uint8_t covered) { int16_t x1 = pixman_fixed_to_int(trap->left.p1.x); uint16_t fx1 = grid_coverage(SAMPLES_X, trap->left.p1.x); int16_t x2 = pixman_fixed_to_int(trap->right.p1.x); uint16_t fx2 = grid_coverage(SAMPLES_X, trap->right.p1.x); if (x1 < extents->x1) x1 = extents->x1, fx1 = 0; if (x2 >= extents->x2) x2 = extents->x2, fx2 = 0; if (x1 < x2) { if (fx1) { pixmask_opacity(pi, x1, 1, y, h, covered * (SAMPLES_X - fx1)); x1++; } if (x2 > x1) pixmask_opacity(pi, x1, x2-x1, y, h, covered*SAMPLES_X); if (fx2) pixmask_opacity(pi, x2, 1, y, h, covered * fx2); } else if (x1 == x2 && fx2 > fx1) { pixmask_opacity(pi, x1, 1, y, h, covered * (fx2 - fx1)); } } struct rectilinear_inplace_thread { pixman_image_t *dst, *src; const RegionRec *clip; const xTrapezoid *trap; int dx, dy, sx, sy; int y1, y2; CARD8 op; }; static void rectilinear_inplace_thread(void *arg) { struct rectilinear_inplace_thread *thread = arg; const xTrapezoid *t = thread->trap; struct pixman_inplace pi; const BoxRec *extents; int count; pi.image = thread->dst; pi.dx = thread->dx; pi.dy = thread->dy; pi.source = thread->src; pi.sx = thread->sx; pi.sy = thread->sy; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, &pi.color, 4); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = thread->op; count = region_count(thread->clip); extents = region_boxes(thread->clip); while (count--) { int16_t y1 = pixman_fixed_to_int(t->top); uint16_t fy1 = pixman_fixed_frac(t->top); int16_t y2 = pixman_fixed_to_int(t->bottom); uint16_t fy2 = pixman_fixed_frac(t->bottom); if (y1 < MAX(thread->y1, extents->y1)) y1 = MAX(thread->y1, extents->y1), fy1 = 0; if (y2 > MIN(thread->y2, extents->y2)) y2 = MIN(thread->y2, extents->y2), fy2 = 0; if (y1 < y2) { if (fy1) { pixmask_unaligned_box_row(&pi, extents, t, y1, 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, fy1)); y1++; } if (y2 > y1) pixmask_unaligned_box_row(&pi, extents, t, y1, y2 - y1, SAMPLES_Y); if (fy2) pixmask_unaligned_box_row(&pi, extents, t, y2, 1, grid_coverage(SAMPLES_Y, fy2)); } else if (y1 == y2 && fy2 > fy1) { pixmask_unaligned_box_row(&pi, extents, t, y1, 1, grid_coverage(SAMPLES_Y, fy2) - grid_coverage(SAMPLES_Y, fy1)); } extents++; } pixman_image_unref(pi.mask); } static bool composite_unaligned_boxes_inplace(struct sna *sna, CARD8 op, PicturePtr src, int16_t src_x, int16_t src_y, PicturePtr dst, int n, const xTrapezoid *t, bool force_fallback) { if (!force_fallback && (is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS) || picture_is_gpu(sna, src, PREFER_GPU_SPANS))) { DBG(("%s: fallback -- not forcing\n", __FUNCTION__)); return false; } DBG(("%s\n", __FUNCTION__)); src_x -= pixman_fixed_to_int(t[0].left.p1.x); src_y -= pixman_fixed_to_int(t[0].left.p1.y); do { RegionRec clip; const BoxRec *extents; int count; int num_threads; clip.extents.x1 = pixman_fixed_to_int(t->left.p1.x); clip.extents.x2 = pixman_fixed_to_int(t->right.p1.x + pixman_fixed_1_minus_e); clip.extents.y1 = pixman_fixed_to_int(t->top); clip.extents.y2 = pixman_fixed_to_int(t->bottom + pixman_fixed_1_minus_e); clip.data = NULL; if (!sna_compute_composite_region(&clip, src, NULL, dst, clip.extents.x1 + src_x, clip.extents.y1 + src_y, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)) continue; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &clip, MOVE_WRITE | MOVE_READ)) { RegionUninit(&clip); continue; } if (src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) { RegionUninit(&clip); continue; } if (src->alphaMap) { if (!sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) { RegionUninit(&clip); continue; } } } num_threads = sna_use_threads(clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, 32); if (num_threads == 1) { struct pixman_inplace pi; pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.source = image_from_pict(src, false, &pi.sx, &pi.sy); pi.sx += src_x; pi.sy += src_y; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, &pi.color, 4); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = op; if (sigtrap_get() == 0) { count = region_num_rects(&clip); extents = region_rects(&clip); while (count--) { int16_t y1 = pixman_fixed_to_int(t->top); uint16_t fy1 = pixman_fixed_frac(t->top); int16_t y2 = pixman_fixed_to_int(t->bottom); uint16_t fy2 = pixman_fixed_frac(t->bottom); if (y1 < extents->y1) y1 = extents->y1, fy1 = 0; if (y2 > extents->y2) y2 = extents->y2, fy2 = 0; if (y1 < y2) { if (fy1) { pixmask_unaligned_box_row(&pi, extents, t, y1, 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, fy1)); y1++; } if (y2 > y1) pixmask_unaligned_box_row(&pi, extents, t, y1, y2 - y1, SAMPLES_Y); if (fy2) pixmask_unaligned_box_row(&pi, extents, t, y2, 1, grid_coverage(SAMPLES_Y, fy2)); } else if (y1 == y2 && fy2 > fy1) { pixmask_unaligned_box_row(&pi, extents, t, y1, 1, grid_coverage(SAMPLES_Y, fy2) - grid_coverage(SAMPLES_Y, fy1)); } extents++; } sigtrap_put(); } pixman_image_unref(pi.image); pixman_image_unref(pi.source); pixman_image_unref(pi.mask); } else { struct rectilinear_inplace_thread thread[num_threads]; int i, y, dy; thread[0].trap = t; thread[0].dst = image_from_pict(dst, false, &thread[0].dx, &thread[0].dy); thread[0].src = image_from_pict(src, false, &thread[0].sx, &thread[0].sy); thread[0].sx += src_x; thread[0].sy += src_y; thread[0].clip = &clip; thread[0].op = op; y = clip.extents.y1; dy = (clip.extents.y2 - clip.extents.y1 + num_threads - 1) / num_threads; num_threads = (clip.extents.y2 - clip.extents.y1 + dy - 1) / dy; if (sigtrap_get() == 0) { for (i = 1; i < num_threads; i++) { thread[i] = thread[0]; thread[i].y1 = y; thread[i].y2 = y += dy; sna_threads_run(i, rectilinear_inplace_thread, &thread[i]); } assert(y < clip.extents.y2); thread[0].y1 = y; thread[0].y2 = clip.extents.y2; rectilinear_inplace_thread(&thread[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); pixman_image_unref(thread[0].dst); pixman_image_unref(thread[0].src); } RegionUninit(&clip); } while (--n && t++); return true; } static bool composite_unaligned_boxes_fallback(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, const xTrapezoid *traps, bool force_fallback) { ScreenPtr screen = dst->pDrawable->pScreen; uint32_t color; int16_t dst_x, dst_y; int16_t dx, dy; int n; if (sna_picture_is_solid(src, &color) && composite_unaligned_boxes_inplace__solid(sna, op, color, dst, ntrap, traps, force_fallback)) return true; if (composite_unaligned_boxes_inplace(sna, op, src, src_x, src_y, dst, ntrap, traps, force_fallback)) return true; trapezoid_origin(&traps[0].left, &dst_x, &dst_y); dx = dst->pDrawable->x; dy = dst->pDrawable->y; for (n = 0; n < ntrap; n++) { const xTrapezoid *t = &traps[n]; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int error; int y1, y2; extents.x1 = pixman_fixed_to_int(t->left.p1.x); extents.x2 = pixman_fixed_to_int(t->right.p1.x + pixman_fixed_1_minus_e); extents.y1 = pixman_fixed_to_int(t->top); extents.y2 = pixman_fixed_to_int(t->bottom + pixman_fixed_1_minus_e); if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) continue; if (force_fallback) scratch = sna_pixmap_create_unattached(screen, extents.x2 - extents.x1, extents.y2 - extents.y1, 8); else scratch = sna_pixmap_create_upload(screen, extents.x2 - extents.x1, extents.y2 - extents.y1, 8, KGEM_BUFFER_WRITE_INPLACE); if (!scratch) continue; memset(scratch->devPrivate.ptr, 0xff, scratch->devKind * (extents.y2 - extents.y1)); extents.x1 -= dx; extents.x2 -= dx; extents.y1 -= dy; extents.y2 -= dy; y1 = pixman_fixed_to_int(t->top) - extents.y1; y2 = pixman_fixed_to_int(t->bottom) - extents.y1; if (y1 == y2) { blt_unaligned_box_row(scratch, &extents, t, y1, y1 + 1, grid_coverage(SAMPLES_Y, t->bottom) - grid_coverage(SAMPLES_Y, t->top)); } else { if (pixman_fixed_frac(t->top)) { blt_unaligned_box_row(scratch, &extents, t, y1, y1 + 1, SAMPLES_Y - grid_coverage(SAMPLES_Y, t->top)); y1++; } if (y2 > y1) blt_unaligned_box_row(scratch, &extents, t, y1, y2, SAMPLES_Y); if (pixman_fixed_frac(t->bottom)) blt_unaligned_box_row(scratch, &extents, t, y2, y2+1, grid_coverage(SAMPLES_Y, t->bottom)); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); } return true; } bool composite_unaligned_boxes(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int ntrap, const xTrapezoid *traps, bool force_fallback) { BoxRec extents; struct sna_composite_spans_op tmp; struct sna_pixmap *priv; pixman_region16_t clip, *c; int16_t dst_x, dst_y; int dx, dy, n; if (NO_UNALIGNED_BOXES) return false; DBG(("%s: force_fallback=%d, mask=%x, n=%d, op=%d\n", __FUNCTION__, force_fallback, maskFormat ? (int)maskFormat->format : 0, ntrap, op)); /* need a span converter to handle overlapping traps */ if (ntrap > 1 && maskFormat) return false; if (force_fallback || !sna->render.check_composite_spans(sna, op, src, dst, 0, 0, COMPOSITE_SPANS_RECTILINEAR)) { fallback: return composite_unaligned_boxes_fallback(sna, op, src, dst, src_x, src_y, ntrap, traps, force_fallback); } trapezoid_origin(&traps[0].left, &dst_x, &dst_y); extents.x1 = pixman_fixed_to_int(traps[0].left.p1.x); extents.x2 = pixman_fixed_to_int(traps[0].right.p1.x + pixman_fixed_1_minus_e); extents.y1 = pixman_fixed_to_int(traps[0].top); extents.y2 = pixman_fixed_to_int(traps[0].bottom + pixman_fixed_1_minus_e); DBG(("%s: src=(%d, %d), dst=(%d, %d)\n", __FUNCTION__, src_x, src_y, dst_x, dst_y)); for (n = 1; n < ntrap; n++) { int x1 = pixman_fixed_to_int(traps[n].left.p1.x); int x2 = pixman_fixed_to_int(traps[n].right.p1.x + pixman_fixed_1_minus_e); int y1 = pixman_fixed_to_int(traps[n].top); int y2 = pixman_fixed_to_int(traps[n].bottom + pixman_fixed_1_minus_e); if (x1 < extents.x1) extents.x1 = x1; if (x2 > extents.x2) extents.x2 = x2; if (y1 < extents.y1) extents.y1 = y1; if (y2 > extents.y2) extents.y2 = y2; } DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, COMPOSITE_SPANS_RECTILINEAR)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); goto fallback; } c = NULL; if (extents.x2 - extents.x1 > clip.extents.x2 - clip.extents.x1 || extents.y2 - extents.y1 > clip.extents.y2 - clip.extents.y1) { DBG(("%s: forcing clip\n", __FUNCTION__)); c = &clip; } extents = *RegionExtents(&clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy)); switch (op) { case PictOpAdd: case PictOpOver: priv = sna_pixmap(get_drawable_pixmap(dst->pDrawable)); assert(priv != NULL); if (priv->clear && priv->clear_color == 0) { DBG(("%s: converting %d to PictOpSrc\n", __FUNCTION__, op)); op = PictOpSrc; } break; case PictOpIn: priv = sna_pixmap(get_drawable_pixmap(dst->pDrawable)); assert(priv != NULL); if (priv->clear && priv->clear_color == 0) { DBG(("%s: clear destination using In, skipping\n", __FUNCTION__)); return true; } break; } if (!sna->render.composite_spans(sna, op, src, dst, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, COMPOSITE_SPANS_RECTILINEAR, memset(&tmp, 0, sizeof(tmp)))) { DBG(("%s: composite spans render op not supported\n", __FUNCTION__)); REGION_UNINIT(NULL, &clip); goto fallback; } for (n = 0; n < ntrap; n++) composite_unaligned_trap(sna, &tmp, &traps[n], dx, dy, c); tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids_imprecise.c000066400000000000000000002733531267532330400271110ustar00rootroot00000000000000/* * Copyright (c) 2007 David Turner * Copyright (c) 2008 M Joonas Pihlaja * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_trapezoids.h" #include "fb/fbpict.h" #include #undef SAMPLES_X #undef SAMPLES_Y /* TODO: Emit unantialiased and MSAA triangles. */ #ifndef MAX #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif #ifndef MIN #define MIN(x,y) ((x) <= (y) ? (x) : (y)) #endif typedef void (*span_func_t)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage); #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif static void apply_damage(struct sna_composite_op *op, RegionPtr region) { DBG(("%s: damage=%p, region=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, op->damage, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (op->damage == NULL) return; RegionTranslate(region, op->dst.x, op->dst.y); assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region)); sna_damage_add(op->damage, region); } static void _apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { BoxRec r; r.x1 = box->x1 + op->dst.x; r.x2 = box->x2 + op->dst.x; r.y1 = box->y1 + op->dst.y; r.y2 = box->y2 + op->dst.y; assert_pixmap_contains_box(op->dst.pixmap, &r); sna_damage_add_box(op->damage, &r); } inline static void apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { if (op->damage) _apply_damage_box(op, box); } #define FAST_SAMPLES_X_TO_INT_FRAC(x, i, f) \ _GRID_TO_INT_FRAC_shift(x, i, f, FAST_SAMPLES_shift) #define FAST_SAMPLES_INT(x) ((x) >> (FAST_SAMPLES_shift)) #define FAST_SAMPLES_FRAC(x) ((x) & (FAST_SAMPLES_mask)) #define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ (f) = FAST_SAMPLES_FRAC(t); \ (i) = FAST_SAMPLES_INT(t); \ } while (0) #define FAST_SAMPLES_XY (FAST_SAMPLES_X*FAST_SAMPLES_Y) /* Unit area on the grid. */ #define AREA_TO_ALPHA(c) ((c) / (float)FAST_SAMPLES_XY) struct quorem { int32_t quo; int64_t rem; }; struct edge { struct edge *next, *prev; int dir; int cell; int height_left; struct quorem x; /* Advance of the current x when moving down a subsample line. */ struct quorem dxdy; int64_t dy; /* The clipped y of the top of the edge. */ int ytop; /* y2-y1 after orienting the edge downwards. */ }; /* Number of subsample rows per y-bucket. Must be SAMPLES_Y. */ #define EDGE_Y_BUCKET_HEIGHT FAST_SAMPLES_Y #define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/EDGE_Y_BUCKET_HEIGHT) /* A collection of sorted and vertically clipped edges of the polygon. * Edges are moved from the polygon to an active list while scan * converting. */ struct polygon { /* The vertical clip extents. */ int ymin, ymax; /* Array of edges all starting in the same bucket. An edge is put * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when * it is added to the polygon. */ struct edge **y_buckets; struct edge *y_buckets_embedded[64]; struct edge edges_embedded[32]; struct edge *edges; int num_edges; }; /* A cell records the effect on pixel coverage of polygon edges * passing through a pixel. It contains two accumulators of pixel * coverage. * * Consider the effects of a polygon edge on the coverage of a pixel * it intersects and that of the following one. The coverage of the * following pixel is the height of the edge multiplied by the width * of the pixel, and the coverage of the pixel itself is the area of * the trapezoid formed by the edge and the right side of the pixel. * * +-----------------------+-----------------------+ * | | | * | | | * |_______________________|_______________________| * | \...................|.......................|\ * | \..................|.......................| | * | \.................|.......................| | * | \....covered.....|.......................| | * | \....area.......|.......................| } covered height * | \..............|.......................| | * |uncovered\.............|.......................| | * | area \............|.......................| | * |___________\...........|.......................|/ * | | | * | | | * | | | * +-----------------------+-----------------------+ * * Since the coverage of the following pixel will always be a multiple * of the width of the pixel, we can store the height of the covered * area instead. The coverage of the pixel itself is the total * coverage minus the area of the uncovered area to the left of the * edge. As it's faster to compute the uncovered area we only store * that and subtract it from the total coverage later when forming * spans to blit. * * The heights and areas are signed, with left edges of the polygon * having positive sign and right edges having negative sign. When * two edges intersect they swap their left/rightness so their * contribution above and below the intersection point must be * computed separately. */ struct cell { struct cell *next; int x; int16_t uncovered_area; int16_t covered_height; }; /* A cell list represents the scan line sparsely as cells ordered by * ascending x. It is geared towards scanning the cells in order * using an internal cursor. */ struct cell_list { struct cell *cursor; /* Points to the left-most cell in the scan line. */ struct cell head, tail; int16_t x1, x2; int16_t count, size; struct cell *cells; struct cell embedded[256]; }; /* The active list contains edges in the current scan line ordered by * the x-coordinate of the intercept of the edge and the scan line. */ struct active_list { /* Leftmost edge on the current scan line. */ struct edge head, tail; }; struct tor { struct polygon polygon[1]; struct active_list active[1]; struct cell_list coverages[1]; BoxRec extents; }; /* Compute the floored division a/b. Assumes / and % perform symmetric * division. */ /* Rewinds the cell list's cursor to the beginning. After rewinding * we're good to cell_list_find() the cell any x coordinate. */ inline static void cell_list_rewind(struct cell_list *cells) { cells->cursor = &cells->head; } static bool cell_list_init(struct cell_list *cells, int x1, int x2) { cells->tail.next = NULL; cells->tail.x = INT_MAX; cells->head.x = INT_MIN; cells->head.next = &cells->tail; cells->head.covered_height = 0; cell_list_rewind(cells); cells->count = 0; cells->x1 = x1; cells->x2 = x2; cells->size = x2 - x1 + 1; cells->cells = cells->embedded; if (cells->size > ARRAY_SIZE(cells->embedded)) cells->cells = malloc(cells->size * sizeof(struct cell)); return cells->cells != NULL; } static void cell_list_fini(struct cell_list *cells) { if (cells->cells != cells->embedded) free(cells->cells); } inline static void cell_list_reset(struct cell_list *cells) { cell_list_rewind(cells); cells->head.next = &cells->tail; cells->head.covered_height = 0; cells->count = 0; } inline static struct cell * cell_list_alloc(struct cell_list *cells, struct cell *tail, int x) { struct cell *cell; assert(cells->count < cells->size); cell = cells->cells + cells->count++; cell->next = tail->next; tail->next = cell; cell->x = x; cell->covered_height = 0; cell->uncovered_area = 0; return cell; } /* Find a cell at the given x-coordinate. Returns %NULL if a new cell * needed to be allocated but couldn't be. Cells must be found with * non-decreasing x-coordinate until the cell list is rewound using * cell_list_rewind(). Ownership of the returned cell is retained by * the cell list. */ inline static struct cell * cell_list_find(struct cell_list *cells, int x) { struct cell *tail; if (x >= cells->x2) return &cells->tail; if (x < cells->x1) return &cells->head; tail = cells->cursor; if (tail->x == x) return tail; do { if (tail->next->x > x) break; tail = tail->next; if (tail->next->x > x) break; tail = tail->next; if (tail->next->x > x) break; tail = tail->next; } while (1); if (tail->x != x) tail = cell_list_alloc(cells, tail, x); return cells->cursor = tail; } /* Add a subpixel span covering [x1, x2) to the coverage cells. */ inline static void cell_list_add_subspan(struct cell_list *cells, int x1, int x2) { struct cell *cell; int ix1, fx1; int ix2, fx2; if (x1 == x2) return; FAST_SAMPLES_X_TO_INT_FRAC(x1, ix1, fx1); FAST_SAMPLES_X_TO_INT_FRAC(x2, ix2, fx2); __DBG(("%s: x1=%d (%d+%d), x2=%d (%d+%d)\n", __FUNCTION__, x1, ix1, fx1, x2, ix2, fx2)); cell = cell_list_find(cells, ix1); if (ix1 != ix2) { cell->uncovered_area += fx1; ++cell->covered_height; cell = cell_list_find(cells, ix2); cell->uncovered_area -= fx2; --cell->covered_height; } else cell->uncovered_area += (fx1-fx2); } inline static void cell_list_add_span(struct cell_list *cells, int x1, int x2) { struct cell *cell; int ix1, fx1; int ix2, fx2; FAST_SAMPLES_X_TO_INT_FRAC(x1, ix1, fx1); FAST_SAMPLES_X_TO_INT_FRAC(x2, ix2, fx2); __DBG(("%s: x1=%d (%d+%d), x2=%d (%d+%d)\n", __FUNCTION__, x1, ix1, fx1, x2, ix2, fx2)); cell = cell_list_find(cells, ix1); if (ix1 != ix2) { cell->uncovered_area += fx1*FAST_SAMPLES_Y; cell->covered_height += FAST_SAMPLES_Y; cell = cell_list_find(cells, ix2); cell->uncovered_area -= fx2*FAST_SAMPLES_Y; cell->covered_height -= FAST_SAMPLES_Y; } else cell->uncovered_area += (fx1-fx2)*FAST_SAMPLES_Y; } static void polygon_fini(struct polygon *polygon) { if (polygon->y_buckets != polygon->y_buckets_embedded) free(polygon->y_buckets); if (polygon->edges != polygon->edges_embedded) free(polygon->edges); } static bool polygon_init(struct polygon *polygon, int num_edges, int ymin, int ymax) { unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax-1, ymin) + 1; if (unlikely(ymax - ymin > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT)) return false; polygon->edges = polygon->edges_embedded; polygon->y_buckets = polygon->y_buckets_embedded; polygon->num_edges = 0; if (num_edges > (int)ARRAY_SIZE(polygon->edges_embedded)) { polygon->edges = malloc(sizeof(struct edge)*num_edges); if (unlikely(NULL == polygon->edges)) goto bail_no_mem; } if (num_buckets >= ARRAY_SIZE(polygon->y_buckets_embedded)) { polygon->y_buckets = malloc((1+num_buckets)*sizeof(struct edge *)); if (unlikely(NULL == polygon->y_buckets)) goto bail_no_mem; } memset(polygon->y_buckets, 0, num_buckets * sizeof(struct edge *)); polygon->y_buckets[num_buckets] = (void *)-1; polygon->ymin = ymin; polygon->ymax = ymax; return true; bail_no_mem: polygon_fini(polygon); return false; } static void _polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, struct edge *e) { unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); struct edge **ptail = &polygon->y_buckets[ix]; assert(e->ytop < polygon->ymax); e->next = *ptail; *ptail = e; } inline static void polygon_add_edge(struct polygon *polygon, const xTrapezoid *t, const xLineFixed *edge, int dir, int dx, int dy) { struct edge *e = &polygon->edges[polygon->num_edges]; int ytop, ybot; assert(t->bottom > t->top); assert(edge->p2.y > edge->p1.y); e->dir = dir; ytop = pixman_fixed_to_fast(t->top) + dy; if (ytop < polygon->ymin) ytop = polygon->ymin; ybot = pixman_fixed_to_fast(t->bottom) + dy; if (ybot > polygon->ymax) ybot = polygon->ymax; e->ytop = ytop; e->height_left = ybot - ytop; if (e->height_left <= 0) return; if (pixman_fixed_to_fast(edge->p1.x) == pixman_fixed_to_fast(edge->p2.x)) { e->cell = e->x.quo = pixman_fixed_to_fast(edge->p1.x) + dx; e->x.rem = 0; e->dxdy.quo = 0; e->dxdy.rem = 0; e->dy = 0; } else { int64_t Ex, Ey, tmp; Ex = ((int64_t)edge->p2.x - edge->p1.x) * FAST_SAMPLES_X; Ey = ((int64_t)edge->p2.y - edge->p1.y) * FAST_SAMPLES_Y * (2 << 16); assert(Ey > 0); e->dxdy.quo = Ex * (2 << 16) / Ey; e->dxdy.rem = Ex * (2 << 16) % Ey; tmp = (int64_t)(2 * (ytop - dy) + 1) << 16; tmp -= (int64_t)edge->p1.y * FAST_SAMPLES_Y * 2; tmp *= Ex; e->x.quo = tmp / Ey; e->x.rem = tmp % Ey; tmp = (int64_t)edge->p1.x * FAST_SAMPLES_X; e->x.quo += tmp / (1 << 16) + dx; tmp &= (1 << 16) - 1; if (tmp) { if (Ey < INT64_MAX >> 16) tmp = (tmp * Ey) / (1 << 16); else /* Handle overflow by losing precision */ tmp = tmp * (Ey / (1 << 16)); e->x.rem += tmp; } if (e->x.rem < 0) { --e->x.quo; e->x.rem += Ey; } else if (e->x.rem >= Ey) { ++e->x.quo; e->x.rem -= Ey; } assert(e->x.rem >= 0 && e->x.rem < Ey); e->cell = e->x.quo + (e->x.rem >= Ey/2); e->dy = Ey; } _polygon_insert_edge_into_its_y_bucket(polygon, e); polygon->num_edges++; } inline static void polygon_add_line(struct polygon *polygon, const xPointFixed *p1, const xPointFixed *p2, int dx, int dy) { struct edge *e = &polygon->edges[polygon->num_edges]; int top, bot; if (p1->y == p2->y) return; __DBG(("%s: line=(%d, %d), (%d, %d)\n", __FUNCTION__, (int)p1->x, (int)p1->y, (int)p2->x, (int)p2->y)); e->dir = 1; if (p2->y < p1->y) { const xPointFixed *t; e->dir = -1; t = p1; p1 = p2; p2 = t; } top = pixman_fixed_to_fast(p1->y) + dy; if (top < polygon->ymin) top = polygon->ymin; bot = pixman_fixed_to_fast(p2->y) + dy; if (bot > polygon->ymax) bot = polygon->ymax; if (bot <= top) return; e->ytop = top; e->height_left = bot - top; if (e->height_left <= 0) return; __DBG(("%s: edge height=%d\n", __FUNCTION__, e->dir * e->height_left)); if (pixman_fixed_to_fast(p1->x) == pixman_fixed_to_fast(p2->x)) { e->cell = e->x.quo = pixman_fixed_to_fast(p1->x) + dx; e->x.rem = 0; e->dxdy.quo = 0; e->dxdy.rem = 0; e->dy = 0; } else { int64_t Ex, Ey, tmp; Ex = ((int64_t)p2->x - p1->x) * FAST_SAMPLES_X; Ey = ((int64_t)p2->y - p1->y) * FAST_SAMPLES_Y * (2 << 16); e->dxdy.quo = Ex * (2 << 16) / Ey; e->dxdy.rem = Ex * (2 << 16) % Ey; tmp = (int64_t)(2 * (top - dy) + 1) << 16; tmp -= (int64_t)p1->y * FAST_SAMPLES_Y * 2; tmp *= Ex; e->x.quo = tmp / Ey; e->x.rem = tmp % Ey; tmp = (int64_t)p1->x * FAST_SAMPLES_X; e->x.quo += tmp / (1 << 16) + dx; e->x.rem += ((tmp & ((1 << 16) - 1)) * Ey) / (1 << 16); if (e->x.rem < 0) { --e->x.quo; e->x.rem += Ey; } else if (e->x.rem >= Ey) { ++e->x.quo; e->x.rem -= Ey; } e->cell = e->x.quo + (e->x.rem >= Ey/2); e->dy = Ey; } if (polygon->num_edges > 0) { struct edge *prev = &polygon->edges[polygon->num_edges-1]; /* detect degenerate triangles inserted into tristrips */ if (e->dir == -prev->dir && e->ytop == prev->ytop && e->height_left == prev->height_left && e->x.quo == prev->x.quo && e->x.rem == prev->x.rem && e->dxdy.quo == prev->dxdy.quo && e->dxdy.rem == prev->dxdy.rem) { unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); polygon->y_buckets[ix] = prev->next; polygon->num_edges--; return; } } _polygon_insert_edge_into_its_y_bucket(polygon, e); polygon->num_edges++; } static void active_list_reset(struct active_list *active) { active->head.height_left = INT_MAX; active->head.cell = INT_MIN; active->head.dy = 0; active->head.prev = NULL; active->head.next = &active->tail; active->tail.prev = &active->head; active->tail.next = NULL; active->tail.cell = INT_MAX; active->tail.height_left = INT_MAX; active->tail.dy = 0; } static struct edge * merge_sorted_edges(struct edge *head_a, struct edge *head_b) { struct edge *head, **next, *prev; int32_t x; if (head_b == NULL) return head_a; prev = head_a->prev; next = &head; if (head_a->cell <= head_b->cell) { head = head_a; } else { head = head_b; head_b->prev = prev; goto start_with_b; } do { x = head_b->cell; while (head_a != NULL && head_a->cell <= x) { prev = head_a; next = &head_a->next; head_a = head_a->next; } head_b->prev = prev; *next = head_b; if (head_a == NULL) return head; start_with_b: x = head_a->cell; while (head_b != NULL && head_b->cell <= x) { prev = head_b; next = &head_b->next; head_b = head_b->next; } head_a->prev = prev; *next = head_a; if (head_b == NULL) return head; } while (1); } static struct edge * sort_edges(struct edge *list, unsigned int level, struct edge **head_out) { struct edge *head_other, *remaining; unsigned int i; head_other = list->next; if (head_other == NULL) { *head_out = list; return NULL; } remaining = head_other->next; if (list->cell <= head_other->cell) { *head_out = list; head_other->next = NULL; } else { *head_out = head_other; head_other->prev = list->prev; head_other->next = list; list->prev = head_other; list->next = NULL; } for (i = 0; i < level && remaining; i++) { remaining = sort_edges(remaining, i, &head_other); *head_out = merge_sorted_edges(*head_out, head_other); } return remaining; } static struct edge *filter(struct edge *edges) { struct edge *e; e = edges; while (e->next) { struct edge *n = e->next; if (e->dir == -n->dir && e->height_left == n->height_left && &e->x.quo == &n->x.quo && &e->x.rem == &n->x.rem && &e->dxdy.quo == &n->dxdy.quo && &e->dxdy.rem == &n->dxdy.rem) { if (e->prev) e->prev->next = n->next; else edges = n->next; if (n->next) n->next->prev = e->prev; else break; e = n->next; } else e = n; } return edges; } static struct edge * merge_unsorted_edges(struct edge *head, struct edge *unsorted) { sort_edges(unsorted, UINT_MAX, &unsorted); return merge_sorted_edges(head, filter(unsorted)); } /* Test if the edges on the active list can be safely advanced by a * full row without intersections or any edges ending. */ inline static int can_full_step(struct active_list *active) { const struct edge *e; int min_height = INT_MAX; assert(active->head.next != &active->tail); for (e = active->head.next; &active->tail != e; e = e->next) { assert(e->height_left > 0); if (e->dy != 0) return 0; if (e->height_left < min_height) { min_height = e->height_left; if (min_height < FAST_SAMPLES_Y) return 0; } } return min_height; } inline static void merge_edges(struct active_list *active, struct edge *edges) { active->head.next = merge_unsorted_edges(active->head.next, edges); } inline static int fill_buckets(struct active_list *active, struct edge *edge, struct edge **buckets) { int ymax = 0; while (edge) { int y = edge->ytop & (FAST_SAMPLES_Y-1); struct edge *next = edge->next; struct edge **b = &buckets[y]; __DBG(("%s: ytop %d -> bucket %d\n", __FUNCTION__, edge->ytop, y)); if (*b) (*b)->prev = edge; edge->next = *b; edge->prev = NULL; *b = edge; edge = next; if (y > ymax) ymax = y; } return ymax; } inline static void nonzero_subrow(struct active_list *active, struct cell_list *coverages) { struct edge *edge = active->head.next; int prev_x = INT_MIN; int winding = 0, xstart = edge->cell; cell_list_rewind(coverages); while (&active->tail != edge) { struct edge *next = edge->next; winding += edge->dir; if (0 == winding && edge->next->cell != edge->cell) { cell_list_add_subspan(coverages, xstart, edge->cell); xstart = edge->next->cell; } assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; edge->x.rem += edge->dxdy.rem; if (edge->x.rem < 0) { --edge->x.quo; edge->x.rem += edge->dy; } else if (edge->x.rem >= edge->dy) { ++edge->x.quo; edge->x.rem -= edge->dy; } edge->cell = edge->x.quo + (edge->x.rem >= edge->dy/2); } if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do pos = pos->prev; while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; } } static void nonzero_row(struct active_list *active, struct cell_list *coverages) { struct edge *left = active->head.next; while (&active->tail != left) { struct edge *right; int winding = left->dir; left->height_left -= FAST_SAMPLES_Y; assert(left->height_left >= 0); if (!left->height_left) { left->prev->next = left->next; left->next->prev = left->prev; } right = left->next; do { right->height_left -= FAST_SAMPLES_Y; assert(right->height_left >= 0); if (!right->height_left) { right->prev->next = right->next; right->next->prev = right->prev; } winding += right->dir; if (0 == winding) break; right = right->next; } while (1); cell_list_add_span(coverages, left->cell, right->cell); left = right->next; } } static void tor_fini(struct tor *converter) { polygon_fini(converter->polygon); cell_list_fini(converter->coverages); } static bool tor_init(struct tor *converter, const BoxRec *box, int num_edges) { __DBG(("%s: (%d, %d),(%d, %d) x (%d, %d), num_edges=%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, FAST_SAMPLES_X, FAST_SAMPLES_Y, num_edges)); converter->extents = *box; if (!cell_list_init(converter->coverages, box->x1, box->x2)) return false; active_list_reset(converter->active); if (!polygon_init(converter->polygon, num_edges, (int)box->y1 * FAST_SAMPLES_Y, (int)box->y2 * FAST_SAMPLES_Y)) { cell_list_fini(converter->coverages); return false; } return true; } static void tor_add_trapezoid(struct tor *tor, const xTrapezoid *t, int dx, int dy) { if (!xTrapezoidValid(t)) { __DBG(("%s: skipping invalid trapezoid: top=%d, bottom=%d, left=(%d, %d), (%d, %d), right=(%d, %d), (%d, %d)\n", __FUNCTION__, t->top, t->bottom, t->left.p1.x, t->left.p1.y, t->left.p2.x, t->left.p2.y, t->right.p1.x, t->right.p1.y, t->right.p2.x, t->right.p2.y)); return; } polygon_add_edge(tor->polygon, t, &t->left, 1, dx, dy); polygon_add_edge(tor->polygon, t, &t->right, -1, dx, dy); } static void step_edges(struct active_list *active, int count) { struct edge *edge; count *= FAST_SAMPLES_Y; for (edge = active->head.next; edge != &active->tail; edge = edge->next) { edge->height_left -= count; assert(edge->height_left >= 0); if (!edge->height_left) { edge->prev->next = edge->next; edge->next->prev = edge->prev; } } } static void tor_blt_span(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); op->box(sna, op, box, AREA_TO_ALPHA(coverage)); apply_damage_box(&op->base, box); } static void tor_blt_span__no_damage(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); op->box(sna, op, box, AREA_TO_ALPHA(coverage)); } static void tor_blt_span_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { pixman_region16_t region; float opacity; opacity = AREA_TO_ALPHA(coverage); __DBG(("%s: %d -> %d @ %f\n", __FUNCTION__, box->x1, box->x2, opacity)); pixman_region_init_rects(®ion, box, 1); RegionIntersect(®ion, ®ion, clip); if (region_num_rects(®ion)) { op->boxes(sna, op, region_rects(®ion), region_num_rects(®ion), opacity); apply_damage(&op->base, ®ion); } pixman_region_fini(®ion); } static void tor_blt_span_mono(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { if (coverage < FAST_SAMPLES_XY/2) return; tor_blt_span(sna, op, clip, box, FAST_SAMPLES_XY); } static void tor_blt_span_mono_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { if (coverage < FAST_SAMPLES_XY/2) return; tor_blt_span_clipped(sna, op, clip, box, FAST_SAMPLES_XY); } static void tor_blt_span_mono_unbounded(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { tor_blt_span(sna, op, clip, box, coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); } static void tor_blt_span_mono_unbounded_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { tor_blt_span_clipped(sna, op, clip, box, coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); } static void tor_blt(struct sna *sna, struct tor *converter, struct sna_composite_spans_op *op, pixman_region16_t *clip, void (*span)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage), int y, int height, int unbounded) { struct cell_list *cells = converter->coverages; struct cell *cell; BoxRec box; int cover; box.y1 = y + converter->extents.y1; box.y2 = box.y1 + height; assert(box.y2 <= converter->extents.y2); box.x1 = converter->extents.x1; /* Form the spans from the coverages and areas. */ cover = cells->head.covered_height*FAST_SAMPLES_X; assert(cover >= 0); for (cell = cells->head.next; cell != &cells->tail; cell = cell->next) { int x = cell->x; assert(x >= converter->extents.x1); assert(x < converter->extents.x2); __DBG(("%s: cell=(%d, %d, %d), cover=%d\n", __FUNCTION__, cell->x, cell->covered_height, cell->uncovered_area, cover)); if (cell->covered_height || cell->uncovered_area) { box.x2 = x; if (box.x2 > box.x1 && (unbounded || cover)) { __DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, cover)); span(sna, op, clip, &box, cover); } box.x1 = box.x2; cover += cell->covered_height*FAST_SAMPLES_X; } if (cell->uncovered_area) { int area = cover - cell->uncovered_area; box.x2 = x + 1; if (unbounded || area) { __DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, area)); span(sna, op, clip, &box, area); } box.x1 = box.x2; } } box.x2 = converter->extents.x2; if (box.x2 > box.x1 && (unbounded || cover)) { __DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, cover)); span(sna, op, clip, &box, cover); } } flatten static void tor_render(struct sna *sna, struct tor *converter, struct sna_composite_spans_op *op, pixman_region16_t *clip, void (*span)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage), int unbounded) { struct polygon *polygon = converter->polygon; struct cell_list *coverages = converter->coverages; struct active_list *active = converter->active; struct edge *buckets[FAST_SAMPLES_Y] = { 0 }; int16_t i, j, h = converter->extents.y2 - converter->extents.y1; __DBG(("%s: unbounded=%d\n", __FUNCTION__, unbounded)); /* Render each pixel row. */ for (i = 0; i < h; i = j) { int do_full_step = 0; j = i + 1; /* Determine if we can ignore this row or use the full pixel * stepper. */ if (fill_buckets(active, polygon->y_buckets[i], buckets) == 0) { if (buckets[0]) { merge_edges(active, buckets[0]); buckets[0] = NULL; } if (active->head.next == &active->tail) { for (; polygon->y_buckets[j] == NULL; j++) ; __DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n", __FUNCTION__, i, j)); assert(j <= h); if (unbounded) { BoxRec box; box = converter->extents; box.y1 += i; box.y2 = converter->extents.y1 + j; span(sna, op, clip, &box, 0); } continue; } do_full_step = can_full_step(active); } __DBG(("%s: y=%d-%d, do_full_step=%d, new edges=%d\n", __FUNCTION__, i, j, do_full_step, polygon->y_buckets[i] != NULL)); if (do_full_step) { nonzero_row(active, coverages); while (polygon->y_buckets[j] == NULL && do_full_step >= 2*FAST_SAMPLES_Y) { do_full_step -= FAST_SAMPLES_Y; j++; } assert(j >= i + 1 && j <= h); if (j != i + 1) step_edges(active, j - (i + 1)); __DBG(("%s: vertical edges, full step (%d, %d)\n", __FUNCTION__, i, j)); } else { int suby; /* Subsample this row. */ for (suby = 0; suby < FAST_SAMPLES_Y; suby++) { if (buckets[suby]) { merge_edges(active, buckets[suby]); buckets[suby] = NULL; } nonzero_subrow(active, coverages); } } assert(j > i); tor_blt(sna, converter, op, clip, span, i, j-i, unbounded); cell_list_reset(coverages); } } static void inplace_row(struct active_list *active, uint8_t *row, int width) { struct edge *left = active->head.next; while (&active->tail != left) { struct edge *right; int winding = left->dir; int lfx, rfx; int lix, rix; left->height_left -= FAST_SAMPLES_Y; assert(left->height_left >= 0); if (!left->height_left) { left->prev->next = left->next; left->next->prev = left->prev; } right = left->next; do { right->height_left -= FAST_SAMPLES_Y; assert(right->height_left >= 0); if (!right->height_left) { right->prev->next = right->next; right->next->prev = right->prev; } winding += right->dir; if (0 == winding && right->cell != right->next->cell) break; right = right->next; } while (1); if (left->cell < 0) { lix = lfx = 0; } else if (left->cell >= width * FAST_SAMPLES_X) { lix = width; lfx = 0; } else FAST_SAMPLES_X_TO_INT_FRAC(left->cell, lix, lfx); if (right->cell < 0) { rix = rfx = 0; } else if (right->cell >= width * FAST_SAMPLES_X) { rix = width; rfx = 0; } else FAST_SAMPLES_X_TO_INT_FRAC(right->cell, rix, rfx); if (lix == rix) { if (rfx != lfx) { assert(lix < width); row[lix] += (rfx-lfx) * 256 / FAST_SAMPLES_X; } } else { assert(lix < width); if (lfx == 0) row[lix] = 0xff; else row[lix] += 256 - lfx * 256 / FAST_SAMPLES_X; assert(rix <= width); if (rfx) { assert(rix < width); row[rix] += rfx * 256 / FAST_SAMPLES_X; } if (rix > ++lix) { uint8_t *r = row + lix; rix -= lix; #if 0 if (rix == 1) *row = 0xff; else memset(row, 0xff, rix); #else if ((uintptr_t)r & 1 && rix) { *r++ = 0xff; rix--; } if ((uintptr_t)r & 2 && rix >= 2) { *(uint16_t *)r = 0xffff; r += 2; rix -= 2; } if ((uintptr_t)r & 4 && rix >= 4) { *(uint32_t *)r = 0xffffffff; r += 4; rix -= 4; } while (rix >= 8) { *(uint64_t *)r = 0xffffffffffffffff; r += 8; rix -= 8; } if (rix & 4) { *(uint32_t *)r = 0xffffffff; r += 4; } if (rix & 2) { *(uint16_t *)r = 0xffff; r += 2; } if (rix & 1) *r = 0xff; #endif } } left = right->next; } } inline static void inplace_subrow(struct active_list *active, int8_t *row, int width, int *min, int *max) { struct edge *edge = active->head.next; int prev_x = INT_MIN; int winding = 0, xstart = INT_MIN; while (&active->tail != edge) { struct edge *next = edge->next; winding += edge->dir; if (0 == winding) { if (edge->next->cell != edge->cell) { if (edge->cell <= xstart) { xstart = INT_MIN; } else { int fx; int ix; if (xstart < FAST_SAMPLES_X * width) { FAST_SAMPLES_X_TO_INT_FRAC(xstart, ix, fx); if (ix < *min) *min = ix; row[ix++] += FAST_SAMPLES_X - fx; if (fx && ix < width) row[ix] += fx; } xstart = edge->cell; if (xstart < FAST_SAMPLES_X * width) { FAST_SAMPLES_X_TO_INT_FRAC(xstart, ix, fx); row[ix] -= FAST_SAMPLES_X - fx; if (fx && ix + 1 < width) row[++ix] -= fx; if (ix >= *max) *max = ix + 1; xstart = INT_MIN; } else *max = width; } } } else if (xstart < 0) { xstart = MAX(edge->cell, 0); } assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; edge->x.rem += edge->dxdy.rem; if (edge->x.rem < 0) { --edge->x.quo; edge->x.rem += edge->dy; } else if (edge->x.rem >= 0) { ++edge->x.quo; edge->x.rem -= edge->dy; } edge->cell = edge->x.quo + (edge->x.rem >= edge->dy/2); } if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do pos = pos->prev; while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; } } inline static void inplace_end_subrows(struct active_list *active, uint8_t *row, int8_t *buf, int width) { int cover = 0; while (width >= 4) { uint32_t dw; int v; dw = *(uint32_t *)buf; buf += 4; if (dw == 0) { v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; v |= v << 8; dw = v | v << 16; } else { cover += (int8_t)(dw & 0xff); if (cover) { assert(cover > 0); v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; dw >>= 8; dw |= v << 24; } else dw >>= 8; cover += (int8_t)(dw & 0xff); if (cover) { assert(cover > 0); v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; dw >>= 8; dw |= v << 24; } else dw >>= 8; cover += (int8_t)(dw & 0xff); if (cover) { assert(cover > 0); v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; dw >>= 8; dw |= v << 24; } else dw >>= 8; cover += (int8_t)(dw & 0xff); if (cover) { assert(cover > 0); v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; dw >>= 8; dw |= v << 24; } else dw >>= 8; } *(uint32_t *)row = dw; row += 4; width -= 4; } while (width--) { int v; cover += *buf++; assert(cover >= 0); v = cover * 256 / FAST_SAMPLES_XY; v -= v >> 8; *row++ = v; } } static void convert_mono(uint8_t *ptr, int w) { while (w--) { *ptr = 0xff * (*ptr >= 0xf0); ptr++; } } static void tor_inplace(struct tor *converter, PixmapPtr scratch, int mono, uint8_t *buf) { int i, j, h = converter->extents.y2; struct polygon *polygon = converter->polygon; struct active_list *active = converter->active; struct edge *buckets[FAST_SAMPLES_Y] = { 0 }; uint8_t *row = scratch->devPrivate.ptr; int stride = scratch->devKind; int width = scratch->drawable.width; __DBG(("%s: mono=%d, buf?=%d\n", __FUNCTION__, mono, buf != NULL)); assert(converter->extents.y1 == 0); assert(converter->extents.x1 == 0); assert(scratch->drawable.depth == 8); /* Render each pixel row. */ for (i = 0; i < h; i = j) { int do_full_step = 0; void *ptr = buf ?: row; j = i + 1; /* Determine if we can ignore this row or use the full pixel * stepper. */ if (fill_buckets(active, polygon->y_buckets[i], buckets) == 0) { if (buckets[0]) { merge_edges(active, buckets[0]); buckets[0] = NULL; } if (active->head.next == &active->tail) { for (; !polygon->y_buckets[j]; j++) ; __DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n", __FUNCTION__, i, j)); memset(row, 0, stride*(j-i)); row += stride*(j-i); continue; } do_full_step = can_full_step(active); } __DBG(("%s: y=%d, do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n", __FUNCTION__, i, do_full_step, polygon->y_buckets[i] != NULL)); if (do_full_step) { memset(ptr, 0, width); inplace_row(active, ptr, width); if (mono) convert_mono(ptr, width); if (row != ptr) memcpy(row, ptr, width); while (polygon->y_buckets[j] == NULL && do_full_step >= 2*FAST_SAMPLES_Y) { do_full_step -= FAST_SAMPLES_Y; row += stride; memcpy(row, ptr, width); j++; } if (j != i + 1) step_edges(active, j - (i + 1)); __DBG(("%s: vertical edges, full step (%d, %d)\n", __FUNCTION__, i, j)); } else { int min = width, max = 0, suby; /* Subsample this row. */ memset(ptr, 0, width); for (suby = 0; suby < FAST_SAMPLES_Y; suby++) { if (buckets[suby]) { merge_edges(active, buckets[suby]); buckets[suby] = NULL; } inplace_subrow(active, ptr, width, &min, &max); } assert(min >= 0 && max <= width); memset(row, 0, min); if (max > min) { inplace_end_subrows(active, row+min, (int8_t*)ptr+min, max-min); if (mono) convert_mono(row+min, max-min); } if (max < width) memset(row+max, 0, width-max); } row += stride; } } static int operator_is_bounded(uint8_t op) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: return true; default: return false; } } static span_func_t choose_span(struct sna_composite_spans_op *tmp, PicturePtr dst, PictFormatPtr maskFormat, RegionPtr clip) { span_func_t span; if (is_mono(dst, maskFormat)) { /* XXX An imprecise approximation */ if (maskFormat && !operator_is_bounded(tmp->base.op)) { span = tor_blt_span_mono_unbounded; if (clip->data) span = tor_blt_span_mono_unbounded_clipped; } else { span = tor_blt_span_mono; if (clip->data) span = tor_blt_span_mono_clipped; } } else { if (clip->data) span = tor_blt_span_clipped; else if (tmp->base.damage == NULL) span = tor_blt_span__no_damage; else span = tor_blt_span; } return span; } struct span_thread { struct sna *sna; const struct sna_composite_spans_op *op; const xTrapezoid *traps; RegionPtr clip; span_func_t span; BoxRec extents; int dx, dy, draw_y; int ntrap; bool unbounded; }; #define SPAN_THREAD_MAX_BOXES (8192/sizeof(struct sna_opacity_box)) struct span_thread_boxes { const struct sna_composite_spans_op *op; const BoxRec *clip_start, *clip_end; int num_boxes; struct sna_opacity_box boxes[SPAN_THREAD_MAX_BOXES]; }; static void span_thread_add_box(struct sna *sna, void *data, const BoxRec *box, float alpha) { struct span_thread_boxes *b = data; __DBG(("%s: adding box with alpha=%f\n", __FUNCTION__, alpha)); if (unlikely(b->num_boxes == SPAN_THREAD_MAX_BOXES)) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, b->num_boxes)); b->op->thread_boxes(sna, b->op, b->boxes, b->num_boxes); b->num_boxes = 0; } b->boxes[b->num_boxes].box = *box++; b->boxes[b->num_boxes].alpha = alpha; b->num_boxes++; assert(b->num_boxes <= SPAN_THREAD_MAX_BOXES); } static void span_thread_box(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct span_thread_boxes *b = (struct span_thread_boxes *)op; __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); if (b->num_boxes) { struct sna_opacity_box *bb = &b->boxes[b->num_boxes-1]; if (bb->box.x1 == box->x1 && bb->box.x2 == box->x2 && bb->box.y2 == box->y1 && bb->alpha == AREA_TO_ALPHA(coverage)) { bb->box.y2 = box->y2; __DBG(("%s: contracted double row: %d -> %d\n", __func__, bb->box.y1, bb->box.y2)); return; } } span_thread_add_box(sna, op, box, AREA_TO_ALPHA(coverage)); } static void span_thread_clipped_box(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct span_thread_boxes *b = (struct span_thread_boxes *)op; const BoxRec *c; __DBG(("%s: %d -> %d @ %f\n", __FUNCTION__, box->x1, box->x2, AREA_TO_ALPHA(coverage))); b->clip_start = find_clip_box_for_y(b->clip_start, b->clip_end, box->y1); c = b->clip_start; while (c != b->clip_end) { BoxRec clipped; if (box->y2 <= c->y1) break; clipped = *box; if (!box_intersect(&clipped, c++)) continue; span_thread_add_box(sna, op, &clipped, AREA_TO_ALPHA(coverage)); } } static span_func_t thread_choose_span(struct sna_composite_spans_op *tmp, PicturePtr dst, PictFormatPtr maskFormat, RegionPtr clip) { span_func_t span; if (tmp->base.damage) { DBG(("%s: damaged -> no thread support\n", __FUNCTION__)); return NULL; } if (is_mono(dst, maskFormat)) { DBG(("%s: mono rendering -> no thread support\n", __FUNCTION__)); return NULL; } else { assert(tmp->thread_boxes); DBG(("%s: clipped? %d\n", __FUNCTION__, clip->data != NULL)); if (clip->data) span = span_thread_clipped_box; else span = span_thread_box; } return span; } inline static void span_thread_boxes_init(struct span_thread_boxes *boxes, const struct sna_composite_spans_op *op, const RegionRec *clip) { boxes->op = op; region_get_boxes(clip, &boxes->clip_start, &boxes->clip_end); boxes->num_boxes = 0; } static void span_thread(void *arg) { struct span_thread *thread = arg; struct span_thread_boxes boxes; struct tor tor; const xTrapezoid *t; int n, y1, y2; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; span_thread_boxes_init(&boxes, thread->op, thread->clip); y1 = thread->extents.y1 - thread->draw_y; y2 = thread->extents.y2 - thread->draw_y; for (n = thread->ntrap, t = thread->traps; n--; t++) { if (pixman_fixed_integer_floor(t->top) >= y2 || pixman_fixed_integer_ceil(t->bottom) <= y1) continue; tor_add_trapezoid(&tor, t, thread->dx, thread->dy); } tor_render(thread->sna, &tor, (struct sna_composite_spans_op *)&boxes, thread->clip, thread->span, thread->unbounded); tor_fini(&tor); if (boxes.num_boxes) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, boxes.num_boxes)); assert(boxes.num_boxes <= SPAN_THREAD_MAX_BOXES); thread->op->thread_boxes(thread->sna, thread->op, boxes.boxes, boxes.num_boxes); } } bool imprecise_trapezoid_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct sna_composite_spans_op tmp; pixman_region16_t clip; int16_t dst_x, dst_y; bool was_clear; int dx, dy, n; int num_threads; if (NO_IMPRECISE) return false; if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, flags)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } if (!trapezoids_bounds(ntrap, traps, &clip.extents)) return true; #if 0 if (clip.extents.y2 - clip.extents.y1 < 64 && clip.extents.x2 - clip.extents.x1 < 64) { DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, extents.y2 - extents.y1, extents.x2 - extents.x1)); return false; } #endif DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); trapezoid_origin(&traps[0].left, &dst_x, &dst_y); if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + clip.extents.x1 - dst_x, src_y + clip.extents.y1 - dst_y, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, flags)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, dx, dy, src_x + clip.extents.x1 - dst_x - dx, src_y + clip.extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); switch (op) { case PictOpAdd: case PictOpOver: if (was_clear) op = PictOpSrc; break; case PictOpIn: if (was_clear) return true; break; } if (!sna->render.composite_spans(sna, op, src, dst, src_x + clip.extents.x1 - dst_x - dx, src_y + clip.extents.y1 - dst_y - dy, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, flags, memset(&tmp, 0, sizeof(tmp)))) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= FAST_SAMPLES_X; dy *= FAST_SAMPLES_Y; num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0 && tmp.thread_boxes && thread_choose_span(&tmp, dst, maskFormat, &clip)) num_threads = sna_use_threads(clip.extents.x2-clip.extents.x1, clip.extents.y2-clip.extents.y1, 16); DBG(("%s: using %d threads\n", __FUNCTION__, num_threads)); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, &clip.extents, 2*ntrap)) goto skip; for (n = 0; n < ntrap; n++) { if (pixman_fixed_integer_floor(traps[n].top) + dst->pDrawable->y >= clip.extents.y2 || pixman_fixed_integer_ceil(traps[n].bottom) + dst->pDrawable->y <= clip.extents.y1) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } tor_render(sna, &tor, &tmp, &clip, choose_span(&tmp, dst, maskFormat, &clip), !was_clear && maskFormat && !operator_is_bounded(op)); tor_fini(&tor); } else { struct span_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for span compositing %dx%d\n", __FUNCTION__, num_threads, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)); threads[0].sna = sna; threads[0].op = &tmp; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = clip.extents; threads[0].clip = &clip; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_y = dst->pDrawable->y; threads[0].unbounded = !was_clear && maskFormat && !operator_is_bounded(op); threads[0].span = thread_choose_span(&tmp, dst, maskFormat, &clip); y = clip.extents.y1; h = clip.extents.y2 - clip.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= clip.extents.y2 - clip.extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, span_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; span_thread(&threads[0]); sna_threads_wait(); } skip: tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } static void tor_blt_mask(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { uint8_t *ptr = (uint8_t *)op; int stride = (intptr_t)clip; int h, w; coverage = 256 * coverage / FAST_SAMPLES_XY; coverage -= coverage >> 8; ptr += box->y1 * stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { *ptr = coverage; } else if (w == 1) { do { *ptr = coverage; ptr += stride; } while (--h); } else do { memset(ptr, coverage, w); ptr += stride; } while (--h); } static void tor_blt_mask_mono(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { tor_blt_mask(sna, op, clip, box, coverage < FAST_SAMPLES_XY/2 ? 0 : FAST_SAMPLES_XY); } bool imprecise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct tor tor; ScreenPtr screen = dst->pDrawable->pScreen; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int16_t dst_x, dst_y; int dx, dy; int error, n; if (NO_IMPRECISE) return false; if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!imprecise_trapezoid_mask_converter(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, &extents)) return true; DBG(("%s: ntraps=%d, extents (%d, %d), (%d, %d)\n", __FUNCTION__, ntrap, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); extents.y2 -= extents.y1; extents.x2 -= extents.x1; extents.x1 -= dst->pDrawable->x; extents.y1 -= dst->pDrawable->y; dst_x = extents.x1; dst_y = extents.y1; dx = -extents.x1 * FAST_SAMPLES_X; dy = -extents.y1 * FAST_SAMPLES_Y; extents.x1 = extents.y1 = 0; DBG(("%s: mask (%dx%d), dx=(%d, %d)\n", __FUNCTION__, extents.x2, extents.y2, dx, dy)); scratch = sna_pixmap_create_upload(screen, extents.x2, extents.y2, 8, KGEM_BUFFER_WRITE_INPLACE); if (!scratch) return true; DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); if (!tor_init(&tor, &extents, 2*ntrap)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) - dst_y >= extents.y2 || pixman_fixed_to_int(traps[n].bottom) - dst_y < 0) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (extents.x2 <= TOR_INPLACE_SIZE) { uint8_t buf[TOR_INPLACE_SIZE]; tor_inplace(&tor, scratch, is_mono(dst, maskFormat), scratch->usage_hint ? NULL : buf); } else { tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, is_mono(dst, maskFormat) ? tor_blt_mask_mono : tor_blt_mask, true); } tor_fini(&tor); mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { int16_t x0, y0; trapezoid_origin(&traps[0].left, &x0, &y0); CompositePicture(op, src, mask, dst, src_x + dst_x - x0, src_y + dst_y - y0, 0, 0, dst_x, dst_y, extents.x2, extents.y2); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); return true; } struct inplace { uint8_t *ptr; uint32_t stride; union { uint8_t opacity; uint32_t color; }; }; static force_inline uint8_t coverage_opacity(int coverage, uint8_t opacity) { coverage = coverage * 256 / FAST_SAMPLES_XY; coverage -= coverage >> 8; return opacity == 255 ? coverage : mul_8_8(coverage, opacity); } static void _tor_blt_src(struct inplace *in, const BoxRec *box, uint8_t v) { uint8_t *ptr = in->ptr; int h, w; ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { *ptr = v; } else if (w == 1) { do { *ptr = v; ptr += in->stride; } while (--h); } else do { memset(ptr, v, w); ptr += in->stride; } while (--h); } struct clipped_span { span_func_t span; const BoxRec *clip_start, *clip_end; }; static void tor_blt_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct clipped_span *cs = (struct clipped_span *)clip; const BoxRec *c; cs->clip_start = find_clip_box_for_y(cs->clip_start, cs->clip_end, box->y1); c = cs->clip_start; while (c != cs->clip_end) { BoxRec clipped; if (box->y2 <= c->y1) break; clipped = *box; if (!box_intersect(&clipped, c++)) continue; cs->span(sna, op, NULL, &clipped, coverage); } } inline static span_func_t clipped_span(struct clipped_span *cs, span_func_t span, const RegionRec *clip) { if (clip->data) { cs->span = span; region_get_boxes(clip, &cs->clip_start, &cs->clip_end); span = tor_blt_clipped; } return span; } static void tor_blt_src(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; _tor_blt_src(in, box, coverage_opacity(coverage, in->opacity)); } static void tor_blt_in(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint8_t *ptr = in->ptr; int h, w, i; if (coverage == 0) { _tor_blt_src(in, box, 0); return; } coverage = coverage_opacity(coverage, in->opacity); if (coverage == 0xff) return; ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; do { for (i = 0; i < w; i++) ptr[i] = mul_8_8(ptr[i], coverage); ptr += in->stride; } while (--h); } static void tor_blt_add(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint8_t *ptr = in->ptr; int h, w, v, i; if (coverage == 0) return; coverage = coverage_opacity(coverage, in->opacity); if (coverage == 0xff) { _tor_blt_src(in, box, 0xff); return; } ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { v = coverage + *ptr; *ptr = v >= 255 ? 255 : v; } else { do { for (i = 0; i < w; i++) { v = coverage + ptr[i]; ptr[i] = v >= 255 ? 255 : v; } ptr += in->stride; } while (--h); } } static void tor_blt_lerp32(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint32_t *ptr = (uint32_t *)in->ptr; int stride = in->stride / sizeof(uint32_t); int h, w, i; if (coverage == 0) return; sigtrap_assert_active(); ptr += box->y1 * stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if (coverage == FAST_SAMPLES_XY) { if ((w | h) == 1) { *ptr = in->color; } else { if (w < 16) { do { for (i = 0; i < w; i++) ptr[i] = in->color; ptr += stride; } while (--h); } else { pixman_fill(ptr, stride, 32, 0, 0, w, h, in->color); } } } else { coverage = coverage * 256 / FAST_SAMPLES_XY; coverage -= coverage >> 8; if ((w | h) == 1) { *ptr = lerp8x4(in->color, coverage, *ptr); } else if (w == 1) { do { *ptr = lerp8x4(in->color, coverage, *ptr); ptr += stride; } while (--h); } else{ do { for (i = 0; i < w; i++) ptr[i] = lerp8x4(in->color, coverage, ptr[i]); ptr += stride; } while (--h); } } } struct pixman_inplace { pixman_image_t *image, *source, *mask; uint32_t color; uint32_t *bits; int dx, dy; int sx, sy; uint8_t op; }; static void pixmask_span_solid(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct pixman_inplace *pi = (struct pixman_inplace *)op; if (coverage != FAST_SAMPLES_XY) { coverage = coverage * 256 / FAST_SAMPLES_XY; coverage -= coverage >> 8; *pi->bits = mul_4x8_8(pi->color, coverage); } else *pi->bits = pi->color; pixman_image_composite(pi->op, pi->source, NULL, pi->image, box->x1, box->y1, 0, 0, pi->dx + box->x1, pi->dy + box->y1, box->x2 - box->x1, box->y2 - box->y1); } static void pixmask_span(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct pixman_inplace *pi = (struct pixman_inplace *)op; pixman_image_t *mask = NULL; if (coverage != FAST_SAMPLES_XY) { coverage = coverage * 256 / FAST_SAMPLES_XY; coverage -= coverage >> 8; *pi->bits = coverage; mask = pi->mask; } pixman_image_composite(pi->op, pi->source, mask, pi->image, pi->sx + box->x1, pi->sy + box->y1, 0, 0, pi->dx + box->x1, pi->dy + box->y1, box->x2 - box->x1, box->y2 - box->y1); } struct inplace_x8r8g8b8_thread { xTrapezoid *traps; PicturePtr dst, src; BoxRec extents; int dx, dy; int ntrap; bool lerp, is_solid; uint32_t color; int16_t src_x, src_y; uint8_t op; }; static void inplace_x8r8g8b8_thread(void *arg) { struct inplace_x8r8g8b8_thread *thread = arg; struct tor tor; span_func_t span; struct clipped_span clipped; RegionPtr clip; int y1, y2, n; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; y1 = thread->extents.y1 - thread->dst->pDrawable->y; y2 = thread->extents.y2 - thread->dst->pDrawable->y; for (n = 0; n < thread->ntrap; n++) { if (pixman_fixed_to_int(thread->traps[n].top) >= y2 || pixman_fixed_to_int(thread->traps[n].bottom) < y1) continue; tor_add_trapezoid(&tor, &thread->traps[n], thread->dx, thread->dy); } clip = thread->dst->pCompositeClip; if (thread->lerp) { struct inplace inplace; int16_t dst_x, dst_y; PixmapPtr pixmap; pixmap = get_drawable_pixmap(thread->dst->pDrawable); inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(thread->dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x * 4; inplace.stride = pixmap->devKind; inplace.color = thread->color; span = clipped_span(&clipped, tor_blt_lerp32, clip); tor_render(NULL, &tor, (void*)&inplace, (void*)&clipped, span, false); } else if (thread->is_solid) { struct pixman_inplace pi; pi.image = image_from_pict(thread->dst, false, &pi.dx, &pi.dy); pi.op = thread->op; pi.color = thread->color; pi.bits = (uint32_t *)&pi.sx; pi.source = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, pi.bits, 0); pixman_image_set_repeat(pi.source, PIXMAN_REPEAT_NORMAL); span = clipped_span(&clipped, pixmask_span_solid, clip); tor_render(NULL, &tor, (void*)&pi, (void *)&clipped, span, false); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } else { struct pixman_inplace pi; int16_t x0, y0; trapezoid_origin(&thread->traps[0].left, &x0, &y0); pi.image = image_from_pict(thread->dst, false, &pi.dx, &pi.dy); pi.source = image_from_pict(thread->src, false, &pi.sx, &pi.sy); pi.sx += thread->src_x - x0; pi.sy += thread->src_y - y0; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = thread->op; span = clipped_span(&clipped, pixmask_span, clip); tor_render(NULL, &tor, (void*)&pi, (void *)&clipped, span, false); pixman_image_unref(pi.mask); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } tor_fini(&tor); } static bool trapezoid_span_inplace__x8r8g8b8(CARD8 op, PicturePtr dst, PicturePtr src, int16_t src_x, int16_t src_y, PictFormatPtr maskFormat, int ntrap, xTrapezoid *traps) { uint32_t color; bool lerp, is_solid; RegionRec region; int dx, dy; int num_threads, n; lerp = false; is_solid = sna_picture_is_solid(src, &color); if (is_solid) { if (op == PictOpOver && (color >> 24) == 0xff) op = PictOpSrc; if (op == PictOpOver && sna_drawable_is_clear(dst->pDrawable)) op = PictOpSrc; lerp = op == PictOpSrc; } if (!lerp) { switch (op) { case PictOpOver: case PictOpAdd: case PictOpOutReverse: break; case PictOpSrc: if (!sna_drawable_is_clear(dst->pDrawable)) return false; break; default: return false; } } if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, NULL, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, ®ion.extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (!sna_compute_composite_extents(®ion.extents, src, NULL, dst, src_x, src_y, 0, 0, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)) return true; DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, MOVE_WRITE | MOVE_READ)) return true; if (!is_solid && src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) return true; if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) return true; } dx = dst->pDrawable->x * FAST_SAMPLES_X; dy = dst->pDrawable->y * FAST_SAMPLES_Y; num_threads = sna_use_threads(4*(region.extents.x2 - region.extents.x1), region.extents.y2 - region.extents.y1, 16); DBG(("%s: %dx%d, format=%x, op=%d, lerp?=%d, num_threads=%d\n", __FUNCTION__, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, dst->format, op, lerp, num_threads)); if (num_threads == 1) { struct tor tor; span_func_t span; struct clipped_span clipped; if (!tor_init(&tor, ®ion.extents, 2*ntrap)) return true; for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) >= region.extents.y2 - dst->pDrawable->y || pixman_fixed_to_int(traps[n].bottom) < region.extents.y1 - dst->pDrawable->y) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (lerp) { struct inplace inplace; PixmapPtr pixmap; int16_t dst_x, dst_y; pixmap = get_drawable_pixmap(dst->pDrawable); inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x * 4; inplace.stride = pixmap->devKind; inplace.color = color; span = clipped_span(&clipped, tor_blt_lerp32, dst->pCompositeClip); DBG(("%s: render inplace op=%d, color=%08x\n", __FUNCTION__, op, color)); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&inplace, (void*)&clipped, span, false); sigtrap_put(); } } else if (is_solid) { struct pixman_inplace pi; pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.op = op; pi.color = color; pi.bits = (uint32_t *)&pi.sx; pi.source = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, pi.bits, 0); pixman_image_set_repeat(pi.source, PIXMAN_REPEAT_NORMAL); span = clipped_span(&clipped, pixmask_span_solid, dst->pCompositeClip); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&pi, (void*)&clipped, span, false); sigtrap_put(); } pixman_image_unref(pi.source); pixman_image_unref(pi.image); } else { struct pixman_inplace pi; int16_t x0, y0; trapezoid_origin(&traps[0].left, &x0, &y0); pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.source = image_from_pict(src, false, &pi.sx, &pi.sy); pi.sx += src_x - x0; pi.sy += src_y - y0; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = op; span = clipped_span(&clipped, pixmask_span, dst->pCompositeClip); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&pi, (void*)&clipped, span, false); sigtrap_put(); } pixman_image_unref(pi.mask); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } tor_fini(&tor); } else { struct inplace_x8r8g8b8_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for inplace compositing %dx%d\n", __FUNCTION__, num_threads, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)); threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = region.extents; threads[0].lerp = lerp; threads[0].is_solid = is_solid; threads[0].color = color; threads[0].dx = dx; threads[0].dy = dy; threads[0].dst = dst; threads[0].src = src; threads[0].op = op; threads[0].src_x = src_x; threads[0].src_y = src_y; y = region.extents.y1; h = region.extents.y2 - region.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, inplace_x8r8g8b8_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; inplace_x8r8g8b8_thread(&threads[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); /* leaks thread allocations */ } return true; } struct inplace_thread { xTrapezoid *traps; span_func_t span; struct inplace inplace; struct clipped_span clipped; BoxRec extents; int dx, dy; int draw_x, draw_y; bool unbounded; int ntrap; }; static void inplace_thread(void *arg) { struct inplace_thread *thread = arg; struct tor tor; int n; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; for (n = 0; n < thread->ntrap; n++) { if (pixman_fixed_to_int(thread->traps[n].top) >= thread->extents.y2 - thread->draw_y || pixman_fixed_to_int(thread->traps[n].bottom) < thread->extents.y1 - thread->draw_y) continue; tor_add_trapezoid(&tor, &thread->traps[n], thread->dx, thread->dy); } tor_render(NULL, &tor, (void*)&thread->inplace, (void*)&thread->clipped, thread->span, thread->unbounded); tor_fini(&tor); } bool imprecise_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback) { struct inplace inplace; struct clipped_span clipped; span_func_t span; PixmapPtr pixmap; struct sna_pixmap *priv; RegionRec region; uint32_t color; bool unbounded; int16_t dst_x, dst_y; int dx, dy; int num_threads, n; if (NO_IMPRECISE) return false; if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) return trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, maskFormat, ntrap, traps); if (!sna_picture_is_solid(src, &color)) { DBG(("%s: fallback -- can not perform operation in place, requires solid source\n", __FUNCTION__)); return false; } if (dst->format != PICT_a8) { DBG(("%s: fallback -- can not perform operation in place, format=%x\n", __FUNCTION__, dst->format)); return false; } pixmap = get_drawable_pixmap(dst->pDrawable); unbounded = false; priv = sna_pixmap(pixmap); if (priv) { switch (op) { case PictOpAdd: if (priv->clear && priv->clear_color == 0) { unbounded = true; op = PictOpSrc; } if ((color >> 24) == 0) return true; break; case PictOpIn: if (priv->clear && priv->clear_color == 0) return true; if (priv->clear && priv->clear_color == 0xff) op = PictOpSrc; unbounded = true; break; case PictOpSrc: unbounded = true; break; default: DBG(("%s: fallback -- can not perform op [%d] in place\n", __FUNCTION__, op)); return false; } } else { switch (op) { case PictOpAdd: if ((color >> 24) == 0) return true; break; case PictOpIn: case PictOpSrc: unbounded = true; break; default: DBG(("%s: fallback -- can not perform op [%d] in place\n", __FUNCTION__, op)); return false; } } DBG(("%s: format=%x, op=%d, color=%x\n", __FUNCTION__, dst->format, op, color)); if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!imprecise_trapezoid_span_inplace(sna, op, src, dst, NULL, flags, src_x, src_y, 1, traps++, fallback)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, ®ion.extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (!sna_compute_composite_extents(®ion.extents, NULL, NULL, dst, 0, 0, 0, 0, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)) return true; DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (op == PictOpSrc) { span = tor_blt_src; } else if (op == PictOpIn) { span = tor_blt_in; } else { assert(op == PictOpAdd); span = tor_blt_add; } DBG(("%s: move-to-cpu\n", __FUNCTION__)); region.data = NULL; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, op == PictOpSrc ? MOVE_WRITE | MOVE_INPLACE_HINT : MOVE_WRITE | MOVE_READ)) return true; dx = dst->pDrawable->x * FAST_SAMPLES_X; dy = dst->pDrawable->y * FAST_SAMPLES_Y; inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x; inplace.stride = pixmap->devKind; inplace.opacity = color >> 24; span = clipped_span(&clipped, span, dst->pCompositeClip); num_threads = 1; if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) num_threads = sna_use_threads(region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, 16); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, ®ion.extents, 2*ntrap)) return true; for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) >= region.extents.y2 - dst->pDrawable->y || pixman_fixed_to_int(traps[n].bottom) < region.extents.y1 - dst->pDrawable->y) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&inplace, (void *)&clipped, span, unbounded); sigtrap_put(); } tor_fini(&tor); } else { struct inplace_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for inplace compositing %dx%d\n", __FUNCTION__, num_threads, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)); threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].inplace = inplace; threads[0].clipped = clipped; threads[0].extents = region.extents; threads[0].span = span; threads[0].unbounded = unbounded; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_x = dst->pDrawable->x; threads[0].draw_y = dst->pDrawable->y; y = region.extents.y1; h = region.extents.y2 - region.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, inplace_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; inplace_thread(&threads[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); /* leaks thread allocations */ } return true; } bool imprecise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct tor tor; ScreenPtr screen = dst->pDrawable->pScreen; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int16_t dst_x, dst_y; int dx, dy; int error, n; if (NO_IMPRECISE) return false; if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!imprecise_trapezoid_span_fallback(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, &extents)) return true; DBG(("%s: ntraps=%d, extents (%d, %d), (%d, %d)\n", __FUNCTION__, ntrap, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); extents.y2 -= extents.y1; extents.x2 -= extents.x1; extents.x1 -= dst->pDrawable->x; extents.y1 -= dst->pDrawable->y; dst_x = extents.x1; dst_y = extents.y1; dx = -extents.x1 * FAST_SAMPLES_X; dy = -extents.y1 * FAST_SAMPLES_Y; extents.x1 = extents.y1 = 0; DBG(("%s: mask (%dx%d), dx=(%d, %d)\n", __FUNCTION__, extents.x2, extents.y2, dx, dy)); scratch = sna_pixmap_create_unattached(screen, extents.x2, extents.y2, 8); if (!scratch) return true; DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); if (!tor_init(&tor, &extents, 2*ntrap)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) - dst_y >= extents.y2 || pixman_fixed_to_int(traps[n].bottom) - dst_y < 0) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (extents.x2 <= TOR_INPLACE_SIZE) { tor_inplace(&tor, scratch, is_mono(dst, maskFormat), NULL); } else { tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, is_mono(dst, maskFormat) ? tor_blt_mask_mono : tor_blt_mask, true); } tor_fini(&tor); mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { RegionRec region; int16_t x0, y0; region.extents.x1 = dst_x + dst->pDrawable->x; region.extents.y1 = dst_y + dst->pDrawable->y; region.extents.x2 = region.extents.x1 + extents.x2; region.extents.y2 = region.extents.y1 + extents.y2; region.data = NULL; trapezoid_origin(&traps[0].left, &x0, &y0); DBG(("%s: fbComposite()\n", __FUNCTION__)); sna_composite_fb(op, src, mask, dst, ®ion, src_x + dst_x - x0, src_y + dst_y - y0, 0, 0, dst_x, dst_y, extents.x2, extents.y2); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); return true; } bool imprecise_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap) { struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; pixman_region16_t *clip; int dx, dy, n; if (dst->pDrawable->depth < 8) return false; if (!sna->render.check_composite_spans(sna, PictOpAdd, sna->render.white_picture, dst, dst->pCompositeClip->extents.x2 - dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y2 - dst->pCompositeClip->extents.y1, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } clip = dst->pCompositeClip; extents = *RegionExtents(clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy)); memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite_spans(sna, PictOpAdd, sna->render.white_picture, dst, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, 0, &tmp)) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= FAST_SAMPLES_X; dy *= FAST_SAMPLES_Y; if (!tor_init(&tor, &extents, 2*ntrap)) goto skip; for (n = 0; n < ntrap; n++) { xPointFixed p1, p2; if (pixman_fixed_to_int(trap[n].top.y) + dst->pDrawable->y >= extents.y2 || pixman_fixed_to_int(trap[n].bot.y) + dst->pDrawable->y < extents.y1) continue; p1.y = trap[n].top.y; p2.y = trap[n].bot.y; p1.x = trap[n].top.l; p2.x = trap[n].bot.l; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); p1.y = trap[n].bot.y; p2.y = trap[n].top.y; p1.x = trap[n].top.r; p2.x = trap[n].bot.r; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); } tor_render(sna, &tor, &tmp, clip, choose_span(&tmp, dst, NULL, clip), false); tor_fini(&tor); skip: tmp.done(sna, &tmp); return true; } static void mark_damaged(PixmapPtr pixmap, struct sna_pixmap *priv, BoxPtr box, int16_t x, int16_t y) { box->x1 += x; box->x2 += x; box->y1 += y; box->y2 += y; if (box->x1 <= 0 && box->y1 <= 0 && box->x2 >= pixmap->drawable.width && box->y2 >= pixmap->drawable.height) { sna_damage_destroy(&priv->cpu_damage); sna_damage_all(&priv->gpu_damage, pixmap); list_del(&priv->flush_list); } else { sna_damage_add_box(&priv->gpu_damage, box); sna_damage_subtract_box(&priv->cpu_damage, box); } } bool trap_mask_converter(struct sna *sna, PicturePtr picture, INT16 x, INT16 y, int ntrap, xTrap *trap) { struct tor tor; ScreenPtr screen = picture->pDrawable->pScreen; PixmapPtr scratch, pixmap; struct sna_pixmap *priv; BoxRec extents; span_func_t span; int dx, dy, n; if (NO_SCAN_CONVERTER) return false; pixmap = get_drawable_pixmap(picture->pDrawable); priv = sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_WRITE); if (priv == NULL) return false; /* XXX strict adherence to the Render specification */ if (picture->polyMode == PolyModePrecise && picture->polyEdge != PolyEdgeSharp) { DBG(("%s: fallback -- precise rasterisation requested\n", __FUNCTION__)); return false; } extents = *RegionExtents(picture->pCompositeClip); for (n = 0; n < ntrap; n++) { int v; v = x + pixman_fixed_integer_floor (MIN(trap[n].top.l, trap[n].bot.l)); if (v < extents.x1) extents.x1 = v; v = x + pixman_fixed_integer_ceil (MAX(trap[n].top.r, trap[n].bot.r)); if (v > extents.x2) extents.x2 = v; v = y + pixman_fixed_integer_floor (trap[n].top.y); if (v < extents.y1) extents.y1 = v; v = y + pixman_fixed_integer_ceil (trap[n].bot.y); if (v > extents.y2) extents.y2 = v; } DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); scratch = sna_pixmap_create_upload(screen, extents.x2-extents.x1, extents.y2-extents.y1, 8, KGEM_BUFFER_WRITE_INPLACE); if (!scratch) return true; dx = picture->pDrawable->x; dy = picture->pDrawable->y; dx *= FAST_SAMPLES_X; dy *= FAST_SAMPLES_Y; if (!tor_init(&tor, &extents, 2*ntrap)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < ntrap; n++) { xPointFixed p1, p2; if (pixman_fixed_to_int(trap[n].top.y) + picture->pDrawable->y >= extents.y2 || pixman_fixed_to_int(trap[n].bot.y) + picture->pDrawable->y < extents.y1) continue; p1.y = trap[n].top.y; p2.y = trap[n].bot.y; p1.x = trap[n].top.l; p2.x = trap[n].bot.l; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); p1.y = trap[n].bot.y; p2.y = trap[n].top.y; p1.x = trap[n].top.r; p2.x = trap[n].bot.r; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); } if (picture->polyEdge == PolyEdgeSharp) span = tor_blt_mask_mono; else span = tor_blt_mask; tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, span, true); tor_fini(&tor); /* XXX clip boxes */ get_drawable_deltas(picture->pDrawable, pixmap, &x, &y); sna = to_sna_from_screen(screen); sna->render.copy_boxes(sna, GXcopy, &scratch->drawable, __sna_pixmap_get_bo(scratch), -extents.x1, -extents.x1, &pixmap->drawable, priv->gpu_bo, x, y, &extents, 1, 0); mark_damaged(pixmap, priv, &extents ,x, y); sna_pixmap_destroy(scratch); return true; } bool triangles_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xTriangle *tri) { struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; pixman_region16_t clip; int16_t dst_x, dst_y; int dx, dy, n; bool was_clear; if (NO_SCAN_CONVERTER) return false; if (is_mono(dst, maskFormat)) return mono_triangles_span_converter(sna, op, src, dst, src_x, src_y, count, tri); /* XXX strict adherence to the Render specification */ if (dst->polyMode == PolyModePrecise) { DBG(("%s: fallback -- precise rasterisation requested\n", __FUNCTION__)); return false; } if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } dst_x = pixman_fixed_to_int(tri[0].p1.x); dst_y = pixman_fixed_to_int(tri[0].p1.y); miTriangleBounds(count, tri, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; #if 0 if (extents.y2 - extents.y1 < 64 && extents.x2 - extents.x1 < 64) { DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, extents.y2 - extents.y1, extents.x2 - extents.x1)); return false; } #endif if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: triangles do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } extents = *RegionExtents(&clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite_spans(sna, op, src, dst, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, 0, &tmp)) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= FAST_SAMPLES_X; dy *= FAST_SAMPLES_Y; if (!tor_init(&tor, &extents, 3*count)) goto skip; for (n = 0; n < count; n++) { polygon_add_line(tor.polygon, &tri[n].p1, &tri[n].p2, dx, dy); polygon_add_line(tor.polygon, &tri[n].p2, &tri[n].p3, dx, dy); polygon_add_line(tor.polygon, &tri[n].p3, &tri[n].p1, dx, dy); } tor_render(sna, &tor, &tmp, &clip, choose_span(&tmp, dst, maskFormat, &clip), !was_clear && maskFormat && !operator_is_bounded(op)); tor_fini(&tor); skip: tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } bool triangles_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xTriangle *tri) { struct tor tor; void (*span)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage); ScreenPtr screen = dst->pDrawable->pScreen; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int16_t dst_x, dst_y; int dx, dy; int error, n; if (NO_SCAN_CONVERTER) return false; if (is_precise(dst, maskFormat)) { DBG(("%s: fallback -- precise rasterisation requested\n", __FUNCTION__)); return false; } if (maskFormat == NULL && count > 1) { DBG(("%s: fallback -- individual rasterisation requested\n", __FUNCTION__)); return false; } miTriangleBounds(count, tri, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); extents.y2 -= extents.y1; extents.x2 -= extents.x1; extents.x1 -= dst->pDrawable->x; extents.y1 -= dst->pDrawable->y; dst_x = extents.x1; dst_y = extents.y1; dx = -extents.x1 * FAST_SAMPLES_X; dy = -extents.y1 * FAST_SAMPLES_Y; extents.x1 = extents.y1 = 0; DBG(("%s: mask (%dx%d)\n", __FUNCTION__, extents.x2, extents.y2)); scratch = sna_pixmap_create_upload(screen, extents.x2, extents.y2, 8, KGEM_BUFFER_WRITE_INPLACE); if (!scratch) return true; DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); if (!tor_init(&tor, &extents, 3*count)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < count; n++) { polygon_add_line(tor.polygon, &tri[n].p1, &tri[n].p2, dx, dy); polygon_add_line(tor.polygon, &tri[n].p2, &tri[n].p3, dx, dy); polygon_add_line(tor.polygon, &tri[n].p3, &tri[n].p1, dx, dy); } if (maskFormat ? maskFormat->depth < 8 : dst->polyEdge == PolyEdgeSharp) span = tor_blt_mask_mono; else span = tor_blt_mask; tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, span, true); mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { CompositePicture(op, src, mask, dst, src_x + dst_x - pixman_fixed_to_int(tri[0].p1.x), src_y + dst_y - pixman_fixed_to_int(tri[0].p1.y), 0, 0, dst_x, dst_y, extents.x2, extents.y2); FreePicture(mask, 0); } tor_fini(&tor); sna_pixmap_destroy(scratch); return true; } struct tristrip_thread { struct sna *sna; const struct sna_composite_spans_op *op; const xPointFixed *points; RegionPtr clip; span_func_t span; BoxRec extents; int dx, dy, draw_y; int count; bool unbounded; }; static void tristrip_thread(void *arg) { struct tristrip_thread *thread = arg; struct span_thread_boxes boxes; struct tor tor; int n, cw, ccw; if (!tor_init(&tor, &thread->extents, 2*thread->count)) return; span_thread_boxes_init(&boxes, thread->op, thread->clip); cw = 0; ccw = 1; polygon_add_line(tor.polygon, &thread->points[ccw], &thread->points[cw], thread->dx, thread->dy); n = 2; do { polygon_add_line(tor.polygon, &thread->points[cw], &thread->points[n], thread->dx, thread->dy); cw = n; if (++n == thread->count) break; polygon_add_line(tor.polygon, &thread->points[n], &thread->points[ccw], thread->dx, thread->dy); ccw = n; if (++n == thread->count) break; } while (1); polygon_add_line(tor.polygon, &thread->points[cw], &thread->points[ccw], thread->dx, thread->dy); assert(tor.polygon->num_edges <= 2*thread->count); tor_render(thread->sna, &tor, (struct sna_composite_spans_op *)&boxes, thread->clip, thread->span, thread->unbounded); tor_fini(&tor); if (boxes.num_boxes) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, boxes.num_boxes)); assert(boxes.num_boxes <= SPAN_THREAD_MAX_BOXES); thread->op->thread_boxes(thread->sna, thread->op, boxes.boxes, boxes.num_boxes); } } bool imprecise_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points) { struct sna_composite_spans_op tmp; BoxRec extents; pixman_region16_t clip; int16_t dst_x, dst_y; int dx, dy, num_threads; bool was_clear; if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } dst_x = pixman_fixed_to_int(points[0].x); dst_y = pixman_fixed_to_int(points[0].y); miPointFixedBounds(count, points, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; #if 0 if (extents.y2 - extents.y1 < 64 && extents.x2 - extents.x1 < 64) { DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, extents.y2 - extents.y1, extents.x2 - extents.x1)); return false; } #endif if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: triangles do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } extents = *RegionExtents(&clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite_spans(sna, op, src, dst, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, 0, &tmp)) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= FAST_SAMPLES_X; dy *= FAST_SAMPLES_Y; num_threads = 1; if (!NO_GPU_THREADS && tmp.thread_boxes && thread_choose_span(&tmp, dst, maskFormat, &clip)) num_threads = sna_use_threads(extents.x2 - extents.x1, extents.y2 - extents.y1, 16); if (num_threads == 1) { struct tor tor; int cw, ccw, n; if (!tor_init(&tor, &extents, 2*count)) goto skip; cw = 0; ccw = 1; polygon_add_line(tor.polygon, &points[ccw], &points[cw], dx, dy); n = 2; do { polygon_add_line(tor.polygon, &points[cw], &points[n], dx, dy); cw = n; if (++n == count) break; polygon_add_line(tor.polygon, &points[n], &points[ccw], dx, dy); ccw = n; if (++n == count) break; } while (1); polygon_add_line(tor.polygon, &points[cw], &points[ccw], dx, dy); assert(tor.polygon->num_edges <= 2*count); tor_render(sna, &tor, &tmp, &clip, choose_span(&tmp, dst, maskFormat, &clip), !was_clear && maskFormat && !operator_is_bounded(op)); tor_fini(&tor); } else { struct tristrip_thread threads[num_threads]; int y, h, n; DBG(("%s: using %d threads for tristrip compositing %dx%d\n", __FUNCTION__, num_threads, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)); threads[0].sna = sna; threads[0].op = &tmp; threads[0].points = points; threads[0].count = count; threads[0].extents = clip.extents; threads[0].clip = &clip; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_y = dst->pDrawable->y; threads[0].unbounded = !was_clear && maskFormat && !operator_is_bounded(op); threads[0].span = thread_choose_span(&tmp, dst, maskFormat, &clip); y = clip.extents.y1; h = clip.extents.y2 - clip.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= clip.extents.y2 - clip.extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, tristrip_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; tristrip_thread(&threads[0]); sna_threads_wait(); } skip: tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids_mono.c000066400000000000000000001222241267532330400260670ustar00rootroot00000000000000/* * Copyright (c) 2007 David Turner * Copyright (c) 2008 M Joonas Pihlaja * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_trapezoids.h" #include "fb/fbpict.h" #include struct quorem { int32_t quo; int64_t rem; }; struct mono_edge { struct mono_edge *next, *prev; int32_t height_left; int32_t dir; int64_t dy; struct quorem x; struct quorem dxdy; }; struct mono_polygon { int num_edges; struct mono_edge *edges; struct mono_edge **y_buckets; struct mono_edge *y_buckets_embedded[64]; struct mono_edge edges_embedded[32]; }; struct mono { /* Leftmost edge on the current scan line. */ struct mono_edge head, tail; int is_vertical; struct sna *sna; struct sna_composite_op op; pixman_region16_t clip; const BoxRec *clip_start, *clip_end; fastcall void (*span)(struct mono *, int, int, BoxPtr); struct mono_polygon polygon; }; #define I(x) pixman_fixed_to_int((x) + pixman_fixed_1_minus_e/2) static struct quorem floored_muldivrem(int32_t x, int32_t a, int32_t b) { struct quorem qr; int64_t xa = (int64_t)x*a; qr.quo = xa/b; qr.rem = xa%b; if (qr.rem < 0) { qr.quo -= 1; qr.rem += b; } return qr; } #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif static void apply_damage(struct sna_composite_op *op, RegionPtr region) { DBG(("%s: damage=%p, region=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, op->damage, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (op->damage == NULL) return; RegionTranslate(region, op->dst.x, op->dst.y); assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region)); sna_damage_add(op->damage, region); } static void _apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { BoxRec r; r.x1 = box->x1 + op->dst.x; r.x2 = box->x2 + op->dst.x; r.y1 = box->y1 + op->dst.y; r.y2 = box->y2 + op->dst.y; assert_pixmap_contains_box(op->dst.pixmap, &r); sna_damage_add_box(op->damage, &r); } inline static void apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { if (op->damage) _apply_damage_box(op, box); } static bool mono_polygon_init(struct mono_polygon *polygon, BoxPtr box, int num_edges) { unsigned h = box->y2 - box->y1; polygon->y_buckets = polygon->y_buckets_embedded; if (h > ARRAY_SIZE (polygon->y_buckets_embedded)) { polygon->y_buckets = malloc (h * sizeof (struct mono_edge *)); if (unlikely (NULL == polygon->y_buckets)) return false; } polygon->num_edges = 0; polygon->edges = polygon->edges_embedded; if (num_edges > (int)ARRAY_SIZE (polygon->edges_embedded)) { polygon->edges = malloc (num_edges * sizeof (struct mono_edge)); if (unlikely (polygon->edges == NULL)) { if (polygon->y_buckets != polygon->y_buckets_embedded) free(polygon->y_buckets); return false; } } memset(polygon->y_buckets, 0, h * sizeof (struct edge *)); return true; } static void mono_polygon_fini(struct mono_polygon *polygon) { if (polygon->y_buckets != polygon->y_buckets_embedded) free(polygon->y_buckets); if (polygon->edges != polygon->edges_embedded) free(polygon->edges); } static void mono_add_line(struct mono *mono, int dst_x, int dst_y, xFixed top, xFixed bottom, const xPointFixed *p1, const xPointFixed *p2, int dir) { struct mono_polygon *polygon = &mono->polygon; struct mono_edge *e; int y, ytop, ybot; __DBG(("%s: top=%d, bottom=%d, line=(%d, %d), (%d, %d) delta=%dx%d, dir=%d\n", __FUNCTION__, (int)top, (int)bottom, (int)p1->x, (int)p1->y, (int)p2->x, (int)p2->y, dst_x, dst_y, dir)); if (top > bottom) { const xPointFixed *t; y = top; top = bottom; bottom = y; t = p1; p1 = p2; p2 = t; dir = -dir; } y = I(top) + dst_y; ytop = MAX(y, mono->clip.extents.y1); y = I(bottom) + dst_y; ybot = MIN(y, mono->clip.extents.y2); __DBG(("%s: edge height [%d, %d] = %d\n", __FUNCTION__, ytop, ybot, ybot - ytop)); if (ybot <= ytop) { __DBG(("discard clipped line\n")); return; } e = polygon->edges + polygon->num_edges++; e->height_left = ybot - ytop; e->dir = dir; if (I(p1->x) == I(p2->x)) { __DBG(("%s: vertical edge x:%d\n", __FUNCTION__, I(p1->x))); e->x.quo = p1->x; e->x.rem = 0; e->dxdy.quo = 0; e->dxdy.rem = 0; e->dy = 0; } else { int64_t dx = (int64_t)p2->x - p1->x; int64_t dy = (int64_t)p2->y - p1->y; __DBG(("%s: diagonal edge (%d, %d), x:[%d, %d]\n", __FUNCTION__, dx, dy, I(p1->x), I(p2->x))); assert(dy > 0); e->dxdy = floored_muldivrem(dx, pixman_fixed_1, dy); e->x = floored_muldivrem((ytop - dst_y) * pixman_fixed_1 + pixman_fixed_1/2 - p1->y, dx, dy); e->x.quo += p1->x; e->x.rem -= dy; e->dy = dy; } e->x.quo += dst_x*pixman_fixed_1; __DBG(("%s: initial x=%d [%d.%d/%d] + dxdy=%d.%d/%d\n", __FUNCTION__, I(e->x.quo), e->x.quo, e->x.rem, e->dy, e->dxdy.quo, e->dxdy.rem, e->dy)); { struct mono_edge **ptail = &polygon->y_buckets[ytop - mono->clip.extents.y1]; assert(ytop - mono->clip.extents.y1 < mono->clip.extents.y2 - mono->clip.extents.y1); if (*ptail) (*ptail)->prev = e; e->next = *ptail; e->prev = NULL; *ptail = e; } } static struct mono_edge * mono_merge_sorted_edges(struct mono_edge *head_a, struct mono_edge *head_b) { struct mono_edge *head, **next, *prev; int32_t x; if (head_b == NULL) return head_a; prev = head_a->prev; next = &head; if (head_a->x.quo <= head_b->x.quo) { head = head_a; } else { head = head_b; head_b->prev = prev; goto start_with_b; } do { x = head_b->x.quo; while (head_a != NULL && head_a->x.quo <= x) { prev = head_a; next = &head_a->next; head_a = head_a->next; } head_b->prev = prev; *next = head_b; if (head_a == NULL) return head; start_with_b: x = head_a->x.quo; while (head_b != NULL && head_b->x.quo <= x) { prev = head_b; next = &head_b->next; head_b = head_b->next; } head_a->prev = prev; *next = head_a; if (head_b == NULL) return head; } while (1); } static struct mono_edge * mono_sort_edges(struct mono_edge *list, unsigned int level, struct mono_edge **head_out) { struct mono_edge *head_other, *remaining; unsigned int i; head_other = list->next; if (head_other == NULL) { *head_out = list; return NULL; } remaining = head_other->next; if (list->x.quo <= head_other->x.quo) { *head_out = list; head_other->next = NULL; } else { *head_out = head_other; head_other->prev = list->prev; head_other->next = list; list->prev = head_other; list->next = NULL; } for (i = 0; i < level && remaining; i++) { remaining = mono_sort_edges(remaining, i, &head_other); *head_out = mono_merge_sorted_edges(*head_out, head_other); } return remaining; } static struct mono_edge *mono_filter(struct mono_edge *edges) { struct mono_edge *e; e = edges; while (e->next) { struct mono_edge *n = e->next; if (e->dir == -n->dir && e->height_left == n->height_left && e->x.quo == n->x.quo && e->x.rem == n->x.rem && e->dxdy.quo == n->dxdy.quo && e->dxdy.rem == n->dxdy.rem) { assert(e->dy == n->dy); __DBG(("%s: discarding cancellation pair (%d.%d) + (%d.%d)\n", __FUNCTION__, e->x.quo, e->x.rem, e->dxdy.quo, e->dxdy.rem)); if (e->prev) e->prev->next = n->next; else edges = n->next; if (n->next) n->next->prev = e->prev; else break; e = n->next; } else { __DBG(("%s: adding edge (%d.%d) + (%d.%d)/%d, height=%d\n", __FUNCTION__, n->x.quo, n->x.rem, n->dxdy.quo, n->dxdy.rem, n->dy, n->height_left)); e = n; } } return edges; } static struct mono_edge * mono_merge_unsorted_edges(struct mono_edge *head, struct mono_edge *unsorted) { mono_sort_edges(unsorted, UINT_MAX, &unsorted); return mono_merge_sorted_edges(head, mono_filter(unsorted)); } #if 0 static inline void __dbg_mono_edges(const char *function, struct mono_edge *edges) { DBG(("%s: ", function)); while (edges) { if (edges->x.quo < INT16_MAX << 16) { DBG(("(%d.%06d)+(%d.%06d)x%d, ", edges->x.quo, edges->x.rem, edges->dxdy.quo, edges->dxdy.rem, edges->dy*edges->dir)); } edges = edges->next; } DBG(("\n")); } #define DBG_MONO_EDGES(x) __dbg_mono_edges(__FUNCTION__, x) static inline void VALIDATE_MONO_EDGES(struct mono_edge *edges) { int prev_x = edges->x.quo; while ((edges = edges->next)) { assert(edges->x.quo >= prev_x); prev_x = edges->x.quo; } } #else #define DBG_MONO_EDGES(x) #define VALIDATE_MONO_EDGES(x) #endif inline static void mono_merge_edges(struct mono *c, struct mono_edge *edges) { struct mono_edge *e; DBG_MONO_EDGES(edges); for (e = edges; c->is_vertical && e; e = e->next) c->is_vertical = e->dy == 0; c->head.next = mono_merge_unsorted_edges(c->head.next, edges); } fastcall static void mono_span(struct mono *c, int x1, int x2, BoxPtr box) { __DBG(("%s [%d, %d]\n", __FUNCTION__, x1, x2)); box->x1 = x1; box->x2 = x2; if (c->clip.data) { pixman_region16_t region; pixman_region_init_rects(®ion, box, 1); RegionIntersect(®ion, ®ion, &c->clip); if (region_num_rects(®ion)) { c->op.boxes(c->sna, &c->op, region_rects(®ion), region_num_rects(®ion)); apply_damage(&c->op, ®ion); } pixman_region_fini(®ion); } else { c->op.box(c->sna, &c->op, box); apply_damage_box(&c->op, box); } } fastcall static void mono_span__fast(struct mono *c, int x1, int x2, BoxPtr box) { __DBG(("%s [%d, %d]\n", __FUNCTION__, x1, x2)); box->x1 = x1; box->x2 = x2; c->op.box(c->sna, &c->op, box); } fastcall static void mono_span__clipped(struct mono *c, int x1, int x2, BoxPtr box) { const BoxRec *b; __DBG(("%s [%d, %d]\n", __FUNCTION__, x1, x2)); c->clip_start = find_clip_box_for_y(c->clip_start, c->clip_end, box->y1); b = c->clip_start; while (b != c->clip_end) { BoxRec clipped; if (box->y2 <= b->y1) break; clipped.x1 = x1; clipped.x2 = x2; clipped.y1 = box->y1; clipped.y2 = box->y2; if (!box_intersect(&clipped, b++)) continue; c->op.box(c->sna, &c->op, &clipped); } } struct mono_span_thread_boxes { const struct sna_composite_op *op; #define MONO_SPAN_MAX_BOXES (8192/sizeof(BoxRec)) BoxRec boxes[MONO_SPAN_MAX_BOXES]; int num_boxes; }; inline static void thread_mono_span_add_box(struct mono *c, const BoxRec *box) { struct mono_span_thread_boxes *b = c->op.priv; if (unlikely(b->num_boxes == MONO_SPAN_MAX_BOXES)) { b->op->thread_boxes(c->sna, b->op, b->boxes, b->num_boxes); b->num_boxes = 0; } b->boxes[b->num_boxes++] = *box; assert(b->num_boxes <= MONO_SPAN_MAX_BOXES); } fastcall static void thread_mono_span_clipped(struct mono *c, int x1, int x2, BoxPtr box) { const BoxRec *b; __DBG(("%s [%d, %d]\n", __FUNCTION__, x1, x2)); c->clip_start = find_clip_box_for_y(c->clip_start, c->clip_end, box->y1); b = c->clip_start; while (b != c->clip_end) { BoxRec clipped; if (box->y2 <= b->y1) break; clipped.x1 = x1; clipped.x2 = x2; clipped.y1 = box->y1; clipped.y2 = box->y2; if (!box_intersect(&clipped, b++)) continue; thread_mono_span_add_box(c, &clipped); } } fastcall static void thread_mono_span(struct mono *c, int x1, int x2, BoxPtr box) { __DBG(("%s [%d, %d]\n", __FUNCTION__, x1, x2)); box->x1 = x1; box->x2 = x2; thread_mono_span_add_box(c, box); } inline static void mono_row(struct mono *c, int16_t y, int16_t h) { struct mono_edge *edge = c->head.next; int prev_x = INT_MIN; int16_t xstart = INT16_MIN; int winding = 0; BoxRec box; __DBG(("%s: y=%d, h=%d\n", __FUNCTION__, y, h)); DBG_MONO_EDGES(edge); VALIDATE_MONO_EDGES(&c->head); box.y1 = c->clip.extents.y1 + y; box.y2 = box.y1 + h; while (&c->tail != edge) { struct mono_edge *next = edge->next; int16_t xend = I(edge->x.quo); __DBG(("%s: adding edge dir=%d [winding=%d], x=%d [%d]\n", __FUNCTION__, edge->dir, winding + edge->dir, xend, edge->x.quo)); if (--edge->height_left) { if (edge->dy) { edge->x.quo += edge->dxdy.quo; edge->x.rem += edge->dxdy.rem; if (edge->x.rem >= 0) { ++edge->x.quo; edge->x.rem -= edge->dy; } __DBG(("%s: stepped edge (%d.%d) + (%d.%d)/%d, height=%d, prev_x=%d\n", __FUNCTION__, edge->x.quo, edge->x.rem, edge->dxdy.quo, edge->dxdy.rem, edge->dy, edge->height_left, edge->x.quo)); } if (edge->x.quo < prev_x) { struct mono_edge *pos = edge->prev; pos->next = next; next->prev = pos; do { pos = pos->prev; } while (edge->x.quo < pos->x.quo); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->x.quo; } else { edge->prev->next = next; next->prev = edge->prev; } winding += edge->dir; if (winding == 0) { assert(I(next->x.quo) >= xend); if (I(next->x.quo) > xend) { __DBG(("%s: end span: %d\n", __FUNCTION__, xend)); if (xstart < c->clip.extents.x1) xstart = c->clip.extents.x1; if (xend > c->clip.extents.x2) xend = c->clip.extents.x2; if (xend > xstart) { __DBG(("%s: emit span [%d, %d]\n", __FUNCTION__, xstart, xend)); c->span(c, xstart, xend, &box); } xstart = INT16_MIN; } } else if (xstart == INT16_MIN) { __DBG(("%s: starting new span: %d\n", __FUNCTION__, xend)); xstart = xend; } edge = next; } DBG_MONO_EDGES(c->head.next); VALIDATE_MONO_EDGES(&c->head); } static bool mono_init(struct mono *c, int num_edges) { if (!mono_polygon_init(&c->polygon, &c->clip.extents, num_edges)) return false; c->head.dy = 0; c->head.height_left = INT_MAX; c->head.x.quo = INT16_MIN << 16; c->head.prev = NULL; c->head.next = &c->tail; c->tail.prev = &c->head; c->tail.next = NULL; c->tail.x.quo = INT16_MAX << 16; c->tail.height_left = INT_MAX; c->tail.dy = 0; c->is_vertical = 1; return true; } static void mono_fini(struct mono *mono) { mono_polygon_fini(&mono->polygon); } static void mono_step_edges(struct mono *c, int count) { struct mono_edge *edge; for (edge = c->head.next; edge != &c->tail; edge = edge->next) { edge->height_left -= count; if (! edge->height_left) { edge->prev->next = edge->next; edge->next->prev = edge->prev; } } } flatten static void mono_render(struct mono *mono) { struct mono_polygon *polygon = &mono->polygon; int i, j, h = mono->clip.extents.y2 - mono->clip.extents.y1; assert(mono->span); for (i = 0; i < h; i = j) { j = i + 1; __DBG(("%s: row=%d, new edges? %d\n", __FUNCTION__, i, polygon->y_buckets[i] != NULL)); if (polygon->y_buckets[i]) mono_merge_edges(mono, polygon->y_buckets[i]); __DBG(("%s: row=%d, vertical? %d\n", __FUNCTION__, i, mono->is_vertical)); if (mono->is_vertical) { struct mono_edge *e = mono->head.next; int min_height = h - i; while (e != &mono->tail) { if (e->height_left < min_height) min_height = e->height_left; e = e->next; } while (--min_height >= 1 && polygon->y_buckets[j] == NULL) j++; if (j != i + 1) mono_step_edges(mono, j - (i + 1)); __DBG(("%s: %d vertical rows\n", __FUNCTION__, j-i)); } mono_row(mono, i, j-i); /* XXX recompute after dropping edges? */ if (mono->head.next == &mono->tail) mono->is_vertical = 1; } } static int operator_is_bounded(uint8_t op) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: return true; default: return false; } } struct mono_span_thread { struct sna *sna; const xTrapezoid *traps; const struct sna_composite_op *op; RegionPtr clip; int ntrap; BoxRec extents; int dx, dy; }; static void mono_span_thread(void *arg) { struct mono_span_thread *thread = arg; struct mono mono; struct mono_span_thread_boxes boxes; const xTrapezoid *t; int n; mono.sna = thread->sna; mono.clip.extents = thread->extents; mono.clip.data = NULL; if (thread->clip->data) { RegionIntersect(&mono.clip, &mono.clip, thread->clip); if (RegionNil(&mono.clip)) return; } region_get_boxes(&mono.clip, &mono.clip_start, &mono.clip_end); boxes.op = thread->op; boxes.num_boxes = 0; mono.op.priv = &boxes; if (!mono_init(&mono, 2*thread->ntrap)) { RegionUninit(&mono.clip); return; } for (n = thread->ntrap, t = thread->traps; n--; t++) { if (!xTrapezoidValid(t)) continue; if (pixman_fixed_to_int(t->top) + thread->dy >= thread->extents.y2 || pixman_fixed_to_int(t->bottom) + thread->dy <= thread->extents.y1) continue; mono_add_line(&mono, thread->dx, thread->dy, t->top, t->bottom, &t->left.p1, &t->left.p2, 1); mono_add_line(&mono, thread->dx, thread->dy, t->top, t->bottom, &t->right.p1, &t->right.p2, -1); } if (mono.clip.data == NULL) mono.span = thread_mono_span; else mono.span = thread_mono_span_clipped; mono_render(&mono); mono_fini(&mono); if (boxes.num_boxes) thread->op->thread_boxes(thread->sna, thread->op, boxes.boxes, boxes.num_boxes); RegionUninit(&mono.clip); } bool mono_trapezoids_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct mono mono; BoxRec extents; int16_t dst_x, dst_y; int16_t dx, dy; bool unbounded; int num_threads, n; if (NO_SCAN_CONVERTER) return false; trapezoid_origin(&traps[0].left, &dst_x, &dst_y); if (!trapezoids_bounds(ntrap, traps, &extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_region(&mono.clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; return true; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2, dx, dy, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy)); unbounded = (!sna_drawable_is_clear(dst->pDrawable) && !operator_is_bounded(op)); if (op == PictOpClear && sna->clear) src = sna->clear; mono.sna = sna; if (!mono.sna->render.composite(mono.sna, op, src, NULL, dst, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) return false; num_threads = 1; if (!NO_GPU_THREADS && mono.op.thread_boxes && mono.op.damage == NULL && !unbounded) num_threads = sna_use_threads(mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, 32); if (num_threads > 1) { struct mono_span_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for mono span compositing %dx%d\n", __FUNCTION__, num_threads, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1)); threads[0].sna = mono.sna; threads[0].op = &mono.op; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = mono.clip.extents; threads[0].clip = &mono.clip; threads[0].dx = dx; threads[0].dy = dy; y = extents.y1; h = extents.y2 - extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= extents.y2 - extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, mono_span_thread, &threads[n]); } threads[0].extents.y1 = y; threads[0].extents.y2 = extents.y2; mono_span_thread(&threads[0]); sna_threads_wait(); mono.op.done(mono.sna, &mono.op); return true; } if (!mono_init(&mono, 2*ntrap)) return false; for (n = 0; n < ntrap; n++) { if (!xTrapezoidValid(&traps[n])) continue; if (pixman_fixed_integer_floor(traps[n].top) + dy >= mono.clip.extents.y2 || pixman_fixed_integer_ceil(traps[n].bottom) + dy <= mono.clip.extents.y1) continue; mono_add_line(&mono, dx, dy, traps[n].top, traps[n].bottom, &traps[n].left.p1, &traps[n].left.p2, 1); mono_add_line(&mono, dx, dy, traps[n].top, traps[n].bottom, &traps[n].right.p1, &traps[n].right.p2, -1); } if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else if (mono.clip.data != NULL && mono.op.damage == NULL) mono.span = mono_span__clipped; else mono.span = mono_span; region_get_boxes(&mono.clip, &mono.clip_start, &mono.clip_end); mono_render(&mono); mono.op.done(mono.sna, &mono.op); mono_fini(&mono); if (unbounded) { xPointFixed p1, p2; if (!mono_init(&mono, 2+2*ntrap)) return false; p1.y = mono.clip.extents.y1 * pixman_fixed_1; p2.y = mono.clip.extents.y2 * pixman_fixed_1; p1.x = mono.clip.extents.x1 * pixman_fixed_1; p2.x = mono.clip.extents.x1 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, -1); p1.x = mono.clip.extents.x2 * pixman_fixed_1; p2.x = mono.clip.extents.x2 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, 1); for (n = 0; n < ntrap; n++) { if (!xTrapezoidValid(&traps[n])) continue; if (pixman_fixed_to_int(traps[n].top) + dy >= mono.clip.extents.y2 || pixman_fixed_to_int(traps[n].bottom) + dy < mono.clip.extents.y1) continue; mono_add_line(&mono, dx, dy, traps[n].top, traps[n].bottom, &traps[n].left.p1, &traps[n].left.p2, 1); mono_add_line(&mono, dx, dy, traps[n].top, traps[n].bottom, &traps[n].right.p1, &traps[n].right.p2, -1); } if (mono.sna->render.composite(mono.sna, PictOpClear, mono.sna->clear, NULL, dst, 0, 0, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { region_get_boxes(&mono.clip, &mono.clip_start, &mono.clip_end); mono_render(&mono); mono.op.done(mono.sna, &mono.op); } mono_fini(&mono); } REGION_UNINIT(NULL, &mono.clip); return true; } struct mono_inplace_composite { pixman_image_t *src, *dst; int dx, dy; int sx, sy; int op; }; struct mono_inplace_fill { uint32_t *data, stride; uint32_t color; int bpp; }; fastcall static void mono_inplace_fill_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct mono_inplace_fill *fill = op->priv; DBG(("(%s: (%d, %d)x(%d, %d):%08x\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, fill->color)); sigtrap_assert_active(); pixman_fill(fill->data, fill->stride, fill->bpp, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, fill->color); } static void mono_inplace_fill_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct mono_inplace_fill *fill = op->priv; do { DBG(("(%s: (%d, %d)x(%d, %d):%08x\n", __FUNCTION__, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, fill->color)); sigtrap_assert_active(); pixman_fill(fill->data, fill->stride, fill->bpp, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1, fill->color); box++; } while (--nbox); } fastcall static void mono_inplace_composite_box(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box) { struct mono_inplace_composite *c = op->priv; pixman_image_composite(c->op, c->src, NULL, c->dst, box->x1 + c->sx, box->y1 + c->sy, 0, 0, box->x1 + c->dx, box->y1 + c->dy, box->x2 - box->x1, box->y2 - box->y1); } static void mono_inplace_composite_boxes(struct sna *sna, const struct sna_composite_op *op, const BoxRec *box, int nbox) { struct mono_inplace_composite *c = op->priv; do { pixman_image_composite(c->op, c->src, NULL, c->dst, box->x1 + c->sx, box->y1 + c->sy, 0, 0, box->x1 + c->dx, box->y1 + c->dy, box->x2 - box->x1, box->y2 - box->y1); box++; } while (--nbox); } bool mono_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct mono mono; union { struct mono_inplace_fill fill; struct mono_inplace_composite composite; } inplace; int was_clear; int x, y, n; if (!trapezoids_bounds(ntrap, traps, &mono.clip.extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2)); if (!sna_compute_composite_region(&mono.clip, src, NULL, dst, src_x, src_y, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; return true; } DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2)); was_clear = sna_drawable_is_clear(dst->pDrawable); if (!sna_drawable_move_region_to_cpu(dst->pDrawable, &mono.clip, MOVE_WRITE | MOVE_READ)) return true; mono.sna = sna; if (!mono_init(&mono, 2*ntrap)) return false; mono.op.damage = NULL; x = dst->pDrawable->x; y = dst->pDrawable->y; for (n = 0; n < ntrap; n++) { if (!xTrapezoidValid(&traps[n])) continue; if (pixman_fixed_to_int(traps[n].top) + y >= mono.clip.extents.y2 || pixman_fixed_to_int(traps[n].bottom) + y < mono.clip.extents.y1) continue; mono_add_line(&mono, x, y, traps[n].top, traps[n].bottom, &traps[n].left.p1, &traps[n].left.p2, 1); mono_add_line(&mono, x, y, traps[n].top, traps[n].bottom, &traps[n].right.p1, &traps[n].right.p2, -1); } if (sna_picture_is_solid(src, &inplace.fill.color) && (op == PictOpSrc || op == PictOpClear || (was_clear && (op == PictOpOver || op == PictOpAdd)) || (op == PictOpOver && inplace.fill.color >> 24 == 0xff))) { PixmapPtr pixmap; int16_t dx, dy; uint8_t *ptr; unbounded_pass: pixmap = get_drawable_pixmap(dst->pDrawable); ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(dst->pDrawable, pixmap, &dx, &dy)) ptr += dy * pixmap->devKind + dx * pixmap->drawable.bitsPerPixel / 8; inplace.fill.data = (uint32_t *)ptr; inplace.fill.stride = pixmap->devKind / sizeof(uint32_t); inplace.fill.bpp = pixmap->drawable.bitsPerPixel; if (op == PictOpClear) inplace.fill.color = 0; else if (dst->format != PICT_a8r8g8b8) inplace.fill.color = sna_rgba_to_color(inplace.fill.color, dst->format); DBG(("%s: fill %x\n", __FUNCTION__, inplace.fill.color)); mono.op.priv = &inplace.fill; mono.op.box = mono_inplace_fill_box; mono.op.boxes = mono_inplace_fill_boxes; op = 0; } else { if (src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) { mono_fini(&mono); return false; } if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) { mono_fini(&mono); return false; } } inplace.composite.dst = image_from_pict(dst, false, &inplace.composite.dx, &inplace.composite.dy); inplace.composite.src = image_from_pict(src, false, &inplace.composite.sx, &inplace.composite.sy); inplace.composite.sx += src_x - pixman_fixed_to_int(traps[0].left.p1.x), inplace.composite.sy += src_y - pixman_fixed_to_int(traps[0].left.p1.y), inplace.composite.op = op; mono.op.priv = &inplace.composite; mono.op.box = mono_inplace_composite_box; mono.op.boxes = mono_inplace_composite_boxes; } if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; if (sigtrap_get() == 0) { mono_render(&mono); sigtrap_put(); } mono_fini(&mono); if (op) { free_pixman_pict(src, inplace.composite.src); free_pixman_pict(dst, inplace.composite.dst); if (!was_clear && !operator_is_bounded(op)) { xPointFixed p1, p2; DBG(("%s: unbounded fixup\n", __FUNCTION__)); if (!mono_init(&mono, 2+2*ntrap)) return false; p1.y = mono.clip.extents.y1 * pixman_fixed_1; p2.y = mono.clip.extents.y2 * pixman_fixed_1; p1.x = mono.clip.extents.x1 * pixman_fixed_1; p2.x = mono.clip.extents.x1 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, -1); p1.x = mono.clip.extents.x2 * pixman_fixed_1; p2.x = mono.clip.extents.x2 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, 1); for (n = 0; n < ntrap; n++) { if (!xTrapezoidValid(&traps[n])) continue; if (pixman_fixed_to_int(traps[n].top) + x >= mono.clip.extents.y2 || pixman_fixed_to_int(traps[n].bottom) + y < mono.clip.extents.y1) continue; mono_add_line(&mono, x, y, traps[n].top, traps[n].bottom, &traps[n].left.p1, &traps[n].left.p2, 1); mono_add_line(&mono, x, y, traps[n].top, traps[n].bottom, &traps[n].right.p1, &traps[n].right.p2, -1); } op = PictOpClear; goto unbounded_pass; } } return true; } bool mono_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 x, INT16 y, int ntrap, xTrap *traps) { struct mono mono; xRenderColor white; PicturePtr src; int error; int n; white.red = white.green = white.blue = white.alpha = 0xffff; src = CreateSolidPicture(0, &white, &error); if (src == NULL) return true; mono.clip = *dst->pCompositeClip; x += dst->pDrawable->x; y += dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2, x, y)); mono.sna = sna; if (!mono_init(&mono, 2*ntrap)) return false; for (n = 0; n < ntrap; n++) { xPointFixed p1, p2; if (pixman_fixed_to_int(traps[n].top.y) + y >= mono.clip.extents.y2 || pixman_fixed_to_int(traps[n].bot.y) + y < mono.clip.extents.y1) continue; p1.y = traps[n].top.y; p2.y = traps[n].bot.y; p1.x = traps[n].top.l; p2.x = traps[n].bot.l; mono_add_line(&mono, x, y, traps[n].top.y, traps[n].bot.y, &p1, &p2, 1); p1.x = traps[n].top.r; p2.x = traps[n].bot.r; mono_add_line(&mono, x, y, traps[n].top.y, traps[n].bot.y, &p1, &p2, -1); } if (mono.sna->render.composite(mono.sna, PictOpAdd, src, NULL, dst, 0, 0, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; mono_render(&mono); mono.op.done(mono.sna, &mono.op); } mono_fini(&mono); FreePicture(src, 0); return true; } bool mono_triangles_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int count, xTriangle *tri) { struct mono mono; BoxRec extents; int16_t dst_x, dst_y; int16_t dx, dy; bool was_clear; int n; mono.sna = sna; dst_x = pixman_fixed_to_int(tri[0].p1.x); dst_y = pixman_fixed_to_int(tri[0].p1.y); miTriangleBounds(count, tri, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; if (!sna_compute_composite_region(&mono.clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: triangles do not intersect drawable clips\n", __FUNCTION__)) ; return true; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2, dx, dy, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); if (!mono_init(&mono, 3*count)) return false; for (n = 0; n < count; n++) { mono_add_line(&mono, dx, dy, tri[n].p1.y, tri[n].p2.y, &tri[n].p1, &tri[n].p2, 1); mono_add_line(&mono, dx, dy, tri[n].p2.y, tri[n].p3.y, &tri[n].p2, &tri[n].p3, 1); mono_add_line(&mono, dx, dy, tri[n].p3.y, tri[n].p1.y, &tri[n].p3, &tri[n].p1, 1); } if (mono.sna->render.composite(mono.sna, op, src, NULL, dst, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; mono_render(&mono); mono.op.done(mono.sna, &mono.op); } mono_fini(&mono); if (!was_clear && !operator_is_bounded(op)) { xPointFixed p1, p2; DBG(("%s: performing unbounded clear\n", __FUNCTION__)); if (!mono_init(&mono, 2+3*count)) return false; p1.y = mono.clip.extents.y1 * pixman_fixed_1; p2.y = mono.clip.extents.y2 * pixman_fixed_1; p1.x = mono.clip.extents.x1 * pixman_fixed_1; p2.x = mono.clip.extents.x1 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, -1); p1.x = mono.clip.extents.x2 * pixman_fixed_1; p2.x = mono.clip.extents.x2 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, 1); for (n = 0; n < count; n++) { mono_add_line(&mono, dx, dy, tri[n].p1.y, tri[n].p2.y, &tri[n].p1, &tri[n].p2, 1); mono_add_line(&mono, dx, dy, tri[n].p2.y, tri[n].p3.y, &tri[n].p2, &tri[n].p3, 1); mono_add_line(&mono, dx, dy, tri[n].p3.y, tri[n].p1.y, &tri[n].p3, &tri[n].p1, 1); } if (mono.sna->render.composite(mono.sna, PictOpClear, mono.sna->clear, NULL, dst, 0, 0, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; mono_render(&mono); mono.op.done(mono.sna, &mono.op); } mono_fini(&mono); } REGION_UNINIT(NULL, &mono.clip); return true; } bool mono_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, INT16 src_x, INT16 src_y, int count, xPointFixed *points) { struct mono mono; BoxRec extents; int16_t dst_x, dst_y; int16_t dx, dy; bool was_clear; int n; mono.sna = sna; dst_x = pixman_fixed_to_int(points[0].x); dst_y = pixman_fixed_to_int(points[0].y); miPointFixedBounds(count, points, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; if (!sna_compute_composite_region(&mono.clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: triangles do not intersect drawable clips\n", __FUNCTION__)) ; return true; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2, mono.clip.extents.y2, dx, dy, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); if (!mono_init(&mono, 2*count)) return false; mono_add_line(&mono, dx, dy, points[0].y, points[1].y, &points[0], &points[1], -1); n = 2; do { mono_add_line(&mono, dx, dy, points[n-2].y, points[n].y, &points[n-2], &points[n], 1); if (++n == count) break; mono_add_line(&mono, dx, dy, points[n-2].y, points[n].y, &points[n-2], &points[n], -1); if (++n == count) break; } while (1); mono_add_line(&mono, dx, dy, points[n-2].y, points[n-1].y, &points[n-2], &points[n-1], 1); if (mono.sna->render.composite(mono.sna, op, src, NULL, dst, src_x + mono.clip.extents.x1 - dst_x - dx, src_y + mono.clip.extents.y1 - dst_y - dy, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; mono_render(&mono); mono.op.done(mono.sna, &mono.op); } if (!was_clear && !operator_is_bounded(op)) { xPointFixed p1, p2; if (!mono_init(&mono, 2+2*count)) return false; p1.y = mono.clip.extents.y1 * pixman_fixed_1; p2.y = mono.clip.extents.y2 * pixman_fixed_1; p1.x = mono.clip.extents.x1 * pixman_fixed_1; p2.x = mono.clip.extents.x1 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, -1); p1.x = mono.clip.extents.x2 * pixman_fixed_1; p2.x = mono.clip.extents.x2 * pixman_fixed_1; mono_add_line(&mono, 0, 0, p1.y, p2.y, &p1, &p2, 1); mono_add_line(&mono, dx, dy, points[0].y, points[1].y, &points[0], &points[1], -1); n = 2; do { mono_add_line(&mono, dx, dy, points[n-2].y, points[n].y, &points[n-2], &points[n], 1); if (++n == count) break; mono_add_line(&mono, dx, dy, points[n-2].y, points[n].y, &points[n-2], &points[n], -1); if (++n == count) break; } while (1); mono_add_line(&mono, dx, dy, points[n-2].y, points[n-1].y, &points[n-2], &points[n-1], 1); if (mono.sna->render.composite(mono.sna, PictOpClear, mono.sna->clear, NULL, dst, 0, 0, 0, 0, mono.clip.extents.x1, mono.clip.extents.y1, mono.clip.extents.x2 - mono.clip.extents.x1, mono.clip.extents.y2 - mono.clip.extents.y1, COMPOSITE_PARTIAL, memset(&mono.op, 0, sizeof(mono.op)))) { if (mono.clip.data == NULL && mono.op.damage == NULL) mono.span = mono_span__fast; else mono.span = mono_span; mono_render(&mono); mono.op.done(mono.sna, &mono.op); } mono_fini(&mono); } mono_fini(&mono); REGION_UNINIT(NULL, &mono.clip); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_trapezoids_precise.c000066400000000000000000002533721267532330400265620ustar00rootroot00000000000000/* * Copyright (c) 2007 David Turner * Copyright (c) 2008 M Joonas Pihlaja * Copyright (c) 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include "sna_render.h" #include "sna_render_inline.h" #include "sna_trapezoids.h" #include "fb/fbpict.h" #include #undef FAST_SAMPLES_X #undef FAST_SAMPLES_Y /* TODO: Emit unantialiased and MSAA triangles. */ #ifndef MAX #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif #ifndef MIN #define MIN(x,y) ((x) <= (y) ? (x) : (y)) #endif #define _GRID_TO_INT_FRAC(t, i, f, m) do { \ (i) = (t) / (m); \ (f) = (t) % (m); \ if ((f) < 0) { \ --(i); \ (f) += (m); \ } \ } while (0) #define GRID_AREA (2*SAMPLES_X*SAMPLES_Y) static inline int pixman_fixed_to_grid_x(pixman_fixed_t v) { return ((int64_t)v * SAMPLES_X + (1<<15)) >> 16; } static inline int pixman_fixed_to_grid_y(pixman_fixed_t v) { return ((int64_t)v * SAMPLES_Y + (1<<15)) >> 16; } typedef void (*span_func_t)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage); #if HAS_DEBUG_FULL static void _assert_pixmap_contains_box(PixmapPtr pixmap, BoxPtr box, const char *function) { if (box->x1 < 0 || box->y1 < 0 || box->x2 > pixmap->drawable.width || box->y2 > pixmap->drawable.height) { FatalError("%s: damage box is beyond the pixmap: box=(%d, %d), (%d, %d), pixmap=(%d, %d)\n", function, box->x1, box->y1, box->x2, box->y2, pixmap->drawable.width, pixmap->drawable.height); } } #define assert_pixmap_contains_box(p, b) _assert_pixmap_contains_box(p, b, __FUNCTION__) #else #define assert_pixmap_contains_box(p, b) #endif static void apply_damage(struct sna_composite_op *op, RegionPtr region) { DBG(("%s: damage=%p, region=%dx[(%d, %d), (%d, %d)]\n", __FUNCTION__, op->damage, region_num_rects(region), region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2)); if (op->damage == NULL) return; RegionTranslate(region, op->dst.x, op->dst.y); assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region)); sna_damage_add(op->damage, region); } static void _apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { BoxRec r; r.x1 = box->x1 + op->dst.x; r.x2 = box->x2 + op->dst.x; r.y1 = box->y1 + op->dst.y; r.y2 = box->y2 + op->dst.y; assert_pixmap_contains_box(op->dst.pixmap, &r); sna_damage_add_box(op->damage, &r); } inline static void apply_damage_box(struct sna_composite_op *op, const BoxRec *box) { if (op->damage) _apply_damage_box(op, box); } #define SAMPLES_X_TO_INT_FRAC(x, i, f) \ _GRID_TO_INT_FRAC(x, i, f, SAMPLES_X) #define AREA_TO_FLOAT(c) ((c) / (float)GRID_AREA) #define TO_ALPHA(c) (((c)+1) >> 1) struct quorem { int64_t quo; int64_t rem; }; struct edge { struct edge *next, *prev; int dir; int height_left; int cell; struct quorem x; /* Advance of the current x when moving down a subsample line. */ struct quorem dxdy; int64_t dy; /* The clipped y of the top of the edge. */ int ytop; /* y2-y1 after orienting the edge downwards. */ }; /* Number of subsample rows per y-bucket. Must be SAMPLES_Y. */ #define EDGE_Y_BUCKET_HEIGHT SAMPLES_Y #define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/EDGE_Y_BUCKET_HEIGHT) /* A collection of sorted and vertically clipped edges of the polygon. * Edges are moved from the polygon to an active list while scan * converting. */ struct polygon { /* The vertical clip extents. */ int ymin, ymax; /* Array of edges all starting in the same bucket. An edge is put * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when * it is added to the polygon. */ struct edge **y_buckets; struct edge *y_buckets_embedded[64]; struct edge edges_embedded[32]; struct edge *edges; int num_edges; }; /* A cell records the effect on pixel coverage of polygon edges * passing through a pixel. It contains two accumulators of pixel * coverage. * * Consider the effects of a polygon edge on the coverage of a pixel * it intersects and that of the following one. The coverage of the * following pixel is the height of the edge multiplied by the width * of the pixel, and the coverage of the pixel itself is the area of * the trapezoid formed by the edge and the right side of the pixel. * * +-----------------------+-----------------------+ * | | | * | | | * |_______________________|_______________________| * | \...................|.......................|\ * | \..................|.......................| | * | \.................|.......................| | * | \....covered.....|.......................| | * | \....area.......|.......................| } covered height * | \..............|.......................| | * |uncovered\.............|.......................| | * | area \............|.......................| | * |___________\...........|.......................|/ * | | | * | | | * | | | * +-----------------------+-----------------------+ * * Since the coverage of the following pixel will always be a multiple * of the width of the pixel, we can store the height of the covered * area instead. The coverage of the pixel itself is the total * coverage minus the area of the uncovered area to the left of the * edge. As it's faster to compute the uncovered area we only store * that and subtract it from the total coverage later when forming * spans to blit. * * The heights and areas are signed, with left edges of the polygon * having positive sign and right edges having negative sign. When * two edges intersect they swap their left/rightness so their * contribution above and below the intersection point must be * computed separately. */ struct cell { struct cell *next; int x; int16_t uncovered_area; int16_t covered_height; }; /* A cell list represents the scan line sparsely as cells ordered by * ascending x. It is geared towards scanning the cells in order * using an internal cursor. */ struct cell_list { struct cell *cursor; /* Points to the left-most cell in the scan line. */ struct cell head, tail; int16_t x1, x2; int16_t count, size; struct cell *cells; struct cell embedded[256]; }; /* The active list contains edges in the current scan line ordered by * the x-coordinate of the intercept of the edge and the scan line. */ struct active_list { /* Leftmost edge on the current scan line. */ struct edge head, tail; }; struct tor { struct polygon polygon[1]; struct active_list active[1]; struct cell_list coverages[1]; BoxRec extents; }; /* Rewinds the cell list's cursor to the beginning. After rewinding * we're good to cell_list_find() the cell any x coordinate. */ inline static void cell_list_rewind(struct cell_list *cells) { cells->cursor = &cells->head; } static bool cell_list_init(struct cell_list *cells, int x1, int x2) { cells->tail.next = NULL; cells->tail.x = INT_MAX; cells->head.x = INT_MIN; cells->head.next = &cells->tail; cells->head.covered_height = 0; cell_list_rewind(cells); cells->count = 0; cells->x1 = x1; cells->x2 = x2; cells->size = x2 - x1 + 1; cells->cells = cells->embedded; if (cells->size > ARRAY_SIZE(cells->embedded)) cells->cells = malloc(cells->size * sizeof(struct cell)); return cells->cells != NULL; } static void cell_list_fini(struct cell_list *cells) { if (cells->cells != cells->embedded) free(cells->cells); } inline static void cell_list_reset(struct cell_list *cells) { cell_list_rewind(cells); cells->head.next = &cells->tail; cells->head.covered_height = 0; cells->count = 0; } inline static struct cell * cell_list_alloc(struct cell_list *cells, struct cell *tail, int x) { struct cell *cell; assert(cells->count < cells->size); cell = cells->cells + cells->count++; cell->next = tail->next; tail->next = cell; cell->x = x; cell->covered_height = 0; cell->uncovered_area = 0; return cell; } /* Find a cell at the given x-coordinate. Returns %NULL if a new cell * needed to be allocated but couldn't be. Cells must be found with * non-decreasing x-coordinate until the cell list is rewound using * cell_list_rewind(). Ownership of the returned cell is retained by * the cell list. */ inline static struct cell * cell_list_find(struct cell_list *cells, int x) { struct cell *tail; if (x >= cells->x2) return &cells->tail; if (x < cells->x1) return &cells->head; tail = cells->cursor; if (tail->x == x) return tail; do { if (tail->next->x > x) break; tail = tail->next; if (tail->next->x > x) break; tail = tail->next; if (tail->next->x > x) break; tail = tail->next; } while (1); if (tail->x != x) tail = cell_list_alloc(cells, tail, x); return cells->cursor = tail; } /* Add a subpixel span covering [x1, x2) to the coverage cells. */ inline static void cell_list_add_subspan(struct cell_list *cells, int x1, int x2) { struct cell *cell; int ix1, fx1; int ix2, fx2; if (x1 == x2) return; SAMPLES_X_TO_INT_FRAC(x1, ix1, fx1); SAMPLES_X_TO_INT_FRAC(x2, ix2, fx2); __DBG(("%s: x1=%d (%d+%d), x2=%d (%d+%d)\n", __FUNCTION__, x1, ix1, fx1, x2, ix2, fx2)); cell = cell_list_find(cells, ix1); if (ix1 != ix2) { cell->uncovered_area += 2*fx1; ++cell->covered_height; cell = cell_list_find(cells, ix2); cell->uncovered_area -= 2*fx2; --cell->covered_height; } else cell->uncovered_area += 2*(fx1-fx2); } inline static void cell_list_add_span(struct cell_list *cells, int x1, int x2) { struct cell *cell; int ix1, fx1; int ix2, fx2; SAMPLES_X_TO_INT_FRAC(x1, ix1, fx1); SAMPLES_X_TO_INT_FRAC(x2, ix2, fx2); __DBG(("%s: x1=%d (%d+%d), x2=%d (%d+%d)\n", __FUNCTION__, x1, ix1, fx1, x2, ix2, fx2)); cell = cell_list_find(cells, ix1); if (ix1 != ix2) { cell->uncovered_area += 2*fx1*SAMPLES_Y; cell->covered_height += SAMPLES_Y; cell = cell_list_find(cells, ix2); cell->uncovered_area -= 2*fx2*SAMPLES_Y; cell->covered_height -= SAMPLES_Y; } else cell->uncovered_area += 2*(fx1-fx2)*SAMPLES_Y; } static void polygon_fini(struct polygon *polygon) { if (polygon->y_buckets != polygon->y_buckets_embedded) free(polygon->y_buckets); if (polygon->edges != polygon->edges_embedded) free(polygon->edges); } static bool polygon_init(struct polygon *polygon, int num_edges, int ymin, int ymax) { unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax-1, ymin) + 1; if (unlikely(ymax - ymin > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT)) return false; polygon->edges = polygon->edges_embedded; polygon->y_buckets = polygon->y_buckets_embedded; polygon->num_edges = 0; if (num_edges > (int)ARRAY_SIZE(polygon->edges_embedded)) { polygon->edges = malloc(sizeof(struct edge)*num_edges); if (unlikely(NULL == polygon->edges)) goto bail_no_mem; } if (num_buckets >= ARRAY_SIZE(polygon->y_buckets_embedded)) { polygon->y_buckets = malloc((1+num_buckets)*sizeof(struct edge *)); if (unlikely(NULL == polygon->y_buckets)) goto bail_no_mem; } memset(polygon->y_buckets, 0, num_buckets * sizeof(struct edge *)); polygon->y_buckets[num_buckets] = (void *)-1; polygon->ymin = ymin; polygon->ymax = ymax; return true; bail_no_mem: polygon_fini(polygon); return false; } static void _polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, struct edge *e) { unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); struct edge **ptail = &polygon->y_buckets[ix]; assert(e->ytop < polygon->ymax); e->next = *ptail; *ptail = e; } static inline int edge_to_cell(struct edge *e) { int x = e->x.quo; if (e->x.rem > e->dy/2) x++; __DBG(("%s: %lld.%lld -> %d\n", __FUNCTION__, e->x.quo, e->x.rem, x)); return x; } static inline int edge_advance(struct edge *e) { __DBG(("%s: %lld.%lld + %lld.%lld\n", __FUNCTION__, e->x.quo, e->x.rem, e->dxdy.quo, e->dxdy.rem)); e->x.quo += e->dxdy.quo; e->x.rem += e->dxdy.rem; if (e->x.rem < 0) { e->x.quo--; e->x.rem += e->dy; } else if (e->x.rem >= e->dy) { e->x.quo++; e->x.rem -= e->dy; } assert(e->x.rem >= 0 && e->x.rem < e->dy); return edge_to_cell(e); } inline static void polygon_add_edge(struct polygon *polygon, const xTrapezoid *t, const xLineFixed *edge, int dir, int dx, int dy) { struct edge *e = &polygon->edges[polygon->num_edges]; const int ymin = polygon->ymin; const int ymax = polygon->ymax; int ytop, ybot; assert(t->bottom > t->top); assert(edge->p2.y > edge->p1.y); ytop = pixman_fixed_to_grid_y(t->top) + dy; if (ytop < ymin) ytop = ymin; ybot = pixman_fixed_to_grid_y(t->bottom) + dy; if (ybot > ymax) ybot = ymax; __DBG(("%s: dx=(%d, %d), y=[%d, %d] +%d, -%d\n", __FUNCTION__, dx, dy, ytop, ybot, ((int64_t)(ytop - dy)<<16) / SAMPLES_Y - edge->p1.y, ((int64_t)(ybot - dy)<<16) / SAMPLES_Y - edge->p2.y)); e->ytop = ytop; e->height_left = ybot - ytop; if (e->height_left <= 0) return; if (pixman_fixed_to_grid_x(edge->p1.x) == pixman_fixed_to_grid_x(edge->p2.x)) { e->cell = pixman_fixed_to_grid_x(edge->p1.x) + dx; e->x.quo = e->x.rem = 0; e->dxdy.quo = e->dxdy.rem = 0; e->dy = 0; } else { int64_t Ey, Ex, tmp; __DBG(("%s: add diagonal edge (%d, %d) -> (%d, %d) [(%d, %d)]\n", __FUNCTION__, edge->p1.x, edge->p1.y, edge->p2.x, edge->p2.y, edge->p2.x - edge->p1.x, edge->p2.y - edge->p1.y)); Ex = ((int64_t)edge->p2.x - edge->p1.x) * SAMPLES_X; Ey = ((int64_t)edge->p2.y - edge->p1.y) * SAMPLES_Y * (2 << 16); assert(Ey > 0); e->dxdy.quo = Ex * (2 << 16) / Ey; e->dxdy.rem = Ex * (2 << 16) % Ey; tmp = (int64_t)(2*(ytop - dy) + 1) << 16; tmp -= (int64_t)edge->p1.y * SAMPLES_Y*2; tmp *= Ex; e->x.quo = tmp / Ey; e->x.rem = tmp % Ey; tmp = (int64_t)edge->p1.x * SAMPLES_X; e->x.quo += (tmp >> 16) + dx; tmp &= (1 << 16) - 1; if (tmp) { if (Ey < INT64_MAX >> 16) tmp = (tmp * Ey) / (1 << 16); else /* Handle overflow by losing precision */ tmp = tmp * (Ey / (1 << 16)); e->x.rem += tmp; } if (e->x.rem < 0) { e->x.quo--; e->x.rem += Ey; } else if (e->x.rem >= Ey) { e->x.quo++; e->x.rem -= Ey; } assert(e->x.rem >= 0 && e->x.rem < Ey); e->dy = Ey; e->cell = edge_to_cell(e); __DBG(("%s: x=%lld.%lld + %lld.%lld %lld -> cell=%d\n", __FUNCTION__, (long long)e->x.quo, (long long)e->x.rem, (long long)e->dxdy.quo, (long long)e->dxdy.rem, (long long)Ey, e->cell)); } e->dir = dir; _polygon_insert_edge_into_its_y_bucket(polygon, e); polygon->num_edges++; } inline static void polygon_add_line(struct polygon *polygon, const xPointFixed *p1, const xPointFixed *p2, int dx, int dy) { struct edge *e = &polygon->edges[polygon->num_edges]; int ytop, ybot; if (p1->y == p2->y) return; __DBG(("%s: line=(%d, %d), (%d, %d)\n", __FUNCTION__, (int)p1->x, (int)p1->y, (int)p2->x, (int)p2->y)); e->dir = 1; if (p2->y < p1->y) { const xPointFixed *t; e->dir = -1; t = p1; p1 = p2; p2 = t; } ytop = pixman_fixed_to_grid_y(p1->y) + dy; if (ytop < polygon->ymin) ytop = polygon->ymin; ybot = pixman_fixed_to_grid_y(p2->y) + dy; if (ybot > polygon->ymax) ybot = polygon->ymax; if (ybot <= ytop) return; e->ytop = ytop; e->height_left = ybot - ytop; if (e->height_left <= 0) return; __DBG(("%s: edge height=%d\n", __FUNCTION__, e->dir * e->height_left)); if (pixman_fixed_to_grid_x(p1->x) == pixman_fixed_to_grid_x(p2->x)) { e->cell = pixman_fixed_to_grid_x(p1->x); e->x.quo = e->x.rem = 0; e->dxdy.quo = e->dxdy.rem = 0; e->dy = 0; } else { int64_t Ey, Ex, tmp; __DBG(("%s: add diagonal line (%d, %d) -> (%d, %d) [(%d, %d)]\n", __FUNCTION__, p1->x, p1->y, p2->x, p2->y, p2->x - p1->x, p2->y - p1->y)); Ex = ((int64_t)p2->x - p1->x) * SAMPLES_X; Ey = ((int64_t)p2->y - p1->y) * SAMPLES_Y * (2 << 16); e->dxdy.quo = Ex * (2 << 16) / Ey; e->dxdy.rem = Ex * (2 << 16) % Ey; tmp = (int64_t)(2*(ytop - dy) + 1) << 16; tmp -= (int64_t)p1->y * SAMPLES_Y*2; tmp *= Ex; e->x.quo = tmp / Ey; e->x.rem = tmp % Ey; tmp = (int64_t)p1->x * SAMPLES_X; e->x.quo += (tmp >> 16) + dx; e->x.rem += ((tmp & ((1 << 16) - 1)) * Ey) / (1 << 16); if (e->x.rem < 0) { e->x.quo--; e->x.rem += Ey; } else if (e->x.rem >= Ey) { e->x.quo++; e->x.rem -= Ey; } assert(e->x.rem >= 0 && e->x.rem < Ey); e->dy = Ey; e->cell = edge_to_cell(e); __DBG(("%s: x=%lld.%lld + %lld.%lld %lld -> cell=%d\n", __FUNCTION__, (long long)e->x.quo, (long long)e->x.rem, (long long)e->dxdy.quo, (long long)e->dxdy.rem, (long long)Ey, e->cell)); } if (polygon->num_edges > 0) { struct edge *prev = &polygon->edges[polygon->num_edges-1]; /* detect degenerate triangles inserted into tristrips */ if (e->dir == -prev->dir && e->ytop == prev->ytop && e->height_left == prev->height_left && e->cell == prev->cell && e->x.quo == prev->x.quo && e->x.rem == prev->x.rem && e->dxdy.quo == prev->dxdy.quo && e->dxdy.rem == prev->dxdy.rem) { unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); polygon->y_buckets[ix] = prev->next; polygon->num_edges--; return; } } _polygon_insert_edge_into_its_y_bucket(polygon, e); polygon->num_edges++; } static void active_list_reset(struct active_list *active) { active->head.height_left = INT_MAX; active->head.x.quo = INT_MIN; active->head.cell = INT_MIN; active->head.dy = 0; active->head.prev = NULL; active->head.next = &active->tail; active->tail.prev = &active->head; active->tail.next = NULL; active->tail.x.quo = INT_MAX; active->tail.cell = INT_MAX; active->tail.height_left = INT_MAX; active->tail.dy = 0; } static struct edge * merge_sorted_edges(struct edge *head_a, struct edge *head_b) { struct edge *head, **next, *prev; int32_t x; if (head_b == NULL) return head_a; prev = head_a->prev; next = &head; if (head_a->cell <= head_b->cell) { head = head_a; } else { head = head_b; head_b->prev = prev; goto start_with_b; } do { x = head_b->cell; while (head_a != NULL && head_a->cell <= x) { prev = head_a; next = &head_a->next; head_a = head_a->next; } head_b->prev = prev; *next = head_b; if (head_a == NULL) return head; start_with_b: x = head_a->cell; while (head_b != NULL && head_b->cell <= x) { prev = head_b; next = &head_b->next; head_b = head_b->next; } head_a->prev = prev; *next = head_a; if (head_b == NULL) return head; } while (1); } static struct edge * sort_edges(struct edge *list, unsigned int level, struct edge **head_out) { struct edge *head_other, *remaining; unsigned int i; head_other = list->next; if (head_other == NULL) { *head_out = list; return NULL; } remaining = head_other->next; if (list->cell <= head_other->cell) { *head_out = list; head_other->next = NULL; } else { *head_out = head_other; head_other->prev = list->prev; head_other->next = list; list->prev = head_other; list->next = NULL; } for (i = 0; i < level && remaining; i++) { remaining = sort_edges(remaining, i, &head_other); *head_out = merge_sorted_edges(*head_out, head_other); } return remaining; } static struct edge *filter(struct edge *edges) { struct edge *e; e = edges; while (e->next) { struct edge *n = e->next; if (e->dir == -n->dir && e->height_left == n->height_left && e->cell == n->cell && e->x.quo == n->x.quo && e->x.rem == n->x.rem && e->dxdy.quo == n->dxdy.quo && e->dxdy.rem == n->dxdy.rem) { if (e->prev) e->prev->next = n->next; else edges = n->next; if (n->next) n->next->prev = e->prev; else break; e = n->next; } else e = n; } return edges; } static struct edge * merge_unsorted_edges(struct edge *head, struct edge *unsorted) { sort_edges(unsorted, UINT_MAX, &unsorted); return merge_sorted_edges(head, filter(unsorted)); } /* Test if the edges on the active list can be safely advanced by a * full row without intersections or any edges ending. */ inline static int can_full_step(struct active_list *active) { const struct edge *e; int min_height = INT_MAX; assert(active->head.next != &active->tail); for (e = active->head.next; &active->tail != e; e = e->next) { assert(e->height_left > 0); if (e->dy != 0) return 0; if (e->height_left < min_height) { min_height = e->height_left; if (min_height < SAMPLES_Y) return 0; } } return min_height; } inline static void merge_edges(struct active_list *active, struct edge *edges) { active->head.next = merge_unsorted_edges(active->head.next, edges); } inline static void fill_buckets(struct active_list *active, struct edge *edge, int ymin, struct edge **buckets) { while (edge) { struct edge *next = edge->next; struct edge **b = &buckets[edge->ytop - ymin]; if (*b) (*b)->prev = edge; edge->next = *b; edge->prev = NULL; *b = edge; edge = next; } } inline static void nonzero_subrow(struct active_list *active, struct cell_list *coverages) { struct edge *edge = active->head.next; int prev_x = INT_MIN; int winding = 0, xstart = edge->cell; cell_list_rewind(coverages); while (&active->tail != edge) { struct edge *next = edge->next; winding += edge->dir; if (0 == winding && edge->next->cell != edge->cell) { cell_list_add_subspan(coverages, xstart, edge->cell); xstart = edge->next->cell; } assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) edge->cell = edge_advance(edge); if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do { pos = pos->prev; } while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; } } static void nonzero_row(struct active_list *active, struct cell_list *coverages) { struct edge *left = active->head.next; while (&active->tail != left) { struct edge *right; int winding = left->dir; left->height_left -= SAMPLES_Y; assert(left->height_left >= 0); if (!left->height_left) { left->prev->next = left->next; left->next->prev = left->prev; } right = left->next; do { right->height_left -= SAMPLES_Y; assert(right->height_left >= 0); if (!right->height_left) { right->prev->next = right->next; right->next->prev = right->prev; } winding += right->dir; if (0 == winding) break; right = right->next; } while (1); cell_list_add_span(coverages, left->cell, right->cell); left = right->next; } } static void tor_fini(struct tor *converter) { polygon_fini(converter->polygon); cell_list_fini(converter->coverages); } static bool tor_init(struct tor *converter, const BoxRec *box, int num_edges) { __DBG(("%s: (%d, %d),(%d, %d) x (%d, %d), num_edges=%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, SAMPLES_X, SAMPLES_Y, num_edges)); converter->extents = *box; if (!cell_list_init(converter->coverages, box->x1, box->x2)) return false; active_list_reset(converter->active); if (!polygon_init(converter->polygon, num_edges, (int)box->y1 * SAMPLES_Y, (int)box->y2 * SAMPLES_Y)) { cell_list_fini(converter->coverages); return false; } return true; } static void tor_add_trapezoid(struct tor *tor, const xTrapezoid *t, int dx, int dy) { if (!xTrapezoidValid(t)) { __DBG(("%s: skipping invalid trapezoid: top=%d, bottom=%d, left=(%d, %d), (%d, %d), right=(%d, %d), (%d, %d)\n", __FUNCTION__, t->top, t->bottom, t->left.p1.x, t->left.p1.y, t->left.p2.x, t->left.p2.y, t->right.p1.x, t->right.p1.y, t->right.p2.x, t->right.p2.y)); return; } polygon_add_edge(tor->polygon, t, &t->left, 1, dx, dy); polygon_add_edge(tor->polygon, t, &t->right, -1, dx, dy); } static void step_edges(struct active_list *active, int count) { struct edge *edge; count *= SAMPLES_Y; for (edge = active->head.next; edge != &active->tail; edge = edge->next) { edge->height_left -= count; assert(edge->height_left >= 0); if (!edge->height_left) { edge->prev->next = edge->next; edge->next->prev = edge->prev; } } } static void tor_blt_span(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); op->box(sna, op, box, AREA_TO_FLOAT(coverage)); apply_damage_box(&op->base, box); } static void tor_blt_span__no_damage(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); op->box(sna, op, box, AREA_TO_FLOAT(coverage)); } static void tor_blt_span_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { pixman_region16_t region; float opacity; opacity = AREA_TO_FLOAT(coverage); __DBG(("%s: %d -> %d @ %f\n", __FUNCTION__, box->x1, box->x2, opacity)); pixman_region_init_rects(®ion, box, 1); RegionIntersect(®ion, ®ion, clip); if (region_num_rects(®ion)) { op->boxes(sna, op, region_rects(®ion), region_num_rects(®ion), opacity); apply_damage(&op->base, ®ion); } pixman_region_fini(®ion); } static void tor_blt(struct sna *sna, struct tor *converter, struct sna_composite_spans_op *op, pixman_region16_t *clip, void (*span)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage), int y, int height, int unbounded) { struct cell_list *cells = converter->coverages; struct cell *cell; BoxRec box; int cover; box.y1 = y + converter->extents.y1; box.y2 = box.y1 + height; assert(box.y2 <= converter->extents.y2); box.x1 = converter->extents.x1; /* Form the spans from the coverages and areas. */ cover = cells->head.covered_height*SAMPLES_X*2; assert(cover >= 0); for (cell = cells->head.next; cell != &cells->tail; cell = cell->next) { int x = cell->x; assert(x >= converter->extents.x1); assert(x < converter->extents.x2); __DBG(("%s: cell=(%d, %d, %d), cover=%d\n", __FUNCTION__, cell->x, cell->covered_height, cell->uncovered_area, cover)); if (cell->covered_height || cell->uncovered_area) { box.x2 = x; if (box.x2 > box.x1 && (unbounded || cover)) { __DBG(("%s: end span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, cover)); span(sna, op, clip, &box, cover); } box.x1 = box.x2; cover += cell->covered_height*SAMPLES_X*2; } if (cell->uncovered_area) { int area = cover - cell->uncovered_area; box.x2 = x + 1; if (unbounded || area) { __DBG(("%s: new span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, area)); span(sna, op, clip, &box, area); } box.x1 = box.x2; } } box.x2 = converter->extents.x2; if (box.x2 > box.x1 && (unbounded || cover)) { __DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1, cover)); span(sna, op, clip, &box, cover); } } flatten static void tor_render(struct sna *sna, struct tor *converter, struct sna_composite_spans_op *op, pixman_region16_t *clip, void (*span)(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage), int unbounded) { struct polygon *polygon = converter->polygon; struct cell_list *coverages = converter->coverages; struct active_list *active = converter->active; struct edge *buckets[SAMPLES_Y] = { 0 }; int16_t i, j, h = converter->extents.y2 - converter->extents.y1; __DBG(("%s: unbounded=%d\n", __FUNCTION__, unbounded)); /* Render each pixel row. */ for (i = 0; i < h; i = j) { int do_full_step = 0; j = i + 1; /* Determine if we can ignore this row or use the full pixel * stepper. */ if (polygon->y_buckets[i] == NULL) { if (active->head.next == &active->tail) { for (; polygon->y_buckets[j] == NULL; j++) ; __DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n", __FUNCTION__, i, j)); assert(j <= h); if (unbounded) { BoxRec box; box = converter->extents; box.y1 += i; box.y2 = converter->extents.y1 + j; span(sna, op, clip, &box, 0); } continue; } do_full_step = can_full_step(active); } __DBG(("%s: y=%d, do_full_step=%d, new edges=%d\n", __FUNCTION__, i, do_full_step, polygon->y_buckets[i] != NULL)); if (do_full_step) { nonzero_row(active, coverages); while (polygon->y_buckets[j] == NULL && do_full_step >= 2*SAMPLES_Y) { do_full_step -= SAMPLES_Y; j++; } assert(j >= i + 1 && j <= h); if (j != i + 1) step_edges(active, j - (i + 1)); __DBG(("%s: vertical edges, full step (%d, %d)\n", __FUNCTION__, i, j)); } else { int suby; fill_buckets(active, polygon->y_buckets[i], (i+converter->extents.y1)*SAMPLES_Y, buckets); /* Subsample this row. */ for (suby = 0; suby < SAMPLES_Y; suby++) { if (buckets[suby]) { merge_edges(active, buckets[suby]); buckets[suby] = NULL; } nonzero_subrow(active, coverages); } } assert(j > i); tor_blt(sna, converter, op, clip, span, i, j-i, unbounded); cell_list_reset(coverages); } } static void inplace_row(struct active_list *active, uint8_t *row, int width) { struct edge *left = active->head.next; while (&active->tail != left) { struct edge *right; int winding = left->dir; int lfx, rfx; int lix, rix; left->height_left -= SAMPLES_Y; assert(left->height_left >= 0); if (!left->height_left) { left->prev->next = left->next; left->next->prev = left->prev; } right = left->next; do { right->height_left -= SAMPLES_Y; assert(right->height_left >= 0); if (!right->height_left) { right->prev->next = right->next; right->next->prev = right->prev; } winding += right->dir; if (0 == winding && right->cell != right->next->cell) break; right = right->next; } while (1); if (left->cell < 0) { lix = lfx = 0; } else if (left->cell >= width * SAMPLES_X) { lix = width; lfx = 0; } else SAMPLES_X_TO_INT_FRAC(left->cell, lix, lfx); if (right->cell < 0) { rix = rfx = 0; } else if (right->cell >= width * SAMPLES_X) { rix = width; rfx = 0; } else SAMPLES_X_TO_INT_FRAC(right->cell, rix, rfx); if (lix == rix) { if (rfx != lfx) { assert(lix < width); row[lix] += (rfx-lfx) * SAMPLES_Y; } } else { assert(lix < width); if (lfx == 0) row[lix] = 0xff; else row[lix] += 255 - lfx * SAMPLES_Y; assert(rix <= width); if (rfx) { assert(rix < width); row[rix] += rfx * SAMPLES_Y; } if (rix > ++lix) { uint8_t *r = row + lix; rix -= lix; #if 0 if (rix == 1) *row = 0xff; else memset(row, 0xff, rix); #else if ((uintptr_t)r & 1 && rix) { *r++ = 0xff; rix--; } if ((uintptr_t)r & 2 && rix >= 2) { *(uint16_t *)r = 0xffff; r += 2; rix -= 2; } if ((uintptr_t)r & 4 && rix >= 4) { *(uint32_t *)r = 0xffffffff; r += 4; rix -= 4; } while (rix >= 8) { *(uint64_t *)r = 0xffffffffffffffff; r += 8; rix -= 8; } if (rix & 4) { *(uint32_t *)r = 0xffffffff; r += 4; } if (rix & 2) { *(uint16_t *)r = 0xffff; r += 2; } if (rix & 1) *r = 0xff; #endif } } left = right->next; } } inline static void inplace_subrow(struct active_list *active, int8_t *row, int width) { struct edge *edge = active->head.next; int prev_x = INT_MIN; while (&active->tail != edge) { struct edge *next = edge->next; int winding = edge->dir; int lfx, rfx; int lix, rix; if (edge->cell < 0) { lix = lfx = 0; } else if (edge->cell >= width * SAMPLES_X) { lix = width; lfx = 0; } else SAMPLES_X_TO_INT_FRAC(edge->cell, lix, lfx); assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) edge->cell = edge_advance(edge); if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do { pos = pos->prev; } while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; do { next = edge->next; winding += edge->dir; if (0 == winding && edge->cell != next->cell) break; assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) edge->cell = edge_advance(edge); if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do { pos = pos->prev; } while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; } while (1); if (edge->cell < 0) { rix = rfx = 0; } else if (edge->cell >= width * SAMPLES_X) { rix = width; rfx = 0; } else SAMPLES_X_TO_INT_FRAC(edge->cell, rix, rfx); assert(edge->height_left > 0); if (--edge->height_left) { if (edge->dy) edge->cell = edge_advance(edge); if (edge->cell < prev_x) { struct edge *pos = edge->prev; pos->next = next; next->prev = pos; do { pos = pos->prev; } while (edge->cell < pos->cell); pos->next->prev = edge; edge->next = pos->next; edge->prev = pos; pos->next = edge; } else prev_x = edge->cell; } else { edge->prev->next = next; next->prev = edge->prev; } edge = next; __DBG(("%s: left=%d.%d, right=%d.%d\n", __FUNCTION__, lix, lfx, rix, rfx)); if (lix == rix) { if (rfx != lfx) { assert(lix < width); row[lix] += (rfx-lfx); } } else { assert(lix < width); row[lix] += SAMPLES_X - lfx; assert(rix <= width); if (rfx) { assert(rix < width); row[rix] += rfx; } while (++lix < rix) row[lix] += SAMPLES_X; } } } flatten static void tor_inplace(struct tor *converter, PixmapPtr scratch) { uint8_t buf[TOR_INPLACE_SIZE]; int i, j, h = converter->extents.y2 - converter->extents.y1; struct polygon *polygon = converter->polygon; struct active_list *active = converter->active; struct edge *buckets[SAMPLES_Y] = { 0 }; uint8_t *row = scratch->devPrivate.ptr; int stride = scratch->devKind; int width = scratch->drawable.width; __DBG(("%s: buf?=%d\n", __FUNCTION__, buf != NULL)); assert(converter->extents.x1 == 0); assert(scratch->drawable.depth == 8); row += converter->extents.y1 * stride; /* Render each pixel row. */ for (i = 0; i < h; i = j) { int do_full_step = 0; void *ptr = scratch->usage_hint ? buf : row; j = i + 1; /* Determine if we can ignore this row or use the full pixel * stepper. */ if (!polygon->y_buckets[i]) { if (active->head.next == &active->tail) { for (; !polygon->y_buckets[j]; j++) ; __DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n", __FUNCTION__, i, j)); memset(row, 0, stride*(j-i)); row += stride*(j-i); continue; } do_full_step = can_full_step(active); } __DBG(("%s: y=%d, do_full_step=%d, new edges=%d\n", __FUNCTION__, i, do_full_step, polygon->y_buckets[i] != NULL)); if (do_full_step) { memset(ptr, 0, width); inplace_row(active, ptr, width); if (row != ptr) memcpy(row, ptr, width); while (polygon->y_buckets[j] == NULL && do_full_step >= 2*SAMPLES_Y) { do_full_step -= SAMPLES_Y; row += stride; memcpy(row, ptr, width); j++; } if (j != i + 1) step_edges(active, j - (i + 1)); __DBG(("%s: vertical edges, full step (%d, %d)\n", __FUNCTION__, i, j)); } else { int suby; fill_buckets(active, polygon->y_buckets[i], (i+converter->extents.y1)*SAMPLES_Y, buckets); /* Subsample this row. */ memset(ptr, 0, width); for (suby = 0; suby < SAMPLES_Y; suby++) { if (buckets[suby]) { merge_edges(active, buckets[suby]); buckets[suby] = NULL; } inplace_subrow(active, ptr, width); } if (row != ptr) memcpy(row, ptr, width); } row += stride; } } static int operator_is_bounded(uint8_t op) { switch (op) { case PictOpOver: case PictOpOutReverse: case PictOpAdd: return true; default: return false; } } static span_func_t choose_span(struct sna_composite_spans_op *tmp, PicturePtr dst, PictFormatPtr maskFormat, RegionPtr clip) { span_func_t span; assert(!is_mono(dst, maskFormat)); if (clip->data) span = tor_blt_span_clipped; else if (tmp->base.damage == NULL) span = tor_blt_span__no_damage; else span = tor_blt_span; return span; } struct span_thread { struct sna *sna; const struct sna_composite_spans_op *op; const xTrapezoid *traps; RegionPtr clip; span_func_t span; BoxRec extents; int dx, dy, draw_y; int ntrap; bool unbounded; }; #define SPAN_THREAD_MAX_BOXES (8192/sizeof(struct sna_opacity_box)) struct span_thread_boxes { const struct sna_composite_spans_op *op; const BoxRec *clip_start, *clip_end; int num_boxes; struct sna_opacity_box boxes[SPAN_THREAD_MAX_BOXES]; }; static void span_thread_add_box(struct sna *sna, void *data, const BoxRec *box, float alpha) { struct span_thread_boxes *b = data; __DBG(("%s: adding box with alpha=%f\n", __FUNCTION__, alpha)); if (unlikely(b->num_boxes == SPAN_THREAD_MAX_BOXES)) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, b->num_boxes)); b->op->thread_boxes(sna, b->op, b->boxes, b->num_boxes); b->num_boxes = 0; } b->boxes[b->num_boxes].box = *box++; b->boxes[b->num_boxes].alpha = alpha; b->num_boxes++; assert(b->num_boxes <= SPAN_THREAD_MAX_BOXES); } static void span_thread_box(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct span_thread_boxes *b = (struct span_thread_boxes *)op; __DBG(("%s: %d -> %d @ %d\n", __FUNCTION__, box->x1, box->x2, coverage)); if (b->num_boxes) { struct sna_opacity_box *bb = &b->boxes[b->num_boxes-1]; if (bb->box.x1 == box->x1 && bb->box.x2 == box->x2 && bb->box.y2 == box->y1 && bb->alpha == AREA_TO_FLOAT(coverage)) { bb->box.y2 = box->y2; __DBG(("%s: contracted double row: %d -> %d\n", __func__, bb->box.y1, bb->box.y2)); return; } } span_thread_add_box(sna, op, box, AREA_TO_FLOAT(coverage)); } static void span_thread_clipped_box(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct span_thread_boxes *b = (struct span_thread_boxes *)op; const BoxRec *c; __DBG(("%s: %d -> %d @ %f\n", __FUNCTION__, box->x1, box->x2, AREA_TO_FLOAT(coverage))); b->clip_start = find_clip_box_for_y(b->clip_start, b->clip_end, box->y1); c = b->clip_start; while (c != b->clip_end) { BoxRec clipped; if (box->y2 <= c->y1) break; clipped = *box; if (!box_intersect(&clipped, c++)) continue; span_thread_add_box(sna, op, &clipped, AREA_TO_FLOAT(coverage)); } } static span_func_t thread_choose_span(struct sna_composite_spans_op *tmp, PicturePtr dst, PictFormatPtr maskFormat, RegionPtr clip) { span_func_t span; if (tmp->base.damage) { DBG(("%s: damaged -> no thread support\n", __FUNCTION__)); return NULL; } assert(!is_mono(dst, maskFormat)); assert(tmp->thread_boxes); DBG(("%s: clipped? %d x %d\n", __FUNCTION__, clip->data != NULL, region_num_rects(clip))); if (clip->data) span = span_thread_clipped_box; else span = span_thread_box; return span; } inline static void span_thread_boxes_init(struct span_thread_boxes *boxes, const struct sna_composite_spans_op *op, const RegionRec *clip) { boxes->op = op; boxes->clip_start = region_rects(clip); boxes->clip_end = boxes->clip_start + region_num_rects(clip); boxes->num_boxes = 0; } static void span_thread(void *arg) { struct span_thread *thread = arg; struct span_thread_boxes boxes; struct tor tor; const xTrapezoid *t; int n, y1, y2; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; span_thread_boxes_init(&boxes, thread->op, thread->clip); y1 = thread->extents.y1 - thread->draw_y; y2 = thread->extents.y2 - thread->draw_y; for (n = thread->ntrap, t = thread->traps; n--; t++) { if (pixman_fixed_integer_floor(t->top) >= y2 || pixman_fixed_integer_ceil(t->bottom) <= y1) continue; tor_add_trapezoid(&tor, t, thread->dx, thread->dy); } tor_render(thread->sna, &tor, (struct sna_composite_spans_op *)&boxes, thread->clip, thread->span, thread->unbounded); tor_fini(&tor); if (boxes.num_boxes) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, boxes.num_boxes)); assert(boxes.num_boxes <= SPAN_THREAD_MAX_BOXES); thread->op->thread_boxes(thread->sna, thread->op, boxes.boxes, boxes.num_boxes); } } bool precise_trapezoid_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned int flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { struct sna_composite_spans_op tmp; pixman_region16_t clip; int16_t dst_x, dst_y; bool was_clear; int dx, dy, n; int num_threads; if (NO_PRECISE) return false; if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, flags)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } if (!trapezoids_bounds(ntrap, traps, &clip.extents)) return true; #if 1 if (((clip.extents.y2 - clip.extents.y1) | (clip.extents.x2 - clip.extents.x1)) < 32) { DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, clip.extents.y2 - clip.extents.y1, clip.extents.x2 - clip.extents.x1)); return false; } #endif DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); trapezoid_origin(&traps[0].left, &dst_x, &dst_y); if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + clip.extents.x1 - dst_x, src_y + clip.extents.y1 - dst_y, 0, 0, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)) { DBG(("%s: trapezoids do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, flags)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2, dx, dy, src_x + clip.extents.x1 - dst_x - dx, src_y + clip.extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); switch (op) { case PictOpAdd: case PictOpOver: if (was_clear) op = PictOpSrc; break; case PictOpIn: if (was_clear) return true; break; } if (!sna->render.composite_spans(sna, op, src, dst, src_x + clip.extents.x1 - dst_x - dx, src_y + clip.extents.y1 - dst_y - dy, clip.extents.x1, clip.extents.y1, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, flags, memset(&tmp, 0, sizeof(tmp)))) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= SAMPLES_X; dy *= SAMPLES_Y; num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0 && tmp.thread_boxes && thread_choose_span(&tmp, dst, maskFormat, &clip)) num_threads = sna_use_threads(clip.extents.x2-clip.extents.x1, clip.extents.y2-clip.extents.y1, 8); DBG(("%s: using %d threads\n", __FUNCTION__, num_threads)); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, &clip.extents, 2*ntrap)) goto skip; for (n = 0; n < ntrap; n++) { if (pixman_fixed_integer_floor(traps[n].top) + dst->pDrawable->y >= clip.extents.y2 || pixman_fixed_integer_ceil(traps[n].bottom) + dst->pDrawable->y <= clip.extents.y1) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } tor_render(sna, &tor, &tmp, &clip, choose_span(&tmp, dst, maskFormat, &clip), !was_clear && maskFormat && !operator_is_bounded(op)); tor_fini(&tor); } else { struct span_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for span compositing %dx%d\n", __FUNCTION__, num_threads, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)); threads[0].sna = sna; threads[0].op = &tmp; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = clip.extents; threads[0].clip = &clip; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_y = dst->pDrawable->y; threads[0].unbounded = !was_clear && maskFormat && !operator_is_bounded(op); threads[0].span = thread_choose_span(&tmp, dst, maskFormat, &clip); y = clip.extents.y1; h = clip.extents.y2 - clip.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= clip.extents.y2 - clip.extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, span_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; span_thread(&threads[0]); sna_threads_wait(); } skip: tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } static void tor_blt_mask(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { uint8_t *ptr = (uint8_t *)op; int stride = (intptr_t)clip; int h, w; coverage = TO_ALPHA(coverage); ptr += box->y1 * stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { *ptr = coverage; } else if (w == 1) { do { *ptr = coverage; ptr += stride; } while (--h); } else do { memset(ptr, coverage, w); ptr += stride; } while (--h); } struct mask_thread { PixmapPtr scratch; const xTrapezoid *traps; BoxRec extents; int dx, dy, dst_y; int ntrap; }; static void mask_thread(void *arg) { struct mask_thread *thread = arg; struct tor tor; const xTrapezoid *t; int n, y1, y2; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; y1 = thread->extents.y1 + thread->dst_y; y2 = thread->extents.y2 + thread->dst_y; for (n = thread->ntrap, t = thread->traps; n--; t++) { if (pixman_fixed_integer_floor(t->top) >= y2 || pixman_fixed_integer_ceil(t->bottom) <= y1) continue; tor_add_trapezoid(&tor, t, thread->dx, thread->dy); } if (thread->extents.x2 <= TOR_INPLACE_SIZE) { tor_inplace(&tor, thread->scratch); } else { tor_render(NULL, &tor, thread->scratch->devPrivate.ptr, (void *)(intptr_t)thread->scratch->devKind, tor_blt_mask, true); } tor_fini(&tor); } bool precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int num_threads; int16_t dst_x, dst_y; int dx, dy; int error, n; if (NO_PRECISE) return false; if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!precise_trapezoid_mask_converter(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, &extents)) return true; DBG(("%s: ntraps=%d, extents (%d, %d), (%d, %d)\n", __FUNCTION__, ntrap, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); extents.y2 -= extents.y1; extents.x2 -= extents.x1; extents.x1 -= dst->pDrawable->x; extents.y1 -= dst->pDrawable->y; dst_x = extents.x1; dst_y = extents.y1; dx = -extents.x1 * SAMPLES_X; dy = -extents.y1 * SAMPLES_Y; extents.x1 = extents.y1 = 0; DBG(("%s: mask (%dx%d), dx=(%d, %d)\n", __FUNCTION__, extents.x2, extents.y2, dx, dy)); scratch = sna_pixmap_create_upload(screen, extents.x2, extents.y2, 8, KGEM_BUFFER_WRITE_INPLACE); if (!scratch) return true; DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0) num_threads = sna_use_threads(extents.x2 - extents.x1, extents.y2 - extents.y1, 4); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, &extents, 2*ntrap)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) - dst_y >= extents.y2 || pixman_fixed_to_int(traps[n].bottom) - dst_y < 0) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (extents.x2 <= TOR_INPLACE_SIZE) { tor_inplace(&tor, scratch); } else { tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, tor_blt_mask, true); } tor_fini(&tor); } else { struct mask_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for mask compositing %dx%d\n", __FUNCTION__, num_threads, extents.x2 - extents.x1, extents.y2 - extents.y1)); threads[0].scratch = scratch; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = extents; threads[0].dx = dx; threads[0].dy = dy; threads[0].dst_y = dst_y; y = extents.y1; h = extents.y2 - extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= extents.y2 - extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, mask_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; mask_thread(&threads[0]); sna_threads_wait(); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { int16_t x0, y0; trapezoid_origin(&traps[0].left, &x0, &y0); CompositePicture(op, src, mask, dst, src_x + dst_x - x0, src_y + dst_y - y0, 0, 0, dst_x, dst_y, extents.x2, extents.y2); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); return true; } struct inplace { uint8_t *ptr; uint32_t stride; union { uint8_t opacity; uint32_t color; }; }; static force_inline uint8_t coverage_opacity(int coverage, uint8_t opacity) { coverage = TO_ALPHA(coverage); return opacity == 255 ? coverage : mul_8_8(coverage, opacity); } struct clipped_span { span_func_t span; const BoxRec *clip_start, *clip_end; }; static void tor_blt_clipped(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct clipped_span *cs = (struct clipped_span *)clip; const BoxRec *c; cs->clip_start = find_clip_box_for_y(cs->clip_start, cs->clip_end, box->y1); c = cs->clip_start; while (c != cs->clip_end) { BoxRec clipped; if (box->y2 <= c->y1) break; clipped = *box; if (!box_intersect(&clipped, c++)) continue; cs->span(sna, op, NULL, &clipped, coverage); } } inline static span_func_t clipped_span(struct clipped_span *cs, span_func_t span, const RegionRec *clip) { if (clip->data) { cs->span = span; region_get_boxes(clip, &cs->clip_start, &cs->clip_end); span = tor_blt_clipped; } return span; } static void _tor_blt_src(struct inplace *in, const BoxRec *box, uint8_t v) { uint8_t *ptr = in->ptr; int h, w; ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { *ptr = v; } else if (w == 1) { do { *ptr = v; ptr += in->stride; } while (--h); } else do { memset(ptr, v, w); ptr += in->stride; } while (--h); } static void tor_blt_src(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; _tor_blt_src(in, box, coverage_opacity(coverage, in->opacity)); } static void tor_blt_in(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint8_t *ptr = in->ptr; int h, w, i; if (coverage == 0 || in->opacity == 0) { _tor_blt_src(in, box, 0); return; } coverage = coverage_opacity(coverage, in->opacity); if (coverage == 0xff) return; ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; do { for (i = 0; i < w; i++) ptr[i] = mul_8_8(ptr[i], coverage); ptr += in->stride; } while (--h); } static void tor_blt_add(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint8_t *ptr = in->ptr; int h, w, v, i; if (coverage == 0) return; coverage = coverage_opacity(coverage, in->opacity); if (coverage == 0xff) { _tor_blt_src(in, box, 0xff); return; } ptr += box->y1 * in->stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if ((w | h) == 1) { v = coverage + *ptr; *ptr = v >= 255 ? 255 : v; } else { do { for (i = 0; i < w; i++) { v = coverage + ptr[i]; ptr[i] = v >= 255 ? 255 : v; } ptr += in->stride; } while (--h); } } static void tor_blt_lerp32(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct inplace *in = (struct inplace *)op; uint32_t *ptr = (uint32_t *)in->ptr; int stride = in->stride / sizeof(uint32_t); int h, w, i; if (coverage == 0) return; sigtrap_assert_active(); ptr += box->y1 * stride + box->x1; h = box->y2 - box->y1; w = box->x2 - box->x1; if (coverage == GRID_AREA) { if ((w | h) == 1) { *ptr = in->color; } else { if (w < 16) { do { for (i = 0; i < w; i++) ptr[i] = in->color; ptr += stride; } while (--h); } else { pixman_fill(ptr, stride, 32, 0, 0, w, h, in->color); } } } else { coverage = TO_ALPHA(coverage); if ((w | h) == 1) { *ptr = lerp8x4(in->color, coverage, *ptr); } else if (w == 1) { do { *ptr = lerp8x4(in->color, coverage, *ptr); ptr += stride; } while (--h); } else{ do { for (i = 0; i < w; i++) ptr[i] = lerp8x4(in->color, coverage, ptr[i]); ptr += stride; } while (--h); } } } struct pixman_inplace { pixman_image_t *image, *source, *mask; uint32_t color; uint32_t *bits; int dx, dy; int sx, sy; uint8_t op; }; static void pixmask_span_solid(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct pixman_inplace *pi = (struct pixman_inplace *)op; if (coverage != GRID_AREA) *pi->bits = mul_4x8_8(pi->color, TO_ALPHA(coverage)); else *pi->bits = pi->color; pixman_image_composite(pi->op, pi->source, NULL, pi->image, box->x1, box->y1, 0, 0, pi->dx + box->x1, pi->dy + box->y1, box->x2 - box->x1, box->y2 - box->y1); } static void pixmask_span(struct sna *sna, struct sna_composite_spans_op *op, pixman_region16_t *clip, const BoxRec *box, int coverage) { struct pixman_inplace *pi = (struct pixman_inplace *)op; pixman_image_t *mask = NULL; if (coverage != GRID_AREA) { *pi->bits = TO_ALPHA(coverage); mask = pi->mask; } pixman_image_composite(pi->op, pi->source, mask, pi->image, pi->sx + box->x1, pi->sy + box->y1, 0, 0, pi->dx + box->x1, pi->dy + box->y1, box->x2 - box->x1, box->y2 - box->y1); } struct inplace_x8r8g8b8_thread { xTrapezoid *traps; PicturePtr dst, src; BoxRec extents; int dx, dy; int ntrap; bool lerp, is_solid; uint32_t color; int16_t src_x, src_y; uint8_t op; }; static void inplace_x8r8g8b8_thread(void *arg) { struct inplace_x8r8g8b8_thread *thread = arg; struct tor tor; span_func_t span; struct clipped_span clipped; RegionPtr clip; int y1, y2, n; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; y1 = thread->extents.y1 - thread->dst->pDrawable->y; y2 = thread->extents.y2 - thread->dst->pDrawable->y; for (n = 0; n < thread->ntrap; n++) { if (pixman_fixed_to_int(thread->traps[n].top) >= y2 || pixman_fixed_to_int(thread->traps[n].bottom) < y1) continue; tor_add_trapezoid(&tor, &thread->traps[n], thread->dx, thread->dy); } clip = thread->dst->pCompositeClip; if (thread->lerp) { struct inplace inplace; int16_t dst_x, dst_y; PixmapPtr pixmap; pixmap = get_drawable_pixmap(thread->dst->pDrawable); inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(thread->dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x * 4; inplace.stride = pixmap->devKind; inplace.color = thread->color; span = clipped_span(&clipped, tor_blt_lerp32, clip); tor_render(NULL, &tor, (void*)&inplace, (void *)&clipped, span, false); } else if (thread->is_solid) { struct pixman_inplace pi; pi.image = image_from_pict(thread->dst, false, &pi.dx, &pi.dy); pi.op = thread->op; pi.color = thread->color; pi.bits = (uint32_t *)&pi.sx; pi.source = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, pi.bits, 0); pixman_image_set_repeat(pi.source, PIXMAN_REPEAT_NORMAL); span = clipped_span(&clipped, pixmask_span_solid, clip); tor_render(NULL, &tor, (void*)&pi, clip, span, false); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } else { struct pixman_inplace pi; int16_t x0, y0; trapezoid_origin(&thread->traps[0].left, &x0, &y0); pi.image = image_from_pict(thread->dst, false, &pi.dx, &pi.dy); pi.source = image_from_pict(thread->src, false, &pi.sx, &pi.sy); pi.sx += thread->src_x - x0; pi.sy += thread->src_y - y0; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = thread->op; span = clipped_span(&clipped, pixmask_span, clip); tor_render(NULL, &tor, (void*)&pi, (void *)&clipped, span, false); pixman_image_unref(pi.mask); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } tor_fini(&tor); } static bool trapezoid_span_inplace__x8r8g8b8(CARD8 op, PicturePtr dst, PicturePtr src, int16_t src_x, int16_t src_y, PictFormatPtr maskFormat, unsigned flags, int ntrap, xTrapezoid *traps) { uint32_t color; bool lerp, is_solid; RegionRec region; int dx, dy; int num_threads, n; lerp = false; is_solid = sna_picture_is_solid(src, &color); if (is_solid) { if (op == PictOpOver && (color >> 24) == 0xff) op = PictOpSrc; if (op == PictOpOver && sna_drawable_is_clear(dst->pDrawable)) op = PictOpSrc; lerp = op == PictOpSrc; } if (!lerp) { switch (op) { case PictOpOver: case PictOpAdd: case PictOpOutReverse: break; case PictOpSrc: if (!sna_drawable_is_clear(dst->pDrawable)) return false; break; default: return false; } } if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, NULL, flags, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, ®ion.extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (!sna_compute_composite_extents(®ion.extents, src, NULL, dst, src_x, src_y, 0, 0, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)) return true; DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); region.data = NULL; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, MOVE_WRITE | MOVE_READ)) return true; if (!is_solid && src->pDrawable) { if (!sna_drawable_move_to_cpu(src->pDrawable, MOVE_READ)) return true; if (src->alphaMap && !sna_drawable_move_to_cpu(src->alphaMap->pDrawable, MOVE_READ)) return true; } dx = dst->pDrawable->x * SAMPLES_X; dy = dst->pDrawable->y * SAMPLES_Y; num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0 && (lerp || is_solid)) num_threads = sna_use_threads(4*(region.extents.x2 - region.extents.x1), region.extents.y2 - region.extents.y1, 4); DBG(("%s: %dx%d, format=%x, op=%d, lerp?=%d, num_threads=%d\n", __FUNCTION__, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, dst->format, op, lerp, num_threads)); if (num_threads == 1) { struct tor tor; span_func_t span; struct clipped_span clipped; if (!tor_init(&tor, ®ion.extents, 2*ntrap)) return true; for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) >= region.extents.y2 - dst->pDrawable->y || pixman_fixed_to_int(traps[n].bottom) < region.extents.y1 - dst->pDrawable->y) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (lerp) { struct inplace inplace; PixmapPtr pixmap; int16_t dst_x, dst_y; pixmap = get_drawable_pixmap(dst->pDrawable); inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x * 4; inplace.stride = pixmap->devKind; inplace.color = color; span = clipped_span(&clipped, tor_blt_lerp32, dst->pCompositeClip); DBG(("%s: render inplace op=%d, color=%08x\n", __FUNCTION__, op, color)); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&inplace, (void*)&clipped, span, false); sigtrap_put(); } } else if (is_solid) { struct pixman_inplace pi; pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.op = op; pi.color = color; pi.bits = (uint32_t *)&pi.sx; pi.source = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, pi.bits, 0); pixman_image_set_repeat(pi.source, PIXMAN_REPEAT_NORMAL); span = clipped_span(&clipped, pixmask_span_solid, dst->pCompositeClip); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&pi, (void*)&clipped, span, false); sigtrap_put(); } pixman_image_unref(pi.source); pixman_image_unref(pi.image); } else { struct pixman_inplace pi; int16_t x0, y0; trapezoid_origin(&traps[0].left, &x0, &y0); pi.image = image_from_pict(dst, false, &pi.dx, &pi.dy); pi.source = image_from_pict(src, false, &pi.sx, &pi.sy); pi.sx += src_x - x0; pi.sy += src_y - y0; pi.mask = pixman_image_create_bits(PIXMAN_a8, 1, 1, NULL, 0); pixman_image_set_repeat(pi.mask, PIXMAN_REPEAT_NORMAL); pi.bits = pixman_image_get_data(pi.mask); pi.op = op; span = clipped_span(&clipped, pixmask_span, dst->pCompositeClip); if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&pi, (void *)&clipped, span, false); sigtrap_put(); } pixman_image_unref(pi.mask); pixman_image_unref(pi.source); pixman_image_unref(pi.image); } tor_fini(&tor); } else { struct inplace_x8r8g8b8_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for inplace compositing %dx%d\n", __FUNCTION__, num_threads, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)); threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = region.extents; threads[0].lerp = lerp; threads[0].is_solid = is_solid; threads[0].color = color; threads[0].dx = dx; threads[0].dy = dy; threads[0].dst = dst; threads[0].src = src; threads[0].op = op; threads[0].src_x = src_x; threads[0].src_y = src_y; y = region.extents.y1; h = region.extents.y2 - region.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, inplace_x8r8g8b8_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; inplace_x8r8g8b8_thread(&threads[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); /* leaks thread allocations */ } return true; } struct inplace_thread { xTrapezoid *traps; span_func_t span; struct inplace inplace; struct clipped_span clipped; BoxRec extents; int dx, dy; int draw_x, draw_y; bool unbounded; int ntrap; }; static void inplace_thread(void *arg) { struct inplace_thread *thread = arg; struct tor tor; int n; if (!tor_init(&tor, &thread->extents, 2*thread->ntrap)) return; for (n = 0; n < thread->ntrap; n++) { if (pixman_fixed_to_int(thread->traps[n].top) >= thread->extents.y2 - thread->draw_y || pixman_fixed_to_int(thread->traps[n].bottom) < thread->extents.y1 - thread->draw_y) continue; tor_add_trapezoid(&tor, &thread->traps[n], thread->dx, thread->dy); } tor_render(NULL, &tor, (void*)&thread->inplace, (void*)&thread->clipped, thread->span, thread->unbounded); tor_fini(&tor); } bool precise_trapezoid_span_inplace(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps, bool fallback) { struct inplace inplace; struct clipped_span clipped; span_func_t span; PixmapPtr pixmap; struct sna_pixmap *priv; RegionRec region; uint32_t color; bool unbounded; int16_t dst_x, dst_y; int dx, dy; int num_threads, n; if (NO_PRECISE) return false; if (dst->format == PICT_a8r8g8b8 || dst->format == PICT_x8r8g8b8) return trapezoid_span_inplace__x8r8g8b8(op, dst, src, src_x, src_y, maskFormat, flags, ntrap, traps); if (!sna_picture_is_solid(src, &color)) { DBG(("%s: fallback -- can not perform operation in place, requires solid source\n", __FUNCTION__)); return false; } if (dst->format != PICT_a8) { DBG(("%s: fallback -- can not perform operation in place, format=%x\n", __FUNCTION__, dst->format)); return false; } pixmap = get_drawable_pixmap(dst->pDrawable); unbounded = false; priv = sna_pixmap(pixmap); if (priv) { switch (op) { case PictOpAdd: if (priv->clear && priv->clear_color == 0) { unbounded = true; op = PictOpSrc; } if ((color >> 24) == 0) return true; break; case PictOpIn: if (priv->clear && priv->clear_color == 0) return true; if (priv->clear && priv->clear_color == 0xff) op = PictOpSrc; unbounded = true; break; case PictOpSrc: unbounded = true; break; default: DBG(("%s: fallback -- can not perform op [%d] in place\n", __FUNCTION__, op)); return false; } } else { switch (op) { case PictOpAdd: if ((color >> 24) == 0) return true; break; case PictOpIn: case PictOpSrc: unbounded = true; break; default: DBG(("%s: fallback -- can not perform op [%d] in place\n", __FUNCTION__, op)); return false; } } DBG(("%s: format=%x, op=%d, color=%x\n", __FUNCTION__, dst->format, op, color)); if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!precise_trapezoid_span_inplace(sna, op, src, dst, NULL, flags, src_x, src_y, 1, traps++, fallback)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, ®ion.extents)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2)); if (!sna_compute_composite_extents(®ion.extents, NULL, NULL, dst, 0, 0, 0, 0, region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)) return true; DBG(("%s: clipped extents (%d, %d), (%d, %d) [complex clip? %d]\n", __FUNCTION__, region.extents.x1, region.extents.y1, region.extents.x2, region.extents.y2, dst->pCompositeClip->data != NULL)); if (op == PictOpSrc) { span = tor_blt_src; } else if (op == PictOpIn) { span = tor_blt_in; } else { assert(op == PictOpAdd); span = tor_blt_add; } DBG(("%s: move-to-cpu(dst)\n", __FUNCTION__)); region.data = NULL; if (!sna_drawable_move_region_to_cpu(dst->pDrawable, ®ion, op == PictOpSrc ? MOVE_WRITE | MOVE_INPLACE_HINT : MOVE_WRITE | MOVE_READ)) return true; dx = dst->pDrawable->x * SAMPLES_X; dy = dst->pDrawable->y * SAMPLES_Y; inplace.ptr = pixmap->devPrivate.ptr; if (get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y)) inplace.ptr += dst_y * pixmap->devKind + dst_x; inplace.stride = pixmap->devKind; inplace.opacity = color >> 24; span = clipped_span(&clipped, span, dst->pCompositeClip); num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0) num_threads = sna_use_threads(region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1, 4); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, ®ion.extents, 2*ntrap)) return true; for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) >= region.extents.y2 - dst->pDrawable->y || pixman_fixed_to_int(traps[n].bottom) < region.extents.y1 - dst->pDrawable->y) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (sigtrap_get() == 0) { tor_render(NULL, &tor, (void*)&inplace, (void *)&clipped, span, unbounded); sigtrap_put(); } tor_fini(&tor); } else { struct inplace_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for inplace compositing %dx%d\n", __FUNCTION__, num_threads, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1)); threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].inplace = inplace; threads[0].extents = region.extents; threads[0].clipped = clipped; threads[0].span = span; threads[0].unbounded = unbounded; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_x = dst->pDrawable->x; threads[0].draw_y = dst->pDrawable->y; y = region.extents.y1; h = region.extents.y2 - region.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= region.extents.y2 - region.extents.y1; if (sigtrap_get() == 0) { for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, inplace_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; inplace_thread(&threads[0]); sna_threads_wait(); sigtrap_put(); } else sna_threads_kill(); /* leaks thread allocations */ } return true; } bool precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, unsigned flags, INT16 src_x, INT16 src_y, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; PixmapPtr scratch; PicturePtr mask; BoxRec extents; int16_t dst_x, dst_y; int dx, dy, num_threads; int error, n; if (NO_PRECISE) return false; if (maskFormat == NULL && ntrap > 1) { DBG(("%s: individual rasterisation requested\n", __FUNCTION__)); do { /* XXX unwind errors? */ if (!precise_trapezoid_span_fallback(op, src, dst, NULL, flags, src_x, src_y, 1, traps++)) return false; } while (--ntrap); return true; } if (!trapezoids_bounds(ntrap, traps, &extents)) return true; DBG(("%s: ntraps=%d, extents (%d, %d), (%d, %d)\n", __FUNCTION__, ntrap, extents.x1, extents.y1, extents.x2, extents.y2)); if (!sna_compute_composite_extents(&extents, src, NULL, dst, src_x, src_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) return true; DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); extents.y2 -= extents.y1; extents.x2 -= extents.x1; extents.x1 -= dst->pDrawable->x; extents.y1 -= dst->pDrawable->y; dst_x = extents.x1; dst_y = extents.y1; dx = -extents.x1 * SAMPLES_X; dy = -extents.y1 * SAMPLES_Y; extents.x1 = extents.y1 = 0; DBG(("%s: mask (%dx%d), dx=(%d, %d)\n", __FUNCTION__, extents.x2, extents.y2, dx, dy)); scratch = sna_pixmap_create_unattached(screen, extents.x2, extents.y2, 8); if (!scratch) return true; DBG(("%s: created buffer %p, stride %d\n", __FUNCTION__, scratch->devPrivate.ptr, scratch->devKind)); num_threads = 1; if (!NO_GPU_THREADS && (flags & COMPOSITE_SPANS_RECTILINEAR) == 0) num_threads = sna_use_threads(extents.x2 - extents.x1, extents.y2 - extents.y1, 4); if (num_threads == 1) { struct tor tor; if (!tor_init(&tor, &extents, 2*ntrap)) { sna_pixmap_destroy(scratch); return true; } for (n = 0; n < ntrap; n++) { if (pixman_fixed_to_int(traps[n].top) - dst_y >= extents.y2 || pixman_fixed_to_int(traps[n].bottom) - dst_y < 0) continue; tor_add_trapezoid(&tor, &traps[n], dx, dy); } if (extents.x2 <= TOR_INPLACE_SIZE) { tor_inplace(&tor, scratch); } else { tor_render(NULL, &tor, scratch->devPrivate.ptr, (void *)(intptr_t)scratch->devKind, tor_blt_mask, true); } tor_fini(&tor); } else { struct mask_thread threads[num_threads]; int y, h; DBG(("%s: using %d threads for mask compositing %dx%d\n", __FUNCTION__, num_threads, extents.x2 - extents.x1, extents.y2 - extents.y1)); threads[0].scratch = scratch; threads[0].traps = traps; threads[0].ntrap = ntrap; threads[0].extents = extents; threads[0].dx = dx; threads[0].dy = dy; threads[0].dst_y = dst_y; y = extents.y1; h = extents.y2 - extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= extents.y2 - extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, mask_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; mask_thread(&threads[0]); sna_threads_wait(); } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, 8, PICT_a8), 0, 0, serverClient, &error); if (mask) { RegionRec region; int16_t x0, y0; region.extents.x1 = dst_x + dst->pDrawable->x; region.extents.y1 = dst_y + dst->pDrawable->y; region.extents.x2 = region.extents.x1 + extents.x2; region.extents.y2 = region.extents.y1 + extents.y2; region.data = NULL; trapezoid_origin(&traps[0].left, &x0, &y0); DBG(("%s: fbComposite()\n", __FUNCTION__)); sna_composite_fb(op, src, mask, dst, ®ion, src_x + dst_x - x0, src_y + dst_y - y0, 0, 0, dst_x, dst_y, extents.x2, extents.y2); FreePicture(mask, 0); } sna_pixmap_destroy(scratch); return true; } struct tristrip_thread { struct sna *sna; const struct sna_composite_spans_op *op; const xPointFixed *points; RegionPtr clip; span_func_t span; BoxRec extents; int dx, dy, draw_y; int count; bool unbounded; }; static void tristrip_thread(void *arg) { struct tristrip_thread *thread = arg; struct span_thread_boxes boxes; struct tor tor; int n, cw, ccw; if (!tor_init(&tor, &thread->extents, 2*thread->count)) return; span_thread_boxes_init(&boxes, thread->op, thread->clip); cw = 0; ccw = 1; polygon_add_line(tor.polygon, &thread->points[ccw], &thread->points[cw], thread->dx, thread->dy); n = 2; do { polygon_add_line(tor.polygon, &thread->points[cw], &thread->points[n], thread->dx, thread->dy); cw = n; if (++n == thread->count) break; polygon_add_line(tor.polygon, &thread->points[n], &thread->points[ccw], thread->dx, thread->dy); ccw = n; if (++n == thread->count) break; } while (1); polygon_add_line(tor.polygon, &thread->points[cw], &thread->points[ccw], thread->dx, thread->dy); assert(tor.polygon->num_edges <= 2*thread->count); tor_render(thread->sna, &tor, (struct sna_composite_spans_op *)&boxes, thread->clip, thread->span, thread->unbounded); tor_fini(&tor); if (boxes.num_boxes) { DBG(("%s: flushing %d boxes\n", __FUNCTION__, boxes.num_boxes)); assert(boxes.num_boxes <= SPAN_THREAD_MAX_BOXES); thread->op->thread_boxes(thread->sna, thread->op, boxes.boxes, boxes.num_boxes); } } bool precise_tristrip_span_converter(struct sna *sna, CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, int count, xPointFixed *points) { struct sna_composite_spans_op tmp; BoxRec extents; pixman_region16_t clip; int16_t dst_x, dst_y; int dx, dy, num_threads; bool was_clear; if (!sna->render.check_composite_spans(sna, op, src, dst, 0, 0, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } dst_x = pixman_fixed_to_int(points[0].x); dst_y = pixman_fixed_to_int(points[0].y); miPointFixedBounds(count, points, &extents); DBG(("%s: extents (%d, %d), (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2)); if (extents.y1 >= extents.y2 || extents.x1 >= extents.x2) return true; #if 0 if (extents.y2 - extents.y1 < 64 && extents.x2 - extents.x1 < 64) { DBG(("%s: fallback -- traps extents too small %dx%d\n", __FUNCTION__, extents.y2 - extents.y1, extents.x2 - extents.x1)); return false; } #endif if (!sna_compute_composite_region(&clip, src, NULL, dst, src_x + extents.x1 - dst_x, src_y + extents.y1 - dst_y, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1)) { DBG(("%s: triangles do not intersect drawable clips\n", __FUNCTION__)) ; return true; } if (!sna->render.check_composite_spans(sna, op, src, dst, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } extents = *RegionExtents(&clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d) src -> (%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy)); was_clear = sna_drawable_is_clear(dst->pDrawable); memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite_spans(sna, op, src, dst, src_x + extents.x1 - dst_x - dx, src_y + extents.y1 - dst_y - dy, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, 0, &tmp)) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= SAMPLES_X; dy *= SAMPLES_Y; num_threads = 1; if (!NO_GPU_THREADS && tmp.thread_boxes && thread_choose_span(&tmp, dst, maskFormat, &clip)) num_threads = sna_use_threads(extents.x2 - extents.x1, extents.y2 - extents.y1, 16); if (num_threads == 1) { struct tor tor; int cw, ccw, n; if (!tor_init(&tor, &extents, 2*count)) goto skip; cw = 0; ccw = 1; polygon_add_line(tor.polygon, &points[ccw], &points[cw], dx, dy); n = 2; do { polygon_add_line(tor.polygon, &points[cw], &points[n], dx, dy); cw = n; if (++n == count) break; polygon_add_line(tor.polygon, &points[n], &points[ccw], dx, dy); ccw = n; if (++n == count) break; } while (1); polygon_add_line(tor.polygon, &points[cw], &points[ccw], dx, dy); assert(tor.polygon->num_edges <= 2*count); tor_render(sna, &tor, &tmp, &clip, choose_span(&tmp, dst, maskFormat, &clip), !was_clear && maskFormat && !operator_is_bounded(op)); tor_fini(&tor); } else { struct tristrip_thread threads[num_threads]; int y, h, n; DBG(("%s: using %d threads for tristrip compositing %dx%d\n", __FUNCTION__, num_threads, clip.extents.x2 - clip.extents.x1, clip.extents.y2 - clip.extents.y1)); threads[0].sna = sna; threads[0].op = &tmp; threads[0].points = points; threads[0].count = count; threads[0].extents = clip.extents; threads[0].clip = &clip; threads[0].dx = dx; threads[0].dy = dy; threads[0].draw_y = dst->pDrawable->y; threads[0].unbounded = !was_clear && maskFormat && !operator_is_bounded(op); threads[0].span = thread_choose_span(&tmp, dst, maskFormat, &clip); y = clip.extents.y1; h = clip.extents.y2 - clip.extents.y1; h = (h + num_threads - 1) / num_threads; num_threads -= (num_threads-1) * h >= clip.extents.y2 - clip.extents.y1; for (n = 1; n < num_threads; n++) { threads[n] = threads[0]; threads[n].extents.y1 = y; threads[n].extents.y2 = y += h; sna_threads_run(n, tristrip_thread, &threads[n]); } assert(y < threads[0].extents.y2); threads[0].extents.y1 = y; tristrip_thread(&threads[0]); sna_threads_wait(); } skip: tmp.done(sna, &tmp); REGION_UNINIT(NULL, &clip); return true; } bool precise_trap_span_converter(struct sna *sna, PicturePtr dst, INT16 src_x, INT16 src_y, int ntrap, xTrap *trap) { struct sna_composite_spans_op tmp; struct tor tor; BoxRec extents; pixman_region16_t *clip; int dx, dy, n; if (dst->pDrawable->depth < 8) return false; if (!sna->render.check_composite_spans(sna, PictOpAdd, sna->render.white_picture, dst, dst->pCompositeClip->extents.x2 - dst->pCompositeClip->extents.x1, dst->pCompositeClip->extents.y2 - dst->pCompositeClip->extents.y1, 0)) { DBG(("%s: fallback -- composite spans not supported\n", __FUNCTION__)); return false; } clip = dst->pCompositeClip; extents = *RegionExtents(clip); dx = dst->pDrawable->x; dy = dst->pDrawable->y; DBG(("%s: after clip -- extents (%d, %d), (%d, %d), delta=(%d, %d)\n", __FUNCTION__, extents.x1, extents.y1, extents.x2, extents.y2, dx, dy)); memset(&tmp, 0, sizeof(tmp)); if (!sna->render.composite_spans(sna, PictOpAdd, sna->render.white_picture, dst, 0, 0, extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1, 0, &tmp)) { DBG(("%s: fallback -- composite spans render op not supported\n", __FUNCTION__)); return false; } dx *= SAMPLES_X; dy *= SAMPLES_Y; if (!tor_init(&tor, &extents, 2*ntrap)) goto skip; for (n = 0; n < ntrap; n++) { xPointFixed p1, p2; if (pixman_fixed_to_int(trap[n].top.y) + dst->pDrawable->y >= extents.y2 || pixman_fixed_to_int(trap[n].bot.y) + dst->pDrawable->y < extents.y1) continue; p1.y = trap[n].top.y; p2.y = trap[n].bot.y; p1.x = trap[n].top.l; p2.x = trap[n].bot.l; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); p1.y = trap[n].bot.y; p2.y = trap[n].top.y; p1.x = trap[n].top.r; p2.x = trap[n].bot.r; polygon_add_line(tor.polygon, &p1, &p2, dx, dy); } tor_render(sna, &tor, &tmp, clip, choose_span(&tmp, dst, NULL, clip), false); tor_fini(&tor); skip: tmp.done(sna, &tmp); return true; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_vertex.c000066400000000000000000000026731267532330400241750ustar00rootroot00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Chris Wilson * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sna.h" #include void sna_vertex_init(struct sna *sna) { pthread_mutex_init(&sna->render.lock, NULL); pthread_cond_init(&sna->render.wait, NULL); sna->render.active = 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video.c000066400000000000000000000502251267532330400237620ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane * David Dawes * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian * Offscreen Images: * Matt Sottek */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "sna.h" #include "sna_reg.h" #include "sna_video.h" #include "intel_options.h" #include #ifdef SNA_XVMC #define _SNA_XVMC_SERVER_ #include "sna_video_hwmc.h" #else static inline void sna_video_xvmc_setup(struct sna *sna, ScreenPtr ptr) { DBG(("%s: XvMC not compiled in\n", __FUNCTION__)); } #endif void sna_video_free_buffers(struct sna_video *video) { unsigned int i; for (i = 0; i < ARRAY_SIZE(video->old_buf); i++) { if (video->old_buf[i]) { kgem_bo_destroy(&video->sna->kgem, video->old_buf[i]); video->old_buf[i] = NULL; } } if (video->buf) { kgem_bo_destroy(&video->sna->kgem, video->buf); video->buf = NULL; } } struct kgem_bo * sna_video_buffer(struct sna_video *video, struct sna_video_frame *frame) { /* Free the current buffer if we're going to have to reallocate */ if (video->buf && __kgem_bo_size(video->buf) < frame->size) sna_video_free_buffers(video); if (video->buf && video->buf->scanout) { if (frame->width != video->width || frame->height != video->height || frame->id != video->format) sna_video_free_buffers(video); } if (video->buf == NULL) { if (video->tiled) { video->buf = kgem_create_2d(&video->sna->kgem, frame->width, frame->height, 32, I915_TILING_X, CREATE_EXACT); } else { video->buf = kgem_create_linear(&video->sna->kgem, frame->size, CREATE_GTT_MAP); } } video->width = frame->width; video->height = frame->height; video->format = frame->id; return video->buf; } void sna_video_buffer_fini(struct sna_video *video) { struct kgem_bo *bo; bo = video->old_buf[1]; video->old_buf[1] = video->old_buf[0]; video->old_buf[0] = video->buf; video->buf = bo; } bool sna_video_clip_helper(struct sna_video *video, struct sna_video_frame *frame, xf86CrtcPtr *crtc_ret, BoxPtr dst, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, RegionPtr reg) { bool ret; RegionRec crtc_region_local; RegionPtr crtc_region = reg; INT32 x1, x2, y1, y2; xf86CrtcPtr crtc; x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dst->x1 = drw_x; dst->x2 = drw_x + drw_w; dst->y1 = drw_y; dst->y2 = drw_y + drw_h; /* * For overlay video, compute the relevant CRTC and * clip video to that */ crtc = sna_covering_crtc(video->sna, dst, video->desired_crtc); /* For textured video, we don't actually want to clip at all. */ if (crtc && !video->textured) { crtc_region_local.extents = crtc->bounds; crtc_region_local.data = NULL; crtc_region = &crtc_region_local; RegionIntersect(crtc_region, crtc_region, reg); } *crtc_ret = crtc; ret = xf86XVClipVideoHelper(dst, &x1, &x2, &y1, &y2, crtc_region, frame->width, frame->height); if (crtc_region != reg) RegionUninit(crtc_region); frame->src.x1 = x1 >> 16; frame->src.y1 = y1 >> 16; frame->src.x2 = (x2 + 0xffff) >> 16; frame->src.y2 = (y2 + 0xffff) >> 16; frame->image.x1 = frame->src.x1 & ~1; frame->image.x2 = ALIGN(frame->src.x2, 2); if (is_planar_fourcc(frame->id)) { frame->image.y1 = frame->src.y1 & ~1; frame->image.y2 = ALIGN(frame->src.y2, 2); } else { frame->image.y1 = frame->src.y1; frame->image.y2 = frame->src.y2; } return ret; } void sna_video_frame_init(struct sna_video *video, int id, short width, short height, struct sna_video_frame *frame) { DBG(("%s: id=%d [planar? %d], width=%d, height=%d, align=%d\n", __FUNCTION__, id, is_planar_fourcc(id), width, height, video->alignment)); assert(width && height); frame->bo = NULL; frame->id = id; frame->width = width; frame->height = height; frame->rotation = 0; } void sna_video_frame_set_rotation(struct sna_video *video, struct sna_video_frame *frame, Rotation rotation) { unsigned width = frame->width; unsigned height = frame->height; unsigned align; DBG(("%s: rotation=%d\n", __FUNCTION__, rotation)); frame->rotation = rotation; align = video->alignment; #if SNA_XVMC /* for i915 xvmc, hw requires 1kb aligned surfaces */ if (frame->id == FOURCC_XVMC && video->sna->kgem.gen < 040 && align < 1024) align = 1024; #endif /* Determine the desired destination pitch (representing the * chroma's pitch in the planar case). */ if (is_planar_fourcc(frame->id)) { assert((width & 1) == 0); assert((height & 1) == 0); if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { frame->pitch[0] = ALIGN((height / 2), align); frame->pitch[1] = ALIGN(height, align); frame->size = width; } else { frame->pitch[0] = ALIGN((width / 2), align); frame->pitch[1] = ALIGN(width, align); frame->size = height; } frame->size *= frame->pitch[0] + frame->pitch[1]; if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { frame->UBufOffset = (int)frame->pitch[1] * width; frame->VBufOffset = frame->UBufOffset + (int)frame->pitch[0] * width / 2; } else { frame->UBufOffset = (int)frame->pitch[1] * height; frame->VBufOffset = frame->UBufOffset + (int)frame->pitch[0] * height / 2; } } else { switch (frame->id) { case FOURCC_RGB888: if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { frame->pitch[0] = ALIGN((height << 2), align); frame->size = (int)frame->pitch[0] * width; } else { frame->pitch[0] = ALIGN((width << 2), align); frame->size = (int)frame->pitch[0] * height; } frame->UBufOffset = frame->VBufOffset = 0; break; case FOURCC_RGB565: if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { frame->pitch[0] = ALIGN((height << 1), align); frame->size = (int)frame->pitch[0] * width; } else { frame->pitch[0] = ALIGN((width << 1), align); frame->size = (int)frame->pitch[0] * height; } frame->UBufOffset = frame->VBufOffset = 0; break; default: if (rotation & (RR_Rotate_90 | RR_Rotate_270)) { frame->pitch[0] = ALIGN((height << 1), align); frame->size = (int)frame->pitch[0] * width; } else { frame->pitch[0] = ALIGN((width << 1), align); frame->size = (int)frame->pitch[0] * height; } break; } frame->pitch[1] = 0; frame->UBufOffset = 0; frame->VBufOffset = 0; } assert(frame->size); } static void sna_memcpy_plane(struct sna_video *video, uint8_t *dst, const uint8_t *src, const struct sna_video_frame *frame, int sub) { int dstPitch = frame->pitch[!sub], srcPitch; const uint8_t *s; int i, j = 0; int x, y, w, h; x = frame->image.x1; y = frame->image.y1; w = frame->image.x2 - frame->image.x1; h = frame->image.y2 - frame->image.y1; if (sub) { x >>= 1; w >>= 1; y >>= 1; h >>= 1; srcPitch = ALIGN((frame->width >> 1), 4); } else srcPitch = ALIGN(frame->width, 4); src += y * srcPitch + x; if (!video->textured) x = y = 0; switch (frame->rotation) { case RR_Rotate_0: dst += y * dstPitch + x; if (srcPitch == dstPitch && srcPitch == w) memcpy(dst, src, srcPitch * h); else while (h--) { memcpy(dst, src, w); src += srcPitch; dst += dstPitch; } break; case RR_Rotate_90: for (i = 0; i < h; i++) { s = src; for (j = 0; j < w; j++) dst[i + ((x + w - j - 1) * dstPitch)] = *s++; src += srcPitch; } break; case RR_Rotate_180: for (i = 0; i < h; i++) { s = src; for (j = 0; j < w; j++) { dst[(x + w - j - 1) + ((h - i - 1) * dstPitch)] = *s++; } src += srcPitch; } break; case RR_Rotate_270: for (i = 0; i < h; i++) { s = src; for (j = 0; j < w; j++) { dst[(h - i - 1) + (x + j * dstPitch)] = *s++; } src += srcPitch; } break; } } static void sna_copy_planar_data(struct sna_video *video, const struct sna_video_frame *frame, const uint8_t *src, uint8_t *dst) { uint8_t *d; sna_memcpy_plane(video, dst, src, frame, 0); src += frame->height * ALIGN(frame->width, 4); if (frame->id == FOURCC_I420) d = dst + frame->UBufOffset; else d = dst + frame->VBufOffset; sna_memcpy_plane(video, d, src, frame, 1); src += (frame->height >> 1) * ALIGN(frame->width >> 1, 4); if (frame->id == FOURCC_I420) d = dst + frame->VBufOffset; else d = dst + frame->UBufOffset; sna_memcpy_plane(video, d, src, frame, 1); } static void sna_copy_packed_data(struct sna_video *video, const struct sna_video_frame *frame, const uint8_t *buf, uint8_t *dst) { int pitch = frame->width << 1; const uint8_t *src, *s; int x, y, w, h; int i, j; if (video->textured) { /* XXX support copying cropped extents */ x = y = 0; w = frame->width; h = frame->height; } else { x = frame->image.x1; y = frame->image.y1; w = frame->image.x2 - frame->image.x1; h = frame->image.y2 - frame->image.y1; } src = buf + (y * pitch) + (x << 1); switch (frame->rotation) { case RR_Rotate_0: w <<= 1; for (i = 0; i < h; i++) { memcpy(dst, src, w); src += pitch; dst += frame->pitch[0]; } break; case RR_Rotate_90: h <<= 1; for (i = 0; i < h; i += 2) { s = src; for (j = 0; j < w; j++) { /* Copy Y */ dst[(i + 0) + ((w - j - 1) * frame->pitch[0])] = *s; s += 2; } src += pitch; } h >>= 1; src = buf + (y * pitch) + (x << 1); for (i = 0; i < h; i += 2) { for (j = 0; j < w; j += 2) { /* Copy U */ dst[((i * 2) + 1) + ((w - j - 1) * frame->pitch[0])] = src[(j * 2) + 1 + (i * pitch)]; dst[((i * 2) + 1) + ((w - j - 2) * frame->pitch[0])] = src[(j * 2) + 1 + ((i + 1) * pitch)]; /* Copy V */ dst[((i * 2) + 3) + ((w - j - 1) * frame->pitch[0])] = src[(j * 2) + 3 + (i * pitch)]; dst[((i * 2) + 3) + ((w - j - 2) * frame->pitch[0])] = src[(j * 2) + 3 + ((i + 1) * pitch)]; } } break; case RR_Rotate_180: w <<= 1; for (i = 0; i < h; i++) { s = src; for (j = 0; j < w; j += 4) { dst[(w - j - 4) + ((h - i - 1) * frame->pitch[0])] = *s++; dst[(w - j - 3) + ((h - i - 1) * frame->pitch[0])] = *s++; dst[(w - j - 2) + ((h - i - 1) * frame->pitch[0])] = *s++; dst[(w - j - 1) + ((h - i - 1) * frame->pitch[0])] = *s++; } src += pitch; } break; case RR_Rotate_270: h <<= 1; for (i = 0; i < h; i += 2) { s = src; for (j = 0; j < w; j++) { /* Copy Y */ dst[(h - i - 2) + (j * frame->pitch[0])] = *s; s += 2; } src += pitch; } h >>= 1; src = buf + (y * pitch) + (x << 1); for (i = 0; i < h; i += 2) { for (j = 0; j < w; j += 2) { /* Copy U */ dst[(((h - i) * 2) - 3) + (j * frame->pitch[0])] = src[(j * 2) + 1 + (i * pitch)]; dst[(((h - i) * 2) - 3) + ((j + 1) * frame->pitch[0])] = src[(j * 2) + 1 + ((i + 1) * pitch)]; /* Copy V */ dst[(((h - i) * 2) - 1) + (j * frame->pitch[0])] = src[(j * 2) + 3 + (i * pitch)]; dst[(((h - i) * 2) - 1) + ((j + 1) * frame->pitch[0])] = src[(j * 2) + 3 + ((i + 1) * pitch)]; } } break; } } bool sna_video_copy_data(struct sna_video *video, struct sna_video_frame *frame, const uint8_t *buf) { uint8_t *dst; DBG(("%s: handle=%d, size=%dx%d [%d], pitch=[%d,%d] rotation=%d, is-texture=%d\n", __FUNCTION__, frame->bo ? frame->bo->handle : 0, frame->width, frame->height, frame->size, frame->pitch[0], frame->pitch[1], frame->rotation, video->textured)); DBG(("%s: image=(%d, %d), (%d, %d), source=(%d, %d), (%d, %d)\n", __FUNCTION__, frame->image.x1, frame->image.y1, frame->image.x2, frame->image.y2, frame->src.x1, frame->src.y1, frame->src.x2, frame->src.y2)); assert(frame->width && frame->height); assert(frame->rotation); assert(frame->size); /* In the common case, we can simply the upload in a single pwrite */ if (frame->rotation == RR_Rotate_0 && !video->tiled) { DBG(("%s: unrotated, untiled fast paths: is-planar?=%d\n", __FUNCTION__, is_planar_fourcc(frame->id))); if (is_planar_fourcc(frame->id)) { int w = frame->image.x2 - frame->image.x1; int h = frame->image.y2 - frame->image.y1; if (ALIGN(h, 2) == frame->height && ALIGN(w >> 1, 4) == frame->pitch[0] && ALIGN(w, 4) == frame->pitch[1]) { if (frame->bo) { if (!kgem_bo_write(&video->sna->kgem, frame->bo, buf, frame->size)) goto use_gtt; } else { frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size, KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE, (void **)&dst); if (frame->bo == NULL) return false; memcpy(dst, buf, frame->size); } if (frame->id != FOURCC_I420) { uint32_t tmp; tmp = frame->VBufOffset; frame->VBufOffset = frame->UBufOffset; frame->UBufOffset = tmp; } return true; } } else { int x, y, w, h; if (video->textured) { /* XXX support copying cropped extents */ x = y = 0; w = frame->width; h = frame->height; } else { x = frame->image.x1; y = frame->image.y1; w = frame->image.x2 - frame->image.x1; h = frame->image.y2 - frame->image.y1; } if (w*2 == frame->pitch[0]) { buf += (2U*y * frame->width) + (x << 1); if (frame->bo) { if (!kgem_bo_write(&video->sna->kgem, frame->bo, buf, 2U*h*frame->width)) goto use_gtt; } else { frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size, KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE, (void **)&dst); if (frame->bo == NULL) return false; memcpy(dst, buf, 2U*h*frame->width); } return true; } } DBG(("%s: source cropped, fallback\n", __FUNCTION__)); } use_gtt: /* copy data, must use GTT so that we keep the overlay uncached */ if (frame->bo) { dst = kgem_bo_map__gtt(&video->sna->kgem, frame->bo); if (dst == NULL) return false; } else { frame->bo = kgem_create_buffer(&video->sna->kgem, frame->size, KGEM_BUFFER_WRITE | KGEM_BUFFER_WRITE_INPLACE, (void **)&dst); if (frame->bo == NULL) return false; } if (is_planar_fourcc(frame->id)) sna_copy_planar_data(video, frame, buf, dst); else sna_copy_packed_data(video, frame, buf, dst); return true; } void sna_video_fill_colorkey(struct sna_video *video, const RegionRec *clip) { struct sna *sna = video->sna; PixmapPtr front = sna->front; struct kgem_bo *bo = __sna_pixmap_get_bo(front); uint8_t *dst, *tmp; int w, width; if (video->AlwaysOnTop || RegionEqual(&video->clip, (RegionPtr)clip)) return; assert(bo); if (!wedged(sna) && sna_blt_fill_boxes(sna, GXcopy, bo, front->drawable.bitsPerPixel, video->color_key, region_rects(clip), region_num_rects(clip))) { RegionCopy(&video->clip, (RegionPtr)clip); return; } dst = kgem_bo_map__gtt(&sna->kgem, bo); if (dst == NULL) return; w = front->drawable.bitsPerPixel/8; width = (clip->extents.x2 - clip->extents.x1) * w; tmp = malloc(width); if (tmp == NULL) return; memcpy(tmp, &video->color_key, w); while (2 * w < width) { memcpy(tmp + w, tmp, w); w *= 2; } if (w < width) memcpy(tmp + w, tmp, width - w); if (sigtrap_get() == 0) { const BoxRec *box = region_rects(clip); int n = region_num_rects(clip); w = front->drawable.bitsPerPixel/8; do { int y = box->y1; uint8_t *row = dst + y*bo->pitch + w*box->x1; width = (box->x2 - box->x1) * w; while (y < box->y2) { memcpy(row, tmp, width); row += bo->pitch; y++; } box++; } while (--n); sigtrap_put(); RegionCopy(&video->clip, (RegionPtr)clip); } free(tmp); } XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna) { XvAdaptorPtr new_adaptors; new_adaptors = realloc(sna->xv.adaptors, (sna->xv.num_adaptors+1)*sizeof(XvAdaptorRec)); if (new_adaptors == NULL) return NULL; if (sna->xv.num_adaptors && new_adaptors != sna->xv.adaptors) { XvAdaptorPtr adaptor = new_adaptors; int i = sna->xv.num_adaptors, j; while (i--) { for (j = 0; j < adaptor->nPorts; j++) adaptor->pPorts[j].pAdaptor = adaptor; adaptor++; } } sna->xv.adaptors = new_adaptors; return &sna->xv.adaptors[sna->xv.num_adaptors++]; } int sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out) { *out = in; return Success; } int sna_xv_free_port(XvPortPtr port) { return Success; } int sna_xv_fixup_formats(ScreenPtr screen, XvFormatPtr formats, int num_formats) { XvFormatPtr out = formats; int count = 0; while (num_formats--) { int num_visuals = screen->numVisuals; VisualPtr v = screen->visuals; while (num_visuals--) { if (v->class == TrueColor && v->nplanes == formats->depth) { int tmp = out[count].depth; out[count].depth = formats->depth; out[count].visual = v->vid; formats->depth = tmp; count++; break; } v++; } formats++; } return count; } #if XORG_XV_VERSION < 2 static int sna_xv_query_adaptors(ScreenPtr screen, XvAdaptorPtr *adaptors, int *num_adaptors) { struct sna *sna = to_sna_from_screen(screen); *num_adaptors = sna->xv.num_adaptors; *adaptors = sna->xv.adaptors; return Success; } static Bool sna_xv_close_screen(CLOSE_SCREEN_ARGS_DECL) { struct sna *sna = to_sna_from_screen(screen); sna_video_close(sna); return TRUE; } #endif void sna_video_init(struct sna *sna, ScreenPtr screen) { XvScreenPtr xv; if (noXvExtension) return; if (xf86LoaderCheckSymbol("xf86XVListGenericAdaptors")) { XF86VideoAdaptorPtr *adaptors = NULL; int num_adaptors = xf86XVListGenericAdaptors(sna->scrn, &adaptors); if (num_adaptors) xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "Ignoring generic xf86XV adaptors"); free(adaptors); } if (XvScreenInit(screen) != Success) return; xv = to_xv(screen); #if XORG_XV_VERSION < 2 xv->ddCloseScreen = sna_xv_close_screen; xv->ddQueryAdaptors = sna_xv_query_adaptors; #endif sna_video_textured_setup(sna, screen); sna_video_sprite_setup(sna, screen); sna_video_overlay_setup(sna, screen); if (sna->xv.num_adaptors >= 2 && xf86ReturnOptValBool(sna->Options, OPTION_PREFER_OVERLAY, false)) { XvAdaptorRec tmp; tmp = sna->xv.adaptors[0]; sna->xv.adaptors[0] = sna->xv.adaptors[1]; sna->xv.adaptors[1] = tmp; } xv->nAdaptors = sna->xv.num_adaptors; xv->pAdaptors = sna->xv.adaptors; sna_video_xvmc_setup(sna, screen); } void sna_video_destroy_window(WindowPtr win) { XvPortPtr port; port = sna_window_get_port(win); if (port) { #if XORG_XV_VERSION < 2 port->pAdaptor->ddStopVideo(NULL, port, &win->drawable); #else port->pAdaptor->ddStopVideo(port, &win->drawable); #endif } assert(sna_window_get_port(win) == NULL); } void sna_video_close(struct sna *sna) { int i; for (i = 0; i < sna->xv.num_adaptors; i++) { free(sna->xv.adaptors[i].pPorts->devPriv.ptr); free(sna->xv.adaptors[i].pPorts); free(sna->xv.adaptors[i].pEncodings); } free(sna->xv.adaptors); sna->xv.adaptors = NULL; sna->xv.num_adaptors = 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video.h000066400000000000000000000145611267532330400237720ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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 SNA_VIDEO_H #define SNA_VIDEO_H #include #include #include #if defined(XvMCExtension) && defined(ENABLE_XVMC) #define SNA_XVMC 1 #endif #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') #define FOURCC_RGB565 ((16 << 24) + ('B' << 16) + ('G' << 8) + 'R') #define FOURCC_RGB888 ((24 << 24) + ('B' << 16) + ('G' << 8) + 'R') /* * Below, a dummy picture type that is used in XvPutImage * only to do an overlay update. * Introduced for the XvMC client lib. * Defined to have a zero data size. */ #define XVMC_YUV { \ FOURCC_XVMC, XvYUV, LSBFirst, \ {'X', 'V', 'M', 'C', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \ 12, XvPlanar, 3, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, \ {'Y', 'V', 'U', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ XvTopToBottom \ } #define XVMC_RGB565 { \ FOURCC_RGB565, XvRGB, LSBFirst, \ {'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '1', '6'}, \ 16, XvPacked, 1, 16, 0x1f<<11, 0x3f<<5, 0x1f<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ {'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ XvTopToBottom \ } #define XVMC_RGB888 { \ FOURCC_RGB888, XvRGB, LSBFirst, \ {'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '2', '4'}, \ 32, XvPacked, 1, 24, 0xff<<16, 0xff<<8, 0xff<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ {'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ XvTopToBottom \ } struct sna_video { struct sna *sna; int brightness; int contrast; int saturation; xf86CrtcPtr desired_crtc; uint32_t gamma0; uint32_t gamma1; uint32_t gamma2; uint32_t gamma3; uint32_t gamma4; uint32_t gamma5; unsigned color_key; unsigned color_key_changed; bool has_color_key; /** YUV data buffers */ struct kgem_bo *old_buf[2]; struct kgem_bo *buf; int width, height, format; int alignment; bool tiled; bool textured; int plane; struct kgem_bo *bo[4]; RegionRec clip; int SyncToVblank; /* -1: auto, 0: off, 1: on */ int AlwaysOnTop; }; struct sna_video_frame { struct kgem_bo *bo; uint32_t id; uint32_t size; uint32_t UBufOffset; uint32_t VBufOffset; Rotation rotation; uint16_t width, height; uint16_t pitch[2]; /* extents */ BoxRec image; BoxRec src; }; static inline XvScreenPtr to_xv(ScreenPtr screen) { return dixLookupPrivate(&screen->devPrivates, XvGetScreenKey()); } void sna_video_init(struct sna *sna, ScreenPtr screen); void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen); void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen); void sna_video_textured_setup(struct sna *sna, ScreenPtr screen); void sna_video_destroy_window(WindowPtr win); void sna_video_close(struct sna *sna); XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna); int sna_xv_fixup_formats(ScreenPtr screen, XvFormatPtr formats, int num_formats); int sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out); int sna_xv_free_port(XvPortPtr port); static inline int xvmc_passthrough(int id) { switch (id) { case FOURCC_XVMC: case FOURCC_RGB565: case FOURCC_RGB888: return true; default: return false; } } static inline int is_planar_fourcc(int id) { switch (id) { case FOURCC_YV12: case FOURCC_I420: case FOURCC_XVMC: return 1; default: return 0; } } bool sna_video_clip_helper(struct sna_video *video, struct sna_video_frame *frame, xf86CrtcPtr *crtc_ret, BoxPtr dst, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, RegionPtr reg); void sna_video_frame_init(struct sna_video *video, int id, short width, short height, struct sna_video_frame *frame); void sna_video_frame_set_rotation(struct sna_video *video, struct sna_video_frame *frame, Rotation rotation); struct kgem_bo * sna_video_buffer(struct sna_video *video, struct sna_video_frame *frame); bool sna_video_copy_data(struct sna_video *video, struct sna_video_frame *frame, const uint8_t *buf); void sna_video_fill_colorkey(struct sna_video *video, const RegionRec *clip); void sna_video_buffer_fini(struct sna_video *video); void sna_video_free_buffers(struct sna_video *video); static inline XvPortPtr sna_window_get_port(WindowPtr window) { return ((void **)__get_private(window, sna_window_key))[2]; } static inline void sna_window_set_port(WindowPtr window, XvPortPtr port) { ((void **)__get_private(window, sna_window_key))[2] = port; } static inline int offset_and_clip(int x, int dx) { x += dx; if (x <= 0) return 0; if (x >= MAXSHORT) return MAXSHORT; return x; } static inline void init_video_region(RegionRec *region, DrawablePtr draw, int drw_x, int drw_y, int drw_w, int drw_h) { region->extents.x1 = offset_and_clip(draw->x, drw_x); region->extents.y1 = offset_and_clip(draw->y, drw_y); region->extents.x2 = offset_and_clip(draw->x, drw_x + drw_w); region->extents.y2 = offset_and_clip(draw->y, drw_y + drw_h); region->data = NULL; } #endif /* SNA_VIDEO_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video_hwmc.c000066400000000000000000000145751267532330400250100ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _SNA_XVMC_SERVER_ #include "sna.h" #include "sna_video_hwmc.h" #include #include #include extern DevPrivateKey XF86XvScreenKey; static int create_subpicture(XvMCSubpicturePtr sub, int *size, CARD32 **priv) { return Success; } static void destroy_subpicture(XvMCSubpicturePtr sub) { } static int create_surface(XvMCSurfacePtr surface, int *size, CARD32 **priv) { return Success; } static void destroy_surface(XvMCSurfacePtr surface) { } static int create_context(XvPortPtr port, XvMCContextPtr ctx, int *size, CARD32 **out) { struct sna *sna = to_sna_from_screen(ctx->pScreen); struct intel_xvmc_hw_context { unsigned int type; union { struct { unsigned int use_phys_addr : 1; } i915; struct { unsigned int is_g4x:1; unsigned int is_965_q:1; unsigned int is_igdng:1; } i965; }; } *priv; ctx->port_priv = port->devPriv.ptr; priv = calloc(1, sizeof(*priv)); if (priv == NULL) return BadAlloc; if (sna->kgem.gen >= 040) { int devid = intel_get_device_id(sna->dev); if (sna->kgem.gen >= 045) priv->type = XVMC_I965_MPEG2_VLD; else priv->type = XVMC_I965_MPEG2_MC; priv->i965.is_g4x = sna->kgem.gen == 045; priv->i965.is_965_q = devid == PCI_CHIP_I965_Q; priv->i965.is_igdng = sna->kgem.gen == 050; } else priv->type = XVMC_I915_MPEG2_MC; *size = sizeof(*priv) >> 2; *out = (CARD32 *)priv; return Success; } static void destroy_context(XvMCContextPtr ctx) { } /* i915 hwmc support */ static XvMCSurfaceInfoRec i915_YV12_mpg2_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_2, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 0, /* &yv12_subpicture_list */ NULL, }; static XvMCSurfaceInfoRec i915_YV12_mpg1_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_1, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 0, NULL, }; static XvMCSurfaceInfoPtr surface_info_i915[2] = { &i915_YV12_mpg2_surface, &i915_YV12_mpg1_surface }; /* i965 and later hwmc support */ #ifndef XVMC_VLD #define XVMC_VLD 0x00020000 #endif static XvMCSurfaceInfoRec yv12_mpeg2_vld_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1936, 1096, 1920, 1080, XVMC_MPEG_2 | XVMC_VLD, XVMC_INTRA_UNSIGNED, NULL }; static XvMCSurfaceInfoRec yv12_mpeg2_i965_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1936, 1096, 1920, 1080, XVMC_MPEG_2 | XVMC_MOCOMP, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ XVMC_INTRA_UNSIGNED, /* &yv12_subpicture_list */ NULL }; static XvMCSurfaceInfoRec yv12_mpeg1_i965_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1920, 1080, 1920, 1080, XVMC_MPEG_1 | XVMC_MOCOMP, /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | XVMC_INTRA_UNSIGNED, */ XVMC_INTRA_UNSIGNED, /*&yv12_subpicture_list */ NULL }; static XvMCSurfaceInfoPtr surface_info_i965[] = { &yv12_mpeg2_i965_surface, &yv12_mpeg1_i965_surface }; static XvMCSurfaceInfoPtr surface_info_vld[] = { &yv12_mpeg2_vld_surface, &yv12_mpeg2_i965_surface, }; /* check chip type and load xvmc driver */ void sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen) { XvMCAdaptorRec *adaptors; struct pci_device *pci; const char *name; char bus[64]; int i; pci = xf86GetPciInfoForEntity(sna->pEnt->index); if (pci == NULL) return; if (!sna->xv.num_adaptors) return; if (!xf86LoaderCheckSymbol("XvMCScreenInit")) return; /* Needs KMS support. */ if (sna->kgem.gen < 031) return; /* Not implemented */ if (sna->kgem.gen >= 060) return; adaptors = calloc(sna->xv.num_adaptors, sizeof(XvMCAdaptorRec)); if (adaptors == NULL) return; for (i = 0; i< sna->xv.num_adaptors; i++) { adaptors[i].xv_adaptor = &sna->xv.adaptors[i]; adaptors[i].num_subpictures = 0; adaptors[i].subpictures = NULL; adaptors[i].CreateContext = create_context; adaptors[i].DestroyContext = destroy_context; adaptors[i].CreateSurface = create_surface; adaptors[i].DestroySurface = destroy_surface; adaptors[i].CreateSubpicture = create_subpicture; adaptors[i].DestroySubpicture = destroy_subpicture; if (sna->kgem.gen >= 045) { adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_vld); adaptors[i].surfaces = surface_info_vld; } else if (sna->kgem.gen >= 040) { adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i965); adaptors[i].surfaces = surface_info_i965; } else { adaptors[i].num_surfaces = ARRAY_SIZE(surface_info_i915); adaptors[i].surfaces = surface_info_i915; } } if (XvMCScreenInit(screen, i, adaptors) != Success) { xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "[XvMC] Failed to initialize XvMC.\n"); free(adaptors); return; } sprintf(bus, "pci:%04x:%02x:%02x.%d", pci->domain, pci->bus, pci->dev, pci->func); xf86XvMCRegisterDRInfo(screen, (char *)SNA_XVMC_LIBNAME, bus, SNA_XVMC_MAJOR, SNA_XVMC_MINOR, SNA_XVMC_PATCHLEVEL); if (sna->kgem.gen >= 045) name = "xvmc_vld"; else if (sna->kgem.gen >= 040) name = "i965_xvmc"; else name = "i915_xvmc"; xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "[XvMC] %s driver initialized.\n", name); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video_hwmc.h000066400000000000000000000032031267532330400247770ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #ifndef SNA_VIDEO_HWMC_H #define SNA_VIDEO_HWMC_H #define SNA_XVMC_LIBNAME "IntelXvMC" #define SNA_XVMC_MAJOR 0 #define SNA_XVMC_MINOR 1 #define SNA_XVMC_PATCHLEVEL 0 /* hw xvmc support type */ #define XVMC_I915_MPEG2_MC 0x01 #define XVMC_I965_MPEG2_MC 0x02 #define XVMC_I945_MPEG2_VLD 0x04 #define XVMC_I965_MPEG2_VLD 0x08 #ifdef _SNA_XVMC_SERVER_ #include void sna_video_xvmc_setup(struct sna *sna, ScreenPtr screen); #endif #endif xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video_overlay.c000066400000000000000000000545121267532330400255260ustar00rootroot00000000000000/*************************************************************************** Copyright 2000-2011 Intel Corporation. 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 INTEL, 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 "sna.h" #include "sna_video.h" #include #include #include #include #include #include "intel_options.h" #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) #define HAS_GAMMA(sna) ((sna)->kgem.gen >= 030) static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvAlwaysOnTop; static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5; /* Limits for the overlay/textured video source sizes. The documented hardware * limits are 2048x2048 or better for overlay and both of our textured video * implementations. Additionally, on the 830 and 845, larger sizes resulted in * the card hanging, so we keep the limits lower there. */ #define IMAGE_MAX_WIDTH 2048 #define IMAGE_MAX_HEIGHT 2048 #define IMAGE_MAX_WIDTH_LEGACY 1024 #define IMAGE_MAX_HEIGHT_LEGACY 1088 static XvFormatRec Formats[] = { {15}, {16}, {24} }; static const XvAttributeRec Attributes[] = { {XvSettable | XvGettable, 0, (1 << 24) - 1, (char *)"XV_COLORKEY"}, {XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP"}, {XvSettable | XvGettable, -128, 127, (char *)"XV_BRIGHTNESS"}, {XvSettable | XvGettable, 0, 255, (char *)"XV_CONTRAST"}, {XvSettable | XvGettable, 0, 1023, (char *)"XV_SATURATION"}, {XvSettable | XvGettable, -1, 1, (char *)"XV_PIPE"}, #define NUM_ATTRIBUTES 6 {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA0"}, {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA1"}, {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA2"}, {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA3"}, {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA4"}, {XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_GAMMA5"} #define GAMMA_ATTRIBUTES 6 }; static const XvImageRec Images[] = { XVIMAGE_YUY2, XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY, XVMC_YUV }; /* kernel modesetting overlay functions */ static bool sna_has_overlay(struct sna *sna) { struct drm_i915_getparam gp; int has_overlay = 0; int ret; VG_CLEAR(gp); gp.param = I915_PARAM_HAS_OVERLAY; gp.value = &has_overlay; ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp); return ret == 0 && has_overlay; } static bool sna_video_overlay_update_attrs(struct sna_video *video) { struct drm_intel_overlay_attrs attrs; DBG(("%s()\n", __FUNCTION__)); attrs.flags = I915_OVERLAY_UPDATE_ATTRS; attrs.brightness = video->brightness; attrs.contrast = video->contrast; attrs.saturation = video->saturation; attrs.color_key = video->color_key; attrs.gamma0 = video->gamma0; attrs.gamma1 = video->gamma1; attrs.gamma2 = video->gamma2; attrs.gamma3 = video->gamma3; attrs.gamma4 = video->gamma4; attrs.gamma5 = video->gamma5; if (video->AlwaysOnTop) attrs.flags |= 1<<2; return drmIoctl(video->sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0; } static int sna_video_overlay_stop(ddStopVideo_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; struct drm_intel_overlay_put_image request; DBG(("%s()\n", __FUNCTION__)); REGION_EMPTY(to_screen_from_sna(sna), &video->clip); request.flags = 0; (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_PUT_IMAGE, &request); if (video->bo[0]) kgem_bo_destroy(&sna->kgem, video->bo[0]); video->bo[0] = NULL; sna_video_free_buffers(video); sna_window_set_port((WindowPtr)draw, NULL); return Success; } static int sna_video_overlay_set_attribute(ddSetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; DBG(("%s: set(%lx) to %d\n", __FUNCTION__, (long)attribute, (int)value)); if (attribute == xvBrightness) { if ((value < -128) || (value > 127)) return BadValue; DBG(("%s: BRIGHTNESS %d -> %d\n", __FUNCTION__, video->contrast, (int)value)); video->brightness = value; } else if (attribute == xvContrast) { if ((value < 0) || (value > 255)) return BadValue; DBG(("%s: CONTRAST %d -> %d\n", __FUNCTION__, video->contrast, (int)value)); video->contrast = value; } else if (attribute == xvSaturation) { if ((value < 0) || (value > 1023)) return BadValue; DBG(("%s: SATURATION %d -> %d\n", __FUNCTION__, video->saturation, (int)value)); video->saturation = value; } else if (attribute == xvPipe) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); if ((value < -1) || (value >= xf86_config->num_crtc)) return BadValue; if (value < 0) video->desired_crtc = NULL; else video->desired_crtc = xf86_config->crtc[value]; } else if (attribute == xvAlwaysOnTop) { DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__, video->AlwaysOnTop, !!value)); video->AlwaysOnTop = !!value; } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) { video->gamma0 = value; } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) { video->gamma1 = value; } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) { video->gamma2 = value; } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) { video->gamma3 = value; } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) { video->gamma4 = value; } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) { video->gamma5 = value; } else if (attribute == xvColorKey) { video->color_key = value; RegionEmpty(&video->clip); DBG(("COLORKEY\n")); } else return BadMatch; if ((attribute == xvGamma0 || attribute == xvGamma1 || attribute == xvGamma2 || attribute == xvGamma3 || attribute == xvGamma4 || attribute == xvGamma5) && HAS_GAMMA(sna)) { DBG(("%s: GAMMA\n", __FUNCTION__)); } if (!sna_video_overlay_update_attrs(video)) return BadValue; return Success; } static int sna_video_overlay_get_attribute(ddGetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; if (attribute == xvBrightness) { *value = video->brightness; } else if (attribute == xvContrast) { *value = video->contrast; } else if (attribute == xvSaturation) { *value = video->saturation; } else if (attribute == xvPipe) { int c; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); for (c = 0; c < xf86_config->num_crtc; c++) if (xf86_config->crtc[c] == video->desired_crtc) break; if (c == xf86_config->num_crtc) c = -1; *value = c; } else if (attribute == xvAlwaysOnTop) { *value = video->AlwaysOnTop; } else if (attribute == xvGamma0 && HAS_GAMMA(sna)) { *value = video->gamma0; } else if (attribute == xvGamma1 && HAS_GAMMA(sna)) { *value = video->gamma1; } else if (attribute == xvGamma2 && HAS_GAMMA(sna)) { *value = video->gamma2; } else if (attribute == xvGamma3 && HAS_GAMMA(sna)) { *value = video->gamma3; } else if (attribute == xvGamma4 && HAS_GAMMA(sna)) { *value = video->gamma4; } else if (attribute == xvGamma5 && HAS_GAMMA(sna)) { *value = video->gamma5; } else if (attribute == xvColorKey) { *value = video->color_key; } else return BadMatch; return Success; } static int sna_video_overlay_best_size(ddQueryBestSize_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; short max_w, max_h; if (vid_w > (drw_w << 1) || vid_h > (drw_h << 1)){ drw_w = vid_w >> 1; drw_h = vid_h >> 1; } if (sna->kgem.gen < 021) { max_w = IMAGE_MAX_WIDTH_LEGACY; max_h = IMAGE_MAX_HEIGHT_LEGACY; } else { max_w = IMAGE_MAX_WIDTH; max_h = IMAGE_MAX_HEIGHT; } while (drw_w > max_w || drw_h > max_h) { drw_w >>= 1; drw_h >>= 1; } *p_w = drw_w; *p_h = drw_h; return Success; } static void update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) { ScrnInfoPtr scrn = sna->scrn; int tmp; /* for overlay, we should take it from crtc's screen * coordinate to current crtc's display mode. * yeah, a bit confusing. */ switch (crtc->rotation & 0xf) { case RR_Rotate_0: dstBox->x1 -= crtc->x; dstBox->x2 -= crtc->x; dstBox->y1 -= crtc->y; dstBox->y2 -= crtc->y; break; case RR_Rotate_90: tmp = dstBox->x1; dstBox->x1 = dstBox->y1 - crtc->x; dstBox->y1 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = dstBox->y2 - crtc->x; dstBox->y2 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->y1; dstBox->y1 = dstBox->y2; dstBox->y2 = tmp; break; case RR_Rotate_180: tmp = dstBox->x1; dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x; dstBox->x2 = scrn->virtualX - tmp - crtc->x; tmp = dstBox->y1; dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y; dstBox->y2 = scrn->virtualY - tmp - crtc->y; break; case RR_Rotate_270: tmp = dstBox->x1; dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x; dstBox->y1 = tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x; dstBox->y2 = tmp - crtc->y; tmp = dstBox->x1; dstBox->x1 = dstBox->x2; dstBox->x2 = tmp; break; } return; } static bool sna_video_overlay_show(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, xf86CrtcPtr crtc, BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) { struct drm_intel_overlay_put_image request; bool planar = is_planar_fourcc(frame->id); float scale; DBG(("%s: src=(%dx%d), dst=(%dx%d)\n", __FUNCTION__, src_w, src_h, drw_w, drw_h)); update_dst_box_to_crtc_coords(sna, crtc, dstBox); if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) { int tmp; tmp = frame->width; frame->width = frame->height; frame->height = tmp; tmp = drw_w; drw_w = drw_h; drw_h = tmp; tmp = src_w; src_w = src_h; src_h = tmp; } memset(&request, 0, sizeof(request)); request.flags = I915_OVERLAY_ENABLE; request.bo_handle = frame->bo->handle; if (planar) { request.stride_Y = frame->pitch[1]; request.stride_UV = frame->pitch[0]; } else { request.stride_Y = frame->pitch[0]; request.stride_UV = 0; } request.offset_Y = 0; request.offset_U = frame->UBufOffset; request.offset_V = frame->VBufOffset; DBG(("%s: handle=%d, stride_Y=%d, stride_UV=%d, off_Y: %i, off_U: %i, off_V: %i\n", __FUNCTION__, request.bo_handle, request.stride_Y, request.stride_UV, request.offset_Y, request.offset_U, request.offset_V)); request.crtc_id = sna_crtc_id(crtc); request.dst_x = dstBox->x1; request.dst_y = dstBox->y1; request.dst_width = dstBox->x2 - dstBox->x1; request.dst_height = dstBox->y2 - dstBox->y1; DBG(("%s: crtc=%d, dst=(%d, %d)x(%d, %d)\n", __FUNCTION__, request.crtc_id, request.dst_x, request.dst_y, request.dst_width, request.dst_height)); request.src_width = frame->width; request.src_height = frame->height; /* adjust src dimensions */ if (request.dst_height > 1) { scale = ((float)request.dst_height - 1) / ((float)drw_h - 1); request.src_scan_height = src_h * scale; } else request.src_scan_height = 1; if (request.dst_width > 1) { scale = ((float)request.dst_width - 1) / ((float)drw_w - 1); request.src_scan_width = src_w * scale; } else request.src_scan_width = 1; DBG(("%s: src=(%d, %d) scan=(%d, %d)\n", __FUNCTION__, request.src_width, request.src_height, request.src_scan_width, request.src_scan_height)); if (planar) { request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420; } else { request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422; if (frame->id == FOURCC_UYVY) request.flags |= I915_OVERLAY_Y_SWAP; } DBG(("%s: flags=%x\n", __FUNCTION__, request.flags)); if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_PUT_IMAGE, &request)) { DBG(("%s: Putimage failed\n", __FUNCTION__)); return false; } if (video->bo[0] != frame->bo) { if (video->bo[0]) kgem_bo_destroy(&sna->kgem, video->bo[0]); video->bo[0] = kgem_bo_reference(frame->bo); } return true; } static int sna_video_overlay_put_image(ddPutImage_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; struct sna_video_frame frame; xf86CrtcPtr crtc; BoxRec dstBox; RegionRec clip; int ret; DBG(("%s: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d), width %d, height %d\n", __FUNCTION__, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height)); /* If dst width and height are less than 1/8th the src size, the * src/dst scale factor becomes larger than 8 and doesn't fit in * the scale register. */ if (src_w >= (drw_w * 8)) drw_w = src_w / 7; if (src_h >= (drw_h * 8)) drw_h = src_h / 7; init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h); DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop)); if (!video->AlwaysOnTop) { ValidateGC(draw, gc); RegionIntersect(&clip, &clip, gc->pCompositeClip); } if (box_empty(&clip.extents)) goto invisible; DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n", __FUNCTION__, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, format->id, width, height, sync)); DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(&clip), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); sna_video_frame_init(video, format->id, width, height, &frame); if (!sna_video_clip_helper(video, &frame, &crtc, &dstBox, src_x, src_y, draw->x + drw_x, draw->y + drw_y, src_w, src_h, drw_w, drw_h, &clip)) goto invisible; if (!crtc) goto invisible; /* overlay can't handle rotation natively, store it for the copy func */ sna_video_frame_set_rotation(video, &frame, crtc->rotation); if (xvmc_passthrough(format->id)) { DBG(("%s: using passthough, name=%d\n", __FUNCTION__, *(uint32_t *)buf)); if (*(uint32_t*)buf == 0) goto invisible; frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); if (frame.bo == NULL) { DBG(("%s: failed to open bo\n", __FUNCTION__)); return BadAlloc; } if (kgem_bo_size(frame.bo) < frame.size) { DBG(("%s: bo size=%d, expected=%d\n", __FUNCTION__, kgem_bo_size(frame.bo), frame.size)); kgem_bo_destroy(&sna->kgem, frame.bo); return BadAlloc; } frame.image.x1 = 0; frame.image.y1 = 0; frame.image.x2 = frame.width; frame.image.y2 = frame.height; } else { frame.bo = sna_video_buffer(video, &frame); if (frame.bo == NULL) { DBG(("%s: failed to allocate video bo\n", __FUNCTION__)); return BadAlloc; } if (!sna_video_copy_data(video, &frame, buf)) { DBG(("%s: failed to copy video data\n", __FUNCTION__)); return BadAlloc; } } ret = Success; if (sna_video_overlay_show (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) { sna_video_fill_colorkey(video, &clip); sna_window_set_port((WindowPtr)draw, port); } else { DBG(("%s: failed to show video frame\n", __FUNCTION__)); ret = BadAlloc; } frame.bo->domain = DOMAIN_NONE; if (xvmc_passthrough(format->id)) kgem_bo_destroy(&sna->kgem, frame.bo); else sna_video_buffer_fini(video); return ret; invisible: /* * If the video isn't visible on any CRTC, turn it off */ #if XORG_XV_VERSION < 2 sna_video_overlay_stop(client, port, draw); #else sna_video_overlay_stop(port, draw); #endif return Success; } static int sna_video_overlay_query(ddQueryImageAttributes_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna_video_frame frame; struct sna *sna = video->sna; int size, tmp; DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h)); if (sna->kgem.gen < 021) { if (*w > IMAGE_MAX_WIDTH_LEGACY) *w = IMAGE_MAX_WIDTH_LEGACY; if (*h > IMAGE_MAX_HEIGHT_LEGACY) *h = IMAGE_MAX_HEIGHT_LEGACY; } else { if (*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; if (*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; } *w = (*w + 1) & ~1; if (offsets) offsets[0] = 0; switch (format->id) { case FOURCC_XVMC: *h = (*h + 1) & ~1; sna_video_frame_init(video, format->id, *w, *h, &frame); sna_video_frame_set_rotation(video, &frame, RR_Rotate_0); size = sizeof(uint32_t); if (pitches) { pitches[0] = frame.pitch[1]; pitches[1] = frame.pitch[0]; pitches[2] = frame.pitch[0]; } if (offsets) { offsets[1] = frame.UBufOffset; offsets[2] = frame.VBufOffset; } break; /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: if (pitches) pitches[0] = *w; size = *w * *h; break; case FOURCC_YV12: case FOURCC_I420: *h = (*h + 1) & ~1; size = (*w + 3) & ~3; if (pitches) pitches[0] = size; size *= *h; if (offsets) offsets[1] = size; tmp = ((*w >> 1) + 3) & ~3; if (pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if (offsets) offsets[2] = size; size += tmp; #if 0 if (pitches) ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", pitches[0], pitches[1], pitches[2]); if (offsets) ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], offsets[2]); if (offsets) ErrorF("size is %d\n", size); #endif break; case FOURCC_UYVY: case FOURCC_YUY2: default: size = *w << 1; if (pitches) pitches[0] = size; size *= *h; break; } return size; } static int sna_video_overlay_color_key(struct sna *sna) { ScrnInfoPtr scrn = sna->scrn; int color_key; if (xf86GetOptValInteger(sna->Options, OPTION_VIDEO_KEY, &color_key)) { } else if (xf86GetOptValInteger(sna->Options, OPTION_COLOR_KEY, &color_key)) { } else { color_key = (1 << scrn->offset.red) | (1 << scrn->offset.green) | (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); } return color_key & ((1 << scrn->depth) - 1); } void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen) { XvAdaptorPtr adaptor; struct sna_video *video; XvPortPtr port; if (sna->flags & SNA_IS_HOSTED) return; if (!sna_has_overlay(sna)) return; DBG(("%s()\n", __FUNCTION__)); adaptor = sna_xv_adaptor_alloc(sna); if (adaptor == NULL) return; video = calloc(1, sizeof(*video)); port = calloc(1, sizeof(*port)); if (video == NULL || port == NULL) { free(video); free(port); sna->xv.num_adaptors--; return; } adaptor->type = XvInputMask | XvImageMask; adaptor->pScreen = screen; adaptor->name = (char *)"Intel(R) Video Overlay"; adaptor->nEncodings = 1; adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec)); adaptor->pEncodings[0].id = 0; adaptor->pEncodings[0].pScreen = screen; adaptor->pEncodings[0].name = (char *)"XV_IMAGE"; adaptor->pEncodings[0].width = sna->kgem.gen < 021 ? IMAGE_MAX_WIDTH_LEGACY : IMAGE_MAX_WIDTH; adaptor->pEncodings[0].height = sna->kgem.gen < 021 ? IMAGE_MAX_HEIGHT_LEGACY : IMAGE_MAX_HEIGHT; adaptor->pEncodings[0].rate.numerator = 1; adaptor->pEncodings[0].rate.denominator = 1; adaptor->pFormats = Formats; adaptor->nFormats = sna_xv_fixup_formats(screen, Formats, ARRAY_SIZE(Formats)); adaptor->nAttributes = NUM_ATTRIBUTES; if (HAS_GAMMA(sna)) adaptor->nAttributes += GAMMA_ATTRIBUTES; adaptor->pAttributes = (XvAttributeRec *)Attributes; adaptor->nImages = ARRAY_SIZE(Images); adaptor->pImages = (XvImageRec *)Images; #if XORG_XV_VERSION < 2 adaptor->ddAllocatePort = sna_xv_alloc_port; adaptor->ddFreePort = sna_xv_free_port; #endif adaptor->ddPutVideo = NULL; adaptor->ddPutStill = NULL; adaptor->ddGetVideo = NULL; adaptor->ddGetStill = NULL; adaptor->ddStopVideo = sna_video_overlay_stop; adaptor->ddSetPortAttribute = sna_video_overlay_set_attribute; adaptor->ddGetPortAttribute = sna_video_overlay_get_attribute; adaptor->ddQueryBestSize = sna_video_overlay_best_size; adaptor->ddPutImage = sna_video_overlay_put_image; adaptor->ddQueryImageAttributes = sna_video_overlay_query; adaptor->nPorts = 1; adaptor->pPorts = port; adaptor->base_id = port->id = FakeClientID(0); AddResource(port->id, XvGetRTPort(), port); port->pAdaptor = adaptor; port->pNotify = NULL; port->pDraw = NULL; port->client = NULL; port->grab.client = NULL; port->time = currentTime; port->devPriv.ptr = video; video->sna = sna; if (sna->kgem.gen >= 040) /* Actually the alignment is 64 bytes, too. But the * stride must be at least 512 bytes. Take the easy fix * and align on 512 bytes unconditionally. */ video->alignment = 512; else if (sna->kgem.gen < 021) /* Harsh, errata on these chipsets limit the stride * to be a multiple of 256 bytes. */ video->alignment = 256; else video->alignment = 64; video->color_key = sna_video_overlay_color_key(sna); video->brightness = -19; /* (255/219) * -16 */ video->contrast = 75; /* 255/219 * 64 */ video->saturation = 146; /* 128/112 * 128 */ video->desired_crtc = NULL; video->gamma5 = 0xc0c0c0; video->gamma4 = 0x808080; video->gamma3 = 0x404040; video->gamma2 = 0x202020; video->gamma1 = 0x101010; video->gamma0 = 0x080808; RegionNull(&video->clip); xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvContrast = MAKE_ATOM("XV_CONTRAST"); xvSaturation = MAKE_ATOM("XV_SATURATION"); /* Allow the pipe to be switched from pipe A to B when in clone mode */ xvPipe = MAKE_ATOM("XV_PIPE"); xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP"); if (HAS_GAMMA(sna)) { xvGamma0 = MAKE_ATOM("XV_GAMMA0"); xvGamma1 = MAKE_ATOM("XV_GAMMA1"); xvGamma2 = MAKE_ATOM("XV_GAMMA2"); xvGamma3 = MAKE_ATOM("XV_GAMMA3"); xvGamma4 = MAKE_ATOM("XV_GAMMA4"); xvGamma5 = MAKE_ATOM("XV_GAMMA5"); } sna_video_overlay_update_attrs(video); DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video_sprite.c000066400000000000000000000464651267532330400253630ustar00rootroot00000000000000/*************************************************************************** Copyright 2000-2011 Intel Corporation. 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 INTEL, 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 "sna.h" #include "sna_video.h" #include "intel_options.h" #include #include #include #include #include #include #include #define fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) #define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ #define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ #define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ #define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ #define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane) struct local_mode_set_plane { uint32_t plane_id; uint32_t crtc_id; uint32_t fb_id; /* fb object contains surface format type */ uint32_t flags; /* Signed dest location allows it to be partially off screen */ int32_t crtc_x, crtc_y; uint32_t crtc_w, crtc_h; /* Source values are 16.16 fixed point */ uint32_t src_x, src_y; uint32_t src_h, src_w; }; #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true) static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank; static XvFormatRec formats[] = { {15}, {16}, {24} }; static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, XVMC_RGB565 }; static const XvAttributeRec attribs[] = { { XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" }, { XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP" }, }; static int sna_video_sprite_stop(ddStopVideo_ARGS) { struct sna_video *video = port->devPriv.ptr; struct local_mode_set_plane s; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn); int i; for (i = 0; i < video->sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; int pipe; pipe = sna_crtc_pipe(crtc); assert(pipe < ARRAY_SIZE(video->bo)); if (video->bo[pipe] == NULL) continue; memset(&s, 0, sizeof(s)); s.plane_id = sna_crtc_to_sprite(crtc); if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n"); if (video->bo[pipe]) kgem_bo_destroy(&video->sna->kgem, video->bo[pipe]); video->bo[pipe] = NULL; } sna_window_set_port((WindowPtr)draw, NULL); return Success; } static int sna_video_sprite_set_attr(ddSetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; if (attribute == xvColorKey) { video->color_key_changed = ~0; video->color_key = value; RegionEmpty(&video->clip); DBG(("COLORKEY = %ld\n", (long)value)); } else if (attribute == xvSyncToVblank) { DBG(("%s: SYNC_TO_VBLANK: %d -> %d\n", __FUNCTION__, video->SyncToVblank, !!value)); video->SyncToVblank = !!value; } else if (attribute == xvAlwaysOnTop) { DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__, video->AlwaysOnTop, !!value)); video->color_key_changed = ~0; video->AlwaysOnTop = !!value; } else return BadMatch; return Success; } static int sna_video_sprite_get_attr(ddGetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; if (attribute == xvColorKey) *value = video->color_key; else if (attribute == xvAlwaysOnTop) *value = video->AlwaysOnTop; else if (attribute == xvSyncToVblank) *value = video->SyncToVblank; else return BadMatch; return Success; } static int sna_video_sprite_best_size(ddQueryBestSize_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; if (sna->kgem.gen >= 075) { *p_w = vid_w; *p_h = vid_h; } else { *p_w = drw_w; *p_h = drw_h; } return Success; } static void update_dst_box_to_crtc_coords(struct sna *sna, xf86CrtcPtr crtc, BoxPtr dstBox) { ScrnInfoPtr scrn = sna->scrn; int tmp; switch (crtc->rotation & 0xf) { case RR_Rotate_0: dstBox->x1 -= crtc->x; dstBox->x2 -= crtc->x; dstBox->y1 -= crtc->y; dstBox->y2 -= crtc->y; break; case RR_Rotate_90: tmp = dstBox->x1; dstBox->x1 = dstBox->y1 - crtc->x; dstBox->y1 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = dstBox->y2 - crtc->x; dstBox->y2 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->y1; dstBox->y1 = dstBox->y2; dstBox->y2 = tmp; break; case RR_Rotate_180: tmp = dstBox->x1; dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x; dstBox->x2 = scrn->virtualX - tmp - crtc->x; tmp = dstBox->y1; dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y; dstBox->y2 = scrn->virtualY - tmp - crtc->y; break; case RR_Rotate_270: tmp = dstBox->x1; dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x; dstBox->y1 = tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x; dstBox->y2 = tmp - crtc->y; tmp = dstBox->x1; dstBox->x1 = dstBox->x2; dstBox->x2 = tmp; break; } } static bool sna_video_sprite_show(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, xf86CrtcPtr crtc, BoxPtr dstBox) { struct local_mode_set_plane s; int pipe = sna_crtc_pipe(crtc); /* XXX handle video spanning multiple CRTC */ VG_CLEAR(s); s.plane_id = sna_crtc_to_sprite(crtc); #define DRM_I915_SET_SPRITE_COLORKEY 0x2b #define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey) #define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2) if (video->color_key_changed & (1 << pipe) && video->has_color_key) { struct local_intel_sprite_colorkey { uint32_t plane_id; uint32_t min_value; uint32_t channel_mask; uint32_t max_value; uint32_t flags; } set; DBG(("%s: updating color key: %x\n", __FUNCTION__, video->color_key)); set.plane_id = s.plane_id; set.min_value = video->color_key; set.max_value = video->color_key; /* not used for destkey */ set.channel_mask = 0x7 << 24 | 0xff << 16 | 0xff << 8 | 0xff << 0; set.flags = 0; if (!video->AlwaysOnTop) set.flags |= 1 << 1; /* COLORKEY_DESTINATION */ if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY, &set)) { xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "failed to update color key, disabling future updates\n"); video->has_color_key = false; } video->color_key_changed &= ~(1 << pipe); } assert(pipe < ARRAY_SIZE(video->bo)); if (video->bo[pipe] == frame->bo) return true; update_dst_box_to_crtc_coords(sna, crtc, dstBox); if (frame->rotation & (RR_Rotate_90 | RR_Rotate_270)) { int tmp = frame->width; frame->width = frame->height; frame->height = tmp; } if (frame->bo->delta == 0) { struct local_mode_fb_cmd2 { uint32_t fb_id; uint32_t width, height; uint32_t pixel_format; uint32_t flags; uint32_t handles[4]; uint32_t pitches[4]; /* pitch for each plane */ uint32_t offsets[4]; /* offset of each plane */ } f; bool purged = true; memset(&f, 0, sizeof(f)); f.width = frame->width; f.height = frame->height; f.handles[0] = frame->bo->handle; f.pitches[0] = frame->pitch[0]; switch (frame->id) { case FOURCC_RGB565: f.pixel_format = DRM_FORMAT_RGB565; purged = sna->scrn->depth != 16; break; case FOURCC_RGB888: f.pixel_format = DRM_FORMAT_XRGB8888; purged = sna->scrn->depth != 24; break; case FOURCC_UYVY: f.pixel_format = DRM_FORMAT_UYVY; break; case FOURCC_YUY2: default: f.pixel_format = DRM_FORMAT_YUYV; break; } DBG(("%s: creating new fb for handle=%d, width=%d, height=%d, stride=%d, format=%x\n", __FUNCTION__, frame->bo->handle, frame->width, frame->height, f.pitches[0], f.pixel_format)); if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_ADDFB2, &f)) { ERR(("%s: ADDFB2 failed, errno=%d\n", __FUNCTION__, errno)); xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR, "failed to add fb, unable to update video\n"); return false; } frame->bo->delta = f.fb_id; frame->bo->scanout = true; /* Don't allow the scanout to be cached if not suitable for front */ frame->bo->purged = purged; } assert(frame->bo->scanout); assert(frame->bo->delta); s.crtc_id = sna_crtc_id(crtc); s.fb_id = frame->bo->delta; s.flags = 0; s.crtc_x = dstBox->x1; s.crtc_y = dstBox->y1; s.crtc_w = dstBox->x2 - dstBox->x1; s.crtc_h = dstBox->y2 - dstBox->y1; s.src_x = 0; s.src_y = 0; s.src_w = (frame->image.x2 - frame->image.x1) << 16; s.src_h = (frame->image.y2 - frame->image.y1) << 16; DBG(("%s: updating crtc=%d, plane=%d, handle=%d [fb %d], dst=(%d,%d)x(%d,%d), src=(%d,%d)x(%d,%d)\n", __FUNCTION__, s.crtc_id, s.plane_id, frame->bo->handle, s.fb_id, s.crtc_x, s.crtc_y, s.crtc_w, s.crtc_h, s.src_x >> 16, s.src_y >> 16, s.src_w >> 16, s.src_h >> 16)); if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) { DBG(("SET_PLANE failed: ret=%d\n", errno)); memset(&s, 0, sizeof(s)); s.plane_id = video->plane; (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); if (video->bo[pipe]) { kgem_bo_destroy(&sna->kgem, video->bo[pipe]); video->bo[pipe] = NULL; } return false; } frame->bo->domain = DOMAIN_NONE; if (video->bo[pipe]) kgem_bo_destroy(&sna->kgem, video->bo[pipe]); video->bo[pipe] = kgem_bo_reference(frame->bo); return true; } static int sna_video_sprite_put_image(ddPutImage_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); RegionRec clip; int ret, i; init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h); DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop)); if (!video->AlwaysOnTop) { ValidateGC(draw, gc); RegionIntersect(&clip, &clip, gc->pCompositeClip); } DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n", __FUNCTION__, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, format->id, width, height, sync)); DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(&clip), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); if (RegionNil(&clip)) { ret = Success; goto err; } for (i = 0; i < video->sna->mode.num_real_crtc; i++) { xf86CrtcPtr crtc = config->crtc[i]; struct sna_video_frame frame; int pipe; INT32 x1, x2, y1, y2; BoxRec dst; RegionRec reg; Rotation rotation; pipe = sna_crtc_pipe(crtc); sna_video_frame_init(video, format->id, width, height, &frame); reg.extents = crtc->bounds; reg.data = NULL; RegionIntersect(®, ®, &clip); if (RegionNil(®)) { off: assert(pipe < ARRAY_SIZE(video->bo)); if (video->bo[pipe]) { struct local_mode_set_plane s; memset(&s, 0, sizeof(s)); s.plane_id = sna_crtc_to_sprite(crtc); if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n"); video->bo[pipe] = NULL; } continue; } x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dst = clip.extents; ret = xf86XVClipVideoHelper(&dst, &x1, &x2, &y1, &y2, ®, frame.width, frame.height); RegionUninit(®); if (!ret) goto off; frame.src.x1 = x1 >> 16; frame.src.y1 = y1 >> 16; frame.src.x2 = (x2 + 0xffff) >> 16; frame.src.y2 = (y2 + 0xffff) >> 16; frame.image.x1 = frame.src.x1 & ~1; frame.image.x2 = ALIGN(frame.src.x2, 2); if (is_planar_fourcc(frame.id)) { frame.image.y1 = frame.src.y1 & ~1; frame.image.y2 = ALIGN(frame.src.y2, 2); } else { frame.image.y1 = frame.src.y1; frame.image.y2 = frame.src.y2; } /* if sprite can't handle rotation natively, store it for the copy func */ rotation = RR_Rotate_0; if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) { sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0); rotation = crtc->rotation; } sna_video_frame_set_rotation(video, &frame, rotation); if (xvmc_passthrough(format->id)) { DBG(("%s: using passthough, name=%d\n", __FUNCTION__, *(uint32_t *)buf)); if (*(uint32_t*)buf == 0) goto err; frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); if (frame.bo == NULL) { ret = BadAlloc; goto err; } if (kgem_bo_size(frame.bo) < frame.size) { DBG(("%s: bo size=%d, expected=%d\n", __FUNCTION__, kgem_bo_size(frame.bo), frame.size)); kgem_bo_destroy(&sna->kgem, frame.bo); ret = BadAlloc; goto err; } frame.image.x1 = 0; frame.image.y1 = 0; frame.image.x2 = frame.width; frame.image.y2 = frame.height; } else { frame.bo = sna_video_buffer(video, &frame); if (frame.bo == NULL) { DBG(("%s: failed to allocate video bo\n", __FUNCTION__)); ret = BadAlloc; goto err; } if (!sna_video_copy_data(video, &frame, buf)) { DBG(("%s: failed to copy video data\n", __FUNCTION__)); ret = BadAlloc; goto err; } } ret = Success; if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst)) { DBG(("%s: failed to show video frame\n", __FUNCTION__)); ret = BadAlloc; } frame.bo->domain = DOMAIN_NONE; if (xvmc_passthrough(format->id)) kgem_bo_destroy(&sna->kgem, frame.bo); else sna_video_buffer_fini(video); if (ret != Success) goto err; } sna_video_fill_colorkey(video, &clip); sna_window_set_port((WindowPtr)draw, port); return Success; err: #if XORG_XV_VERSION < 2 (void)sna_video_sprite_stop(client, port, draw); #else (void)sna_video_sprite_stop(port, draw); #endif return ret; } static int sna_video_sprite_query(ddQueryImageAttributes_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna_video_frame frame; int size; if (*w > video->sna->mode.max_crtc_width) *w = video->sna->mode.max_crtc_width; if (*h > video->sna->mode.max_crtc_height) *h = video->sna->mode.max_crtc_height; if (offsets) offsets[0] = 0; switch (format->id) { case FOURCC_RGB888: case FOURCC_RGB565: if (pitches) { sna_video_frame_init(video, format->id, *w, *h, &frame); sna_video_frame_set_rotation(video, &frame, RR_Rotate_0); pitches[0] = frame.pitch[0]; } size = 4; break; default: *w = (*w + 1) & ~1; *h = (*h + 1) & ~1; size = *w << 1; if (pitches) pitches[0] = size; size *= *h; break; } return size; } static int sna_video_sprite_color_key(struct sna *sna) { ScrnInfoPtr scrn = sna->scrn; int color_key; if (xf86GetOptValInteger(sna->Options, OPTION_VIDEO_KEY, &color_key)) { } else if (xf86GetOptValInteger(sna->Options, OPTION_COLOR_KEY, &color_key)) { } else { color_key = (1 << scrn->offset.red) | (1 << scrn->offset.green) | (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); } return color_key & ((1 << scrn->depth) - 1); } static bool sna_video_has_sprites(struct sna *sna) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; DBG(("%s: num_crtc=%d\n", __FUNCTION__, sna->mode.num_real_crtc)); if (sna->mode.num_real_crtc == 0) return false; for (i = 0; i < sna->mode.num_real_crtc; i++) { if (!sna_crtc_to_sprite(config->crtc[i])) { DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i]))); return false; } } DBG(("%s: yes\n", __FUNCTION__)); return true; } void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) { XvAdaptorPtr adaptor; struct sna_video *video; XvPortPtr port; if (!sna_video_has_sprites(sna)) return; adaptor = sna_xv_adaptor_alloc(sna); if (!adaptor) return; video = calloc(1, sizeof(*video)); port = calloc(1, sizeof(*port)); if (video == NULL || port == NULL) { free(video); free(port); sna->xv.num_adaptors--; return; } adaptor->type = XvInputMask | XvImageMask; adaptor->pScreen = screen; adaptor->name = (char *)"Intel(R) Video Sprite"; adaptor->nEncodings = 1; adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec)); adaptor->pEncodings[0].id = 0; adaptor->pEncodings[0].pScreen = screen; adaptor->pEncodings[0].name = (char *)"XV_IMAGE"; adaptor->pEncodings[0].width = sna->mode.max_crtc_width; adaptor->pEncodings[0].height = sna->mode.max_crtc_height; adaptor->pEncodings[0].rate.numerator = 1; adaptor->pEncodings[0].rate.denominator = 1; adaptor->pFormats = formats; adaptor->nFormats = sna_xv_fixup_formats(screen, formats, ARRAY_SIZE(formats)); adaptor->nAttributes = ARRAY_SIZE(attribs); adaptor->pAttributes = (XvAttributeRec *)attribs; adaptor->pImages = (XvImageRec *)images; adaptor->nImages = 3; if (sna->kgem.gen == 071) adaptor->nImages = 4; #if XORG_XV_VERSION < 2 adaptor->ddAllocatePort = sna_xv_alloc_port; adaptor->ddFreePort = sna_xv_free_port; #endif adaptor->ddPutVideo = NULL; adaptor->ddPutStill = NULL; adaptor->ddGetVideo = NULL; adaptor->ddGetStill = NULL; adaptor->ddStopVideo = sna_video_sprite_stop; adaptor->ddSetPortAttribute = sna_video_sprite_set_attr; adaptor->ddGetPortAttribute = sna_video_sprite_get_attr; adaptor->ddQueryBestSize = sna_video_sprite_best_size; adaptor->ddPutImage = sna_video_sprite_put_image; adaptor->ddQueryImageAttributes = sna_video_sprite_query; adaptor->nPorts = 1; adaptor->pPorts = port; adaptor->base_id = port->id = FakeClientID(0); AddResource(port->id, XvGetRTPort(), port); port->pAdaptor = adaptor; port->pNotify = NULL; port->pDraw = NULL; port->client = NULL; port->grab.client = NULL; port->time = currentTime; port->devPriv.ptr = video; video->sna = sna; video->alignment = 64; video->color_key = sna_video_sprite_color_key(sna); video->color_key_changed = ~0; video->has_color_key = true; video->brightness = -19; /* (255/219) * -16 */ video->contrast = 75; /* 255/219 * 64 */ video->saturation = 146; /* 128/112 * 128 */ video->desired_crtc = NULL; video->gamma5 = 0xc0c0c0; video->gamma4 = 0x808080; video->gamma3 = 0x404040; video->gamma2 = 0x202020; video->gamma1 = 0x101010; video->gamma0 = 0x080808; RegionNull(&video->clip); video->SyncToVblank = 1; xvColorKey = MAKE_ATOM("XV_COLORKEY"); xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP"); xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/sna_video_textured.c000066400000000000000000000253711267532330400257120ustar00rootroot00000000000000/*************************************************************************** Copyright 2000-2011 Intel Corporation. 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 INTEL, 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 "sna.h" #include "sna_video.h" #include #include #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true) static Atom xvBrightness, xvContrast, xvSyncToVblank; static XvFormatRec Formats[] = { {15}, {16}, {24} }; static const XvAttributeRec Attributes[] = { {XvSettable | XvGettable, -1, 1, (char *)"XV_SYNC_TO_VBLANK"}, //{XvSettable | XvGettable, -128, 127, (char *)"XV_BRIGHTNESS"}, //{XvSettable | XvGettable, 0, 255, (char *)"XV_CONTRAST"}, }; static const XvImageRec Images[] = { XVIMAGE_YUY2, XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY, XVMC_YUV, }; static int sna_video_textured_stop(ddStopVideo_ARGS) { struct sna_video *video = port->devPriv.ptr; DBG(("%s()\n", __FUNCTION__)); RegionUninit(&video->clip); sna_video_free_buffers(video); return Success; } static int sna_video_textured_set_attribute(ddSetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; if (attribute == xvBrightness) { if (value < -128 || value > 127) return BadValue; video->brightness = value; } else if (attribute == xvContrast) { if (value < 0 || value > 255) return BadValue; video->contrast = value; } else if (attribute == xvSyncToVblank) { if (value < -1 || value > 1) return BadValue; video->SyncToVblank = value; } else return BadMatch; return Success; } static int sna_video_textured_get_attribute(ddGetPortAttribute_ARGS) { struct sna_video *video = port->devPriv.ptr; if (attribute == xvBrightness) *value = video->brightness; else if (attribute == xvContrast) *value = video->contrast; else if (attribute == xvSyncToVblank) *value = video->SyncToVblank; else return BadMatch; return Success; } static int sna_video_textured_best_size(ddQueryBestSize_ARGS) { if (vid_w > (drw_w << 1)) drw_w = vid_w >> 1; if (vid_h > (drw_h << 1)) drw_h = vid_h >> 1; *p_w = drw_w; *p_h = drw_h; return Success; } /* * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h). * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h). * id is a fourcc code for the format of the video. * buf is the pointer to the source data in system memory. * width and height are the w/h of the source data. * If "sync" is true, then we must be finished with *buf at the point of return * (which we always are). * clip is the clipping region in screen space. * data is a pointer to our port private. * drawable is some Drawable, which might not be the screen in the case of * compositing. It's a new argument to the function in the 1.1 server. */ static int sna_video_textured_put_image(ddPutImage_ARGS) { struct sna_video *video = port->devPriv.ptr; struct sna *sna = video->sna; struct sna_video_frame frame; PixmapPtr pixmap = get_drawable_pixmap(draw); unsigned int flags; BoxRec dstBox; RegionRec clip; xf86CrtcPtr crtc; int16_t dx, dy; bool flush = false; bool ret; if (wedged(sna)) return BadAlloc; init_video_region(&clip, draw, drw_x, drw_y, drw_w, drw_h); ValidateGC(draw, gc); RegionIntersect(&clip, &clip, gc->pCompositeClip); if (!RegionNotEmpty(&clip)) return Success; DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n", __FUNCTION__, src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, format->id, width, height, sync)); DBG(("%s: region %d:(%d, %d), (%d, %d)\n", __FUNCTION__, region_num_rects(&clip), clip.extents.x1, clip.extents.y1, clip.extents.x2, clip.extents.y2)); sna_video_frame_init(video, format->id, width, height, &frame); if (!sna_video_clip_helper(video, &frame, &crtc, &dstBox, src_x, src_y, drw_x + draw->x, drw_y + draw->y, src_w, src_h, drw_w, drw_h, &clip)) return Success; if (get_drawable_deltas(draw, pixmap, &dx, &dy)) RegionTranslate(&clip, dx, dy); flags = MOVE_WRITE | __MOVE_FORCE; if (clip.data) flags |= MOVE_READ; if (!sna_pixmap_move_area_to_gpu(pixmap, &clip.extents, flags)) { DBG(("%s: attempting to render to a non-GPU pixmap\n", __FUNCTION__)); return BadAlloc; } sna_video_frame_set_rotation(video, &frame, RR_Rotate_0); if (xvmc_passthrough(format->id)) { DBG(("%s: using passthough, name=%d\n", __FUNCTION__, *(uint32_t *)buf)); frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf); if (frame.bo == NULL) { DBG(("%s: failed to open bo\n", __FUNCTION__)); return BadAlloc; } if (kgem_bo_size(frame.bo) < frame.size) { DBG(("%s: bo size=%d, expected=%d\n", __FUNCTION__, kgem_bo_size(frame.bo), frame.size)); kgem_bo_destroy(&sna->kgem, frame.bo); return BadAlloc; } frame.image.x1 = 0; frame.image.y1 = 0; frame.image.x2 = frame.width; frame.image.y2 = frame.height; } else { if (!sna_video_copy_data(video, &frame, buf)) { DBG(("%s: failed to copy frame\n", __FUNCTION__)); kgem_bo_destroy(&sna->kgem, frame.bo); return BadAlloc; } } if (crtc && video->SyncToVblank != 0 && sna_pixmap_is_scanout(sna, pixmap)) { kgem_set_mode(&sna->kgem, KGEM_RENDER, sna_pixmap(pixmap)->gpu_bo); flush = sna_wait_for_scanline(sna, pixmap, crtc, &clip.extents); } ret = Success; if (!sna->render.video(sna, video, &frame, &clip, pixmap)) { DBG(("%s: failed to render video\n", __FUNCTION__)); ret = BadAlloc; } else DamageDamageRegion(&pixmap->drawable, &clip); kgem_bo_destroy(&sna->kgem, frame.bo); /* Push the frame to the GPU as soon as possible so * we can hit the next vsync. */ if (flush || sync) kgem_submit(&sna->kgem); RegionUninit(&clip); return ret; } static int sna_video_textured_query(ddQueryImageAttributes_ARGS) { int size, tmp; if (*w > 8192) *w = 8192; if (*h > 8192) *h = 8192; *w = (*w + 1) & ~1; if (offsets) offsets[0] = 0; switch (format->id) { /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: if (pitches) pitches[0] = *w; size = *w * *h; break; case FOURCC_YV12: case FOURCC_I420: *h = (*h + 1) & ~1; size = (*w + 3) & ~3; if (pitches) pitches[0] = size; size *= *h; if (offsets) offsets[1] = size; tmp = ((*w >> 1) + 3) & ~3; if (pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if (offsets) offsets[2] = size; size += tmp; break; case FOURCC_UYVY: case FOURCC_YUY2: default: size = *w << 1; if (pitches) pitches[0] = size; size *= *h; break; case FOURCC_XVMC: *h = (*h + 1) & ~1; size = sizeof(uint32_t); if (pitches) pitches[0] = size; break; } return size; } void sna_video_textured_setup(struct sna *sna, ScreenPtr screen) { XvAdaptorPtr adaptor; struct sna_video *video; int nports, i; if (!sna->render.video) { xf86DrvMsg(sna->scrn->scrnIndex, X_INFO, "Textured video not supported on this hardware or backend\n"); return; } if (wedged(sna)) { xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING, "cannot enable XVideo whilst the GPU is wedged\n"); return; } adaptor = sna_xv_adaptor_alloc(sna); if (adaptor == NULL) return; nports = 16; if (sna->kgem.gen >= 060) nports = 32; if (sna->kgem.gen >= 0100) nports = 64; video = calloc(nports, sizeof(struct sna_video)); adaptor->pPorts = calloc(nports, sizeof(XvPortRec)); if (video == NULL || adaptor->pPorts == NULL) { free(video); free(adaptor->pPorts); sna->xv.num_adaptors--; return; } adaptor->type = XvInputMask | XvImageMask; adaptor->pScreen = screen; adaptor->name = (char *)"Intel(R) Textured Video"; adaptor->nEncodings = 1; adaptor->pEncodings = xnfalloc(sizeof(XvEncodingRec)); adaptor->pEncodings[0].id = 0; adaptor->pEncodings[0].pScreen = screen; adaptor->pEncodings[0].name = (char *)"XV_IMAGE"; adaptor->pEncodings[0].width = sna->render.max_3d_size; adaptor->pEncodings[0].height = sna->render.max_3d_size; adaptor->pEncodings[0].rate.numerator = 1; adaptor->pEncodings[0].rate.denominator = 1; adaptor->pFormats = Formats; adaptor->nFormats = sna_xv_fixup_formats(screen, Formats, ARRAY_SIZE(Formats)); adaptor->nAttributes = ARRAY_SIZE(Attributes); adaptor->pAttributes = (XvAttributeRec *)Attributes; adaptor->nImages = ARRAY_SIZE(Images); adaptor->pImages = (XvImageRec *)Images; #if XORG_XV_VERSION < 2 adaptor->ddAllocatePort = sna_xv_alloc_port; adaptor->ddFreePort = sna_xv_free_port; #endif adaptor->ddPutVideo = NULL; adaptor->ddPutStill = NULL; adaptor->ddGetVideo = NULL; adaptor->ddGetStill = NULL; adaptor->ddStopVideo = sna_video_textured_stop; adaptor->ddSetPortAttribute = sna_video_textured_set_attribute; adaptor->ddGetPortAttribute = sna_video_textured_get_attribute; adaptor->ddQueryBestSize = sna_video_textured_best_size; adaptor->ddPutImage = sna_video_textured_put_image; adaptor->ddQueryImageAttributes = sna_video_textured_query; for (i = 0; i < nports; i++) { struct sna_video *v = &video[i]; XvPortPtr port = &adaptor->pPorts[i]; v->sna = sna; v->textured = true; v->alignment = 4; v->SyncToVblank = (sna->flags & SNA_NO_WAIT) == 0; RegionNull(&v->clip); port->id = FakeClientID(0); AddResource(port->id, XvGetRTPort(), port); port->pAdaptor = adaptor; port->pNotify = NULL; port->pDraw = NULL; port->client = NULL; port->grab.client = NULL; port->time = currentTime; port->devPriv.ptr = v; } adaptor->base_id = adaptor->pPorts[0].id; adaptor->nPorts = nports; xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); xvContrast = MAKE_ATOM("XV_CONTRAST"); xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); DBG(("%s: '%s' initialized %d ports\n", __FUNCTION__, adaptor->name, adaptor->nPorts)); } xserver-xorg-video-intel-2.99.917+git20160325/src/sna/xassert.h000066400000000000000000000040171267532330400235070ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __XASSERT_H__ #define __XASSERT_H__ /* Rewrap the traditional assert so that we can capture the error message * via Xorg.0.log */ #include #ifndef NDEBUG #include #include "compiler.h" #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,0,0,0) #define xorg_backtrace() #endif #undef assert #define assert(E) do if (unlikely(!(E))) { \ xorg_backtrace(); \ FatalError("%s:%d assertion '%s' failed\n", __func__, __LINE__, #E); \ } while (0) #define warn_unless(E) \ ({ \ bool fail = !(E); \ if (unlikely(fail)) { \ static int __warn_once__; \ if (!__warn_once__) { \ xorg_backtrace(); \ ErrorF("%s:%d assertion '%s' failed\n", __func__, __LINE__, #E); \ __warn_once__ = 1; \ } \ } \ unlikely(fail); \ }) #define dbg(EXPR) EXPR #else #define warn_unless(E) ({ bool fail = !(E); unlikely(fail); }) #define dbg(EXPR) #endif #endif /* __XASSERT_H__ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/000077500000000000000000000000001267532330400216575ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/Makefile.am000066400000000000000000000046311267532330400237170ustar00rootroot00000000000000# 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. AM_CFLAGS = @CWARNFLAGS@ $(XORG_CFLAGS) $(DRM_CFLAGS) $(PCIACCESS_CFLAGS) AM_CFLAGS += $(UDEV_CFLAGS) $(DRM_CFLAGS) $(DRMINTEL_CFLAGS) AM_CFLAGS += -I$(top_srcdir)/xvmc -I$(top_srcdir)/src -I$(top_srcdir)/src/render_program noinst_LTLIBRARIES = libuxa.la libuxa_la_LIBADD = $(UDEV_LIBS) $(DRMINTEL_LIBS) $(DRM_LIBS) libuxa_la_SOURCES = \ intel_uxa.h \ brw_defines.h \ brw_structs.h \ common.h \ intel.h \ intel_batchbuffer.c \ intel_batchbuffer.h \ intel_display.c \ intel_driver.c \ intel_memory.c \ intel_uxa.c \ intel_video.c \ intel_video.h \ intel_video_overlay.c \ intel_video_overlay.h \ intel_uxa_video.c \ i830_3d.c \ i830_render.c \ i830_reg.h \ i915_3d.h \ i915_reg.h \ i915_3d.c \ i915_render.c \ i915_video.c \ i965_reg.h \ i965_3d.c \ i965_video.c \ i965_render.c \ uxa_module.h \ uxa.c \ uxa.h \ uxa-accel.c \ uxa-glyphs.c \ uxa-render.c \ uxa-priv.h \ uxa-unaccel.c $(NULL) if DRI2 AM_CFLAGS += $(DRI2_CFLAGS) libuxa_la_SOURCES += \ intel_dri.c \ $(NULL) libuxa_la_LIBADD += \ $(DRI2_LIBS) \ $(CLOCK_GETTIME_LIBS) \ $(NULL) endif if DRI3 libuxa_la_SOURCES += \ intel_dri3.c \ intel_sync.c \ $(NULL) endif if PRESENT libuxa_la_SOURCES += \ intel_present.c \ $(NULL) endif if XVMC AM_CFLAGS += -I$(top_srcdir)/xvmc libuxa_la_SOURCES += \ intel_hwmc.c \ $(NULL) endif xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/brw_defines.h000066400000000000000000001061751267532330400243310ustar00rootroot00000000000000 /************************************************************************** * * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 BRW_DEFINES_H #define BRW_DEFINES_H /* */ #if 0 #define MI_NOOP 0x00 #define MI_USER_INTERRUPT 0x02 #define MI_WAIT_FOR_EVENT 0x03 #define MI_FLUSH 0x04 #define MI_REPORT_HEAD 0x07 #define MI_ARB_ON_OFF 0x08 #define MI_BATCH_BUFFER_END 0x0A #define MI_OVERLAY_FLIP 0x11 #define MI_LOAD_SCAN_LINES_INCL 0x12 #define MI_LOAD_SCAN_LINES_EXCL 0x13 #define MI_DISPLAY_BUFFER_INFO 0x14 #define MI_SET_CONTEXT 0x18 #define MI_STORE_DATA_IMM 0x20 #define MI_STORE_DATA_INDEX 0x21 #define MI_LOAD_REGISTER_IMM 0x22 #define MI_STORE_REGISTER_MEM 0x24 #define MI_BATCH_BUFFER_START 0x31 #define MI_SYNCHRONOUS_FLIP 0x0 #define MI_ASYNCHRONOUS_FLIP 0x1 #define MI_BUFFER_SECURE 0x0 #define MI_BUFFER_NONSECURE 0x1 #define MI_ARBITRATE_AT_CHAIN_POINTS 0x0 #define MI_ARBITRATE_BETWEEN_INSTS 0x1 #define MI_NO_ARBITRATION 0x3 #define MI_CONDITION_CODE_WAIT_DISABLED 0x0 #define MI_CONDITION_CODE_WAIT_0 0x1 #define MI_CONDITION_CODE_WAIT_1 0x2 #define MI_CONDITION_CODE_WAIT_2 0x3 #define MI_CONDITION_CODE_WAIT_3 0x4 #define MI_CONDITION_CODE_WAIT_4 0x5 #define MI_DISPLAY_PIPE_A 0x0 #define MI_DISPLAY_PIPE_B 0x1 #define MI_DISPLAY_PLANE_A 0x0 #define MI_DISPLAY_PLANE_B 0x1 #define MI_DISPLAY_PLANE_C 0x2 #define MI_STANDARD_FLIP 0x0 #define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD 0x1 #define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE 0x2 #define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER 0x3 #define MI_PHYSICAL_ADDRESS 0x0 #define MI_VIRTUAL_ADDRESS 0x1 #define MI_BUFFER_MEMORY_MAIN 0x0 #define MI_BUFFER_MEMORY_GTT 0x2 #define MI_BUFFER_MEMORY_PER_PROCESS_GTT 0x3 #define MI_FLIP_CONTINUE 0x0 #define MI_FLIP_ON 0x1 #define MI_FLIP_OFF 0x2 #define MI_UNTRUSTED_REGISTER_SPACE 0x0 #define MI_TRUSTED_REGISTER_SPACE 0x1 #endif /* 3D state: */ #define _3DOP_3DSTATE_PIPELINED 0x0 #define _3DOP_3DSTATE_NONPIPELINED 0x1 #define _3DOP_3DCONTROL 0x2 #define _3DOP_3DPRIMITIVE 0x3 #define _3DSTATE_PIPELINED_POINTERS 0x00 #define _3DSTATE_BINDING_TABLE_POINTERS 0x01 #define _3DSTATE_VERTEX_BUFFERS 0x08 #define _3DSTATE_VERTEX_ELEMENTS 0x09 #define _3DSTATE_INDEX_BUFFER 0x0A #define _3DSTATE_VF_STATISTICS 0x0B #define _3DSTATE_DRAWING_RECTANGLE 0x00 #define _3DSTATE_CONSTANT_COLOR 0x01 #define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 #define _3DSTATE_CHROMA_KEY 0x04 #define _3DSTATE_DEPTH_BUFFER 0x05 #define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 #define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 #define _3DSTATE_LINE_STIPPLE 0x08 #define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 #define _3DCONTROL 0x00 #define _3DPRIMITIVE 0x00 #define PIPE_CONTROL_NOWRITE 0x00 #define PIPE_CONTROL_WRITEIMMEDIATE 0x01 #define PIPE_CONTROL_WRITEDEPTH 0x02 #define PIPE_CONTROL_WRITETIMESTAMP 0x03 #define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00 #define PIPE_CONTROL_GTTWRITE_GLOBAL 0x01 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define BRW_ANISORATIO_2 0 #define BRW_ANISORATIO_4 1 #define BRW_ANISORATIO_6 2 #define BRW_ANISORATIO_8 3 #define BRW_ANISORATIO_10 4 #define BRW_ANISORATIO_12 5 #define BRW_ANISORATIO_14 6 #define BRW_ANISORATIO_16 7 #define BRW_BLENDFACTOR_ONE 0x1 #define BRW_BLENDFACTOR_SRC_COLOR 0x2 #define BRW_BLENDFACTOR_SRC_ALPHA 0x3 #define BRW_BLENDFACTOR_DST_ALPHA 0x4 #define BRW_BLENDFACTOR_DST_COLOR 0x5 #define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define BRW_BLENDFACTOR_CONST_COLOR 0x7 #define BRW_BLENDFACTOR_CONST_ALPHA 0x8 #define BRW_BLENDFACTOR_SRC1_COLOR 0x9 #define BRW_BLENDFACTOR_SRC1_ALPHA 0x0A #define BRW_BLENDFACTOR_ZERO 0x11 #define BRW_BLENDFACTOR_INV_SRC_COLOR 0x12 #define BRW_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define BRW_BLENDFACTOR_INV_DST_ALPHA 0x14 #define BRW_BLENDFACTOR_INV_DST_COLOR 0x15 #define BRW_BLENDFACTOR_INV_CONST_COLOR 0x17 #define BRW_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define BRW_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define BRW_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define BRW_BLENDFUNCTION_ADD 0 #define BRW_BLENDFUNCTION_SUBTRACT 1 #define BRW_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define BRW_BLENDFUNCTION_MIN 3 #define BRW_BLENDFUNCTION_MAX 4 #define BRW_ALPHATEST_FORMAT_UNORM8 0 #define BRW_ALPHATEST_FORMAT_FLOAT32 1 #define BRW_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define BRW_CHROMAKEY_REPLACE_BLACK 1 #define BRW_CLIP_API_OGL 0 #define BRW_CLIP_API_DX 1 #define BRW_CLIPMODE_NORMAL 0 #define BRW_CLIPMODE_CLIP_ALL 1 #define BRW_CLIPMODE_CLIP_NON_REJECTED 2 #define BRW_CLIPMODE_REJECT_ALL 3 #define BRW_CLIPMODE_ACCEPT_ALL 4 #define BRW_CLIP_NDCSPACE 0 #define BRW_CLIP_SCREENSPACE 1 #define BRW_COMPAREFUNCTION_ALWAYS 0 #define BRW_COMPAREFUNCTION_NEVER 1 #define BRW_COMPAREFUNCTION_LESS 2 #define BRW_COMPAREFUNCTION_EQUAL 3 #define BRW_COMPAREFUNCTION_LEQUAL 4 #define BRW_COMPAREFUNCTION_GREATER 5 #define BRW_COMPAREFUNCTION_NOTEQUAL 6 #define BRW_COMPAREFUNCTION_GEQUAL 7 #define BRW_COVERAGE_PIXELS_HALF 0 #define BRW_COVERAGE_PIXELS_1 1 #define BRW_COVERAGE_PIXELS_2 2 #define BRW_COVERAGE_PIXELS_4 3 #define BRW_CULLMODE_BOTH 0 #define BRW_CULLMODE_NONE 1 #define BRW_CULLMODE_FRONT 2 #define BRW_CULLMODE_BACK 3 #define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define BRW_DEPTHFORMAT_D32_FLOAT 1 #define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define BRW_DEPTHFORMAT_D16_UNORM 5 #define BRW_FLOATING_POINT_IEEE_754 0 #define BRW_FLOATING_POINT_NON_IEEE_754 1 #define BRW_FRONTWINDING_CW 0 #define BRW_FRONTWINDING_CCW 1 #define BRW_INDEX_BYTE 0 #define BRW_INDEX_WORD 1 #define BRW_INDEX_DWORD 2 #define BRW_LOGICOPFUNCTION_CLEAR 0 #define BRW_LOGICOPFUNCTION_NOR 1 #define BRW_LOGICOPFUNCTION_AND_INVERTED 2 #define BRW_LOGICOPFUNCTION_COPY_INVERTED 3 #define BRW_LOGICOPFUNCTION_AND_REVERSE 4 #define BRW_LOGICOPFUNCTION_INVERT 5 #define BRW_LOGICOPFUNCTION_XOR 6 #define BRW_LOGICOPFUNCTION_NAND 7 #define BRW_LOGICOPFUNCTION_AND 8 #define BRW_LOGICOPFUNCTION_EQUIV 9 #define BRW_LOGICOPFUNCTION_NOOP 10 #define BRW_LOGICOPFUNCTION_OR_INVERTED 11 #define BRW_LOGICOPFUNCTION_COPY 12 #define BRW_LOGICOPFUNCTION_OR_REVERSE 13 #define BRW_LOGICOPFUNCTION_OR 14 #define BRW_LOGICOPFUNCTION_SET 15 #define BRW_MAPFILTER_NEAREST 0x0 #define BRW_MAPFILTER_LINEAR 0x1 #define BRW_MAPFILTER_ANISOTROPIC 0x2 #define BRW_MIPFILTER_NONE 0 #define BRW_MIPFILTER_NEAREST 1 #define BRW_MIPFILTER_LINEAR 3 #define BRW_POLYGON_FRONT_FACING 0 #define BRW_POLYGON_BACK_FACING 1 #define BRW_PREFILTER_ALWAYS 0x0 #define BRW_PREFILTER_NEVER 0x1 #define BRW_PREFILTER_LESS 0x2 #define BRW_PREFILTER_EQUAL 0x3 #define BRW_PREFILTER_LEQUAL 0x4 #define BRW_PREFILTER_GREATER 0x5 #define BRW_PREFILTER_NOTEQUAL 0x6 #define BRW_PREFILTER_GEQUAL 0x7 #define BRW_PROVOKING_VERTEX_0 0 #define BRW_PROVOKING_VERTEX_1 1 #define BRW_PROVOKING_VERTEX_2 2 #define BRW_RASTRULE_UPPER_LEFT 0 #define BRW_RASTRULE_UPPER_RIGHT 1 #define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0 #define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1 #define BRW_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define BRW_STENCILOP_KEEP 0 #define BRW_STENCILOP_ZERO 1 #define BRW_STENCILOP_REPLACE 2 #define BRW_STENCILOP_INCRSAT 3 #define BRW_STENCILOP_DECRSAT 4 #define BRW_STENCILOP_INCR 5 #define BRW_STENCILOP_DECR 6 #define BRW_STENCILOP_INVERT 7 #define BRW_SURFACE_MIPMAPLAYOUT_BELOW 0 #define BRW_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define BRW_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define BRW_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define BRW_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define BRW_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define BRW_SURFACEFORMAT_R64G64_FLOAT 0x005 #define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define BRW_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define BRW_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define BRW_SURFACEFORMAT_R32G32B32_SINT 0x041 #define BRW_SURFACEFORMAT_R32G32B32_UINT 0x042 #define BRW_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define BRW_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define BRW_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define BRW_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define BRW_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define BRW_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define BRW_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define BRW_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define BRW_SURFACEFORMAT_R32G32_FLOAT 0x085 #define BRW_SURFACEFORMAT_R32G32_SINT 0x086 #define BRW_SURFACEFORMAT_R32G32_UINT 0x087 #define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define BRW_SURFACEFORMAT_L32A32_FLOAT 0x08A #define BRW_SURFACEFORMAT_R32G32_UNORM 0x08B #define BRW_SURFACEFORMAT_R32G32_SNORM 0x08C #define BRW_SURFACEFORMAT_R64_FLOAT 0x08D #define BRW_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define BRW_SURFACEFORMAT_A32X32_FLOAT 0x090 #define BRW_SURFACEFORMAT_L32X32_FLOAT 0x091 #define BRW_SURFACEFORMAT_I32X32_FLOAT 0x092 #define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define BRW_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define BRW_SURFACEFORMAT_R32G32_SSCALED 0x095 #define BRW_SURFACEFORMAT_R32G32_USCALED 0x096 #define BRW_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define BRW_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define BRW_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define BRW_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define BRW_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define BRW_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define BRW_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define BRW_SURFACEFORMAT_R16G16_UNORM 0x0CC #define BRW_SURFACEFORMAT_R16G16_SNORM 0x0CD #define BRW_SURFACEFORMAT_R16G16_SINT 0x0CE #define BRW_SURFACEFORMAT_R16G16_UINT 0x0CF #define BRW_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define BRW_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define BRW_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define BRW_SURFACEFORMAT_R32_SINT 0x0D6 #define BRW_SURFACEFORMAT_R32_UINT 0x0D7 #define BRW_SURFACEFORMAT_R32_FLOAT 0x0D8 #define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define BRW_SURFACEFORMAT_L16A16_UNORM 0x0DF #define BRW_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define BRW_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define BRW_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define BRW_SURFACEFORMAT_I32_FLOAT 0x0E3 #define BRW_SURFACEFORMAT_L32_FLOAT 0x0E4 #define BRW_SURFACEFORMAT_A32_FLOAT 0x0E5 #define BRW_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define BRW_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define BRW_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define BRW_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define BRW_SURFACEFORMAT_R32_UNORM 0x0F1 #define BRW_SURFACEFORMAT_R32_SNORM 0x0F2 #define BRW_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define BRW_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define BRW_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define BRW_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define BRW_SURFACEFORMAT_R32_SSCALED 0x0F8 #define BRW_SURFACEFORMAT_R32_USCALED 0x0F9 #define BRW_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define BRW_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define BRW_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define BRW_SURFACEFORMAT_R8G8_UNORM 0x106 #define BRW_SURFACEFORMAT_R8G8_SNORM 0x107 #define BRW_SURFACEFORMAT_R8G8_SINT 0x108 #define BRW_SURFACEFORMAT_R8G8_UINT 0x109 #define BRW_SURFACEFORMAT_R16_UNORM 0x10A #define BRW_SURFACEFORMAT_R16_SNORM 0x10B #define BRW_SURFACEFORMAT_R16_SINT 0x10C #define BRW_SURFACEFORMAT_R16_UINT 0x10D #define BRW_SURFACEFORMAT_R16_FLOAT 0x10E #define BRW_SURFACEFORMAT_I16_UNORM 0x111 #define BRW_SURFACEFORMAT_L16_UNORM 0x112 #define BRW_SURFACEFORMAT_A16_UNORM 0x113 #define BRW_SURFACEFORMAT_L8A8_UNORM 0x114 #define BRW_SURFACEFORMAT_I16_FLOAT 0x115 #define BRW_SURFACEFORMAT_L16_FLOAT 0x116 #define BRW_SURFACEFORMAT_A16_FLOAT 0x117 #define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define BRW_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define BRW_SURFACEFORMAT_R8G8_SSCALED 0x11C #define BRW_SURFACEFORMAT_R8G8_USCALED 0x11D #define BRW_SURFACEFORMAT_R16_SSCALED 0x11E #define BRW_SURFACEFORMAT_R16_USCALED 0x11F #define BRW_SURFACEFORMAT_R8_UNORM 0x140 #define BRW_SURFACEFORMAT_R8_SNORM 0x141 #define BRW_SURFACEFORMAT_R8_SINT 0x142 #define BRW_SURFACEFORMAT_R8_UINT 0x143 #define BRW_SURFACEFORMAT_A8_UNORM 0x144 #define BRW_SURFACEFORMAT_I8_UNORM 0x145 #define BRW_SURFACEFORMAT_L8_UNORM 0x146 #define BRW_SURFACEFORMAT_P4A4_UNORM 0x147 #define BRW_SURFACEFORMAT_A4P4_UNORM 0x148 #define BRW_SURFACEFORMAT_R8_SSCALED 0x149 #define BRW_SURFACEFORMAT_R8_USCALED 0x14A #define BRW_SURFACEFORMAT_R1_UINT 0x181 #define BRW_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define BRW_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define BRW_SURFACEFORMAT_BC1_UNORM 0x186 #define BRW_SURFACEFORMAT_BC2_UNORM 0x187 #define BRW_SURFACEFORMAT_BC3_UNORM 0x188 #define BRW_SURFACEFORMAT_BC4_UNORM 0x189 #define BRW_SURFACEFORMAT_BC5_UNORM 0x18A #define BRW_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define BRW_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define BRW_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define BRW_SURFACEFORMAT_MONO8 0x18E #define BRW_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define BRW_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define BRW_SURFACEFORMAT_DXT1_RGB 0x191 #define BRW_SURFACEFORMAT_FXT1 0x192 #define BRW_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define BRW_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define BRW_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define BRW_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define BRW_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define BRW_SURFACEFORMAT_BC4_SNORM 0x199 #define BRW_SURFACEFORMAT_BC5_SNORM 0x19A #define BRW_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define BRW_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define BRW_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define BRW_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define BRW_SURFACERETURNFORMAT_FLOAT32 0 #define BRW_SURFACERETURNFORMAT_S1 1 #define BRW_SURFACE_1D 0 #define BRW_SURFACE_2D 1 #define BRW_SURFACE_3D 2 #define BRW_SURFACE_CUBE 3 #define BRW_SURFACE_BUFFER 4 #define BRW_SURFACE_NULL 7 #define BRW_BORDER_COLOR_MODE_DEFAULT 0 #define BRW_BORDER_COLOR_MODE_LEGACY 1 #define HSW_SCS_ZERO 0 #define HSW_SCS_ONE 1 #define HSW_SCS_RED 4 #define HSW_SCS_GREEN 5 #define HSW_SCS_BLUE 6 #define HSW_SCS_ALPHA 7 #define BRW_TEXCOORDMODE_WRAP 0 #define BRW_TEXCOORDMODE_MIRROR 1 #define BRW_TEXCOORDMODE_CLAMP 2 #define BRW_TEXCOORDMODE_CUBE 3 #define BRW_TEXCOORDMODE_CLAMP_BORDER 4 #define BRW_TEXCOORDMODE_MIRROR_ONCE 5 #define BRW_THREAD_PRIORITY_NORMAL 0 #define BRW_THREAD_PRIORITY_HIGH 1 #define BRW_TILEWALK_XMAJOR 0 #define BRW_TILEWALK_YMAJOR 1 #define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define BRW_VFCOMPONENT_NOSTORE 0 #define BRW_VFCOMPONENT_STORE_SRC 1 #define BRW_VFCOMPONENT_STORE_0 2 #define BRW_VFCOMPONENT_STORE_1_FLT 3 #define BRW_VFCOMPONENT_STORE_1_INT 4 #define BRW_VFCOMPONENT_STORE_VID 5 #define BRW_VFCOMPONENT_STORE_IID 6 #define BRW_VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define BRW_ALIGN_1 0 #define BRW_ALIGN_16 1 #define BRW_ADDRESS_DIRECT 0 #define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define BRW_CHANNEL_X 0 #define BRW_CHANNEL_Y 1 #define BRW_CHANNEL_Z 2 #define BRW_CHANNEL_W 3 #define BRW_COMPRESSION_NONE 0 #define BRW_COMPRESSION_2NDHALF 1 #define BRW_COMPRESSION_COMPRESSED 2 #define BRW_CONDITIONAL_NONE 0 #define BRW_CONDITIONAL_Z 1 #define BRW_CONDITIONAL_NZ 2 #define BRW_CONDITIONAL_EQ 1 /* Z */ #define BRW_CONDITIONAL_NEQ 2 /* NZ */ #define BRW_CONDITIONAL_G 3 #define BRW_CONDITIONAL_GE 4 #define BRW_CONDITIONAL_L 5 #define BRW_CONDITIONAL_LE 6 #define BRW_CONDITIONAL_C 7 #define BRW_CONDITIONAL_O 8 #define BRW_DEBUG_NONE 0 #define BRW_DEBUG_BREAKPOINT 1 #define BRW_DEPENDENCY_NORMAL 0 #define BRW_DEPENDENCY_NOTCLEARED 1 #define BRW_DEPENDENCY_NOTCHECKED 2 #define BRW_DEPENDENCY_DISABLE 3 #define BRW_EXECUTE_1 0 #define BRW_EXECUTE_2 1 #define BRW_EXECUTE_4 2 #define BRW_EXECUTE_8 3 #define BRW_EXECUTE_16 4 #define BRW_EXECUTE_32 5 #define BRW_HORIZONTAL_STRIDE_0 0 #define BRW_HORIZONTAL_STRIDE_1 1 #define BRW_HORIZONTAL_STRIDE_2 2 #define BRW_HORIZONTAL_STRIDE_4 3 #define BRW_INSTRUCTION_NORMAL 0 #define BRW_INSTRUCTION_SATURATE 1 #define BRW_MASK_ENABLE 0 #define BRW_MASK_DISABLE 1 #define BRW_OPCODE_MOV 1 #define BRW_OPCODE_SEL 2 #define BRW_OPCODE_NOT 4 #define BRW_OPCODE_AND 5 #define BRW_OPCODE_OR 6 #define BRW_OPCODE_XOR 7 #define BRW_OPCODE_SHR 8 #define BRW_OPCODE_SHL 9 #define BRW_OPCODE_RSR 10 #define BRW_OPCODE_RSL 11 #define BRW_OPCODE_ASR 12 #define BRW_OPCODE_CMP 16 #define BRW_OPCODE_JMPI 32 #define BRW_OPCODE_IF 34 #define BRW_OPCODE_IFF 35 #define BRW_OPCODE_ELSE 36 #define BRW_OPCODE_ENDIF 37 #define BRW_OPCODE_DO 38 #define BRW_OPCODE_WHILE 39 #define BRW_OPCODE_BREAK 40 #define BRW_OPCODE_CONTINUE 41 #define BRW_OPCODE_HALT 42 #define BRW_OPCODE_MSAVE 44 #define BRW_OPCODE_MRESTORE 45 #define BRW_OPCODE_PUSH 46 #define BRW_OPCODE_POP 47 #define BRW_OPCODE_WAIT 48 #define BRW_OPCODE_SEND 49 #define BRW_OPCODE_ADD 64 #define BRW_OPCODE_MUL 65 #define BRW_OPCODE_AVG 66 #define BRW_OPCODE_FRC 67 #define BRW_OPCODE_RNDU 68 #define BRW_OPCODE_RNDD 69 #define BRW_OPCODE_RNDE 70 #define BRW_OPCODE_RNDZ 71 #define BRW_OPCODE_MAC 72 #define BRW_OPCODE_MACH 73 #define BRW_OPCODE_LZD 74 #define BRW_OPCODE_SAD2 80 #define BRW_OPCODE_SADA2 81 #define BRW_OPCODE_DP4 84 #define BRW_OPCODE_DPH 85 #define BRW_OPCODE_DP3 86 #define BRW_OPCODE_DP2 87 #define BRW_OPCODE_DPA2 88 #define BRW_OPCODE_LINE 89 #define BRW_OPCODE_NOP 126 #define BRW_PREDICATE_NONE 0 #define BRW_PREDICATE_NORMAL 1 #define BRW_PREDICATE_ALIGN1_ANYV 2 #define BRW_PREDICATE_ALIGN1_ALLV 3 #define BRW_PREDICATE_ALIGN1_ANY2H 4 #define BRW_PREDICATE_ALIGN1_ALL2H 5 #define BRW_PREDICATE_ALIGN1_ANY4H 6 #define BRW_PREDICATE_ALIGN1_ALL4H 7 #define BRW_PREDICATE_ALIGN1_ANY8H 8 #define BRW_PREDICATE_ALIGN1_ALL8H 9 #define BRW_PREDICATE_ALIGN1_ANY16H 10 #define BRW_PREDICATE_ALIGN1_ALL16H 11 #define BRW_PREDICATE_ALIGN16_REPLICATE_X 2 #define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3 #define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4 #define BRW_PREDICATE_ALIGN16_REPLICATE_W 5 #define BRW_PREDICATE_ALIGN16_ANY4H 6 #define BRW_PREDICATE_ALIGN16_ALL4H 7 #define BRW_ARCHITECTURE_REGISTER_FILE 0 #define BRW_GENERAL_REGISTER_FILE 1 #define BRW_MESSAGE_REGISTER_FILE 2 #define BRW_IMMEDIATE_VALUE 3 #define BRW_REGISTER_TYPE_UD 0 #define BRW_REGISTER_TYPE_D 1 #define BRW_REGISTER_TYPE_UW 2 #define BRW_REGISTER_TYPE_W 3 #define BRW_REGISTER_TYPE_UB 4 #define BRW_REGISTER_TYPE_B 5 #define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define BRW_REGISTER_TYPE_HF 6 #define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define BRW_REGISTER_TYPE_F 7 #define BRW_ARF_NULL 0x00 #define BRW_ARF_ADDRESS 0x10 #define BRW_ARF_ACCUMULATOR 0x20 #define BRW_ARF_FLAG 0x30 #define BRW_ARF_MASK 0x40 #define BRW_ARF_MASK_STACK 0x50 #define BRW_ARF_MASK_STACK_DEPTH 0x60 #define BRW_ARF_STATE 0x70 #define BRW_ARF_CONTROL 0x80 #define BRW_ARF_NOTIFICATION_COUNT 0x90 #define BRW_ARF_IP 0xA0 #define BRW_AMASK 0 #define BRW_IMASK 1 #define BRW_LMASK 2 #define BRW_CMASK 3 #define BRW_THREAD_NORMAL 0 #define BRW_THREAD_ATOMIC 1 #define BRW_THREAD_SWITCH 2 #define BRW_VERTICAL_STRIDE_0 0 #define BRW_VERTICAL_STRIDE_1 1 #define BRW_VERTICAL_STRIDE_2 2 #define BRW_VERTICAL_STRIDE_4 3 #define BRW_VERTICAL_STRIDE_8 4 #define BRW_VERTICAL_STRIDE_16 5 #define BRW_VERTICAL_STRIDE_32 6 #define BRW_VERTICAL_STRIDE_64 7 #define BRW_VERTICAL_STRIDE_128 8 #define BRW_VERTICAL_STRIDE_256 9 #define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define BRW_WIDTH_1 0 #define BRW_WIDTH_2 1 #define BRW_WIDTH_4 2 #define BRW_WIDTH_8 3 #define BRW_WIDTH_16 4 #define BRW_STATELESS_BUFFER_BOUNDARY_1K 0 #define BRW_STATELESS_BUFFER_BOUNDARY_2K 1 #define BRW_STATELESS_BUFFER_BOUNDARY_4K 2 #define BRW_STATELESS_BUFFER_BOUNDARY_8K 3 #define BRW_STATELESS_BUFFER_BOUNDARY_16K 4 #define BRW_STATELESS_BUFFER_BOUNDARY_32K 5 #define BRW_STATELESS_BUFFER_BOUNDARY_64K 6 #define BRW_STATELESS_BUFFER_BOUNDARY_128K 7 #define BRW_STATELESS_BUFFER_BOUNDARY_256K 8 #define BRW_STATELESS_BUFFER_BOUNDARY_512K 9 #define BRW_STATELESS_BUFFER_BOUNDARY_1M 10 #define BRW_STATELESS_BUFFER_BOUNDARY_2M 11 #define BRW_POLYGON_FACING_FRONT 0 #define BRW_POLYGON_FACING_BACK 1 #define BRW_MESSAGE_TARGET_NULL 0 #define BRW_MESSAGE_TARGET_MATH 1 #define BRW_MESSAGE_TARGET_SAMPLER 2 #define BRW_MESSAGE_TARGET_GATEWAY 3 #define BRW_MESSAGE_TARGET_DATAPORT_READ 4 #define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5 #define BRW_MESSAGE_TARGET_URB 6 #define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7 #define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define BRW_SAMPLER_RETURN_FORMAT_UINT32 2 #define BRW_SAMPLER_RETURN_FORMAT_SINT32 3 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0 #define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define BRW_MATH_FUNCTION_INV 1 #define BRW_MATH_FUNCTION_LOG 2 #define BRW_MATH_FUNCTION_EXP 3 #define BRW_MATH_FUNCTION_SQRT 4 #define BRW_MATH_FUNCTION_RSQ 5 #define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ #define BRW_MATH_FUNCTION_COS 7 /* was 8 */ #define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define BRW_MATH_FUNCTION_TAN 9 #define BRW_MATH_FUNCTION_POW 10 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define BRW_MATH_INTEGER_UNSIGNED 0 #define BRW_MATH_INTEGER_SIGNED 1 #define BRW_MATH_PRECISION_FULL 0 #define BRW_MATH_PRECISION_PARTIAL 1 #define BRW_MATH_SATURATE_NONE 0 #define BRW_MATH_SATURATE_SATURATE 1 #define BRW_MATH_DATA_VECTOR 0 #define BRW_MATH_DATA_SCALAR 1 #define BRW_URB_OPCODE_WRITE 0 #define BRW_URB_SWIZZLE_NONE 0 #define BRW_URB_SWIZZLE_INTERLEAVE 1 #define BRW_URB_SWIZZLE_TRANSPOSE 2 #define BRW_SCRATCH_SPACE_SIZE_1K 0 #define BRW_SCRATCH_SPACE_SIZE_2K 1 #define BRW_SCRATCH_SPACE_SIZE_4K 2 #define BRW_SCRATCH_SPACE_SIZE_8K 3 #define BRW_SCRATCH_SPACE_SIZE_16K 4 #define BRW_SCRATCH_SPACE_SIZE_32K 5 #define BRW_SCRATCH_SPACE_SIZE_64K 6 #define BRW_SCRATCH_SPACE_SIZE_128K 7 #define BRW_SCRATCH_SPACE_SIZE_256K 8 #define BRW_SCRATCH_SPACE_SIZE_512K 9 #define BRW_SCRATCH_SPACE_SIZE_1M 10 #define BRW_SCRATCH_SPACE_SIZE_2M 11 #define CMD_URB_FENCE 0x6000 #define CMD_CONST_BUFFER_STATE 0x6001 #define CMD_CONST_BUFFER 0x6002 #define CMD_STATE_BASE_ADDRESS 0x6101 #define CMD_STATE_INSN_POINTER 0x6102 #define CMD_PIPELINE_SELECT 0x6104 #define CMD_PIPELINED_STATE_POINTERS 0x7800 #define CMD_BINDING_TABLE_PTRS 0x7801 #define CMD_VERTEX_BUFFER 0x7808 #define CMD_VERTEX_ELEMENT 0x7809 #define CMD_INDEX_BUFFER 0x780a #define CMD_VF_STATISTICS 0x780b #define CMD_DRAW_RECT 0x7900 #define CMD_BLEND_CONSTANT_COLOR 0x7901 #define CMD_CHROMA_KEY 0x7904 #define CMD_DEPTH_BUFFER 0x7905 #define CMD_POLY_STIPPLE_OFFSET 0x7906 #define CMD_POLY_STIPPLE_PATTERN 0x7907 #define CMD_LINE_STIPPLE_PATTERN 0x7908 #define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908 #define CMD_PIPE_CONTROL 0x7a00 #define CMD_3D_PRIM 0x7b00 #define CMD_MI_FLUSH 0x0200 /* Various values from the R0 vertex header: */ #define R02_PRIM_END 0x1 #define R02_PRIM_START 0x2 /* media pipeline */ #define BRW_VFE_MODE_GENERIC 0x0 #define BRW_VFE_MODE_VLD_MPEG2 0x1 #define BRW_VFE_MODE_IS 0x2 #define BRW_VFE_MODE_AVC_MC 0x4 #define BRW_VFE_MODE_AVC_IT 0x7 #define BRW_VFE_MODE_VC1_IT 0xB #define BRW_VFE_DEBUG_COUNTER_FREE 0 #define BRW_VFE_DEBUG_COUNTER_FROZEN 1 #define BRW_VFE_DEBUG_COUNTER_ONCE 2 #define BRW_VFE_DEBUG_COUNTER_ALWAYS 3 /* VLD_STATE */ #define BRW_MPEG_TOP_FIELD 1 #define BRW_MPEG_BOTTOM_FIELD 2 #define BRW_MPEG_FRAME 3 #define BRW_MPEG_QSCALE_LINEAR 0 #define BRW_MPEG_QSCALE_NONLINEAR 1 #define BRW_MPEG_ZIGZAG_SCAN 0 #define BRW_MPEG_ALTER_VERTICAL_SCAN 1 #define BRW_MPEG_I_PICTURE 1 #define BRW_MPEG_P_PICTURE 2 #define BRW_MPEG_B_PICTURE 3 #endif xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/brw_structs.h000066400000000000000000001136111267532330400244140ustar00rootroot00000000000000 /************************************************************************** * * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 BRW_STRUCTS_H #define BRW_STRUCTS_H /* Command packets: */ struct header { unsigned int length:16; unsigned int opcode:16; }; union header_union { struct header bits; unsigned int dword; }; struct brw_3d_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:3; unsigned int wc_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } dest; unsigned int dword2; unsigned int dword3; }; struct brw_3d_primitive { struct { unsigned int length:8; unsigned int pad:2; unsigned int topology:5; unsigned int indexed:1; unsigned int opcode:16; } header; unsigned int verts_per_instance; unsigned int start_vert_location; unsigned int instance_count; unsigned int start_instance_location; unsigned int base_vert_location; }; /* These seem to be passed around as function args, so it works out * better to keep them as #defines: */ #define BRW_FLUSH_READ_CACHE 0x1 #define BRW_FLUSH_STATE_CACHE 0x2 #define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4 #define BRW_FLUSH_SNAPSHOT_COUNTERS 0x8 struct brw_mi_flush { unsigned int flags:4; unsigned int pad:12; unsigned int opcode:16; }; struct brw_vf_statistics { unsigned int statistics_enable:1; unsigned int pad:15; unsigned int opcode:16; }; struct brw_binding_table_pointers { struct header header; unsigned int vs; unsigned int gs; unsigned int clp; unsigned int sf; unsigned int wm; }; struct brw_blend_constant_color { struct header header; float blend_constant_color[4]; }; struct brw_depthbuffer { union header_union header; union { struct { unsigned int pitch:18; unsigned int format:3; unsigned int pad:4; unsigned int depth_offset_disable:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad2:1; unsigned int surface_type:3; } bits; unsigned int dword; } dword1; unsigned int dword2_base_addr; union { struct { unsigned int pad:1; unsigned int mipmap_layout:1; unsigned int lod:4; unsigned int width:13; unsigned int height:13; } bits; unsigned int dword; } dword3; union { struct { unsigned int pad:12; unsigned int min_array_element:9; unsigned int depth:11; } bits; unsigned int dword; } dword4; }; struct brw_drawrect { struct header header; unsigned int xmin:16; unsigned int ymin:16; unsigned int xmax:16; unsigned int ymax:16; unsigned int xorg:16; unsigned int yorg:16; }; struct brw_global_depth_offset_clamp { struct header header; float depth_offset_clamp; }; struct brw_indexbuffer { union { struct { unsigned int length:8; unsigned int index_format:2; unsigned int cut_index_enable:1; unsigned int pad:5; unsigned int opcode:16; } bits; unsigned int dword; } header; unsigned int buffer_start; unsigned int buffer_end; }; struct brw_line_stipple { struct header header; struct { unsigned int pattern:16; unsigned int pad:16; } bits0; struct { unsigned int repeat_count:9; unsigned int pad:7; unsigned int inverse_repeat_count:16; } bits1; }; struct brw_pipelined_state_pointers { struct header header; struct { unsigned int pad:5; unsigned int offset:27; } vs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } gs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } clp; struct { unsigned int pad:5; unsigned int offset:27; } sf; struct { unsigned int pad:5; unsigned int offset:27; } wm; struct { unsigned int pad:5; unsigned int offset:27; /* KW: check me! */ } cc; }; struct brw_polygon_stipple_offset { struct header header; struct { unsigned int y_offset:5; unsigned int pad:3; unsigned int x_offset:5; unsigned int pad0:19; } bits0; }; struct brw_polygon_stipple { struct header header; unsigned int stipple[32]; }; struct brw_pipeline_select { struct { unsigned int pipeline_select:1; unsigned int pad:15; unsigned int opcode:16; } header; }; struct brw_pipe_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:2; unsigned int instruction_state_cache_flush_enable:1; unsigned int write_cache_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int post_sync_operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } bits1; unsigned int data0; unsigned int data1; }; struct brw_urb_fence { struct { unsigned int length:8; unsigned int vs_realloc:1; unsigned int gs_realloc:1; unsigned int clp_realloc:1; unsigned int sf_realloc:1; unsigned int vfe_realloc:1; unsigned int cs_realloc:1; unsigned int pad:2; unsigned int opcode:16; } header; struct { unsigned int vs_fence:10; unsigned int gs_fence:10; unsigned int clp_fence:10; unsigned int pad:2; } bits0; struct { unsigned int sf_fence:10; unsigned int vf_fence:10; unsigned int cs_fence:10; unsigned int pad:2; } bits1; }; struct brw_constant_buffer_state /* previously brw_command_streamer */ { struct header header; struct { unsigned int nr_urb_entries:3; unsigned int pad:1; unsigned int urb_entry_size:5; unsigned int pad0:23; } bits0; }; struct brw_constant_buffer { struct { unsigned int length:8; unsigned int valid:1; unsigned int pad:7; unsigned int opcode:16; } header; struct { unsigned int buffer_length:6; unsigned int buffer_address:26; } bits0; }; struct brw_state_base_address { struct header header; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int general_state_address:27; } bits0; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int surface_state_address:27; } bits1; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int indirect_object_state_address:27; } bits2; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int general_state_upper_bound:20; } bits3; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int indirect_object_state_upper_bound:20; } bits4; }; struct brw_state_prefetch { struct header header; struct { unsigned int prefetch_count:3; unsigned int pad:3; unsigned int prefetch_pointer:26; } bits0; }; struct brw_system_instruction_pointer { struct header header; struct { unsigned int pad:4; unsigned int system_instruction_pointer:28; } bits0; }; /* State structs for the various fixed function units: */ struct thread0 { unsigned int pad0:1; unsigned int grf_reg_count:3; unsigned int pad1:2; unsigned int kernel_start_pointer:26; }; struct thread1 { unsigned int ext_halt_exception_enable:1; unsigned int sw_exception_enable:1; unsigned int mask_stack_exception_enable:1; unsigned int timeout_exception_enable:1; unsigned int illegal_op_exception_enable:1; unsigned int pad0:3; unsigned int depth_coef_urb_read_offset:6; /* WM only */ unsigned int pad1:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad3:5; unsigned int single_program_flow:1; }; struct thread2 { unsigned int per_thread_scratch_space:4; unsigned int pad0:6; unsigned int scratch_space_base_pointer:22; }; struct thread3 { unsigned int dispatch_grf_start_reg:4; unsigned int urb_entry_read_offset:6; unsigned int pad0:1; unsigned int urb_entry_read_length:6; unsigned int pad1:1; unsigned int const_urb_entry_read_offset:6; unsigned int pad2:1; unsigned int const_urb_entry_read_length:6; unsigned int pad3:1; }; struct brw_clip_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:9; unsigned int gs_output_stats:1; /* not always */ unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; /* may be less */ unsigned int pad3:1; } thread4; struct { unsigned int pad0:13; unsigned int clip_mode:3; unsigned int userclip_enable_flags:8; unsigned int userclip_must_clip:1; unsigned int pad1:1; unsigned int guard_band_enable:1; unsigned int viewport_z_clip_enable:1; unsigned int viewport_xy_clip_enable:1; unsigned int vertex_position_space:1; unsigned int api_mode:1; unsigned int pad2:1; } clip5; struct { unsigned int pad0:5; unsigned int clipper_viewport_state_ptr:27; } clip6; float viewport_xmin; float viewport_xmax; float viewport_ymin; float viewport_ymax; }; struct brw_cc_unit_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } cc0; struct { unsigned int bf_stencil_ref:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; unsigned int stencil_ref:8; } cc1; struct { unsigned int logicop_enable:1; unsigned int pad0:10; unsigned int depth_write_enable:1; unsigned int depth_test_function:3; unsigned int depth_test:1; unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; } cc2; struct { unsigned int pad0:8; unsigned int alpha_test_func:3; unsigned int alpha_test:1; unsigned int blend_enable:1; unsigned int ia_blend_enable:1; unsigned int pad1:1; unsigned int alpha_test_format:1; unsigned int pad2:16; } cc3; struct { unsigned int pad0:5; unsigned int cc_viewport_state_offset:27; } cc4; struct { unsigned int pad0:2; unsigned int ia_dest_blend_factor:5; unsigned int ia_src_blend_factor:5; unsigned int ia_blend_function:3; unsigned int statistics_enable:1; unsigned int logicop_func:4; unsigned int pad1:11; unsigned int dither_enable:1; } cc5; struct { unsigned int clamp_post_alpha_blend:1; unsigned int clamp_pre_alpha_blend:1; unsigned int clamp_range:2; unsigned int pad0:11; unsigned int y_dither_offset:2; unsigned int x_dither_offset:2; unsigned int dest_blend_factor:5; unsigned int src_blend_factor:5; unsigned int blend_function:3; } cc6; struct { union { float f; unsigned char ub[4]; } alpha_ref; } cc7; }; struct brw_sf_unit_state { struct thread0 thread0; struct { unsigned int pad0:7; unsigned int sw_exception_enable:1; unsigned int pad1:3; unsigned int mask_stack_exception_enable:1; unsigned int pad2:1; unsigned int illegal_op_exception_enable:1; unsigned int pad3:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad4:5; unsigned int single_program_flow:1; } sf1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; unsigned int pad3:1; } thread4; struct { unsigned int front_winding:1; unsigned int viewport_transform:1; unsigned int pad0:3; unsigned int sf_viewport_state_offset:27; } sf5; struct { unsigned int pad0:9; unsigned int dest_org_vbias:4; unsigned int dest_org_hbias:4; unsigned int scissor:1; unsigned int disable_2x2_trifilter:1; unsigned int disable_zero_pix_trifilter:1; unsigned int point_rast_rule:2; unsigned int line_endcap_aa_region_width:2; unsigned int line_width:4; unsigned int fast_scissor_disable:1; unsigned int cull_mode:2; unsigned int aa_enable:1; } sf6; struct { unsigned int point_size:11; unsigned int use_point_size_state:1; unsigned int subpixel_precision:1; unsigned int sprite_point:1; unsigned int pad0:11; unsigned int trifan_pv:2; unsigned int linestrip_pv:2; unsigned int tristrip_pv:2; unsigned int line_last_pixel_enable:1; } sf7; }; struct brw_gs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:1; unsigned int pad3:6; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } gs5; struct { unsigned int max_vp_index:4; unsigned int pad0:26; unsigned int reorder_enable:1; unsigned int pad1:1; } gs6; }; struct brw_vs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:4; unsigned int pad3:3; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } vs5; struct { unsigned int vs_enable:1; unsigned int vert_cache_disable:1; unsigned int pad0:30; } vs6; }; struct brw_wm_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int stats_enable:1; unsigned int pad0:1; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } wm4; struct { unsigned int enable_8_pix:1; unsigned int enable_16_pix:1; unsigned int enable_32_pix:1; unsigned int pad0:7; unsigned int legacy_global_depth_bias:1; unsigned int line_stipple:1; unsigned int depth_offset:1; unsigned int polygon_stipple:1; unsigned int line_aa_region_width:2; unsigned int line_endcap_aa_region_width:2; unsigned int early_depth_test:1; unsigned int thread_dispatch_enable:1; unsigned int program_uses_depth:1; unsigned int program_computes_depth:1; unsigned int program_uses_killpixel:1; unsigned int legacy_line_rast: 1; unsigned int transposed_urb_read:1; unsigned int max_threads:7; } wm5; float global_depth_offset_constant; float global_depth_offset_scale; struct { unsigned int pad0:1; unsigned int grf_reg_count_1:3; unsigned int pad1:2; unsigned int kernel_start_pointer_1:26; } wm8; struct { unsigned int pad0:1; unsigned int grf_reg_count_2:3; unsigned int pad1:2; unsigned int kernel_start_pointer_2:26; } wm9; struct { unsigned int pad0:1; unsigned int grf_reg_count_3:3; unsigned int pad1:2; unsigned int kernel_start_pointer_3:26; } wm10; }; struct brw_wm_unit_state_padded { struct brw_wm_unit_state state; char pad[64 - sizeof(struct brw_wm_unit_state)]; }; /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct brw_sampler_default_border_color { float color[4]; }; struct brw_sampler_legacy_border_color { uint8_t color[4]; }; struct brw_sampler_state { struct { unsigned int shadow_function:3; unsigned int lod_bias:11; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad:1; unsigned int lod_preclamp:1; unsigned int border_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:3; unsigned int max_lod:10; unsigned int min_lod:10; } ss1; struct { unsigned int pad:5; unsigned int border_color_pointer:27; } ss2; struct { unsigned int pad:19; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int monochrome_filter_width:3; unsigned int monochrome_filter_height:3; } ss3; }; struct brw_clipper_viewport { float xmin; float xmax; float ymin; float ymax; }; struct brw_cc_viewport { float min_depth; float max_depth; }; struct brw_sf_viewport { struct { float m00; float m11; float m22; float m30; float m31; float m32; } viewport; struct { short xmin; short ymin; short xmax; short ymax; } scissor; }; /* Documented in the subsystem/shared-functions/sampler chapter... */ struct brw_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad:3; unsigned int render_cache_read_mode:1; unsigned int mipmap_layout_mode:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int color_blend:1; unsigned int writedisable_blue:1; unsigned int writedisable_green:1; unsigned int writedisable_red:1; unsigned int writedisable_alpha:1; unsigned int surface_format:9; unsigned int data_return_format:1; unsigned int pad0:1; unsigned int surface_type:3; } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int render_target_rotation:2; unsigned int mip_count:4; unsigned int width:13; unsigned int height:13; } ss2; struct { unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad:1; unsigned int pitch:18; unsigned int depth:11; } ss3; struct { unsigned int pad:19; unsigned int min_array_elt:9; unsigned int min_lod:4; } ss4; struct { unsigned int pad:20; unsigned int y_offset:4; unsigned int pad2:1; unsigned int x_offset:7; } ss5; }; struct brw_vertex_buffer_state { struct { unsigned int pitch:11; unsigned int pad:15; unsigned int access_type:1; unsigned int vb_index:5; } vb0; unsigned int start_addr; unsigned int max_index; #if 1 unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */ #endif }; #define BRW_VBP_MAX 17 struct brw_vb_array_state { struct header header; struct brw_vertex_buffer_state vb[BRW_VBP_MAX]; }; struct brw_vertex_element_state { struct { unsigned int src_offset:11; unsigned int pad:5; unsigned int src_format:9; unsigned int pad0:1; unsigned int valid:1; unsigned int vertex_buffer_index:5; } ve0; struct { unsigned int dst_offset:8; unsigned int pad:8; unsigned int vfcomponent3:4; unsigned int vfcomponent2:4; unsigned int vfcomponent1:4; unsigned int vfcomponent0:4; } ve1; }; #define BRW_VEP_MAX 18 struct brw_vertex_element_packet { struct header header; struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */ }; struct brw_urb_immediate { unsigned int opcode:4; unsigned int offset:6; unsigned int swizzle_control:2; unsigned int pad:1; unsigned int allocate:1; unsigned int used:1; unsigned int complete:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; }; /* Instruction format for the execution units: */ struct brw_instruction { struct { unsigned int opcode:7; unsigned int pad:1; unsigned int access_mode:1; unsigned int mask_control:1; unsigned int dependency_control:2; unsigned int compression_control:2; unsigned int thread_control:2; unsigned int predicate_control:4; unsigned int predicate_inverse:1; unsigned int execution_size:3; unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */ unsigned int pad0:2; unsigned int debug_control:1; unsigned int saturate:1; } header; union { struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad:1; unsigned int dest_subreg_nr:5; unsigned int dest_reg_nr:8; unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } da1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad:6; int dest_indirect_offset:10; /* offset against the deref'd address reg */ unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */ unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } ia1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad0:1; unsigned int dest_writemask:4; unsigned int dest_subreg_nr:1; unsigned int dest_reg_nr:8; unsigned int pad1:2; unsigned int dest_address_mode:1; } da16; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad0:6; unsigned int dest_writemask:4; int dest_indirect_offset:6; unsigned int dest_subreg_nr:3; unsigned int pad1:2; unsigned int dest_address_mode:1; } ia16; } bits1; union { struct { unsigned int src0_subreg_nr:5; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } da1; struct { int src0_indirect_offset:10; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } ia1; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; unsigned int src0_subreg_nr:1; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } da16; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; int src0_indirect_offset:6; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia16; } bits2; union { struct { unsigned int src1_subreg_nr:5; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int pad0:7; } da1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; unsigned int src1_subreg_nr:1; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int pad2:7; } da16; struct { int src1_indirect_offset:10; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; int src1_indirect_offset:6; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad2:6; } ia16; struct { int jump_count:16; /* note: signed */ unsigned int pop_count:4; unsigned int pad0:12; } if_else; struct { unsigned int function:4; unsigned int int_type:1; unsigned int precision:1; unsigned int saturate:1; unsigned int data_type:1; unsigned int pad0:8; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } math; struct { unsigned int binding_table_index:8; unsigned int sampler:4; unsigned int return_format:2; unsigned int msg_type:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } sampler; struct brw_urb_immediate urb; struct { unsigned int binding_table_index:8; unsigned int msg_control:4; unsigned int msg_type:2; unsigned int target_cache:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_read; struct { unsigned int binding_table_index:8; unsigned int msg_control:3; unsigned int pixel_scoreboard_clear:1; unsigned int msg_type:3; unsigned int send_commit_msg:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_write; struct { unsigned int pad:16; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } generic; unsigned int ud; } bits3; }; /* media pipeline */ struct brw_vfe_state { struct { unsigned int per_thread_scratch_space:4; unsigned int pad3:3; unsigned int extend_vfe_state_present:1; unsigned int pad2:2; unsigned int scratch_base:22; } vfe0; struct { unsigned int debug_counter_control:2; unsigned int children_present:1; unsigned int vfe_mode:4; unsigned int pad2:2; unsigned int num_urb_entries:7; unsigned int urb_entry_alloc_size:9; unsigned int max_threads:7; } vfe1; struct { unsigned int pad4:4; unsigned int interface_descriptor_base:28; } vfe2; }; struct brw_vld_state { struct { unsigned int pad6:6; unsigned int scan_order:1; unsigned int intra_vlc_format:1; unsigned int quantizer_scale_type:1; unsigned int concealment_motion_vector:1; unsigned int frame_predict_frame_dct:1; unsigned int top_field_first:1; unsigned int picture_structure:2; unsigned int intra_dc_precision:2; unsigned int f_code_0_0:4; unsigned int f_code_0_1:4; unsigned int f_code_1_0:4; unsigned int f_code_1_1:4; } vld0; struct { unsigned int pad2:9; unsigned int picture_coding_type:2; unsigned int pad:21; } vld1; struct { unsigned int index_0:4; unsigned int index_1:4; unsigned int index_2:4; unsigned int index_3:4; unsigned int index_4:4; unsigned int index_5:4; unsigned int index_6:4; unsigned int index_7:4; } desc_remap_table0; struct { unsigned int index_8:4; unsigned int index_9:4; unsigned int index_10:4; unsigned int index_11:4; unsigned int index_12:4; unsigned int index_13:4; unsigned int index_14:4; unsigned int index_15:4; } desc_remap_table1; }; struct brw_interface_descriptor { struct { unsigned int grf_reg_blocks:4; unsigned int pad:2; unsigned int kernel_start_pointer:26; } desc0; struct { unsigned int pad:7; unsigned int software_exception:1; unsigned int pad2:3; unsigned int maskstack_exception:1; unsigned int pad3:1; unsigned int illegal_opcode_exception:1; unsigned int pad4:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int single_program_flow:1; unsigned int pad5:1; unsigned int const_urb_entry_read_offset:6; unsigned int const_urb_entry_read_len:6; } desc1; struct { unsigned int pad:2; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } desc2; struct { unsigned int binding_table_entry_count:5; unsigned int binding_table_pointer:27; } desc3; }; struct gen6_blend_state { struct { unsigned int dest_blend_factor:5; unsigned int source_blend_factor:5; unsigned int pad3:1; unsigned int blend_func:3; unsigned int pad2:1; unsigned int ia_dest_blend_factor:5; unsigned int ia_source_blend_factor:5; unsigned int pad1:1; unsigned int ia_blend_func:3; unsigned int pad0:1; unsigned int ia_blend_enable:1; unsigned int blend_enable:1; } blend0; struct { unsigned int post_blend_clamp_enable:1; unsigned int pre_blend_clamp_enable:1; unsigned int clamp_range:2; unsigned int pad0:4; unsigned int x_dither_offset:2; unsigned int y_dither_offset:2; unsigned int dither_enable:1; unsigned int alpha_test_func:3; unsigned int alpha_test_enable:1; unsigned int pad1:1; unsigned int logic_op_func:4; unsigned int logic_op_enable:1; unsigned int pad2:1; unsigned int write_disable_b:1; unsigned int write_disable_g:1; unsigned int write_disable_r:1; unsigned int write_disable_a:1; unsigned int pad3:1; unsigned int alpha_to_coverage_dither:1; unsigned int alpha_to_one:1; unsigned int alpha_to_coverage:1; } blend1; }; struct gen6_color_calc_state { struct { unsigned int alpha_test_format:1; unsigned int pad0:14; unsigned int round_disable:1; unsigned int bf_stencil_ref:8; unsigned int stencil_ref:8; } cc0; union { float alpha_ref_f; struct { unsigned int ui:8; unsigned int pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen6_depth_stencil_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } ds0; struct { unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; } ds1; struct { unsigned int pad0:26; unsigned int depth_write_enable:1; unsigned int depth_test_func:3; unsigned int pad1:1; unsigned int depth_test_enable:1; } ds2; }; struct gen7_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad2:2; unsigned int render_cache_read_write:1; unsigned int pad1:1; unsigned int surface_array_spacing:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int horizontal_alignment:1; unsigned int vertical_alignment:2; unsigned int surface_format:9; /**< BRW_SURFACEFORMAT_x */ unsigned int pad0:1; unsigned int is_array:1; unsigned int surface_type:3; /**< BRW_SURFACE_1D/2D/3D/CUBE */ } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int width:14; unsigned int pad1:2; unsigned int height:14; unsigned int pad0:2; } ss2; struct { unsigned int pitch:18; unsigned int pad:3; unsigned int depth:11; } ss3; struct { unsigned int multisample_position_palette_index:3; unsigned int num_multisamples:3; unsigned int multisampled_surface_storage_format:1; unsigned int render_target_view_extent:11; unsigned int min_array_elt:11; unsigned int rotation:2; unsigned int pad0:1; } ss4; struct { unsigned int mip_count:4; unsigned int min_lod:4; unsigned int pad1:12; unsigned int y_offset:4; unsigned int pad0:1; unsigned int x_offset:7; } ss5; struct { unsigned int pad; /* Multisample Control Surface stuff */ } ss6; struct { unsigned int resource_min_lod:12; unsigned int pad0:4; unsigned int shader_chanel_select_a:3; unsigned int shader_chanel_select_b:3; unsigned int shader_chanel_select_g:3; unsigned int shader_chanel_select_r:3; unsigned int alpha_clear_color:1; unsigned int blue_clear_color:1; unsigned int green_clear_color:1; unsigned int red_clear_color:1; } ss7; }; struct gen7_sampler_state { struct { unsigned int aniso_algorithm:1; unsigned int lod_bias:13; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad1:1; unsigned int lod_preclamp:1; unsigned int default_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int cube_control_mode:1; unsigned int shadow_function:3; unsigned int pad:4; unsigned int max_lod:12; unsigned int min_lod:12; } ss1; struct { unsigned int pad:5; unsigned int default_color_pointer:27; } ss2; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:1; unsigned int non_normalized_coord:1; unsigned int trilinear_quality:2; unsigned int address_round:6; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int pad0:6; } ss3; }; #endif xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/common.h000066400000000000000000000043431267532330400233240ustar00rootroot00000000000000 /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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: * Keith Whitwell * David Dawes * */ #ifndef _INTEL_COMMON_H_ #define _INTEL_COMMON_H_ #include /* Provide substitutes for gcc's __FUNCTION__ on other compilers */ #if !defined(__GNUC__) && !defined(__FUNCTION__) # if defined(__STDC__) && (__STDC_VERSION__>=199901L) /* C99 */ # define __FUNCTION__ __func__ # else # define __FUNCTION__ "" # endif #endif #define PFX __FILE__,__LINE__,__FUNCTION__ #define FUNCTION_NAME __FUNCTION__ #define KB(x) ((x) * 1024) #define MB(x) ((x) * KB(1024)) /** * Hints to CreatePixmap to tell the driver how the pixmap is going to be * used. * * Compare to CREATE_PIXMAP_USAGE_* in the server. */ enum { INTEL_CREATE_PIXMAP_TILING_X = 0x10000000, INTEL_CREATE_PIXMAP_TILING_Y = 0x20000000, INTEL_CREATE_PIXMAP_TILING_NONE = 0x40000000, INTEL_CREATE_PIXMAP_DRI2 = 0x80000000, }; #endif /* _INTEL_COMMON_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i830_3d.c000066400000000000000000000167121267532330400231030ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 "xorg-server.h" #include "xf86.h" #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" void I830EmitInvarientState(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(intel->in_batch_atomic); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0)); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1)); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2)); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(3)); OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_DFLT_Z_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_FOG_MODE_CMD); OUT_BATCH(FOGFUNC_ENABLE | FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(0) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(0) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(1) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(1) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(2) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(2) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | MAP_UNIT(3) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(3) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE | ENABLE_LINE_STRIP_PROVOKE_VRTX | ENABLE_TRI_FAN_PROVOKE_VRTX | ENABLE_TRI_STRIP_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) | TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); OUT_BATCH(_3DSTATE_W_STATE_CMD); OUT_BATCH(MAGIC_W_STATE_DWORD1); OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD); OUT_BATCH(TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); /* copy from mesa */ OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND | ENABLE_ALPHA_BLENDFUNC | ABLENDFUNC_ADD); OUT_BATCH(_3DSTATE_FOG_COLOR_CMD | FOG_COLOR_RED(0) | FOG_COLOR_GREEN(0) | FOG_COLOR_BLUE(0)); OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_MODES_1_CMD | ENABLE_COLR_BLND_FUNC | BLENDFUNC_ADD | ENABLE_SRC_BLND_FACTOR | SRC_BLND_FACT(BLENDFACTOR_ONE) | ENABLE_DST_BLND_FACTOR | DST_BLND_FACT(BLENDFACTOR_ZERO)); OUT_BATCH(_3DSTATE_MODES_2_CMD | ENABLE_GLOBAL_DEPTH_BIAS | GLOBAL_DEPTH_BIAS(0) | ENABLE_ALPHA_TEST_FUNC | ALPHA_TEST_FUNC(0) | /* always */ ALPHA_REF_VALUE(0)); OUT_BATCH(_3DSTATE_MODES_3_CMD | ENABLE_DEPTH_TEST_FUNC | DEPTH_TEST_FUNC(0x2) | /* COMPAREFUNC_LESS */ ENABLE_ALPHA_SHADE_MODE | ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | ENABLE_FOG_SHADE_MODE | FOG_SHADE_MODE(SHADE_MODE_LINEAR) | ENABLE_SPEC_SHADE_MODE | SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | ENABLE_COLOR_SHADE_MODE | COLOR_SHADE_MODE(SHADE_MODE_LINEAR) | ENABLE_CULL_MODE | CULLMODE_NONE); OUT_BATCH(_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff) | ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff)); OUT_BATCH(_3DSTATE_STENCIL_TEST_CMD | ENABLE_STENCIL_PARMS | STENCIL_FAIL_OP(0) | /* STENCILOP_KEEP */ STENCIL_PASS_DEPTH_FAIL_OP(0) | /* STENCILOP_KEEP */ STENCIL_PASS_DEPTH_PASS_OP(0) | /* STENCILOP_KEEP */ ENABLE_STENCIL_TEST_FUNC | STENCIL_TEST_FUNC(0) | /* COMPAREFUNC_ALWAYS */ ENABLE_STENCIL_REF_VALUE | STENCIL_REF_VALUE(0)); OUT_BATCH(_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ ENABLE_FIXED_POINT_WIDTH | FIXED_POINT_WIDTH(1)); OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); OUT_BATCH(_3DSTATE_ENABLES_2_CMD | DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | DISABLE_DITHER | ENABLE_COLOR_MASK | ENABLE_COLOR_WRITE | DISABLE_DEPTH_WRITE); OUT_BATCH(_3DSTATE_STIPPLE); /* Set default blend state */ OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) | TEXPIPE_COLOR | ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT | DISABLE_TEX_CNTRL_STAGE | TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); OUT_BATCH(_3DSTATE_MAP_BLEND_OP_CMD(0) | TEXPIPE_ALPHA | ENABLE_TEXOUTPUT_WRT_SEL | TEXOP_OUTPUT_CURRENT | TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) | TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE); OUT_BATCH(_3DSTATE_MAP_BLEND_ARG_CMD(0) | TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_DIFFUSE); OUT_BATCH(_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 | AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0 | AA_LINE_DISABLE); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i830_reg.h000066400000000000000000000702531267532330400233570ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 _I830_REG_H_ #define _I830_REG_H_ #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) /* Flush */ #define MI_FLUSH (0x04<<23) #define MI_FLUSH_DW (0x26<<23) #define MI_WRITE_DIRTY_STATE (1<<4) #define MI_END_SCENE (1<<3) #define MI_GLOBAL_SNAPSHOT_COUNT_RESET (1<<3) #define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2) #define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1) #define MI_INVALIDATE_MAP_CACHE (1<<0) /* broadwater flush bits */ #define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3) #define MI_BATCH_BUFFER_END (0xA << 23) /* Noop */ #define MI_NOOP 0x00 #define MI_NOOP_WRITE_ID (1<<22) #define MI_NOOP_ID_MASK (1<<22 - 1) /* Wait for Events */ #define MI_WAIT_FOR_EVENT (0x03<<23) #define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18) #define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17) #define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) #define MI_WAIT_FOR_PIPEB_VBLANK (1<<7) #define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5) #define MI_WAIT_FOR_PIPEA_VBLANK (1<<3) #define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<1) /* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */ #define MI_LOAD_SCAN_LINES_INCL (0x12<<23) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20) /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) #define COLOR_BLT_WRITE_ALPHA (1<<21) #define COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)) #define XY_COLOR_BLT_WRITE_ALPHA (1<<21) #define XY_COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_TILED (1<<11) #define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)) #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)) #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) #define XY_SRC_COPY_BLT_DST_TILED (1<<11) #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)) #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22)) #define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)) #define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) #define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) #define XY_MONO_PAT_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_PAT_BLT_WRITE_RGB (1<<20) #define XY_MONO_SRC_BLT_CMD ((0x2<<29)|(0x54<<22)) #define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_SRC_BLT_WRITE_RGB (1<<20) #define CMD_3D (0x3<<29) #define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) #define PRIM3D_TRILIST (0x0<<18) #define PRIM3D_TRISTRIP (0x1<<18) #define PRIM3D_TRISTRIP_RVRSE (0x2<<18) #define PRIM3D_TRIFAN (0x3<<18) #define PRIM3D_POLY (0x4<<18) #define PRIM3D_LINELIST (0x5<<18) #define PRIM3D_LINESTRIP (0x6<<18) #define PRIM3D_RECTLIST (0x7<<18) #define PRIM3D_POINTLIST (0x8<<18) #define PRIM3D_DIB (0x9<<18) #define PRIM3D_CLEAR_RECT (0xa<<18) #define PRIM3D_ZONE_INIT (0xd<<18) #define PRIM3D_MASK (0x1f<<18) #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) #define AA_LINE_ENABLE ((1<<1) | 1) #define AA_LINE_DISABLE (1<<1) #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) #define BUF_3D_PITCH(x) (((x)/4)<<2) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) #define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) #define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ ((0x90+(stage))<<16)) #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) #define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define DEPTH_IS_Z 0 #define DEPTH_IS_W (1<<6) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 0 #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((x)<<16) #define DRAW_XMIN(x) (x) /* Dword 3 */ #define DRAW_YMAX(x) ((x)<<16) #define DRAW_XMAX(x) (x) /* Dword 4 */ #define DRAW_YORG(x) ((x)<<16) #define DRAW_XORG(x) (x) #define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) #define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) #define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) #define DISABLE_LOGIC_OP (1<<23) #define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) #define DISABLE_STENCIL_TEST (1<<21) #define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) #define DISABLE_DEPTH_BIAS (1<<11) #define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) #define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) #define DISABLE_SPEC_ADD (1<<9) #define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) #define ENABLE_FOG ((1<<7)|(1<<6)) #define DISABLE_FOG (1<<7) #define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) #define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) #define DISABLE_ALPHA_TEST (1<<5) #define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) #define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) #define DISABLE_COLOR_BLEND (1<<3) #define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) #define ENABLE_DEPTH_TEST ((1<<1)|1) #define DISABLE_DEPTH_TEST (1<<1) /* _3DSTATE_ENABLES_2, p138 */ #define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) #define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) #define DISABLE_STENCIL_WRITE (1<<21) #define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) #define DISABLE_TEX_CACHE (1<<17) #define ENABLE_DITHER ((1<<9)|(1<<8)) #define DISABLE_DITHER (1<<9) #define ENABLE_COLOR_MASK (1<<10) #define WRITEMASK_ALPHA (1<<7) #define WRITEMASK_ALPHA_SHIFT 7 #define WRITEMASK_RED (1<<6) #define WRITEMASK_RED_SHIFT 6 #define WRITEMASK_GREEN (1<<5) #define WRITEMASK_GREEN_SHIFT 5 #define WRITEMASK_BLUE (1<<4) #define WRITEMASK_BLUE_SHIFT 4 #define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) #define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) #define DISABLE_COLOR_WRITE (1<<3) #define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 #define ENABLE_DEPTH_WRITE ((1<<1)|1) #define DISABLE_DEPTH_WRITE (1<<1) /* _3DSTATE_FOG_COLOR, p139 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p140 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FOGFUNC_ENABLE (1<<31) #define FOGFUNC_VERTEX 0 #define FOGFUNC_PIXEL_EXP (1<<28) #define FOGFUNC_PIXEL_EXP2 (2<<28) #define FOGFUNC_PIXEL_LINEAR (3<<28) #define FOGSRC_INDEX_Z (1<<27) #define FOGSRC_INDEX_W ((1<<27)|(1<<25)) #define FOG_LINEAR_CONST (1<<24) #define FOG_CONST_1(x) ((x)<<4) #define ENABLE_FOG_DENSITY (1<<23) /* Dword 2 */ #define FOG_CONST_2(x) (x) /* Dword 3 */ #define FOG_DENSITY(x) (x) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ #define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) #define DISABLE_INDPT_ALPHA_BLEND (1<<23) #define ALPHA_BLENDFUNC_MASK 0x3f0000 #define ENABLE_ALPHA_BLENDFUNC (1<<21) #define ABLENDFUNC_ADD 0 #define ABLENDFUNC_SUB (1<<16) #define ABLENDFUNC_RVSE_SUB (2<<16) #define ABLENDFUNC_MIN (3<<16) #define ABLENDFUNC_MAX (4<<16) #define SRC_DST_ABLEND_MASK 0xfff #define ENABLE_SRC_ABLEND_FACTOR (1<<11) #define SRC_ABLEND_FACT(x) ((x)<<6) #define ENABLE_DST_ABLEND_FACTOR (1<<5) #define DST_ABLEND_FACT(x) (x) #define BLENDFACTOR_ZERO 0x01 #define BLENDFACTOR_ONE 0x02 #define BLENDFACTOR_SRC_COLR 0x03 #define BLENDFACTOR_INV_SRC_COLR 0x04 #define BLENDFACTOR_SRC_ALPHA 0x05 #define BLENDFACTOR_INV_SRC_ALPHA 0x06 #define BLENDFACTOR_DST_ALPHA 0x07 #define BLENDFACTOR_INV_DST_ALPHA 0x08 #define BLENDFACTOR_DST_COLR 0x09 #define BLENDFACTOR_INV_DST_COLR 0x0a #define BLENDFACTOR_SRC_ALPHA_SATURATE 0x0b #define BLENDFACTOR_CONST_COLOR 0x0c #define BLENDFACTOR_INV_CONST_COLOR 0x0d #define BLENDFACTOR_CONST_ALPHA 0x0e #define BLENDFACTOR_INV_CONST_ALPHA 0x0f #define BLENDFACTOR_MASK 0x0f /* _3DSTATE_MAP_BLEND_ARG, p152 */ #define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) #define TEXPIPE_COLOR 0 #define TEXPIPE_ALPHA (1<<18) #define TEXPIPE_KILL (2<<18) #define TEXBLEND_ARG0 0 #define TEXBLEND_ARG1 (1<<15) #define TEXBLEND_ARG2 (2<<15) #define TEXBLEND_ARG3 (3<<15) #define TEXBLENDARG_MODIFY_PARMS (1<<6) #define TEXBLENDARG_REPLICATE_ALPHA (1<<5) #define TEXBLENDARG_INV_ARG (1<<4) #define TEXBLENDARG_ONE 0 #define TEXBLENDARG_FACTOR 0x01 #define TEXBLENDARG_ACCUM 0x02 #define TEXBLENDARG_DIFFUSE 0x03 #define TEXBLENDARG_SPEC 0x04 #define TEXBLENDARG_CURRENT 0x05 #define TEXBLENDARG_TEXEL0 0x06 #define TEXBLENDARG_TEXEL1 0x07 #define TEXBLENDARG_TEXEL2 0x08 #define TEXBLENDARG_TEXEL3 0x09 #define TEXBLENDARG_FACTOR_N 0x0e /* _3DSTATE_MAP_BLEND_OP, p155 */ #define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) #if 0 # define TEXPIPE_COLOR 0 # define TEXPIPE_ALPHA (1<<18) # define TEXPIPE_KILL (2<<18) #endif #define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) #define TEXOP_OUTPUT_CURRENT 0 #define TEXOP_OUTPUT_ACCUM (1<<15) #define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) #define DISABLE_TEX_CNTRL_STAGE (1<<12) #define TEXOP_SCALE_SHIFT 9 #define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) #define TEXOP_MODIFY_PARMS (1<<8) #define TEXOP_LAST_STAGE (1<<7) #define TEXBLENDOP_KILLPIXEL 0x02 #define TEXBLENDOP_ARG1 0x01 #define TEXBLENDOP_ARG2 0x02 #define TEXBLENDOP_MODULATE 0x03 #define TEXBLENDOP_ADD 0x06 #define TEXBLENDOP_ADDSIGNED 0x07 #define TEXBLENDOP_BLEND 0x08 #define TEXBLENDOP_BLEND_AND_ADD 0x09 #define TEXBLENDOP_SUBTRACT 0x0a #define TEXBLENDOP_DOT3 0x0b #define TEXBLENDOP_DOT4 0x0c #define TEXBLENDOP_MODULATE_AND_ADD 0x0d #define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e #define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f /* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ /* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ #define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) #define DISABLE_TEX_TRANSFORM (1<<28) #define TEXTURE_SET(x) (x<<29) #define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define DISABLE_PERSPECTIVE_DIVIDE (1<<29) /* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ #define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) #define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) #define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) #define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) #define TEXBIND_SET3(x) ((x)<<12) #define TEXBIND_SET2(x) ((x)<<8) #define TEXBIND_SET1(x) ((x)<<4) #define TEXBIND_SET0(x) (x) #define TEXCOORDSRC_KEEP 0 #define TEXCOORDSRC_DEFAULT 0x01 #define TEXCOORDSRC_VTXSET_0 0x08 #define TEXCOORDSRC_VTXSET_1 0x09 #define TEXCOORDSRC_VTXSET_2 0x0a #define TEXCOORDSRC_VTXSET_3 0x0b #define TEXCOORDSRC_VTXSET_4 0x0c #define TEXCOORDSRC_VTXSET_5 0x0d #define TEXCOORDSRC_VTXSET_6 0x0e #define TEXCOORDSRC_VTXSET_7 0x0f #define MAP_UNIT(unit) ((unit)<<16) #define MAP_UNIT_MASK (0x7<<16) /* _3DSTATE_MAP_COORD_SETS, p164 */ #define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) #define TEXCOORD_SET(n) ((n)<<16) #define ENABLE_TEXCOORD_PARAMS (1<<15) #define TEXCOORDS_ARE_NORMAL (1<<14) #define TEXCOORDS_ARE_IN_TEXELUNITS 0 #define TEXCOORDTYPE_CARTESIAN 0 #define TEXCOORDTYPE_HOMOGENEOUS (1<<11) #define TEXCOORDTYPE_VECTOR (2<<11) #define TEXCOORDTYPE_MASK (0x7<<11) #define ENABLE_ADDR_V_CNTL (1<<7) #define ENABLE_ADDR_U_CNTL (1<<3) #define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) #define TEXCOORD_ADDR_U_MODE(x) (x) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP 2 #define TEXCOORDMODE_WRAP_SHORTEST 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORD_ADDR_V_MASK 0x70 #define TEXCOORD_ADDR_U_MASK 0x7 /* _3DSTATE_MAP_CUBE, p168 TODO */ #define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) #define CUBE_NEGX_ENABLE (1<<5) #define CUBE_POSX_ENABLE (1<<4) #define CUBE_NEGY_ENABLE (1<<3) #define CUBE_POSY_ENABLE (1<<2) #define CUBE_NEGZ_ENABLE (1<<1) #define CUBE_POSZ_ENABLE (1<<0) #define _3DSTATE_MAP_INFO_CMD (CMD_3D|(0x1d<<24)|(0x0<<16)|3) #define TEXMAP_INDEX(x) ((x)<<28) #define MAP_SURFACE_8BIT (1<<24) #define MAP_SURFACE_16BIT (2<<24) #define MAP_SURFACE_32BIT (3<<24) #define MAP_FORMAT_2D (0) #define MAP_FORMAT_3D_CUBE (1<<11) /* _3DSTATE_MODES_1, p190 */ #define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) #define BLENDFUNC_MASK 0x3f0000 #define ENABLE_COLR_BLND_FUNC (1<<21) #define BLENDFUNC_ADD 0 #define BLENDFUNC_SUB (1<<16) #define BLENDFUNC_RVRSE_SUB (2<<16) #define BLENDFUNC_MIN (3<<16) #define BLENDFUNC_MAX (4<<16) #define SRC_DST_BLND_MASK 0xfff #define ENABLE_SRC_BLND_FACTOR (1<<11) #define ENABLE_DST_BLND_FACTOR (1<<5) #define SRC_BLND_FACT(x) ((x)<<6) #define DST_BLND_FACT(x) (x) /* _3DSTATE_MODES_2, p192 */ #define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) #define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) #define GLOBAL_DEPTH_BIAS(x) ((x)<<14) #define ENABLE_ALPHA_TEST_FUNC (1<<13) #define ENABLE_ALPHA_REF_VALUE (1<<8) #define ALPHA_TEST_FUNC(x) ((x)<<9) #define ALPHA_REF_VALUE(x) (x) #define ALPHA_TEST_REF_MASK 0x3fff /* _3DSTATE_MODES_3, p193 */ #define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) #define DEPTH_TEST_FUNC_MASK 0x1f0000 #define ENABLE_DEPTH_TEST_FUNC (1<<20) /* Uses COMPAREFUNC */ #define DEPTH_TEST_FUNC(x) ((x)<<16) #define ENABLE_ALPHA_SHADE_MODE (1<<11) #define ENABLE_FOG_SHADE_MODE (1<<9) #define ENABLE_SPEC_SHADE_MODE (1<<7) #define ENABLE_COLOR_SHADE_MODE (1<<5) #define ALPHA_SHADE_MODE(x) ((x)<<10) #define FOG_SHADE_MODE(x) ((x)<<8) #define SPEC_SHADE_MODE(x) ((x)<<6) #define COLOR_SHADE_MODE(x) ((x)<<4) #define CULLMODE_MASK 0xf #define ENABLE_CULL_MODE (1<<3) #define CULLMODE_BOTH 0 #define CULLMODE_NONE 1 #define CULLMODE_CW 2 #define CULLMODE_CCW 3 #define SHADE_MODE_LINEAR 0 #define SHADE_MODE_FLAT 0x1 /* _3DSTATE_MODES_4, p195 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) #define LOGICOP_CLEAR 0 #define LOGICOP_NOR 0x1 #define LOGICOP_AND_INV 0x2 #define LOGICOP_COPY_INV 0x3 #define LOGICOP_AND_RVRSE 0x4 #define LOGICOP_INV 0x5 #define LOGICOP_XOR 0x6 #define LOGICOP_NAND 0x7 #define LOGICOP_AND 0x8 #define LOGICOP_EQUIV 0x9 #define LOGICOP_NOOP 0xa #define LOGICOP_OR_INV 0xb #define LOGICOP_COPY 0xc #define LOGICOP_OR_RVRSE 0xd #define LOGICOP_OR 0xe #define LOGICOP_SET 0xf #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p196 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define ENABLE_SPRITE_POINT_TEX (1<<23) #define SPRITE_POINT_TEX_ON (1<<22) #define SPRITE_POINT_TEX_OFF 0 #define FLUSH_RENDER_CACHE (1<<18) #define FLUSH_TEXTURE_CACHE (1<<16) #define FIXED_LINE_WIDTH_MASK 0xfc00 #define ENABLE_FIXED_LINE_WIDTH (1<<15) #define FIXED_LINE_WIDTH(x) ((x)<<10) #define FIXED_POINT_WIDTH_MASK 0x3ff #define ENABLE_FIXED_POINT_WIDTH (1<<9) #define FIXED_POINT_WIDTH(x) (x) /* _3DSTATE_RASTERIZATION_RULES, p198 */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) #define TRI_STRIP_PROVOKE_VRTX(x) (x) /* _3DSTATE_SCISSOR_ENABLE, p200 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* _3DSTATE_STENCIL_TEST, p202 */ #define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) #define ENABLE_STENCIL_PARMS (1<<23) #define STENCIL_OPS_MASK (0xffc000) #define STENCIL_FAIL_OP(x) ((x)<<20) #define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) #define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) #define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) #define ENABLE_STENCIL_TEST_FUNC (1<<13) /* Uses COMPAREFUNC */ #define STENCIL_TEST_FUNC(x) ((x)<<9) #define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) #define ENABLE_STENCIL_REF_VALUE (1<<8) #define STENCIL_REF_VALUE(x) (x) /* _3DSTATE_VERTEX_FORMAT, p204 */ #define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) #define VFT0_POINT_WIDTH (1<<12) #define VFT0_TEX_COUNT_MASK (7<<8) #define VFT0_TEX_COUNT_SHIFT 8 #define VFT0_TEX_COUNT(x) ((x)<<8) #define VFT0_SPEC (1<<7) #define VFT0_DIFFUSE (1<<6) #define VFT0_DEPTH_OFFSET (1<<5) #define VFT0_XYZ (1<<1) #define VFT0_XYZW (2<<1) #define VFT0_XY (3<<1) #define VFT0_XYW (4<<1) #define VFT0_XYZW_MASK (7<<1) /* _3DSTATE_VERTEX_FORMAT_2, p206 */ #define _3DSTATE_VERTEX_FORMAT_2_CMD (CMD_3D|(0x0a<<24)) #define VFT1_TEX7_FMT(x) ((x)<<14) #define VFT1_TEX6_FMT(x) ((x)<<12) #define VFT1_TEX5_FMT(x) ((x)<<10) #define VFT1_TEX4_FMT(x) ((x)<<8) #define VFT1_TEX3_FMT(x) ((x)<<6) #define VFT1_TEX2_FMT(x) ((x)<<4) #define VFT1_TEX1_FMT(x) ((x)<<2) #define VFT1_TEX0_FMT(x) (x) #define VFT1_TEX0_MASK 3 #define VFT1_TEX1_SHIFT 2 #define TEXCOORDFMT_2D 0 #define TEXCOORDFMT_3D 1 #define TEXCOORDFMT_4D 2 #define TEXCOORDFMT_1D 3 /*New stuff picked up along the way */ #define MLC_LOD_BIAS_MASK ((1<<7)-1) /* _3DSTATE_VERTEX_TRANSFORM, p207 */ #define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) #define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) /* Dword 1 */ #define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) #define DISABLE_PERSP_DIVIDE (1<<29) #define VRTX_TRANS_LOAD_MATRICES 0x7421 #define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 /* Dword 2 -> 7 are matrix elements */ /* _3DSTATE_W_STATE, p209 */ #define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) /* Dword 1 */ #define MAGIC_W_STATE_DWORD1 0x00000008 /* Dword 2 */ #define WFAR_VALUE(x) (x) /* Stipple command, carried over from the i810, apparently: */ #define _3DSTATE_STIPPLE (CMD_3D|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<((n)+4)) #define S3_POINT_WIDTH_SHIFT 23 #define S3_LINE_WIDTH_SHIFT 19 #define S3_ALPHA_SHADE_MODE_SHIFT 18 #define S3_FOG_SHADE_MODE_SHIFT 17 #define S3_SPEC_SHADE_MODE_SHIFT 16 #define S3_COLOR_SHADE_MODE_SHIFT 15 #define S3_CULL_MODE_SHIFT 13 #define S3_CULLMODE_BOTH (0) #define S3_CULLMODE_NONE (1<<13) #define S3_CULLMODE_CW (2<<13) #define S3_CULLMODE_CCW (3<<13) #define S3_POINT_WIDTH_PRESENT (1<<12) #define S3_SPEC_FOG_PRESENT (1<<11) #define S3_DIFFUSE_PRESENT (1<<10) #define S3_DEPTH_OFFSET_PRESENT (1<<9) #define S3_POSITION_SHIFT 6 #define S3_VERTEXHAS_XYZ (1<<6) #define S3_VERTEXHAS_XYZW (2<<6) #define S3_VERTEXHAS_XY (3<<6) #define S3_VERTEXHAS_XYW (4<<6) #define S3_ENABLE_SPEC_ADD (1<<5) #define S3_ENABLE_FOG (1<<4) #define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3) #define S3_ENABLE_SPRITE_POINT (1<<1) #define S3_ENABLE_ANTIALIASING 1 #define S8_ENABLE_ALPHA_TEST (1<<31) #define S8_ALPHA_TEST_FUNC_SHIFT 28 #define S8_ALPHA_REFVALUE_SHIFT 20 #define S8_ENABLE_DEPTH_TEST (1<<19) #define S8_DEPTH_TEST_FUNC_SHIFT 16 #define S8_ENABLE_COLOR_BLEND (1<<15) #define S8_COLOR_BLEND_FUNC_SHIFT 12 #define S8_BLENDFUNC_ADD (0) #define S8_BLENDFUNC_SUB (1<<12) #define S8_BLENDFUNC_RVRSE_SUB (2<<12) #define S8_BLENDFUNC_MIN (3<<12) #define S8_BLENDFUNC_MAX (4<<12) #define S8_SRC_BLEND_FACTOR_SHIFT 8 #define S8_DST_BLEND_FACTOR_SHIFT 4 #define S8_ENABLE_DEPTH_BUFFER_WRITE (1<<3) #define S8_ENABLE_COLOR_BUFFER_WRITE (1<<2) #define _3DSTATE_LOAD_STATE_IMMEDIATE_2 (CMD_3D|(0x1d<<24)|(0x03<<16)) #define LOAD_TEXTURE_MAP(x) (1<<((x)+11)) #define LOAD_TEXTURE_BLEND_STAGE(x) (1<<((x)+7)) #define LOAD_GLOBAL_COLOR_FACTOR (1<<6) #define TM0S0_ADDRESS_MASK 0xfffffffc #define TM0S0_USE_FENCE (1<<1) #define TM0S1_HEIGHT_SHIFT 21 #define TM0S1_WIDTH_SHIFT 10 #define TM0S1_PALETTE_SELECT (1<<9) #define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) #define TM0S1_MAPSURF_FORMAT_SHIFT 6 #define MAPSURF_8BIT_INDEXED (0<<6) #define MAPSURF_8BIT (1<<6) #define MAPSURF_16BIT (2<<6) #define MAPSURF_32BIT (3<<6) #define MAPSURF_411 (4<<6) #define MAPSURF_422 (5<<6) #define MAPSURF_COMPRESSED (6<<6) #define MAPSURF_4BIT_INDEXED (7<<6) #define TM0S1_MT_FORMAT_MASK (0x7 << 3) #define TM0S1_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ #define MT_8BIT_IDX_ARGB1555 (1<<3) #define MT_8BIT_IDX_ARGB4444 (2<<3) #define MT_8BIT_IDX_AY88 (3<<3) #define MT_8BIT_IDX_ABGR8888 (4<<3) #define MT_8BIT_IDX_BUMP_88DVDU (5<<3) #define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) #define MT_8BIT_IDX_ARGB8888 (7<<3) #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_DIB_ARGB1555_8888 (4<<3) #define MT_16BIT_BUMP_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_DIB_RGB565_8888 (7<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) #define MT_32BIT_DIB_8888 (7<<3) #define MT_411_YUV411 (0<<3) /* SURFACE_411 */ #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define TM0S1_COLORSPACE_CONVERSION (1 << 2) #define TM0S1_TILED_SURFACE (1 << 1) #define TM0S1_TILE_WALK (1 << 0) #define TM0S2_PITCH_SHIFT 21 #define TM0S2_CUBE_FACE_ENA_SHIFT 15 #define TM0S2_CUBE_FACE_ENA_MASK (1<<15) #define TM0S2_MAP_FORMAT (1<<14) #define TM0S2_MAP_2D (0<<14) #define TM0S2_MAP_3D_CUBE (1<<14) #define TM0S2_VERTICAL_LINE_STRIDE (1<<13) #define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) #define TM0S2_OUTPUT_CHAN_SHIFT 10 #define TM0S2_OUTPUT_CHAN_MASK (3<<10) #define TM0S3_MIP_FILTER_MASK (0x3<<30) #define TM0S3_MIP_FILTER_SHIFT 30 #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define TM0S3_MAG_FILTER_MASK (0x3<<28) #define TM0S3_MAG_FILTER_SHIFT 28 #define TM0S3_MIN_FILTER_MASK (0x3<<26) #define TM0S3_MIN_FILTER_SHIFT 26 #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define TM0S3_LOD_BIAS_SHIFT 17 #define TM0S3_LOD_BIAS_MASK (0x1ff<<17) #define TM0S3_MAX_MIP_SHIFT 9 #define TM0S3_MAX_MIP_MASK (0xff<<9) #define TM0S3_MIN_MIP_SHIFT 3 #define TM0S3_MIN_MIP_MASK (0x3f<<3) #define TM0S3_KILL_PIXEL (1<<2) #define TM0S3_KEYED_FILTER (1<<1) #define TM0S3_CHROMA_KEY (1<<0) /* _3DSTATE_MAP_TEXEL_STREAM, p188 */ #define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) #define DISABLE_TEX_STREAM_BUMP (1<<12) #define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) #define TEX_MODIFY_UNIT_0 0 #define TEX_MODIFY_UNIT_1 (1<<8) #define ENABLE_TEX_STREAM_COORD_SET (1<<7) #define TEX_STREAM_COORD_SET(x) ((x)<<4) #define ENABLE_TEX_STREAM_MAP_IDX (1<<3) #define TEX_STREAM_MAP_IDX(x) (x) #define FLUSH_MAP_CACHE (1<<0) #define _3DSTATE_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19)) #define FILTER_TEXMAP_INDEX(x) ((x) << 16) #define MAG_MODE_FILTER_ENABLE (1 << 5) #define MIN_MODE_FILTER_ENABLE (1 << 2) #define MAG_MAPFILTER_NEAREST (0 << 3) #define MAG_MAPFILTER_LINEAR (1 << 3) #define MAG_MAPFILTER_ANISOTROPIC (2 << 3) #define MIN_MAPFILTER_NEAREST (0) #define MIN_MAPFILTER_LINEAR (1) #define MIN_MAPFILTER_ANISOTROPIC (2) #define ENABLE_KEYS (1<<15) #define DISABLE_COLOR_KEY 0 #define DISABLE_CHROMA_KEY 0 #define DISABLE_KILL_PIXEL 0 #define ENABLE_MIP_MODE_FILTER (1 << 9) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #endif xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i830_render.c000066400000000000000000000620761267532330400240600ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" struct blendinfo { Bool dst_alpha; Bool src_alpha; uint32_t src_blend; uint32_t dst_blend; }; struct formatinfo { int fmt; uint32_t card_fmt; }; #define TB0C_LAST_STAGE (1 << 31) #define TB0C_RESULT_SCALE_1X (0 << 29) #define TB0C_RESULT_SCALE_2X (1 << 29) #define TB0C_RESULT_SCALE_4X (2 << 29) #define TB0C_OP_MODULE (3 << 25) #define TB0C_OUTPUT_WRITE_CURRENT (0 << 24) #define TB0C_OUTPUT_WRITE_ACCUM (1 << 24) #define TB0C_ARG3_REPLICATE_ALPHA (1<<23) #define TB0C_ARG3_INVERT (1<<22) #define TB0C_ARG3_SEL_XXX #define TB0C_ARG2_REPLICATE_ALPHA (1<<17) #define TB0C_ARG2_INVERT (1<<16) #define TB0C_ARG2_SEL_ONE (0 << 12) #define TB0C_ARG2_SEL_FACTOR (1 << 12) #define TB0C_ARG2_SEL_TEXEL0 (6 << 12) #define TB0C_ARG2_SEL_TEXEL1 (7 << 12) #define TB0C_ARG2_SEL_TEXEL2 (8 << 12) #define TB0C_ARG2_SEL_TEXEL3 (9 << 12) #define TB0C_ARG1_REPLICATE_ALPHA (1<<11) #define TB0C_ARG1_INVERT (1<<10) #define TB0C_ARG1_SEL_ONE (0 << 6) #define TB0C_ARG1_SEL_TEXEL0 (6 << 6) #define TB0C_ARG1_SEL_TEXEL1 (7 << 6) #define TB0C_ARG1_SEL_TEXEL2 (8 << 6) #define TB0C_ARG1_SEL_TEXEL3 (9 << 6) #define TB0C_ARG0_REPLICATE_ALPHA (1<<5) #define TB0C_ARG0_SEL_XXX #define TB0A_CTR_STAGE_ENABLE (1<<31) #define TB0A_RESULT_SCALE_1X (0 << 29) #define TB0A_RESULT_SCALE_2X (1 << 29) #define TB0A_RESULT_SCALE_4X (2 << 29) #define TB0A_OP_MODULE (3 << 25) #define TB0A_OUTPUT_WRITE_CURRENT (0<<24) #define TB0A_OUTPUT_WRITE_ACCUM (1<<24) #define TB0A_CTR_STAGE_SEL_BITS_XXX #define TB0A_ARG3_SEL_XXX #define TB0A_ARG3_INVERT (1<<17) #define TB0A_ARG2_INVERT (1<<16) #define TB0A_ARG2_SEL_ONE (0 << 12) #define TB0A_ARG2_SEL_TEXEL0 (6 << 12) #define TB0A_ARG2_SEL_TEXEL1 (7 << 12) #define TB0A_ARG2_SEL_TEXEL2 (8 << 12) #define TB0A_ARG2_SEL_TEXEL3 (9 << 12) #define TB0A_ARG1_INVERT (1<<10) #define TB0A_ARG1_SEL_ONE (0 << 6) #define TB0A_ARG1_SEL_TEXEL0 (6 << 6) #define TB0A_ARG1_SEL_TEXEL1 (7 << 6) #define TB0A_ARG1_SEL_TEXEL2 (8 << 6) #define TB0A_ARG1_SEL_TEXEL3 (9 << 6) static struct blendinfo i830_blend_op[] = { /* Clear */ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ZERO}, /* Src */ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ZERO}, /* Dst */ {0, 0, BLENDFACTOR_ZERO, BLENDFACTOR_ONE}, /* Over */ {0, 1, BLENDFACTOR_ONE, BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ONE}, /* In */ {1, 0, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_ZERO}, /* InReverse */ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_SRC_ALPHA}, /* Out */ {1, 0, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_ZERO}, /* OutReverse */ {0, 1, BLENDFACTOR_ZERO, BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, 1, BLENDFACTOR_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, 1, BLENDFACTOR_INV_DST_ALPHA, BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, 0, BLENDFACTOR_ONE, BLENDFACTOR_ONE}, }; static struct formatinfo i830_tex_formats[] = { {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8}, {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888}, {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888}, {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565}, {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555}, {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444}, }; static struct formatinfo i855_tex_formats[] = { {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888}, {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888}, }; static Bool i830_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format) { ScrnInfoPtr scrn; switch (dest_picture->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: *dst_format = COLR_BUF_ARGB8888; break; case PICT_r5g6b5: *dst_format = COLR_BUF_RGB565; break; case PICT_a1r5g5b5: case PICT_x1r5g5b5: *dst_format = COLR_BUF_ARGB1555; break; case PICT_a8: *dst_format = COLR_BUF_8BIT; break; case PICT_a4r4g4b4: case PICT_x4r4g4b4: *dst_format = COLR_BUF_ARGB4444; break; default: scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); intel_uxa_debug_fallback(scrn, "Unsupported dest format 0x%x\n", (int)dest_picture->format); return FALSE; } *dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8); return TRUE; } static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask, uint32_t dst_format, uint32_t * blendctl) { uint32_t sblend, dblend; sblend = i830_blend_op[op].src_blend; dblend = i830_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0 && i830_blend_op[op].dst_alpha) { if (sblend == BLENDFACTOR_DST_ALPHA) sblend = BLENDFACTOR_ONE; else if (sblend == BLENDFACTOR_INV_DST_ALPHA) sblend = BLENDFACTOR_ZERO; } /* For blending purposes, COLR_BUF_8BIT values show up in the green * channel. So we can't use the alpha channel. */ if (dst_format == PICT_a8 && ((sblend == BLENDFACTOR_DST_ALPHA || sblend == BLENDFACTOR_INV_DST_ALPHA))) { intel_uxa_debug_fallback(scrn, "Can't do dst alpha blending with " "PICT_a8 dest.\n"); return FALSE; } /* If the source alpha is being used, then we should only be in a case * where the source blend factor is 0, and the source blend value is the * mask channels multiplied by the source picture's alpha. */ if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) && i830_blend_op[op].src_alpha) { if (dblend == BLENDFACTOR_SRC_ALPHA) { dblend = BLENDFACTOR_SRC_COLR; } else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) { dblend = BLENDFACTOR_INV_SRC_COLR; } } *blendctl = (sblend << S8_SRC_BLEND_FACTOR_SHIFT) | (dblend << S8_DST_BLEND_FACTOR_SHIFT); return TRUE; } static uint32_t i8xx_get_card_format(intel_screen_private *intel, PicturePtr picture) { int i; for (i = 0; i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]); i++) { if (i830_tex_formats[i].fmt == picture->format) return i830_tex_formats[i].card_fmt; } if (!(IS_I830(intel) || IS_845G(intel))) { for (i = 0; i < sizeof(i855_tex_formats) / sizeof(i855_tex_formats[0]); i++) { if (i855_tex_formats[i].fmt == picture->format) return i855_tex_formats[i].card_fmt; } } return 0; } static void i830_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit) { ScrnInfoPtr scrn = xf86ScreenToScrn(picture->pDrawable->pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, tiling_bits, pitch, filter; uint32_t wrap_mode; uint32_t texcoordtype; pitch = intel_pixmap_pitch(pixmap); intel->scale_units[unit][0] = pixmap->drawable.width; intel->scale_units[unit][1] = pixmap->drawable.height; intel->transform[unit] = picture->transform; if (intel_uxa_transform_is_affine(intel->transform[unit])) texcoordtype = TEXCOORDTYPE_CARTESIAN; else texcoordtype = TEXCOORDTYPE_HOMOGENEOUS; switch (picture->repeatType) { case RepeatNone: wrap_mode = TEXCOORDMODE_CLAMP_BORDER; break; case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; break; case RepeatPad: wrap_mode = TEXCOORDMODE_CLAMP; break; case RepeatReflect: wrap_mode = TEXCOORDMODE_MIRROR; break; default: FatalError("Unknown repeat type %d\n", picture->repeatType); } switch (picture->filter) { case PictFilterNearest: filter = ((FILTER_NEAREST << TM0S3_MAG_FILTER_SHIFT) | (FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT)); break; case PictFilterBilinear: filter = ((FILTER_LINEAR << TM0S3_MAG_FILTER_SHIFT) | (FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT)); break; default: FatalError("Bad filter 0x%x\n", picture->filter); } filter |= (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT); if (intel_uxa_pixmap_tiled(pixmap)) { tiling_bits = TM0S1_TILED_SURFACE; if (intel_uxa_get_pixmap_private(pixmap)->tiling == I915_TILING_Y) tiling_bits |= TM0S1_TILE_WALK; } else tiling_bits = 0; format = i8xx_get_card_format(intel, picture); assert(intel->in_batch_atomic); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4); OUT_RELOC_PIXMAP(pixmap, I915_GEM_DOMAIN_SAMPLER, 0, 0); OUT_BATCH(((pixmap->drawable.height - 1) << TM0S1_HEIGHT_SHIFT) | ((pixmap->drawable.width - 1) << TM0S1_WIDTH_SHIFT) | format | tiling_bits); OUT_BATCH((pitch / 4 - 1) << TM0S2_PITCH_SHIFT | TM0S2_MAP_2D); OUT_BATCH(filter); OUT_BATCH(0); /* default color */ OUT_BATCH(_3DSTATE_MAP_COORD_SET_CMD | TEXCOORD_SET(unit) | ENABLE_TEXCOORD_PARAMS | TEXCOORDS_ARE_NORMAL | texcoordtype | ENABLE_ADDR_V_CNTL | TEXCOORD_ADDR_V_MODE(wrap_mode) | ENABLE_ADDR_U_CNTL | TEXCOORD_ADDR_U_MODE(wrap_mode)); /* map texel stream */ OUT_BATCH(_3DSTATE_MAP_COORD_SETBIND_CMD); if (unit == 0) OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | TEXBIND_SET1(TEXCOORDSRC_KEEP) | TEXBIND_SET2(TEXCOORDSRC_KEEP) | TEXBIND_SET3(TEXCOORDSRC_KEEP)); else OUT_BATCH(TEXBIND_SET0(TEXCOORDSRC_VTXSET_0) | TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | TEXBIND_SET2(TEXCOORDSRC_KEEP) | TEXBIND_SET3(TEXCOORDSRC_KEEP)); OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | (unit << 16) | DISABLE_TEX_STREAM_BUMP | ENABLE_TEX_STREAM_COORD_SET | TEX_STREAM_COORD_SET(unit) | ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(unit)); } Bool i830_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, int width, int height) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); uint32_t tmp1; /* Check for unsupported compositing operations. */ if (op >= sizeof(i830_blend_op) / sizeof(i830_blend_op[0])) { intel_uxa_debug_fallback(scrn, "Unsupported Composite op 0x%x\n", op); return FALSE; } if (mask_picture != NULL && mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (i830_blend_op[op].src_alpha && (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) { intel_uxa_debug_fallback(scrn, "Component alpha not " "supported with source alpha and " "source value blending.\n"); return FALSE; } } if (!i830_get_dest_format(dest_picture, &tmp1)) { intel_uxa_debug_fallback(scrn, "Get Color buffer format\n"); return FALSE; } if (width > 2048 || height > 2048) { intel_uxa_debug_fallback(scrn, "Operation is too large (%d, %d)\n", width, height); return FALSE; } return TRUE; } Bool i830_check_composite_target(PixmapPtr pixmap) { if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048) return FALSE; if(!intel_uxa_check_pitch_3d(pixmap)) return FALSE; return TRUE; } Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); if (picture->repeatType > RepeatReflect) { intel_uxa_debug_fallback(scrn, "Unsupported picture repeat %d\n", picture->repeatType); return FALSE; } if (picture->filter != PictFilterNearest && picture->filter != PictFilterBilinear) { intel_uxa_debug_fallback(scrn, "Unsupported filter 0x%x\n", picture->filter); return FALSE; } if (picture->pDrawable) { int w, h; w = picture->pDrawable->width; h = picture->pDrawable->height; if ((w > 2048) || (h > 2048)) { intel_uxa_debug_fallback(scrn, "Picture w/h too large (%dx%d)\n", w, h); return FALSE; } /* XXX we can use the xrgb32 types if there the picture covers the clip */ if (!i8xx_get_card_format(intel, picture)) { intel_uxa_debug_fallback(scrn, "Unsupported picture format " "0x%x\n", (int)picture->format); return FALSE; } return TRUE; } return FALSE; } Bool i830_prepare_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, PixmapPtr source, PixmapPtr mask, PixmapPtr dest) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ intel_uxa_get_pixmap_bo(source), mask ? intel_uxa_get_pixmap_bo(mask) : NULL, intel_uxa_get_pixmap_bo(dest), }; intel->render_source_picture = source_picture; intel->render_source = source; intel->render_mask_picture = mask_picture; intel->render_mask = mask; intel->render_dest_picture = dest_picture; intel->render_dest = dest; if (!intel_uxa_check_pitch_3d(source)) return FALSE; if (mask) { if (mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (i830_blend_op[op].src_alpha && (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) { intel_uxa_debug_fallback(scrn, "Component alpha not " "supported with source alpha and " "source value blending.\n"); return FALSE; } } if (!intel_uxa_check_pitch_3d(mask)) return FALSE; } if (!intel_uxa_check_pitch_3d(dest)) return FALSE; if (!i830_get_dest_format(dest_picture, &intel->render_dest_format)) return FALSE; if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) return FALSE; if (mask) { intel->transform[1] = NULL; intel->scale_units[1][0] = -1; intel->scale_units[1][1] = -1; } { uint32_t cblend, ablend, blendctl; /* If component alpha is active in the mask and the blend operation * uses the source alpha, then we know we don't need the source * value (otherwise we would have hit a fallback earlier), so we * provide the source alpha (src.A * mask.X) as output color. * Conversely, if CA is set and we don't need the source alpha, then * we produce the source value (src.X * mask.X) and the source alpha * is unused.. Otherwise, we provide the non-CA source value * (src.X * mask.A). * * The PICT_FORMAT_RGB(pict) == 0 fixups are not needed on 855+'s a8 * pictures, but we need to implement it for 830/845 and there's no * harm done in leaving it in. */ cblend = TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE | TB0C_OUTPUT_WRITE_CURRENT; ablend = TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE | TB0A_OUTPUT_WRITE_CURRENT; /* Get the source picture's channels into TBx_ARG1 */ if ((mask_picture != NULL && mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format) && i830_blend_op[op].src_alpha) || dest_picture->format == PICT_a8) { /* Producing source alpha value, so the first set of channels * is src.A instead of src.X. We also do this if the destination * is a8, in which case src.G is what's written, and the other * channels are ignored. */ ablend |= TB0A_ARG1_SEL_TEXEL0; cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA; } else { if (PICT_FORMAT_RGB(source_picture->format) != 0) cblend |= TB0C_ARG1_SEL_TEXEL0; else cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */ ablend |= TB0A_ARG1_SEL_TEXEL0; } if (mask) { cblend |= TB0C_ARG2_SEL_TEXEL1; if (dest_picture->format == PICT_a8 || ! mask_picture->componentAlpha || ! PICT_FORMAT_RGB(mask_picture->format)) cblend |= TB0C_ARG2_REPLICATE_ALPHA; ablend |= TB0A_ARG2_SEL_TEXEL1; } else { cblend |= TB0C_ARG2_SEL_ONE; ablend |= TB0A_ARG2_SEL_ONE; } if (!i830_get_blend_cntl (scrn, op, mask_picture, dest_picture->format, &blendctl)) { return FALSE; } intel->cblend = cblend; intel->ablend = ablend; intel->s8_blendctl = blendctl; } if (intel_uxa_pixmap_is_dirty(source) || intel_uxa_pixmap_is_dirty(mask)) intel_batch_emit_flush(scrn); intel->needs_render_state_emit = TRUE; return TRUE; } static void i830_emit_composite_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t vf2, tiling_bits; uint32_t texcoordfmt = 0; intel->needs_render_state_emit = FALSE; IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_RENDER; assert(intel->in_batch_atomic); if (intel_uxa_pixmap_tiled(intel->render_dest)) { tiling_bits = BUF_3D_TILED_SURFACE; if (intel_uxa_get_pixmap_private(intel->render_dest)->tiling == I915_TILING_Y) tiling_bits |= BUF_3D_TILE_WALK_Y; } else tiling_bits = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits | BUF_3D_PITCH(intel_pixmap_pitch(intel->render_dest))); OUT_RELOC_PIXMAP(intel->render_dest, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(intel->render_dest_format); OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(0); OUT_BATCH(0); /* ymin, xmin */ OUT_BATCH(DRAW_YMAX(intel->render_dest->drawable.height - 1) | DRAW_XMAX(intel->render_dest->drawable.width - 1)); OUT_BATCH(0); /* yorig, xorig */ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(3) | I1_LOAD_S(8) | 2); if (intel->render_mask) vf2 = 2 << 12; /* 2 texture coord sets */ else vf2 = 1 << 12; OUT_BATCH(vf2); /* number of coordinate sets */ OUT_BATCH(S3_CULLMODE_NONE | S3_VERTEXHAS_XY); OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD | intel-> s8_blendctl | S8_ENABLE_COLOR_BUFFER_WRITE); OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_BLEND_STAGE(0) | 1); OUT_BATCH(intel->cblend); OUT_BATCH(intel->ablend); OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP | DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS | DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST | ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST); /* We have to explicitly say we don't want write disabled */ OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK | DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE | DISABLE_DITHER | ENABLE_COLOR_WRITE | DISABLE_DEPTH_WRITE); if (intel_uxa_transform_is_affine(intel->render_source_picture->transform)) texcoordfmt |= (TEXCOORDFMT_2D << 0); else texcoordfmt |= (TEXCOORDFMT_3D << 0); if (intel->render_mask) { if (intel_uxa_transform_is_affine (intel->render_mask_picture->transform)) texcoordfmt |= (TEXCOORDFMT_2D << 2); else texcoordfmt |= (TEXCOORDFMT_3D << 2); } OUT_BATCH(_3DSTATE_VERTEX_FORMAT_2_CMD | texcoordfmt); i830_texture_setup(intel->render_source_picture, intel->render_source, 0); if (intel->render_mask) { i830_texture_setup(intel->render_mask_picture, intel->render_mask, 1); } } /* Emit the vertices for a single composite rectangle. * * This function is no longer shared between i830 and i915 generation code. */ static void i830_emit_composite_primitive(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); Bool is_affine_src, is_affine_mask = TRUE; int per_vertex; float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; per_vertex = 2; /* dest x/y */ { float x = srcX, y = srcY; is_affine_src = intel_uxa_transform_is_affine(intel->transform[0]); if (is_affine_src) { if (!intel_uxa_get_transformed_coordinates(x, y, intel-> transform[0], &src_x[0], &src_y[0])) return; if (!intel_uxa_get_transformed_coordinates(x, y + h, intel-> transform[0], &src_x[1], &src_y[1])) return; if (!intel_uxa_get_transformed_coordinates(x + w, y + h, intel-> transform[0], &src_x[2], &src_y[2])) return; per_vertex += 2; /* src x/y */ } else { if (!intel_uxa_get_transformed_coordinates_3d(x, y, intel-> transform[0], &src_x[0], &src_y[0], &src_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(x, y + h, intel-> transform[0], &src_x[1], &src_y[1], &src_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(x + w, y + h, intel-> transform[0], &src_x[2], &src_y[2], &src_w[2])) return; per_vertex += 3; /* src x/y/w */ } } if (intel->render_mask) { float x = maskX, y = maskY; is_affine_mask = intel_uxa_transform_is_affine(intel->transform[1]); if (is_affine_mask) { if (!intel_uxa_get_transformed_coordinates(x, y, intel-> transform[1], &mask_x[0], &mask_y[0])) return; if (!intel_uxa_get_transformed_coordinates(x, y + h, intel-> transform[1], &mask_x[1], &mask_y[1])) return; if (!intel_uxa_get_transformed_coordinates(x + w, y + h, intel-> transform[1], &mask_x[2], &mask_y[2])) return; per_vertex += 2; /* mask x/y */ } else { if (!intel_uxa_get_transformed_coordinates_3d(x, y, intel-> transform[1], &mask_x[0], &mask_y[0], &mask_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(x, y + h, intel-> transform[1], &mask_x[1], &mask_y[1], &mask_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(x + w, y + h, intel-> transform[1], &mask_x[2], &mask_y[2], &mask_w[2])) return; per_vertex += 3; /* mask x/y/w */ } } if (intel->vertex_count == 0) { intel->vertex_index = intel->batch_used; OUT_BATCH(PRIM3D_INLINE | PRIM3D_RECTLIST); } OUT_BATCH_F(dstX + w); OUT_BATCH_F(dstY + h); OUT_BATCH_F(src_x[2] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[2] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[2]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[2] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[2] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[2]); } } OUT_BATCH_F(dstX); OUT_BATCH_F(dstY + h); OUT_BATCH_F(src_x[1] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[1] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[1]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[1] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[1] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[1]); } } OUT_BATCH_F(dstX); OUT_BATCH_F(dstY); OUT_BATCH_F(src_x[0] / intel->scale_units[0][0]); OUT_BATCH_F(src_y[0] / intel->scale_units[0][1]); if (!is_affine_src) { OUT_BATCH_F(src_w[0]); } if (intel->render_mask) { OUT_BATCH_F(mask_x[0] / intel->scale_units[1][0]); OUT_BATCH_F(mask_y[0] / intel->scale_units[1][1]); if (!is_affine_mask) { OUT_BATCH_F(mask_w[0]); } } intel->vertex_count += 3 * per_vertex; } void i830_vertex_flush(intel_screen_private *intel) { if (intel->vertex_count) { intel->batch_ptr[intel->vertex_index] |= intel->vertex_count - 1; intel->vertex_count = 0; } } /** * Do a single rectangle composite operation. */ void i830_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); intel_batch_start_atomic(scrn, 58 + /* invarient */ 22 + /* setup */ 20 + /* 2 * setup_texture */ 1 + 30 /* verts */ ); if (intel->needs_render_state_emit) i830_emit_composite_state(scrn); i830_emit_composite_primitive(dest, srcX, srcY, maskX, maskY, dstX, dstY, w, h); intel_batch_end_atomic(scrn); } void i830_batch_commit_notify(intel_screen_private *intel) { intel->needs_render_state_emit = TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i915_3d.c000066400000000000000000000072311267532330400231030ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 "xorg-server.h" #include "xf86.h" #include "intel.h" #include "intel_uxa.h" #include "i915_reg.h" void I915EmitInvarientState(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(intel->in_batch_atomic); OUT_BATCH(_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 | AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); /* Disable independent alpha blend */ OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) | IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE << IAB_SRC_FACTOR_SHIFT) | IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO << IAB_DST_FACTOR_SHIFT)); OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); OUT_BATCH(0); OUT_BATCH(_3DSTATE_DFLT_Z_CMD); OUT_BATCH(0); /* Don't support texture crossbar yet */ OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | CSB_TCB(0, 0) | CSB_TCB(1, 1) | CSB_TCB(2, 2) | CSB_TCB(3, 3) | CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | ENABLE_POINT_RASTER_RULE | OGL_POINT_RASTER_RULE | ENABLE_LINE_STRIP_PROVOKE_VRTX | ENABLE_TRI_FAN_PROVOKE_VRTX | LINE_STRIP_PROVOKE_VRTX(1) | TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); OUT_BATCH(_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) | ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) | ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff)); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2); OUT_BATCH(0x00000000); /* Disable texture coordinate wrap-shortest */ OUT_BATCH((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE | S4_CULLMODE_NONE | S4_VFMT_XY); OUT_BATCH(0x00000000); /* Stencil. */ OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ OUT_BATCH(0); OUT_BATCH(_3DSTATE_STIPPLE); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i915_3d.h000066400000000000000000000552211267532330400231120ustar00rootroot00000000000000/* -*- c-basic-offset: 4 -*- */ /* * Copyright © 2006,2010 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * Chris Wilson * */ /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. */ #define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_TYPE_SHIFT 4 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* MASK_* are the unshifted bitmasks of the destination mask in arithmetic * operations */ #define MASK_X 0x1 #define MASK_Y 0x2 #define MASK_Z 0x4 #define MASK_W 0x8 #define MASK_XYZ (MASK_X | MASK_Y | MASK_Z) #define MASK_XYZW (MASK_XYZ | MASK_W) #define MASK_SATURATE 0x10 /* Temporary, undeclared regs. Preserved between phases */ #define FS_R0 ((REG_TYPE_R << REG_TYPE_SHIFT) | 0) #define FS_R1 ((REG_TYPE_R << REG_TYPE_SHIFT) | 1) #define FS_R2 ((REG_TYPE_R << REG_TYPE_SHIFT) | 2) #define FS_R3 ((REG_TYPE_R << REG_TYPE_SHIFT) | 3) /* Texture coordinate regs. Must be declared. */ #define FS_T0 ((REG_TYPE_T << REG_TYPE_SHIFT) | 0) #define FS_T1 ((REG_TYPE_T << REG_TYPE_SHIFT) | 1) #define FS_T2 ((REG_TYPE_T << REG_TYPE_SHIFT) | 2) #define FS_T3 ((REG_TYPE_T << REG_TYPE_SHIFT) | 3) #define FS_T4 ((REG_TYPE_T << REG_TYPE_SHIFT) | 4) #define FS_T5 ((REG_TYPE_T << REG_TYPE_SHIFT) | 5) #define FS_T6 ((REG_TYPE_T << REG_TYPE_SHIFT) | 6) #define FS_T7 ((REG_TYPE_T << REG_TYPE_SHIFT) | 7) #define FS_T8 ((REG_TYPE_T << REG_TYPE_SHIFT) | 8) #define FS_T9 ((REG_TYPE_T << REG_TYPE_SHIFT) | 9) #define FS_T10 ((REG_TYPE_T << REG_TYPE_SHIFT) | 10) /* Constant values */ #define FS_C0 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 0) #define FS_C1 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 1) #define FS_C2 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 2) #define FS_C3 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 3) #define FS_C4 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 4) #define FS_C5 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 5) #define FS_C6 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 6) #define FS_C7 ((REG_TYPE_CONST << REG_TYPE_SHIFT) | 7) /* Sampler regs */ #define FS_S0 ((REG_TYPE_S << REG_TYPE_SHIFT) | 0) #define FS_S1 ((REG_TYPE_S << REG_TYPE_SHIFT) | 1) #define FS_S2 ((REG_TYPE_S << REG_TYPE_SHIFT) | 2) #define FS_S3 ((REG_TYPE_S << REG_TYPE_SHIFT) | 3) /* Output color */ #define FS_OC ((REG_TYPE_OC << REG_TYPE_SHIFT) | 0) /* Output depth */ #define FS_OD ((REG_TYPE_OD << REG_TYPE_SHIFT) | 0) /* Unpreserved temporary regs */ #define FS_U0 ((REG_TYPE_U << REG_TYPE_SHIFT) | 0) #define FS_U1 ((REG_TYPE_U << REG_TYPE_SHIFT) | 1) #define FS_U2 ((REG_TYPE_U << REG_TYPE_SHIFT) | 2) #define FS_U3 ((REG_TYPE_U << REG_TYPE_SHIFT) | 3) #define X_CHANNEL_SHIFT (REG_TYPE_SHIFT + 3) #define Y_CHANNEL_SHIFT (X_CHANNEL_SHIFT + 4) #define Z_CHANNEL_SHIFT (Y_CHANNEL_SHIFT + 4) #define W_CHANNEL_SHIFT (Z_CHANNEL_SHIFT + 4) #define REG_CHANNEL_MASK 0xf #define REG_NR(reg) ((reg) & REG_NR_MASK) #define REG_TYPE(reg) (((reg) >> REG_TYPE_SHIFT) & REG_TYPE_MASK) #define REG_X(reg) (((reg) >> X_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_Y(reg) (((reg) >> Y_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_Z(reg) (((reg) >> Z_CHANNEL_SHIFT) & REG_CHANNEL_MASK) #define REG_W(reg) (((reg) >> W_CHANNEL_SHIFT) & REG_CHANNEL_MASK) enum i915_fs_channel { X_CHANNEL_VAL = 0, Y_CHANNEL_VAL, Z_CHANNEL_VAL, W_CHANNEL_VAL, ZERO_CHANNEL_VAL, ONE_CHANNEL_VAL, NEG_X_CHANNEL_VAL = X_CHANNEL_VAL | 0x8, NEG_Y_CHANNEL_VAL = Y_CHANNEL_VAL | 0x8, NEG_Z_CHANNEL_VAL = Z_CHANNEL_VAL | 0x8, NEG_W_CHANNEL_VAL = W_CHANNEL_VAL | 0x8, NEG_ONE_CHANNEL_VAL = ONE_CHANNEL_VAL | 0x8 }; #define i915_fs_operand(reg, x, y, z, w) \ (reg) | \ (x##_CHANNEL_VAL << X_CHANNEL_SHIFT) | \ (y##_CHANNEL_VAL << Y_CHANNEL_SHIFT) | \ (z##_CHANNEL_VAL << Z_CHANNEL_SHIFT) | \ (w##_CHANNEL_VAL << W_CHANNEL_SHIFT) /** * Construct an operand description for using a register with no swizzling */ #define i915_fs_operand_reg(reg) \ i915_fs_operand(reg, X, Y, Z, W) #define i915_fs_operand_reg_negate(reg) \ i915_fs_operand(reg, NEG_X, NEG_Y, NEG_Z, NEG_W) /** * Returns an operand containing (0.0, 0.0, 0.0, 0.0). */ #define i915_fs_operand_zero() i915_fs_operand(FS_R0, ZERO, ZERO, ZERO, ZERO) /** * Returns an unused operand */ #define i915_fs_operand_none() i915_fs_operand_zero() /** * Returns an operand containing (1.0, 1.0, 1.0, 1.0). */ #define i915_fs_operand_one() i915_fs_operand(FS_R0, ONE, ONE, ONE, ONE) #define i915_get_hardware_channel_val(val, shift, negate) \ (((val & 0x7) << shift) | ((val & 0x8) ? negate : 0)) /** * Outputs a fragment shader command to declare a sampler or texture register. */ #define i915_fs_dcl(reg) \ do { \ OUT_BATCH(D0_DCL | \ (REG_TYPE(reg) << D0_TYPE_SHIFT) | \ (REG_NR(reg) << D0_NR_SHIFT) | \ ((REG_TYPE(reg) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0)); \ OUT_BATCH(0); \ OUT_BATCH(0); \ } while (0) #define i915_fs_texld(dest_reg, sampler_reg, address_reg) \ do { \ OUT_BATCH(T0_TEXLD | \ (REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << T0_DEST_NR_SHIFT) | \ (REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT)); \ OUT_BATCH((REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT) | \ (REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT)); \ OUT_BATCH(0); \ } while (0) #define i915_fs_texldp(dest_reg, sampler_reg, address_reg) \ do { \ OUT_BATCH(T0_TEXLDP | \ (REG_TYPE(dest_reg) << T0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << T0_DEST_NR_SHIFT) | \ (REG_NR(sampler_reg) << T0_SAMPLER_NR_SHIFT)); \ OUT_BATCH((REG_TYPE(address_reg) << T1_ADDRESS_REG_TYPE_SHIFT) | \ (REG_NR(address_reg) << T1_ADDRESS_REG_NR_SHIFT)); \ OUT_BATCH(0); \ } while (0) #define i915_fs_arith_masked(op, dest_reg, dest_mask, operand0, operand1, operand2) \ _i915_fs_arith_masked(A0_##op, dest_reg, dest_mask, operand0, operand1, operand2) #define i915_fs_arith(op, dest_reg, operand0, operand1, operand2) \ _i915_fs_arith(A0_##op, dest_reg, operand0, operand1, operand2) #define _i915_fs_arith_masked(cmd, dest_reg, dest_mask, operand0, operand1, operand2) \ do { \ /* Set up destination register and write mask */ \ OUT_BATCH(cmd | \ (REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << A0_DEST_NR_SHIFT) | \ (((dest_mask) & ~MASK_SATURATE) << A0_DEST_CHANNEL_SHIFT) | \ (((dest_mask) & MASK_SATURATE) ? A0_DEST_SATURATE : 0) | \ /* Set up operand 0 */ \ (REG_TYPE(operand0) << A0_SRC0_TYPE_SHIFT) | \ (REG_NR(operand0) << A0_SRC0_NR_SHIFT)); \ OUT_BATCH(i915_get_hardware_channel_val(REG_X(operand0), \ A1_SRC0_CHANNEL_X_SHIFT, \ A1_SRC0_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand0), \ A1_SRC0_CHANNEL_Y_SHIFT, \ A1_SRC0_CHANNEL_Y_NEGATE) | \ i915_get_hardware_channel_val(REG_Z(operand0), \ A1_SRC0_CHANNEL_Z_SHIFT, \ A1_SRC0_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand0), \ A1_SRC0_CHANNEL_W_SHIFT, \ A1_SRC0_CHANNEL_W_NEGATE) | \ /* Set up operand 1 */ \ (REG_TYPE(operand1) << A1_SRC1_TYPE_SHIFT) | \ (REG_NR(operand1) << A1_SRC1_NR_SHIFT) | \ i915_get_hardware_channel_val(REG_X(operand1), \ A1_SRC1_CHANNEL_X_SHIFT, \ A1_SRC1_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand1), \ A1_SRC1_CHANNEL_Y_SHIFT, \ A1_SRC1_CHANNEL_Y_NEGATE)); \ OUT_BATCH(i915_get_hardware_channel_val(REG_Z(operand1), \ A2_SRC1_CHANNEL_Z_SHIFT, \ A2_SRC1_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand1), \ A2_SRC1_CHANNEL_W_SHIFT, \ A2_SRC1_CHANNEL_W_NEGATE) | \ /* Set up operand 2 */ \ (REG_TYPE(operand2) << A2_SRC2_TYPE_SHIFT) | \ (REG_NR(operand2) << A2_SRC2_NR_SHIFT) | \ i915_get_hardware_channel_val(REG_X(operand2), \ A2_SRC2_CHANNEL_X_SHIFT, \ A2_SRC2_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand2), \ A2_SRC2_CHANNEL_Y_SHIFT, \ A2_SRC2_CHANNEL_Y_NEGATE) | \ i915_get_hardware_channel_val(REG_Z(operand2), \ A2_SRC2_CHANNEL_Z_SHIFT, \ A2_SRC2_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand2), \ A2_SRC2_CHANNEL_W_SHIFT, \ A2_SRC2_CHANNEL_W_NEGATE)); \ } while (0) #define _i915_fs_arith(cmd, dest_reg, operand0, operand1, operand2) do {\ /* Set up destination register and write mask */ \ OUT_BATCH(cmd | \ (REG_TYPE(dest_reg) << A0_DEST_TYPE_SHIFT) | \ (REG_NR(dest_reg) << A0_DEST_NR_SHIFT) | \ (A0_DEST_CHANNEL_ALL) | \ /* Set up operand 0 */ \ (REG_TYPE(operand0) << A0_SRC0_TYPE_SHIFT) | \ (REG_NR(operand0) << A0_SRC0_NR_SHIFT)); \ OUT_BATCH(i915_get_hardware_channel_val(REG_X(operand0), \ A1_SRC0_CHANNEL_X_SHIFT, \ A1_SRC0_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand0), \ A1_SRC0_CHANNEL_Y_SHIFT, \ A1_SRC0_CHANNEL_Y_NEGATE) | \ i915_get_hardware_channel_val(REG_Z(operand0), \ A1_SRC0_CHANNEL_Z_SHIFT, \ A1_SRC0_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand0), \ A1_SRC0_CHANNEL_W_SHIFT, \ A1_SRC0_CHANNEL_W_NEGATE) | \ /* Set up operand 1 */ \ (REG_TYPE(operand1) << A1_SRC1_TYPE_SHIFT) | \ (REG_NR(operand1) << A1_SRC1_NR_SHIFT) | \ i915_get_hardware_channel_val(REG_X(operand1), \ A1_SRC1_CHANNEL_X_SHIFT, \ A1_SRC1_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand1), \ A1_SRC1_CHANNEL_Y_SHIFT, \ A1_SRC1_CHANNEL_Y_NEGATE)); \ OUT_BATCH(i915_get_hardware_channel_val(REG_Z(operand1), \ A2_SRC1_CHANNEL_Z_SHIFT, \ A2_SRC1_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand1), \ A2_SRC1_CHANNEL_W_SHIFT, \ A2_SRC1_CHANNEL_W_NEGATE) | \ /* Set up operand 2 */ \ (REG_TYPE(operand2) << A2_SRC2_TYPE_SHIFT) | \ (REG_NR(operand2) << A2_SRC2_NR_SHIFT) | \ i915_get_hardware_channel_val(REG_X(operand2), \ A2_SRC2_CHANNEL_X_SHIFT, \ A2_SRC2_CHANNEL_X_NEGATE) | \ i915_get_hardware_channel_val(REG_Y(operand2), \ A2_SRC2_CHANNEL_Y_SHIFT, \ A2_SRC2_CHANNEL_Y_NEGATE) | \ i915_get_hardware_channel_val(REG_Z(operand2), \ A2_SRC2_CHANNEL_Z_SHIFT, \ A2_SRC2_CHANNEL_Z_NEGATE) | \ i915_get_hardware_channel_val(REG_W(operand2), \ A2_SRC2_CHANNEL_W_SHIFT, \ A2_SRC2_CHANNEL_W_NEGATE)); \ } while (0) #define i915_fs_mov(dest_reg, operand0) \ i915_fs_arith(MOV, dest_reg, \ operand0, \ i915_fs_operand_none(), \ i915_fs_operand_none()) #define i915_fs_mov_masked(dest_reg, dest_mask, operand0) \ i915_fs_arith_masked (MOV, dest_reg, dest_mask, \ operand0, \ i915_fs_operand_none(), \ i915_fs_operand_none()) #define i915_fs_frc(dest_reg, operand0) \ i915_fs_arith (FRC, dest_reg, \ operand0, \ i915_fs_operand_none(), \ i915_fs_operand_none()) /** Add operand0 and operand1 and put the result in dest_reg */ #define i915_fs_add(dest_reg, operand0, operand1) \ i915_fs_arith (ADD, dest_reg, \ operand0, operand1, \ i915_fs_operand_none()) /** Multiply operand0 and operand1 and put the result in dest_reg */ #define i915_fs_mul(dest_reg, operand0, operand1) \ i915_fs_arith (MUL, dest_reg, \ operand0, operand1, \ i915_fs_operand_none()) /** Computes 1/sqrt(operand0.replicate_swizzle) puts the result in dest_reg */ #define i915_fs_rsq(dest_reg, dest_mask, operand0) \ do { \ if (dest_mask) { \ i915_fs_arith_masked (RSQ, dest_reg, dest_mask, \ operand0, \ i915_fs_operand_none (), \ i915_fs_operand_none ()); \ } else { \ i915_fs_arith (RSQ, dest_reg, \ operand0, \ i915_fs_operand_none (), \ i915_fs_operand_none ()); \ } \ } while (0) /** Puts the minimum of operand0 and operand1 in dest_reg */ #define i915_fs_min(dest_reg, operand0, operand1) \ i915_fs_arith (MIN, dest_reg, \ operand0, operand1, \ i915_fs_operand_none()) /** Puts the maximum of operand0 and operand1 in dest_reg */ #define i915_fs_max(dest_reg, operand0, operand1) \ i915_fs_arith (MAX, dest_reg, \ operand0, operand1, \ i915_fs_operand_none()) #define i915_fs_cmp(dest_reg, operand0, operand1, operand2) \ i915_fs_arith (CMP, dest_reg, operand0, operand1, operand2) /** Perform operand0 * operand1 + operand2 and put the result in dest_reg */ #define i915_fs_mad(dest_reg, dest_mask, op0, op1, op2) \ do { \ if (dest_mask) { \ i915_fs_arith_masked (MAD, dest_reg, dest_mask, op0, op1, op2); \ } else { \ i915_fs_arith (MAD, dest_reg, op0, op1, op2); \ } \ } while (0) #define i915_fs_dp2add(dest_reg, dest_mask, op0, op1, op2) \ do { \ if (dest_mask) { \ i915_fs_arith_masked (DP2ADD, dest_reg, dest_mask, op0, op1, op2); \ } else { \ i915_fs_arith (DP2ADD, dest_reg, op0, op1, op2); \ } \ } while (0) /** * Perform a 3-component dot-product of operand0 and operand1 and put the * resulting scalar in the channels of dest_reg specified by the dest_mask. */ #define i915_fs_dp3(dest_reg, dest_mask, op0, op1) \ do { \ if (dest_mask) { \ i915_fs_arith_masked (DP3, dest_reg, dest_mask, \ op0, op1,\ i915_fs_operand_none()); \ } else { \ i915_fs_arith (DP3, dest_reg, op0, op1,\ i915_fs_operand_none()); \ } \ } while (0) /** * Sets up local state for accumulating a fragment shader buffer. * * \param x maximum number of shader commands that may be used between * a FS_START and FS_END */ #define FS_LOCALS() \ uint32_t _shader_offset #define FS_BEGIN() \ do { \ _shader_offset = intel->batch_used++; \ } while (0) #define FS_END() \ do { \ intel->batch_ptr[_shader_offset] = \ _3DSTATE_PIXEL_SHADER_PROGRAM | \ (intel->batch_used - _shader_offset - 2); \ } while (0); xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i915_reg.h000066400000000000000000000776261267532330400233760ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 _I915_REG_H_ #define _I915_REG_H_ #define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) #define CMD_3D (0x3<<29) #define PRIM3D (CMD_3D | (0x1f<<24)) #define PRIM3D_INDIRECT_SEQUENTIAL ((1<<23) | (0<<17)) #define PRIM3D_TRILIST (PRIM3D | (0x0<<18)) #define PRIM3D_TRISTRIP (PRIM3D | (0x1<<18)) #define PRIM3D_TRISTRIP_RVRSE (PRIM3D | (0x2<<18)) #define PRIM3D_TRIFAN (PRIM3D | (0x3<<18)) #define PRIM3D_POLY (PRIM3D | (0x4<<18)) #define PRIM3D_LINELIST (PRIM3D | (0x5<<18)) #define PRIM3D_LINESTRIP (PRIM3D | (0x6<<18)) #define PRIM3D_RECTLIST (PRIM3D | (0x7<<18)) #define PRIM3D_POINTLIST (PRIM3D | (0x8<<18)) #define PRIM3D_DIB (PRIM3D | (0x9<<18)) #define PRIM3D_CLEAR_RECT (PRIM3D | (0xa<<18)) #define PRIM3D_ZONE_INIT (PRIM3D | (0xd<<18)) #define PRIM3D_MASK (0x1f<<18) /* p137 */ #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) /* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ #define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) #define BFO_ENABLE_STENCIL_REF (1<<23) #define BFO_STENCIL_REF_SHIFT 15 #define BFO_STENCIL_REF_MASK (0xff<<15) #define BFO_ENABLE_STENCIL_FUNCS (1<<14) #define BFO_STENCIL_TEST_SHIFT 11 #define BFO_STENCIL_TEST_MASK (0x7<<11) #define BFO_STENCIL_FAIL_SHIFT 8 #define BFO_STENCIL_FAIL_MASK (0x7<<8) #define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 #define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) #define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 #define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) #define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) #define BFO_STENCIL_TWO_SIDE (1<<0) /* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ #define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) #define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) #define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) #define BFM_STENCIL_TEST_MASK_SHIFT 8 #define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) #define BFM_STENCIL_WRITE_MASK_SHIFT 0 #define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) /* 3DSTATE_BIN_CONTROL p141 */ /* p143 */ #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) #define BUF_3D_PITCH(x) (((x)/4)<<2) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) /* 3DSTATE_CHROMA_KEY */ /* 3DSTATE_CLEAR_PARAMETERS, p150 */ #define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) /* Dword 1 */ #define CLEARPARAM_CLEAR_RECT (1 << 16) #define CLEARPARAM_ZONE_INIT (0 << 16) #define CLEARPARAM_WRITE_COLOR (1 << 2) #define CLEARPARAM_WRITE_DEPTH (1 << 1) #define CLEARPARAM_WRITE_STENCIL (1 << 0) /* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) /* 3DSTATE_COORD_SET_BINDINGS, p154 */ #define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) #define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) /* p156 */ #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) /* p157 */ #define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) /* p158 */ #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) /* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ #define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) /* scale in dword 1 */ /* The depth subrectangle is not supported, but must be disabled. */ /* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ #define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | (1 << 1) | (0 << 0)) /* p161 */ #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define TEX_DEFAULT_COLOR_OGL (0<<30) #define TEX_DEFAULT_COLOR_D3D (1<<30) #define ZR_EARLY_DEPTH (1<<29) #define LOD_PRECLAMP_OGL (1<<28) #define LOD_PRECLAMP_D3D (0<<28) #define DITHER_FULL_ALWAYS (0<<26) #define DITHER_FULL_ON_FB_BLEND (1<<26) #define DITHER_CLAMPED_ALWAYS (2<<26) #define LINEAR_GAMMA_BLEND_32BPP (1<<25) #define DEBUG_DISABLE_ENH_DITHER (1<<24) #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define COLR_BUF_ARGB2AAA (0xa<<8) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 (0<<1) #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 /* p166 */ #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((x)<<16) #define DRAW_XMIN(x) (x) /* Dword 3 */ #define DRAW_YMAX(x) ((x)<<16) #define DRAW_XMAX(x) (x) /* Dword 4 */ #define DRAW_YORG(x) ((x)<<16) #define DRAW_XORG(x) (x) /* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ /* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ /* _3DSTATE_FOG_COLOR, p173 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p174 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) #define FMC1_FOGFUNC_VERTEX (0<<28) #define FMC1_FOGFUNC_PIXEL_EXP (1<<28) #define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) #define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) #define FMC1_FOGFUNC_MASK (3<<28) #define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) #define FMC1_FOGINDEX_Z (0<<25) #define FMC1_FOGINDEX_W (1<<25) #define FMC1_C1_C2_MODIFY_ENABLE (1<<24) #define FMC1_DENSITY_MODIFY_ENABLE (1<<23) #define FMC1_C1_ONE (1<<13) #define FMC1_C1_MASK (0xffff<<4) /* Dword 2 */ #define FMC2_C2_ONE (1<<16) /* Dword 3 */ #define FMC3_D_ONE (1<<16) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ #define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define IAB_MODIFY_ENABLE (1<<23) #define IAB_ENABLE (1<<22) #define IAB_MODIFY_FUNC (1<<21) #define IAB_FUNC_SHIFT 16 #define IAB_MODIFY_SRC_FACTOR (1<<11) #define IAB_SRC_FACTOR_SHIFT 6 #define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) #define IAB_MODIFY_DST_FACTOR (1<<5) #define IAB_DST_FACTOR_SHIFT 0 #define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) #define BLENDFACT_ZERO 0x01 #define BLENDFACT_ONE 0x02 #define BLENDFACT_SRC_COLR 0x03 #define BLENDFACT_INV_SRC_COLR 0x04 #define BLENDFACT_SRC_ALPHA 0x05 #define BLENDFACT_INV_SRC_ALPHA 0x06 #define BLENDFACT_DST_ALPHA 0x07 #define BLENDFACT_INV_DST_ALPHA 0x08 #define BLENDFACT_DST_COLR 0x09 #define BLENDFACT_INV_DST_COLR 0x0a #define BLENDFACT_SRC_ALPHA_SATURATE 0x0b #define BLENDFACT_CONST_COLOR 0x0c #define BLENDFACT_INV_CONST_COLOR 0x0d #define BLENDFACT_CONST_ALPHA 0x0e #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f #define BLENDFUNC_ADD 0x0 #define BLENDFUNC_SUBTRACT 0x1 #define BLENDFUNC_REVERSE_SUBTRACT 0x2 #define BLENDFUNC_MIN 0x3 #define BLENDFUNC_MAX 0x4 #define BLENDFUNC_MASK 0x7 /* 3DSTATE_LOAD_INDIRECT, p180 */ #define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) #define LI0_STATE_STATIC_INDIRECT (0x01<<8) #define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) #define LI0_STATE_SAMPLER (0x04<<8) #define LI0_STATE_MAP (0x08<<8) #define LI0_STATE_PROGRAM (0x10<<8) #define LI0_STATE_CONSTANTS (0x20<<8) #define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SIS0_FORCE_LOAD (1<<1) #define SIS0_BUFFER_VALID (1<<0) #define SIS1_BUFFER_LENGTH(x) ((x)&0xff) #define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define DIS0_BUFFER_RESET (1<<1) #define DIS0_BUFFER_VALID (1<<0) #define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SSB0_FORCE_LOAD (1<<1) #define SSB0_BUFFER_VALID (1<<0) #define SSB1_BUFFER_LENGTH(x) ((x)&0xff) #define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define MSB0_FORCE_LOAD (1<<1) #define MSB0_BUFFER_VALID (1<<0) #define MSB1_BUFFER_LENGTH(x) ((x)&0xff) #define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSP0_FORCE_LOAD (1<<1) #define PSP0_BUFFER_VALID (1<<0) #define PSP1_BUFFER_LENGTH(x) ((x)&0xff) #define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSC0_FORCE_LOAD (1<<1) #define PSC0_BUFFER_VALID (1<<0) #define PSC1_BUFFER_LENGTH(x) ((x)&0xff) /* _3DSTATE_RASTERIZATION_RULES */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_TEXKILL_3D_4D (1<<10) #define TEXKILL_3D (0<<9) #define TEXKILL_4D (1<<9) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) /* _3DSTATE_SCISSOR_ENABLE, p256 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* p189 */ #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<(4+n)) #define S0_VB_OFFSET_MASK 0xffffffc #define S0_AUTO_CACHE_INV_DISABLE (1<<0) #define S1_VERTEX_WIDTH_SHIFT 24 #define S1_VERTEX_WIDTH_MASK (0x3f<<24) #define S1_VERTEX_PITCH_SHIFT 16 #define S1_VERTEX_PITCH_MASK (0x3f<<16) #define TEXCOORDFMT_2D 0x0 #define TEXCOORDFMT_3D 0x1 #define TEXCOORDFMT_4D 0x2 #define TEXCOORDFMT_1D 0x3 #define TEXCOORDFMT_2D_16 0x4 #define TEXCOORDFMT_4D_16 0x5 #define TEXCOORDFMT_NOT_PRESENT 0xf #define S2_TEXCOORD_FMT0_MASK 0xf #define S2_TEXCOORD_FMT1_SHIFT 4 #define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) #define S2_TEXCOORD_NONE (~0) #define TEXCOORD_WRAP_SHORTEST_TCX 8 #define TEXCOORD_WRAP_SHORTEST_TCY 4 #define TEXCOORD_WRAP_SHORTEST_TCZ 2 #define TEXCOORD_PERSPECTIVE_DISABLE 1 #define S3_WRAP_SHORTEST_TCX(unit) (TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCY(unit) (TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCZ(unit) (TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4)) #define S3_PERSPECTIVE_DISABLE(unit) (TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4)) /* S3 not interesting */ #define S4_POINT_WIDTH_SHIFT 23 #define S4_POINT_WIDTH_MASK (0x1ff<<23) #define S4_LINE_WIDTH_SHIFT 19 #define S4_LINE_WIDTH_ONE (0x2<<19) #define S4_LINE_WIDTH_MASK (0xf<<19) #define S4_FLATSHADE_ALPHA (1<<18) #define S4_FLATSHADE_FOG (1<<17) #define S4_FLATSHADE_SPECULAR (1<<16) #define S4_FLATSHADE_COLOR (1<<15) #define S4_CULLMODE_BOTH (0<<13) #define S4_CULLMODE_NONE (1<<13) #define S4_CULLMODE_CW (2<<13) #define S4_CULLMODE_CCW (3<<13) #define S4_CULLMODE_MASK (3<<13) #define S4_VFMT_POINT_WIDTH (1<<12) #define S4_VFMT_SPEC_FOG (1<<11) #define S4_VFMT_COLOR (1<<10) #define S4_VFMT_DEPTH_OFFSET (1<<9) #define S4_VFMT_XYZ (1<<6) #define S4_VFMT_XYZW (2<<6) #define S4_VFMT_XY (3<<6) #define S4_VFMT_XYW (4<<6) #define S4_VFMT_XYZW_MASK (7<<6) #define S4_FORCE_DEFAULT_DIFFUSE (1<<5) #define S4_FORCE_DEFAULT_SPECULAR (1<<4) #define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) #define S4_VFMT_FOG_PARAM (1<<2) #define S4_SPRITE_POINT_ENABLE (1<<1) #define S4_LINE_ANTIALIAS_ENABLE (1<<0) #define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ S4_VFMT_SPEC_FOG | \ S4_VFMT_COLOR | \ S4_VFMT_DEPTH_OFFSET | \ S4_VFMT_XYZW_MASK | \ S4_VFMT_FOG_PARAM) #define S5_WRITEDISABLE_ALPHA (1<<31) #define S5_WRITEDISABLE_RED (1<<30) #define S5_WRITEDISABLE_GREEN (1<<29) #define S5_WRITEDISABLE_BLUE (1<<28) #define S5_WRITEDISABLE_MASK (0xf<<28) #define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) #define S5_LAST_PIXEL_ENABLE (1<<26) #define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) #define S5_FOG_ENABLE (1<<24) #define S5_STENCIL_REF_SHIFT 16 #define S5_STENCIL_REF_MASK (0xff<<16) #define S5_STENCIL_TEST_FUNC_SHIFT 13 #define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) #define S5_STENCIL_FAIL_SHIFT 10 #define S5_STENCIL_FAIL_MASK (0x7<<10) #define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 #define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) #define S5_STENCIL_PASS_Z_PASS_SHIFT 4 #define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) #define S5_STENCIL_WRITE_ENABLE (1<<3) #define S5_STENCIL_TEST_ENABLE (1<<2) #define S5_COLOR_DITHER_ENABLE (1<<1) #define S5_LOGICOP_ENABLE (1<<0) #define S6_ALPHA_TEST_ENABLE (1<<31) #define S6_ALPHA_TEST_FUNC_SHIFT 28 #define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) #define S6_ALPHA_REF_SHIFT 20 #define S6_ALPHA_REF_MASK (0xff<<20) #define S6_DEPTH_TEST_ENABLE (1<<19) #define S6_DEPTH_TEST_FUNC_SHIFT 16 #define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) #define S6_CBUF_BLEND_ENABLE (1<<15) #define S6_CBUF_BLEND_FUNC_SHIFT 12 #define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) #define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 #define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) #define S6_CBUF_DST_BLEND_FACT_SHIFT 4 #define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) #define S6_DEPTH_WRITE_ENABLE (1<<3) #define S6_COLOR_WRITE_ENABLE (1<<2) #define S6_TRISTRIP_PV_SHIFT 0 #define S6_TRISTRIP_PV_MASK (0x3<<0) #define S7_DEPTH_OFFSET_CONST_MASK ~0 /* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ /* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ /* _3DSTATE_MODES_4, p218 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK (0xf<<18) #define LOGICOP_COPY 0xc #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p220 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define PIPELINE_FLUSH_RENDER_CACHE (1<<18) #define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) /* p221 */ #define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) #define PS1_REG(n) (1<<(n)) #define PS2_CONST_X(n) (n) #define PS3_CONST_Y(n) (n) #define PS4_CONST_Z(n) (n) #define PS5_CONST_W(n) (n) /* p222 */ #define I915_MAX_TEX_INDIRECT 4 #define I915_MAX_TEX_INSN 32 #define I915_MAX_ALU_INSN 64 #define I915_MAX_DECL_INSN 27 #define I915_MAX_TEMPORARY 16 /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. */ #define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* p207. * The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK */ #define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) #define MS1_MAPMASK_SHIFT 0 #define MS1_MAPMASK_MASK (0x8fff<<0) #define MS2_UNTRUSTED_SURFACE (1<<31) #define MS2_ADDRESS_MASK 0xfffffffc #define MS2_VERTICAL_LINE_STRIDE (1<<1) #define MS2_VERTICAL_OFFSET (1<<1) #define MS3_HEIGHT_SHIFT 21 #define MS3_WIDTH_SHIFT 10 #define MS3_PALETTE_SELECT (1<<9) #define MS3_MAPSURF_FORMAT_SHIFT 7 #define MS3_MAPSURF_FORMAT_MASK (0x7<<7) #define MAPSURF_8BIT (1<<7) #define MAPSURF_16BIT (2<<7) #define MAPSURF_32BIT (3<<7) #define MAPSURF_422 (5<<7) #define MAPSURF_COMPRESSED (6<<7) #define MAPSURF_4BIT_INDEXED (7<<7) #define MS3_MT_FORMAT_MASK (0x7 << 3) #define MS3_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_8BIT_MONO8 (5<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_I16 (7<<3) #define MT_16BIT_L16 (8<<3) #define MT_16BIT_A16 (9<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_QWVU8888 (4<<3) #define MT_32BIT_AXVU8888 (5<<3) #define MT_32BIT_LXVU8888 (6<<3) #define MT_32BIT_XLVU8888 (7<<3) #define MT_32BIT_ARGB2101010 (8<<3) #define MT_32BIT_ABGR2101010 (9<<3) #define MT_32BIT_AWVU2101010 (0xA<<3) #define MT_32BIT_GR1616 (0xB<<3) #define MT_32BIT_VU1616 (0xC<<3) #define MT_32BIT_xI824 (0xD<<3) #define MT_32BIT_xA824 (0xE<<3) #define MT_32BIT_xL824 (0xF<<3) #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define MT_COMPRESS_DXT1_RGB (4<<3) #define MS3_USE_FENCE_REGS (1<<2) #define MS3_TILED_SURFACE (1<<1) #define MS3_TILE_WALK (1<<0) /* The pitch is the pitch measured in DWORDS, minus 1 */ #define MS4_PITCH_SHIFT 21 #define MS4_CUBE_FACE_ENA_NEGX (1<<20) #define MS4_CUBE_FACE_ENA_POSX (1<<19) #define MS4_CUBE_FACE_ENA_NEGY (1<<18) #define MS4_CUBE_FACE_ENA_POSY (1<<17) #define MS4_CUBE_FACE_ENA_NEGZ (1<<16) #define MS4_CUBE_FACE_ENA_POSZ (1<<15) #define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) #define MS4_MAX_LOD_SHIFT 9 #define MS4_MAX_LOD_MASK (0x3f<<9) #define MS4_MIP_LAYOUT_LEGACY (0<<8) #define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) #define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) #define MS4_VOLUME_DEPTH_SHIFT 0 #define MS4_VOLUME_DEPTH_MASK (0xff<<0) /* p244. * The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK. */ #define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) #define SS1_MAPMASK_SHIFT 0 #define SS1_MAPMASK_MASK (0x8fff<<0) #define SS2_REVERSE_GAMMA_ENABLE (1<<31) #define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) #define SS2_COLORSPACE_CONVERSION (1<<29) #define SS2_CHROMAKEY_SHIFT 27 #define SS2_BASE_MIP_LEVEL_SHIFT 22 #define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) #define SS2_MIP_FILTER_SHIFT 20 #define SS2_MIP_FILTER_MASK (0x3<<20) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define SS2_MAG_FILTER_SHIFT 17 #define SS2_MAG_FILTER_MASK (0x7<<17) #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define FILTER_4X4_1 3 #define FILTER_4X4_2 4 #define FILTER_4X4_FLAT 5 #define FILTER_6X5_MONO 6 /* XXX - check */ #define SS2_MIN_FILTER_SHIFT 14 #define SS2_MIN_FILTER_MASK (0x7<<14) #define SS2_LOD_BIAS_SHIFT 5 #define SS2_LOD_BIAS_ONE (0x10<<5) #define SS2_LOD_BIAS_MASK (0x1ff<<5) /* Shadow requires: * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format * FILTER_4X4_x MIN and MAG filters */ #define SS2_SHADOW_ENABLE (1<<4) #define SS2_MAX_ANISO_MASK (1<<3) #define SS2_MAX_ANISO_2 (0<<3) #define SS2_MAX_ANISO_4 (1<<3) #define SS2_SHADOW_FUNC_SHIFT 0 #define SS2_SHADOW_FUNC_MASK (0x7<<0) /* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ #define SS3_MIN_LOD_SHIFT 24 #define SS3_MIN_LOD_ONE (0x10<<24) #define SS3_MIN_LOD_MASK (0xff<<24) #define SS3_KILL_PIXEL_ENABLE (1<<17) #define SS3_TCX_ADDR_MODE_SHIFT 12 #define SS3_TCX_ADDR_MODE_MASK (0x7<<12) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP_EDGE 2 #define TEXCOORDMODE_CUBE 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORDMODE_MIRROR_ONCE 5 #define SS3_TCY_ADDR_MODE_SHIFT 9 #define SS3_TCY_ADDR_MODE_MASK (0x7<<9) #define SS3_TCZ_ADDR_MODE_SHIFT 6 #define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) #define SS3_NORMALIZED_COORDS (1<<5) #define SS3_TEXTUREMAP_INDEX_SHIFT 1 #define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) #define SS3_DEINTERLACER_ENABLE (1<<0) #define SS4_BORDER_COLOR_MASK (~0) /* 3DSTATE_SPAN_STIPPLE, p258 */ #define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define FLUSH_MAP_CACHE (1<<0) #define FLUSH_RENDER_CACHE (1<<1) #endif xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i915_render.c000066400000000000000000000702561267532330400240630ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "intel.h" #include "intel_uxa.h" #include "i915_reg.h" #include "i915_3d.h" struct formatinfo { int fmt; uint32_t card_fmt; }; struct blendinfo { Bool dst_alpha; Bool src_alpha; uint32_t src_blend; uint32_t dst_blend; }; static struct blendinfo i915_blend_op[] = { /* Clear */ {0, 0, BLENDFACT_ZERO, BLENDFACT_ZERO}, /* Src */ {0, 0, BLENDFACT_ONE, BLENDFACT_ZERO}, /* Dst */ {0, 0, BLENDFACT_ZERO, BLENDFACT_ONE}, /* Over */ {0, 1, BLENDFACT_ONE, BLENDFACT_INV_SRC_ALPHA}, /* OverReverse */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ONE}, /* In */ {1, 0, BLENDFACT_DST_ALPHA, BLENDFACT_ZERO}, /* InReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_SRC_ALPHA}, /* Out */ {1, 0, BLENDFACT_INV_DST_ALPHA, BLENDFACT_ZERO}, /* OutReverse */ {0, 1, BLENDFACT_ZERO, BLENDFACT_INV_SRC_ALPHA}, /* Atop */ {1, 1, BLENDFACT_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA}, /* AtopReverse */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_SRC_ALPHA}, /* Xor */ {1, 1, BLENDFACT_INV_DST_ALPHA, BLENDFACT_INV_SRC_ALPHA}, /* Add */ {0, 0, BLENDFACT_ONE, BLENDFACT_ONE}, }; static struct formatinfo i915_tex_formats[] = { {PICT_a8, MAPSURF_8BIT | MT_8BIT_A8}, {PICT_a8r8g8b8, MAPSURF_32BIT | MT_32BIT_ARGB8888}, {PICT_x8r8g8b8, MAPSURF_32BIT | MT_32BIT_XRGB8888}, {PICT_a8b8g8r8, MAPSURF_32BIT | MT_32BIT_ABGR8888}, {PICT_x8b8g8r8, MAPSURF_32BIT | MT_32BIT_XBGR8888}, #if XORG_VERSION_CURRENT >= 10699900 {PICT_a2r10g10b10, MAPSURF_32BIT | MT_32BIT_ARGB2101010}, {PICT_a2b10g10r10, MAPSURF_32BIT | MT_32BIT_ABGR2101010}, #endif {PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565}, {PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555}, {PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444}, }; static uint32_t i915_get_blend_cntl(int op, PicturePtr mask, uint32_t dst_format) { uint32_t sblend, dblend; sblend = i915_blend_op[op].src_blend; dblend = i915_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll * treat it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0 && i915_blend_op[op].dst_alpha) { if (sblend == BLENDFACT_DST_ALPHA) sblend = BLENDFACT_ONE; else if (sblend == BLENDFACT_INV_DST_ALPHA) sblend = BLENDFACT_ZERO; } /* i915 engine reads 8bit color buffer into green channel in cases like color buffer blending .etc, and also writes back green channel. So with dst_alpha blend we should use color factor. See spec on "8-bit rendering" */ if ((dst_format == PICT_a8) && i915_blend_op[op].dst_alpha) { if (sblend == BLENDFACT_DST_ALPHA) sblend = BLENDFACT_DST_COLR; else if (sblend == BLENDFACT_INV_DST_ALPHA) sblend = BLENDFACT_INV_DST_COLR; } /* If the source alpha is being used, then we should only be in a case * where the source blend factor is 0, and the source blend value is the * mask channels multiplied by the source picture's alpha. */ if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) && i915_blend_op[op].src_alpha) { if (dblend == BLENDFACT_SRC_ALPHA) { dblend = BLENDFACT_SRC_COLR; } else if (dblend == BLENDFACT_INV_SRC_ALPHA) { dblend = BLENDFACT_INV_SRC_COLR; } } return S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE | (BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT) | (sblend << S6_CBUF_SRC_BLEND_FACT_SHIFT) | (dblend << S6_CBUF_DST_BLEND_FACT_SHIFT); } #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format) { ScrnInfoPtr scrn; switch (dest_picture->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: *dst_format = COLR_BUF_ARGB8888; break; case PICT_r5g6b5: *dst_format = COLR_BUF_RGB565; break; case PICT_a1r5g5b5: case PICT_x1r5g5b5: *dst_format = COLR_BUF_ARGB1555; break; #if XORG_VERSION_CURRENT >= 10699900 case PICT_a2r10g10b10: case PICT_x2r10g10b10: *dst_format = COLR_BUF_ARGB2AAA; break; #endif case PICT_a8: *dst_format = COLR_BUF_8BIT; break; case PICT_a4r4g4b4: case PICT_x4r4g4b4: *dst_format = COLR_BUF_ARGB4444; break; default: scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); intel_uxa_debug_fallback(scrn, "Unsupported dest format 0x%x\n", (int)dest_picture->format); return FALSE; } *dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8); return TRUE; } Bool i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, int width, int height) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); uint32_t tmp1; /* Check for unsupported compositing operations. */ if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) { intel_uxa_debug_fallback(scrn, "Unsupported Composite op 0x%x\n", op); return FALSE; } if (mask_picture != NULL && mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha * and on the source value. We can only get one of those * into the single source value that we get to blend with. */ if (i915_blend_op[op].src_alpha && (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) { if (op != PictOpOver) { intel_uxa_debug_fallback(scrn, "Component alpha not supported " "with source alpha and source " "value blending.\n"); return FALSE; } } } if (!i915_get_dest_format(dest_picture, &tmp1)) { intel_uxa_debug_fallback(scrn, "Get Color buffer format\n"); return FALSE; } if (width > 2048 || height > 2048) return FALSE; return TRUE; } Bool i915_check_composite_target(PixmapPtr pixmap) { if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048) return FALSE; if(!intel_uxa_check_pitch_3d(pixmap)) return FALSE; return TRUE; } Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture) { if (picture->repeatType > RepeatReflect) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Unsupported picture repeat %d\n", picture->repeatType); return FALSE; } if (picture->filter != PictFilterNearest && picture->filter != PictFilterBilinear) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Unsupported filter 0x%x\n", picture->filter); return FALSE; } if (picture->pSourcePict) return FALSE; if (picture->pDrawable) { int w, h, i; w = picture->pDrawable->width; h = picture->pDrawable->height; if ((w > 2048) || (h > 2048)) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Picture w/h too large (%dx%d)\n", w, h); return FALSE; } for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]); i++) { if (i915_tex_formats[i].fmt == picture->format) break; } if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Unsupported picture format " "0x%x\n", (int)picture->format); return FALSE; } return TRUE; } return FALSE; } static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit) { ScrnInfoPtr scrn = xf86ScreenToScrn(picture->pDrawable->pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, pitch, filter; uint32_t wrap_mode, tiling_bits; int i; pitch = intel_pixmap_pitch(pixmap); intel->scale_units[unit][0] = 1. / pixmap->drawable.width; intel->scale_units[unit][1] = 1. / pixmap->drawable.height; for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]); i++) { if (i915_tex_formats[i].fmt == picture->format) break; } if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) { intel_uxa_debug_fallback(scrn, "unknown texture format\n"); return FALSE; } format = i915_tex_formats[i].card_fmt; switch (picture->repeatType) { case RepeatNone: wrap_mode = TEXCOORDMODE_CLAMP_BORDER; break; case RepeatNormal: wrap_mode = TEXCOORDMODE_WRAP; break; case RepeatPad: wrap_mode = TEXCOORDMODE_CLAMP_EDGE; break; case RepeatReflect: wrap_mode = TEXCOORDMODE_MIRROR; break; default: FatalError("Unknown repeat type %d\n", picture->repeatType); } switch (picture->filter) { case PictFilterNearest: filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) | (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT); break; case PictFilterBilinear: filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT); break; default: intel_uxa_debug_fallback(scrn, "Bad filter 0x%x\n", picture->filter); return FALSE; } /* offset filled in at emit time */ if (intel_uxa_pixmap_tiled(pixmap)) { tiling_bits = MS3_TILED_SURFACE; if (intel_uxa_get_pixmap_private(pixmap)->tiling == I915_TILING_Y) tiling_bits |= MS3_TILE_WALK; } else tiling_bits = 0; intel->texture[unit] = pixmap; intel->mapstate[unit * 3 + 0] = 0; intel->mapstate[unit * 3 + 1] = format | tiling_bits | ((pixmap->drawable.height - 1) << MS3_HEIGHT_SHIFT) | ((pixmap->drawable.width - 1) << MS3_WIDTH_SHIFT); intel->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT; intel->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT); intel->samplerstate[unit * 3 + 0] |= filter; intel->samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS; intel->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCX_ADDR_MODE_SHIFT; intel->samplerstate[unit * 3 + 1] |= wrap_mode << SS3_TCY_ADDR_MODE_SHIFT; intel->samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT; intel->samplerstate[unit * 3 + 2] = 0x00000000; /* border color */ intel->transform[unit] = picture->transform; return TRUE; } static void i915_emit_composite_primitive_identity_source(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX((srcX + w) * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX(srcY * intel->scale_units[0][1]); } static void i915_emit_composite_primitive_affine_source(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { float src_x[3], src_y[3]; if (!intel_uxa_get_transformed_coordinates(srcX, srcY, intel->transform[0], &src_x[0], &src_y[0])) return; if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h, intel->transform[0], &src_x[1], &src_y[1])) return; if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h, intel->transform[0], &src_x[2], &src_y[2])) return; OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[2] * intel->scale_units[0][0]); OUT_VERTEX(src_y[2] * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[1] * intel->scale_units[0][0]); OUT_VERTEX(src_y[1] * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(src_x[0] * intel->scale_units[0][0]); OUT_VERTEX(src_y[0] * intel->scale_units[0][1]); } static void i915_emit_composite_primitive_identity_source_mask(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX((srcX + w) * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX((maskX + w) * intel->scale_units[1][0]); OUT_VERTEX((maskY + h) * intel->scale_units[1][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(maskX * intel->scale_units[1][0]); OUT_VERTEX((maskY + h) * intel->scale_units[1][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX(srcY * intel->scale_units[0][1]); OUT_VERTEX(maskX * intel->scale_units[1][0]); OUT_VERTEX(maskY * intel->scale_units[1][1]); } static void i915_emit_composite_primitive(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { Bool is_affine_src = TRUE, is_affine_mask = TRUE; int tex_unit = 0; int src_unit = -1, mask_unit = -1; float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; src_unit = tex_unit++; is_affine_src = intel_uxa_transform_is_affine(intel->transform[src_unit]); if (is_affine_src) { if (!intel_uxa_get_transformed_coordinates(srcX, srcY, intel-> transform[src_unit], &src_x[0], &src_y[0])) return; if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h, intel-> transform[src_unit], &src_x[1], &src_y[1])) return; if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h, intel-> transform[src_unit], &src_x[2], &src_y[2])) return; } else { if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY, intel-> transform[src_unit], &src_x[0], &src_y[0], &src_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY + h, intel-> transform[src_unit], &src_x[1], &src_y[1], &src_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(srcX + w, srcY + h, intel-> transform[src_unit], &src_x[2], &src_y[2], &src_w[2])) return; } if (intel->render_mask) { mask_unit = tex_unit++; is_affine_mask = intel_uxa_transform_is_affine(intel->transform[mask_unit]); if (is_affine_mask) { if (!intel_uxa_get_transformed_coordinates(maskX, maskY, intel-> transform[mask_unit], &mask_x[0], &mask_y[0])) return; if (!intel_uxa_get_transformed_coordinates(maskX, maskY + h, intel-> transform[mask_unit], &mask_x[1], &mask_y[1])) return; if (!intel_uxa_get_transformed_coordinates(maskX + w, maskY + h, intel-> transform[mask_unit], &mask_x[2], &mask_y[2])) return; } else { if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY, intel-> transform[mask_unit], &mask_x[0], &mask_y[0], &mask_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY + h, intel-> transform[mask_unit], &mask_x[1], &mask_y[1], &mask_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(maskX + w, maskY + h, intel-> transform[mask_unit], &mask_x[2], &mask_y[2], &mask_w[2])) return; } } OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[2] * intel->scale_units[src_unit][0]); OUT_VERTEX(src_y[2] * intel->scale_units[src_unit][1]); if (!is_affine_src) { OUT_VERTEX(0.0); OUT_VERTEX(src_w[2]); } if (intel->render_mask) { OUT_VERTEX(mask_x[2] * intel->scale_units[mask_unit][0]); OUT_VERTEX(mask_y[2] * intel->scale_units[mask_unit][1]); if (!is_affine_mask) { OUT_VERTEX(0.0); OUT_VERTEX(mask_w[2]); } } OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[1] * intel->scale_units[src_unit][0]); OUT_VERTEX(src_y[1] * intel->scale_units[src_unit][1]); if (!is_affine_src) { OUT_VERTEX(0.0); OUT_VERTEX(src_w[1]); } if (intel->render_mask) { OUT_VERTEX(mask_x[1] * intel->scale_units[mask_unit][0]); OUT_VERTEX(mask_y[1] * intel->scale_units[mask_unit][1]); if (!is_affine_mask) { OUT_VERTEX(0.0); OUT_VERTEX(mask_w[1]); } } OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(src_x[0] * intel->scale_units[src_unit][0]); OUT_VERTEX(src_y[0] * intel->scale_units[src_unit][1]); if (!is_affine_src) { OUT_VERTEX(0.0); OUT_VERTEX(src_w[0]); } if (intel->render_mask) { OUT_VERTEX(mask_x[0] * intel->scale_units[mask_unit][0]); OUT_VERTEX(mask_y[0] * intel->scale_units[mask_unit][1]); if (!is_affine_mask) { OUT_VERTEX(0.0); OUT_VERTEX(mask_w[0]); } } } Bool i915_prepare_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, PixmapPtr source, PixmapPtr mask, PixmapPtr dest) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ intel_uxa_get_pixmap_bo(dest), intel_uxa_get_pixmap_bo(source), mask ? intel_uxa_get_pixmap_bo(mask) : NULL, }; int tex_unit = 0; int floats_per_vertex; intel->render_source_picture = source_picture; intel->render_source = source; intel->render_mask_picture = mask_picture; intel->render_mask = mask; intel->render_dest_picture = dest_picture; intel->render_dest = dest; if (!intel_uxa_check_pitch_3d(source)) return FALSE; if (mask && !intel_uxa_check_pitch_3d(mask)) return FALSE; if (!intel_uxa_check_pitch_3d(dest)) return FALSE; if (!i915_get_dest_format(dest_picture, &intel->i915_render_state.dst_format)) return FALSE; if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) return FALSE; if (mask_picture != NULL && mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha * and on the source value. We can only get one of those * into the single source value that we get to blend with. */ if (i915_blend_op[op].src_alpha && (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) return FALSE; } intel->transform[0] = NULL; intel->scale_units[0][0] = -1; intel->scale_units[0][1] = -1; intel->transform[1] = NULL; intel->scale_units[1][0] = -1; intel->scale_units[1][1] = -1; floats_per_vertex = 2; /* dest x/y */ if (!i915_texture_setup(source_picture, source, tex_unit++)) { intel_uxa_debug_fallback(scrn, "fail to setup src texture\n"); return FALSE; } if (intel_uxa_transform_is_affine(source_picture->transform)) floats_per_vertex += 2; /* src x/y */ else floats_per_vertex += 4; /* src x/y/z/w */ if (mask_picture != NULL) { assert(mask != NULL); if (!i915_texture_setup(mask_picture, mask, tex_unit++)) { intel_uxa_debug_fallback(scrn, "fail to setup mask texture\n"); return FALSE; } if (intel_uxa_transform_is_affine(mask_picture->transform)) floats_per_vertex += 2; /* mask x/y */ else floats_per_vertex += 4; /* mask x/y/z/w */ } intel->i915_render_state.op = op; if (intel_uxa_pixmap_is_dirty(source) || intel_uxa_pixmap_is_dirty(mask)) intel_batch_emit_flush(scrn); intel->needs_render_state_emit = TRUE; intel->prim_emit = i915_emit_composite_primitive; if (!mask) { if (intel->transform[0] == NULL) intel->prim_emit = i915_emit_composite_primitive_identity_source; else if (intel_uxa_transform_is_affine(intel->transform[0])) intel->prim_emit = i915_emit_composite_primitive_affine_source; } else { if (intel->transform[0] == NULL) { if (intel->transform[1] == NULL) intel->prim_emit = i915_emit_composite_primitive_identity_source_mask; } } if (floats_per_vertex != intel->floats_per_vertex) { intel->floats_per_vertex = floats_per_vertex; intel->needs_render_vertex_emit = TRUE; } return TRUE; } static void i915_composite_emit_shader(intel_screen_private *intel, CARD8 op) { PicturePtr mask_picture = intel->render_mask_picture; PixmapPtr mask = intel->render_mask; int src_reg, mask_reg; Bool dest_is_alpha = PIXMAN_FORMAT_RGB(intel->render_dest_picture->format) == 0; FS_LOCALS(); FS_BEGIN(); /* Declare the registers necessary for our program. */ i915_fs_dcl(FS_T0); i915_fs_dcl(FS_S0); if (!mask) { /* No mask, so load directly to output color */ if (dest_is_alpha) src_reg = FS_R0; else src_reg = FS_OC; if (intel_uxa_transform_is_affine(intel->transform[0])) i915_fs_texld(src_reg, FS_S0, FS_T0); else i915_fs_texldp(src_reg, FS_S0, FS_T0); if (src_reg != FS_OC) i915_fs_mov(FS_OC, i915_fs_operand(src_reg, W, W, W, W)); } else { i915_fs_dcl(FS_T1); i915_fs_dcl(FS_S1); /* Load the source_picture texel */ if (intel_uxa_transform_is_affine(intel->transform[0])) i915_fs_texld(FS_R0, FS_S0, FS_T0); else i915_fs_texldp(FS_R0, FS_S0, FS_T0); src_reg = FS_R0; /* Load the mask_picture texel */ if (intel_uxa_transform_is_affine(intel->transform[1])) i915_fs_texld(FS_R1, FS_S1, FS_T1); else i915_fs_texldp(FS_R1, FS_S1, FS_T1); mask_reg = FS_R1; if (dest_is_alpha) { i915_fs_mul(FS_OC, i915_fs_operand(src_reg, W, W, W, W), i915_fs_operand(mask_reg, W, W, W, W)); } else { /* If component alpha is active in the mask and the blend * operation uses the source alpha, then we know we don't * need the source value (otherwise we would have hit a * fallback earlier), so we provide the source alpha (src.A * * mask.X) as output color. * Conversely, if CA is set and we don't need the source alpha, * then we produce the source value (src.X * mask.X) and the * source alpha is unused. Otherwise, we provide the non-CA * source value (src.X * mask.A). */ if (mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { if (i915_blend_op[op].src_alpha) { i915_fs_mul(FS_OC, i915_fs_operand(src_reg, W, W, W, W), i915_fs_operand_reg(mask_reg)); } else { i915_fs_mul(FS_OC, i915_fs_operand_reg(src_reg), i915_fs_operand_reg(mask_reg)); } } else { i915_fs_mul(FS_OC, i915_fs_operand_reg(src_reg), i915_fs_operand(mask_reg, W, W, W, W)); } } } FS_END(); } static void i915_emit_composite_setup(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int op = intel->i915_render_state.op; PicturePtr mask_picture = intel->render_mask_picture; PicturePtr dest_picture = intel->render_dest_picture; PixmapPtr mask = intel->render_mask; PixmapPtr dest = intel->render_dest; int tex_count, t; intel->needs_render_state_emit = FALSE; IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_RENDER; tex_count = 1 + (mask != NULL); assert(intel->in_batch_atomic); if (tex_count != 0) { OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (t = 0; t < tex_count; t++) { OUT_RELOC_PIXMAP(intel->texture[t], I915_GEM_DOMAIN_SAMPLER, 0, 0); OUT_BATCH(intel->mapstate[3*t + 1]); OUT_BATCH(intel->mapstate[3*t + 2]); } OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count)); OUT_BATCH((1 << tex_count) - 1); for (t = 0; t < tex_count; t++) { OUT_BATCH(intel->samplerstate[3*t + 0]); OUT_BATCH(intel->samplerstate[3*t + 1]); OUT_BATCH(intel->samplerstate[3*t + 2]); } } /* BUF_INFO is an implicit flush, so avoid if the target has not changed. * XXX However for reasons unfathomed, correct rendering in KDE requires * at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here. */ if (1) { uint32_t tiling_bits; if (intel_uxa_pixmap_tiled(dest)) { tiling_bits = BUF_3D_TILED_SURFACE; if (intel_uxa_get_pixmap_private(dest)->tiling == I915_TILING_Y) tiling_bits |= BUF_3D_TILE_WALK_Y; } else tiling_bits = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits | BUF_3D_PITCH(intel_pixmap_pitch(dest))); OUT_RELOC_PIXMAP(dest, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(intel->i915_render_state.dst_format); /* draw rect is unconditional */ OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(0x00000000); OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) | DRAW_XMAX(dest->drawable.width - 1)); /* yorig, xorig (relate to color buffer?) */ OUT_BATCH(0x00000000); } { uint32_t ss2; ss2 = ~0; ss2 &= ~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(0, intel_uxa_transform_is_affine(intel->transform[0]) ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); if (mask) { ss2 &= ~S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT); ss2 |= S2_TEXCOORD_FMT(1, intel_uxa_transform_is_affine(intel->transform[1]) ? TEXCOORDFMT_2D : TEXCOORDFMT_4D); } OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1); OUT_BATCH(ss2); OUT_BATCH(i915_get_blend_cntl(op, mask_picture, dest_picture->format)); } i915_composite_emit_shader(intel, op); } void i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); /* 28 + 16 + 10 + 20 + 32 + 16 */ intel_batch_start_atomic(scrn, 150); if (intel->needs_render_state_emit) i915_emit_composite_setup(scrn); if (intel->needs_render_vertex_emit || intel_vertex_space(intel) < 3*4*intel->floats_per_vertex) { i915_vertex_flush(intel); if (intel_vertex_space(intel) < 256) { intel_next_vertex(intel); OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(0) | I1_LOAD_S(1) | 1); OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) | (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT)); intel->vertex_index = 0; } else if (intel->floats_per_vertex != intel->last_floats_per_vertex){ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | 0); OUT_BATCH((intel->floats_per_vertex << S1_VERTEX_WIDTH_SHIFT) | (intel->floats_per_vertex << S1_VERTEX_PITCH_SHIFT)); intel->vertex_index = (intel->vertex_used + intel->floats_per_vertex - 1) / intel->floats_per_vertex; intel->vertex_used = intel->vertex_index * intel->floats_per_vertex; } intel->last_floats_per_vertex = intel->floats_per_vertex; intel->needs_render_vertex_emit = FALSE; } if (intel->prim_offset == 0) { intel->prim_offset = intel->batch_used; OUT_BATCH(PRIM3D_RECTLIST | PRIM3D_INDIRECT_SEQUENTIAL); OUT_BATCH(intel->vertex_index); } intel->vertex_count += 3; intel->prim_emit(intel, srcX, srcY, maskX, maskY, dstX, dstY, w, h); intel_batch_end_atomic(scrn); } void i915_vertex_flush(intel_screen_private *intel) { if (intel->prim_offset == 0) return; intel->batch_ptr[intel->prim_offset] |= intel->vertex_count; intel->prim_offset = 0; intel->vertex_index += intel->vertex_count; intel->vertex_count = 0; } void i915_batch_commit_notify(intel_screen_private *intel) { intel->needs_render_state_emit = TRUE; intel->last_floats_per_vertex = 0; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i915_video.c000066400000000000000000000345231267532330400237070ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86xv.h" #include "fourcc.h" #include "gcstruct.h" #include "intel.h" #include "intel_uxa.h" #include "i915_reg.h" #include "i915_3d.h" void I915DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t format, ms3, s5, tiling; BoxPtr pbox = REGION_RECTS(dstRegion); int nbox_total = REGION_NUM_RECTS(dstRegion); int nbox_this_time; int dxo, dyo, pix_xoff, pix_yoff; PixmapPtr target; #if 0 ErrorF("I915DisplayVideo: %dx%d (pitch %d)\n", width, height, video_pitch); #endif dxo = dstRegion->extents.x1; dyo = dstRegion->extents.y1; if (pixmap->drawable.width > 2048 || pixmap->drawable.height > 2048 || !intel_uxa_check_pitch_3d(pixmap)) { ScreenPtr screen = pixmap->drawable.pScreen; target = screen->CreatePixmap(screen, dstRegion->extents.x2 - dxo, dstRegion->extents.y2 - dyo, pixmap->drawable.depth, CREATE_PIXMAP_USAGE_SCRATCH); if (target == NULL) return; if (intel_uxa_get_pixmap_bo(target) == NULL) { screen->DestroyPixmap(target); return; } pix_xoff = -dxo; pix_yoff = -dyo; } else { target = pixmap; /* Set up the offset for translating from the given region * (in screen coordinates) to the backing pixmap. */ #ifdef COMPOSITE pix_xoff = -target->screen_x + target->drawable.x; pix_yoff = -target->screen_y + target->drawable.y; #else pix_xoff = 0; pix_yoff = 0; #endif } #define BYTES_FOR_BOXES(n) ((200 + (n) * 20) * 4) #define BOXES_IN_BYTES(s) ((((s)/4) - 200) / 20) #define BATCH_BYTES(p) ((p)->batch_bo->size - 16) while (nbox_total) { nbox_this_time = nbox_total; if (BYTES_FOR_BOXES(nbox_this_time) > BATCH_BYTES(intel)) nbox_this_time = BOXES_IN_BYTES(BATCH_BYTES(intel)); nbox_total -= nbox_this_time; intel_batch_start_atomic(scrn, 200 + 20 * nbox_this_time); IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_VIDEO; /* draw rect -- just clipping */ OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); OUT_BATCH(DRAW_DITHER_OFS_X(pixmap->drawable.x & 3) | DRAW_DITHER_OFS_Y(pixmap->drawable.y & 3)); OUT_BATCH(0x00000000); /* ymin, xmin */ /* ymax, xmax */ OUT_BATCH((target->drawable.width - 1) | (target->drawable.height - 1) << 16); OUT_BATCH(0x00000000); /* yorigin, xorigin */ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(5) | I1_LOAD_S(6) | 2); OUT_BATCH(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); s5 = 0x0; if (intel->cpp == 2) s5 |= S5_COLOR_DITHER_ENABLE; OUT_BATCH(s5); /* S5 - enable bits */ OUT_BATCH((2 << S6_DEPTH_TEST_FUNC_SHIFT) | (2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) | (1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE | (2 << S6_TRISTRIP_PV_SHIFT)); OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); if (intel->cpp == 2) format = COLR_BUF_RGB565; else format = COLR_BUF_ARGB8888 | DEPTH_FRMT_24_FIXED_8_OTHER; OUT_BATCH(LOD_PRECLAMP_OGL | DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8) | format); /* front buffer, pitch, offset */ if (intel_uxa_pixmap_tiled(target)) { tiling = BUF_3D_TILED_SURFACE; if (intel_uxa_get_pixmap_private(target)->tiling == I915_TILING_Y) tiling |= BUF_3D_TILE_WALK_Y; } else tiling = 0; OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling | BUF_3D_PITCH(intel_pixmap_pitch(target))); OUT_RELOC_PIXMAP(target, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); if (!is_planar_fourcc(id)) { FS_LOCALS(); OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | 4); OUT_BATCH(0x0000001); /* constant 0 */ /* constant 0: brightness/contrast */ OUT_BATCH_F(adaptor_priv->brightness / 128.0); OUT_BATCH_F(adaptor_priv->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); OUT_BATCH(_3DSTATE_SAMPLER_STATE | 3); OUT_BATCH(0x00000001); OUT_BATCH(SS2_COLORSPACE_CONVERSION | (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_MAP_STATE | 3); OUT_BATCH(0x00000001); /* texture map #1 */ if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->YBufOffset); else OUT_BATCH(adaptor_priv->YBufOffset); ms3 = MAPSURF_422; switch (id) { case FOURCC_YUY2: ms3 |= MT_422_YCRCB_NORMAL; break; case FOURCC_UYVY: ms3 |= MT_422_YCRCB_SWAPY; break; } ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); FS_BEGIN(); i915_fs_dcl(FS_S0); i915_fs_dcl(FS_T0); i915_fs_texld(FS_OC, FS_S0, FS_T0); if (adaptor_priv->brightness != 0) { i915_fs_add(FS_OC, i915_fs_operand_reg(FS_OC), i915_fs_operand(FS_C0, X, X, X, ZERO)); } FS_END(); } else { FS_LOCALS(); /* For the planar formats, we set up three samplers -- * one for each plane, in a Y8 format. Because I * couldn't get the special PLANAR_TO_PACKED * shader setup to work, I did the manual pixel shader: * * y' = y - .0625 * u' = u - .5 * v' = v - .5; * * r = 1.1643 * y' + 0.0 * u' + 1.5958 * v' * g = 1.1643 * y' - 0.39173 * u' - 0.81290 * v' * b = 1.1643 * y' + 2.017 * u' + 0.0 * v' * * register assignment: * r0 = (y',u',v',0) * r1 = (y,y,y,y) * r2 = (u,u,u,u) * r3 = (v,v,v,v) * OC = (r,g,b,1) */ OUT_BATCH(_3DSTATE_PIXEL_SHADER_CONSTANTS | (22 - 2)); OUT_BATCH(0x000001f); /* constants 0-4 */ /* constant 0: normalization offsets */ OUT_BATCH_F(-0.0625); OUT_BATCH_F(-0.5); OUT_BATCH_F(-0.5); OUT_BATCH_F(0.0); /* constant 1: r coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(0.0); OUT_BATCH_F(1.5958); OUT_BATCH_F(0.0); /* constant 2: g coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(-0.39173); OUT_BATCH_F(-0.81290); OUT_BATCH_F(0.0); /* constant 3: b coefficients */ OUT_BATCH_F(1.1643); OUT_BATCH_F(2.017); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); /* constant 4: brightness/contrast */ OUT_BATCH_F(adaptor_priv->brightness / 128.0); OUT_BATCH_F(adaptor_priv->contrast / 255.0); OUT_BATCH_F(0.0); OUT_BATCH_F(0.0); OUT_BATCH(_3DSTATE_SAMPLER_STATE | 9); OUT_BATCH(0x00000007); /* sampler 0 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 1 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (1 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 2 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (2 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); OUT_BATCH(_3DSTATE_MAP_STATE | 9); OUT_BATCH(0x00000007); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->YBufOffset); else OUT_BATCH(adaptor_priv->YBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); /* check to see if Y has special pitch than normal * double u/v pitch, e.g i915 XvMC hw requires at * least 1K alignment, so Y pitch might * be same as U/V's.*/ if (video_pitch2) OUT_BATCH(((video_pitch2 / 4) - 1) << MS4_PITCH_SHIFT); else OUT_BATCH(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->UBufOffset); else OUT_BATCH(adaptor_priv->UBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); if (adaptor_priv->buf) OUT_RELOC(adaptor_priv->buf, I915_GEM_DOMAIN_SAMPLER, 0, adaptor_priv->VBufOffset); else OUT_BATCH(adaptor_priv->VBufOffset); ms3 = MAPSURF_8BIT | MT_8BIT_I8; ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT; ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT; OUT_BATCH(ms3); OUT_BATCH(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT); FS_BEGIN(); /* Declare samplers */ i915_fs_dcl(FS_S0); /* Y */ i915_fs_dcl(FS_S1); /* U */ i915_fs_dcl(FS_S2); /* V */ i915_fs_dcl(FS_T0); /* normalized coords */ /* Load samplers to temporaries. */ i915_fs_texld(FS_R1, FS_S0, FS_T0); i915_fs_texld(FS_R2, FS_S1, FS_T0); i915_fs_texld(FS_R3, FS_S2, FS_T0); /* Move the sampled YUV data in R[123] to the first * 3 channels of R0. */ i915_fs_mov_masked(FS_R0, MASK_X, i915_fs_operand_reg(FS_R1)); i915_fs_mov_masked(FS_R0, MASK_Y, i915_fs_operand_reg(FS_R2)); i915_fs_mov_masked(FS_R0, MASK_Z, i915_fs_operand_reg(FS_R3)); /* Normalize the YUV data */ i915_fs_add(FS_R0, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C0)); /* dot-product the YUV data in R0 by the vectors of * coefficients for calculating R, G, and B, storing * the results in the R, G, or B channels of the output * color. The OC results are implicitly clamped * at the end of the program. */ i915_fs_dp3(FS_OC, MASK_X, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C1)); i915_fs_dp3(FS_OC, MASK_Y, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C2)); i915_fs_dp3(FS_OC, MASK_Z, i915_fs_operand_reg(FS_R0), i915_fs_operand_reg(FS_C3)); /* Set alpha of the output to 1.0, by wiring W to 1 * and not actually using the source. */ i915_fs_mov_masked(FS_OC, MASK_W, i915_fs_operand_one()); if (adaptor_priv->brightness != 0) { i915_fs_add(FS_OC, i915_fs_operand_reg(FS_OC), i915_fs_operand(FS_C4, X, X, X, ZERO)); } FS_END(); } OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1)); while (nbox_this_time--) { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; int box_y2 = pbox->y2; float src_scale_x, src_scale_y; pbox++; src_scale_x = ((float)src_w / width) / drw_w; src_scale_y = ((float)src_h / height) / drw_h; /* vertex data - rect list consists of bottom right, * bottom left, and top left vertices. */ /* bottom right */ OUT_BATCH_F(box_x2 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F((box_x2 - dxo) * src_scale_x); OUT_BATCH_F((box_y2 - dyo) * src_scale_y); /* bottom left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); OUT_BATCH_F((box_x1 - dxo) * src_scale_x); OUT_BATCH_F((box_y2 - dyo) * src_scale_y); /* top left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y1 + pix_yoff); OUT_BATCH_F((box_x1 - dxo) * src_scale_x); OUT_BATCH_F((box_y1 - dyo) * src_scale_y); } intel_batch_end_atomic(scrn); } if (target != pixmap) { GCPtr gc; gc = GetScratchGC(pixmap->drawable.depth, pixmap->drawable.pScreen); if (gc) { gc->subWindowMode = ClipByChildren; if (REGION_NUM_RECTS(dstRegion) > 1) { RegionPtr tmp; tmp = REGION_CREATE(pixmap->drawable.pScreen, NULL, 0); if (tmp) { REGION_COPY(pixmap->drawable.pScreen, tmp, dstRegion); gc->funcs->ChangeClip(gc, CT_REGION, tmp, 0); } } ValidateGC(&pixmap->drawable, gc); gc->ops->CopyArea(&target->drawable, &pixmap->drawable, gc, 0, 0, target->drawable.width, target->drawable.height, -pix_xoff, -pix_yoff); FreeScratchGC(gc); } target->drawable.pScreen->DestroyPixmap(target); } intel_uxa_debug_flush(scrn); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i965_3d.c000066400000000000000000000253471267532330400231200ustar00rootroot00000000000000/* * Copyright 2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "intel.h" #include "intel_uxa.h" #include "i965_reg.h" #include "brw_defines.h" void gen6_upload_invariant_states(intel_screen_private *intel) { Bool ivb = INTEL_INFO(intel)->gen >= 070; OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_IS_FLUSH | BRW_PIPE_CONTROL_WC_FLUSH | BRW_PIPE_CONTROL_DEPTH_CACHE_FLUSH | BRW_PIPE_CONTROL_NOWRITE); OUT_BATCH(0); /* write address */ OUT_BATCH(0); /* write data */ OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE | ((ivb ? 4 : 3) - 2)); OUT_BATCH(GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER | GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */ OUT_BATCH(0); if (ivb) OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SAMPLE_MASK | (2 - 2)); OUT_BATCH(1); /* Set system instruction pointer */ OUT_BATCH(BRW_STATE_SIP | 0); OUT_BATCH(0); } void gen6_upload_viewport_state_pointers(intel_screen_private *intel, drm_intel_bo *cc_vp_bo) { OUT_BATCH(GEN6_3DSTATE_VIEWPORT_STATE_POINTERS | GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_RELOC(cc_vp_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); } void gen7_upload_viewport_state_pointers(intel_screen_private *intel, drm_intel_bo *cc_vp_bo) { OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC | (2 - 2)); OUT_RELOC(cc_vp_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH(GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL | (2 - 2)); OUT_BATCH(0); } void gen6_upload_urb(intel_screen_private *intel) { OUT_BATCH(GEN6_3DSTATE_URB | (3 - 2)); OUT_BATCH(((1 - 1) << GEN6_3DSTATE_URB_VS_SIZE_SHIFT) | (24 << GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT)); /* at least 24 on GEN6 */ OUT_BATCH((0 << GEN6_3DSTATE_URB_GS_SIZE_SHIFT) | (0 << GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT)); /* no GS thread */ } /* * URB layout on GEN7 * ---------------------------------------- * | PS Push Constants (8KB) | VS entries | * ---------------------------------------- */ void gen7_upload_urb(intel_screen_private *intel) { unsigned int num_urb_entries = 32; if (IS_HSW(intel)) num_urb_entries = 64; OUT_BATCH(GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2)); OUT_BATCH(8); /* in 1KBs */ OUT_BATCH(GEN7_3DSTATE_URB_VS | (2 - 2)); OUT_BATCH( (num_urb_entries << GEN7_URB_ENTRY_NUMBER_SHIFT) | (2 - 1) << GEN7_URB_ENTRY_SIZE_SHIFT | (1 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_GS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (1 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_HS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (2 << GEN7_URB_STARTING_ADDRESS_SHIFT)); OUT_BATCH(GEN7_3DSTATE_URB_DS | (2 - 2)); OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) | (2 << GEN7_URB_STARTING_ADDRESS_SHIFT)); } void gen6_upload_cc_state_pointers(intel_screen_private *intel, drm_intel_bo *blend_bo, drm_intel_bo *cc_bo, drm_intel_bo *depth_stencil_bo, uint32_t blend_offset) { OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (4 - 2)); if (blend_bo) OUT_RELOC(blend_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, blend_offset | 1); else OUT_BATCH(0); if (depth_stencil_bo) OUT_RELOC(depth_stencil_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); else OUT_BATCH(0); if (cc_bo) OUT_RELOC(cc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); else OUT_BATCH(0); } void gen7_upload_cc_state_pointers(intel_screen_private *intel, drm_intel_bo *blend_bo, drm_intel_bo *cc_bo, drm_intel_bo *depth_stencil_bo, uint32_t blend_offset) { OUT_BATCH(GEN7_3DSTATE_BLEND_STATE_POINTERS | (2 - 2)); if (blend_bo) OUT_RELOC(blend_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, blend_offset | 1); else OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_CC_STATE_POINTERS | (2 - 2)); if (cc_bo) OUT_RELOC(cc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); else OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS | (2 - 2)); if (depth_stencil_bo) OUT_RELOC(depth_stencil_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); else OUT_BATCH(0); } void gen6_upload_sampler_state_pointers(intel_screen_private *intel, drm_intel_bo *sampler_bo) { OUT_BATCH(GEN6_3DSTATE_SAMPLER_STATE_POINTERS | GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS | (4 - 2)); OUT_BATCH(0); /* VS */ OUT_BATCH(0); /* GS */ OUT_RELOC(sampler_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); } void gen7_upload_sampler_state_pointers(intel_screen_private *intel, drm_intel_bo *sampler_bo) { OUT_BATCH(GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS | (2 - 2)); OUT_RELOC(sampler_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); } void gen7_upload_bypass_states(intel_screen_private *intel) { /* bypass GS */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2)); OUT_BATCH(0); /* without GS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS | (2 - 2)); OUT_BATCH(0); /* disable HS */ OUT_BATCH(GEN7_3DSTATE_CONSTANT_HS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_HS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS | (2 - 2)); OUT_BATCH(0); /* Disable TE */ OUT_BATCH(GEN7_3DSTATE_TE | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* Disable DS */ OUT_BATCH(GEN7_3DSTATE_CONSTANT_DS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_DS | (6 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS | (2 - 2)); OUT_BATCH(0); /* Disable STREAMOUT */ OUT_BATCH(GEN7_3DSTATE_STREAMOUT | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); } void gen6_upload_vs_state(intel_screen_private *intel) { Bool ivb = INTEL_INFO(intel)->gen >= 070; /* disable VS constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | ((ivb ? 7 : 5) - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); if (ivb) { OUT_BATCH(0); OUT_BATCH(0); } OUT_BATCH(GEN6_3DSTATE_VS | (6 - 2)); OUT_BATCH(0); /* without VS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ } void gen6_upload_gs_state(intel_screen_private *intel) { /* disable GS constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_GS | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_GS | (7 - 2)); OUT_BATCH(0); /* without GS kernel */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ } void gen6_upload_clip_state(intel_screen_private *intel) { OUT_BATCH(GEN6_3DSTATE_CLIP | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); /* pass-through */ OUT_BATCH(0); } void gen6_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset) { OUT_BATCH(GEN6_3DSTATE_SF | (20 - 2)); OUT_BATCH((num_sf_outputs << GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT) | (1 << GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT) | (read_offset << GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT)); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE); OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); /* DW4 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW9 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW14 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW19 */ } void gen7_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset) { OUT_BATCH(GEN7_3DSTATE_SBE | (14 - 2)); OUT_BATCH((num_sf_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT) | (1 << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT) | (read_offset << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW4 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); /* DW9 */ OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SF | (7 - 2)); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_SF_CULL_NONE); OUT_BATCH(2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); } void gen6_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset) { /* Binding table pointers */ OUT_BATCH(BRW_3DSTATE_BINDING_TABLE_POINTERS | GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS | (4 - 2)); OUT_BATCH(0); /* VS */ OUT_BATCH(0); /* GS */ /* Only the PS uses the binding table */ OUT_BATCH(ps_binding_table_offset); } void gen7_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset) { OUT_BATCH(GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS | (2 - 2)); OUT_BATCH(ps_binding_table_offset); } void gen6_upload_depth_buffer_state(intel_screen_private *intel) { OUT_BATCH(BRW_3DSTATE_DEPTH_BUFFER | (7 - 2)); OUT_BATCH((BRW_SURFACE_NULL << BRW_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT) | (BRW_DEPTHFORMAT_D32_FLOAT << BRW_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(BRW_3DSTATE_CLEAR_PARAMS | (2 - 2)); OUT_BATCH(0); } void gen7_upload_depth_buffer_state(intel_screen_private *intel) { OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER | (7 - 2)); OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) | (BRW_SURFACE_NULL << 29)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_CLEAR_PARAMS | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i965_reg.h000066400000000000000000000530531267532330400233670ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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. * **************************************************************************/ /* * New regs for broadwater -- we need to split this file up sensibly somehow. */ #define BRW_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define BRW_URB_FENCE BRW_3D(0, 0, 0) #define BRW_CS_URB_STATE BRW_3D(0, 0, 1) #define BRW_CONSTANT_BUFFER BRW_3D(0, 0, 2) #define BRW_STATE_PREFETCH BRW_3D(0, 0, 3) #define BRW_STATE_BASE_ADDRESS BRW_3D(0, 1, 1) #define BRW_STATE_SIP BRW_3D(0, 1, 2) #define BRW_PIPELINE_SELECT BRW_3D(0, 1, 4) #define NEW_PIPELINE_SELECT BRW_3D(1, 1, 4) #define BRW_MEDIA_STATE_POINTERS BRW_3D(2, 0, 0) #define BRW_MEDIA_OBJECT BRW_3D(2, 1, 0) #define BRW_3DSTATE_PIPELINED_POINTERS BRW_3D(3, 0, 0) #define BRW_3DSTATE_BINDING_TABLE_POINTERS BRW_3D(3, 0, 1) # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS (1 << 12)/* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_GS (1 << 9) /* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_VS (1 << 8) /* for GEN6 */ #define BRW_3DSTATE_VERTEX_BUFFERS BRW_3D(3, 0, 8) #define BRW_3DSTATE_VERTEX_ELEMENTS BRW_3D(3, 0, 9) #define BRW_3DSTATE_INDEX_BUFFER BRW_3D(3, 0, 0xa) #define BRW_3DSTATE_VF_STATISTICS BRW_3D(3, 0, 0xb) #define BRW_3DSTATE_DRAWING_RECTANGLE BRW_3D(3, 1, 0) #define BRW_3DSTATE_CONSTANT_COLOR BRW_3D(3, 1, 1) #define BRW_3DSTATE_SAMPLER_PALETTE_LOAD BRW_3D(3, 1, 2) #define BRW_3DSTATE_CHROMA_KEY BRW_3D(3, 1, 4) #define BRW_3DSTATE_DEPTH_BUFFER BRW_3D(3, 1, 5) # define BRW_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define BRW_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define BRW_3DSTATE_POLY_STIPPLE_OFFSET BRW_3D(3, 1, 6) #define BRW_3DSTATE_POLY_STIPPLE_PATTERN BRW_3D(3, 1, 7) #define BRW_3DSTATE_LINE_STIPPLE BRW_3D(3, 1, 8) #define BRW_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP BRW_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define BRW_3DSTATE_AA_LINE_PARAMS BRW_3D(3, 1, 0xa) #define BRW_3DSTATE_GS_SVB_INDEX BRW_3D(3, 1, 0xb) #define BRW_PIPE_CONTROL BRW_3D(3, 2, 0) #define BRW_3DPRIMITIVE BRW_3D(3, 3, 0) #define BRW_3DSTATE_CLEAR_PARAMS BRW_3D(3, 1, 0x10) /* DW1 */ # define BRW_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) /* for GEN6+ */ #define GEN6_3DSTATE_SAMPLER_STATE_POINTERS BRW_3D(3, 0, 0x02) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN6_3DSTATE_URB BRW_3D(3, 0, 0x05) /* DW1 */ # define GEN6_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN6_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN6_3DSTATE_VIEWPORT_STATE_POINTERS BRW_3D(3, 0, 0x0d) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN6_3DSTATE_CC_STATE_POINTERS BRW_3D(3, 0, 0x0e) #define GEN6_3DSTATE_VS BRW_3D(3, 0, 0x10) #define GEN6_3DSTATE_GS BRW_3D(3, 0, 0x11) /* DW4 */ # define GEN6_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN6_3DSTATE_CLIP BRW_3D(3, 0, 0x12) #define GEN6_3DSTATE_SF BRW_3D(3, 0, 0x13) /* DW1 */ # define GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN6_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN6_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN6_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN6_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN6_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN6_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN6_3DSTATE_WM BRW_3D(3, 0, 0x14) /* DW2 */ # define GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF 27 # define GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 /* DW4 */ # define GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT 16 /* DW5 */ # define GEN6_3DSTATE_WM_MAX_THREADS_SHIFT 25 # define GEN6_3DSTATE_WM_DISPATCH_ENABLE (1 << 19) # define GEN6_3DSTATE_WM_16_DISPATCH_ENABLE (1 << 1) # define GEN6_3DSTATE_WM_8_DISPATCH_ENABLE (1 << 0) /* DW6 */ # define GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT 20 # define GEN6_3DSTATE_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 15) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 14) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 13) # define GEN6_3DSTATE_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_3DSTATE_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) #define GEN6_3DSTATE_CONSTANT_VS BRW_3D(3, 0, 0x15) #define GEN6_3DSTATE_CONSTANT_GS BRW_3D(3, 0, 0x16) #define GEN6_3DSTATE_CONSTANT_PS BRW_3D(3, 0, 0x17) #define GEN6_3DSTATE_SAMPLE_MASK BRW_3D(3, 0, 0x18) #define GEN6_3DSTATE_MULTISAMPLE BRW_3D(3, 1, 0x0d) /* DW1 */ # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) /* on GEN7+ */ /* _3DSTATE_VERTEX_BUFFERS on GEN7*/ /* DW1 */ #define GEN7_VB0_ADDRESS_MODIFYENABLE (1 << 14) /* _3DPRIMITIVE on GEN7 */ /* DW1 */ # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8) # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM (1 << 8) /* 3DSTATE_WM on GEN7 */ /* DW1 */ # define GEN7_WM_STATISTICS_ENABLE (1 << 31) # define GEN7_WM_DEPTH_CLEAR (1 << 30) # define GEN7_WM_DISPATCH_ENABLE (1 << 29) # define GEN6_WM_DEPTH_RESOLVE (1 << 28) # define GEN7_WM_HIERARCHICAL_DEPTH_RESOLVE (1 << 27) # define GEN7_WM_KILL_ENABLE (1 << 25) # define GEN7_WM_PSCDEPTH_OFF (0 << 23) # define GEN7_WM_PSCDEPTH_ON (1 << 23) # define GEN7_WM_PSCDEPTH_ON_GE (2 << 23) # define GEN7_WM_PSCDEPTH_ON_LE (3 << 23) # define GEN7_WM_USES_SOURCE_DEPTH (1 << 20) # define GEN7_WM_USES_SOURCE_W (1 << 19) # define GEN7_WM_POSITION_ZW_PIXEL (0 << 17) # define GEN7_WM_POSITION_ZW_CENTROID (2 << 17) # define GEN7_WM_POSITION_ZW_SAMPLE (3 << 17) # define GEN7_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16) # define GEN7_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15) # define GEN7_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14) # define GEN7_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13) # define GEN7_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12) # define GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11) # define GEN7_WM_USES_INPUT_COVERAGE_MASK (1 << 10) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_2_0 (2 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_4_0 (3 << 8) # define GEN7_WM_LINE_AA_WIDTH_0_5 (0 << 6) # define GEN7_WM_LINE_AA_WIDTH_1_0 (1 << 6) # define GEN7_WM_LINE_AA_WIDTH_2_0 (2 << 6) # define GEN7_WM_LINE_AA_WIDTH_4_0 (3 << 6) # define GEN7_WM_POLYGON_STIPPLE_ENABLE (1 << 4) # define GEN7_WM_LINE_STIPPLE_ENABLE (1 << 3) # define GEN7_WM_POINT_RASTRULE_UPPER_RIGHT (1 << 2) # define GEN7_WM_MSRAST_OFF_PIXEL (0 << 0) # define GEN7_WM_MSRAST_OFF_PATTERN (1 << 0) # define GEN7_WM_MSRAST_ON_PIXEL (2 << 0) # define GEN7_WM_MSRAST_ON_PATTERN (3 << 0) /* DW2 */ # define GEN7_WM_MSDISPMODE_PERPIXEL (1 << 31) #define GEN7_3DSTATE_CLEAR_PARAMS BRW_3D(3, 0, 0x04) #define GEN7_3DSTATE_DEPTH_BUFFER BRW_3D(3, 0, 0x05) #define GEN7_3DSTATE_CONSTANT_HS BRW_3D(3, 0, 0x19) #define GEN7_3DSTATE_CONSTANT_DS BRW_3D(3, 0, 0x1a) #define GEN7_3DSTATE_HS BRW_3D(3, 0, 0x1b) #define GEN7_3DSTATE_TE BRW_3D(3, 0, 0x1c) #define GEN7_3DSTATE_DS BRW_3D(3, 0, 0x1d) #define GEN7_3DSTATE_STREAMOUT BRW_3D(3, 0, 0x1e) #define GEN7_3DSTATE_SBE BRW_3D(3, 0, 0x1f) /* DW1 */ # define GEN7_SBE_SWIZZLE_CONTROL_MODE (1 << 28) # define GEN7_SBE_NUM_OUTPUTS_SHIFT 22 # define GEN7_SBE_SWIZZLE_ENABLE (1 << 21) # define GEN7_SBE_POINT_SPRITE_LOWERLEFT (1 << 20) # define GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT 4 #define GEN7_3DSTATE_PS BRW_3D(3, 0, 0x20) /* DW1: kernel pointer */ /* DW2 */ # define GEN7_PS_SPF_MODE (1 << 31) # define GEN7_PS_VECTOR_MASK_ENABLE (1 << 30) # define GEN7_PS_SAMPLER_COUNT_SHIFT 27 # define GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 # define GEN7_PS_FLOATING_POINT_MODE_IEEE_754 (0 << 16) # define GEN7_PS_FLOATING_POINT_MODE_ALT (1 << 16) /* DW3: scratch space */ /* DW4 */ # define GEN7_PS_MAX_THREADS_SHIFT_IVB 24 # define GEN7_PS_MAX_THREADS_SHIFT_HSW 23 # define GEN7_PS_SAMPLE_MASK_SHIFT_HSW 12 # define GEN7_PS_PUSH_CONSTANT_ENABLE (1 << 11) # define GEN7_PS_ATTRIBUTE_ENABLE (1 << 10) # define GEN7_PS_OMASK_TO_RENDER_TARGET (1 << 9) # define GEN7_PS_DUAL_SOURCE_BLEND_ENABLE (1 << 7) # define GEN7_PS_POSOFFSET_NONE (0 << 3) # define GEN7_PS_POSOFFSET_CENTROID (2 << 3) # define GEN7_PS_POSOFFSET_SAMPLE (3 << 3) # define GEN7_PS_32_DISPATCH_ENABLE (1 << 2) # define GEN7_PS_16_DISPATCH_ENABLE (1 << 1) # define GEN7_PS_8_DISPATCH_ENABLE (1 << 0) /* DW5 */ # define GEN7_PS_DISPATCH_START_GRF_SHIFT_0 16 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_1 8 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_2 0 /* DW6: kernel 1 pointer */ /* DW7: kernel 2 pointer */ #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL BRW_3D(3, 0, 0x21) #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC BRW_3D(3, 0, 0x23) #define GEN7_3DSTATE_BLEND_STATE_POINTERS BRW_3D(3, 0, 0x24) #define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS BRW_3D(3, 0, 0x25) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS BRW_3D(3, 0, 0x26) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS BRW_3D(3, 0, 0x27) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS BRW_3D(3, 0, 0x28) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS BRW_3D(3, 0, 0x29) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS BRW_3D(3, 0, 0x2a) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS BRW_3D(3, 0, 0x2b) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS BRW_3D(3, 0, 0x2e) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS BRW_3D(3, 0, 0x2f) #define GEN7_3DSTATE_URB_VS BRW_3D(3, 0, 0x30) #define GEN7_3DSTATE_URB_HS BRW_3D(3, 0, 0x31) #define GEN7_3DSTATE_URB_DS BRW_3D(3, 0, 0x32) #define GEN7_3DSTATE_URB_GS BRW_3D(3, 0, 0x33) /* DW1 */ # define GEN7_URB_ENTRY_NUMBER_SHIFT 0 # define GEN7_URB_ENTRY_SIZE_SHIFT 16 # define GEN7_URB_STARTING_ADDRESS_SHIFT 25 #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS BRW_3D(3, 1, 0x12) #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS BRW_3D(3, 1, 0x16) /* DW1 */ # define GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT 16 #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 #define UF0_CS_REALLOC (1 << 13) #define UF0_VFE_REALLOC (1 << 12) #define UF0_SF_REALLOC (1 << 11) #define UF0_CLIP_REALLOC (1 << 10) #define UF0_GS_REALLOC (1 << 9) #define UF0_VS_REALLOC (1 << 8) #define UF1_CLIP_FENCE_SHIFT 20 #define UF1_GS_FENCE_SHIFT 10 #define UF1_VS_FENCE_SHIFT 0 #define UF2_CS_FENCE_SHIFT 20 #define UF2_VFE_FENCE_SHIFT 10 #define UF2_SF_FENCE_SHIFT 0 /* for BRW_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for BRW_3DSTATE_PIPELINED_POINTERS */ #define BRW_GS_DISABLE 0 #define BRW_GS_ENABLE 1 #define BRW_CLIP_DISABLE 0 #define BRW_CLIP_ENABLE 1 /* for BRW_PIPE_CONTROL */ #define BRW_PIPE_CONTROL_CS_STALL (1 << 20) #define BRW_PIPE_CONTROL_NOWRITE (0 << 14) #define BRW_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define BRW_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define BRW_PIPE_CONTROL_WRITE_TIME (3 << 14) #define BRW_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define BRW_PIPE_CONTROL_WC_FLUSH (1 << 12) #define BRW_PIPE_CONTROL_IS_FLUSH (1 << 11) #define BRW_PIPE_CONTROL_TC_FLUSH (1 << 10) #define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define BRW_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define BRW_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) #define BRW_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define VB0_BUFFER_INDEX_SHIFT 27 #define GEN6_VB0_BUFFER_INDEX_SHIFT 26 #define VB0_VERTEXDATA (0 << 26) #define VB0_INSTANCEDATA (1 << 26) #define GEN6_VB0_VERTEXDATA (0 << 20) #define GEN6_VB0_INSTANCEDATA (1 << 20) #define VB0_BUFFER_PITCH_SHIFT 0 /* VERTEX_ELEMENT_STATE Structure */ #define VE0_VERTEX_BUFFER_INDEX_SHIFT 27 #define GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT 26 /* for GEN6 */ #define VE0_VALID (1 << 26) #define GEN6_VE0_VALID (1 << 25) /* for GEN6 */ #define VE0_FORMAT_SHIFT 16 #define VE0_OFFSET_SHIFT 0 #define VE1_VFCOMPONENT_0_SHIFT 28 #define VE1_VFCOMPONENT_1_SHIFT 24 #define VE1_VFCOMPONENT_2_SHIFT 20 #define VE1_VFCOMPONENT_3_SHIFT 16 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define BRW_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in brw_defines.h */ #define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define BRW_SVG_CTL 0x7400 #define BRW_SVG_CTL_GS_BA (0 << 8) #define BRW_SVG_CTL_SS_BA (1 << 8) #define BRW_SVG_CTL_IO_BA (2 << 8) #define BRW_SVG_CTL_GS_AUB (3 << 8) #define BRW_SVG_CTL_IO_AUB (4 << 8) #define BRW_SVG_CTL_SIP (5 << 8) #define BRW_SVG_RDATA 0x7404 #define BRW_SVG_WORK_CTL 0x7408 #define BRW_VF_CTL 0x7500 #define BRW_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define BRW_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define BRW_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define BRW_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define BRW_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_VF_STRG_VAL 0x7504 #define BRW_VF_STR_VL_OVR 0x7508 #define BRW_VF_VC_OVR 0x750c #define BRW_VF_STR_PSKIP 0x7510 #define BRW_VF_MAX_PRIM 0x7514 #define BRW_VF_RDATA 0x7518 #define BRW_VS_CTL 0x7600 #define BRW_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define BRW_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_VS_STRG_VAL 0x7604 #define BRW_VS_RDATA 0x7608 #define BRW_SF_CTL 0x7b00 #define BRW_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define BRW_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define BRW_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define BRW_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_SF_STRG_VAL 0x7b04 #define BRW_SF_RDATA 0x7b18 #define BRW_WIZ_CTL 0x7c00 #define BRW_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define BRW_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define BRW_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define BRW_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define BRW_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define BRW_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define BRW_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_WIZ_STRG_VAL 0x7c04 #define BRW_WIZ_RDATA 0x7c18 #define BRW_TS_CTL 0x7e00 #define BRW_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define BRW_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define BRW_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_TS_STRG_VAL 0x7e04 #define BRW_TS_RDATA 0x7e08 #define BRW_TD_CTL 0x8000 #define BRW_TD_CTL_MUX_SHIFT 8 #define BRW_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define BRW_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define BRW_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define BRW_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define BRW_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define BRW_TD_CTL2 0x8004 #define BRW_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define BRW_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define BRW_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define BRW_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define BRW_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define BRW_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define BRW_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define BRW_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define BRW_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define BRW_TD_VF_VS_EMSK 0x8008 #define BRW_TD_GS_EMSK 0x800c #define BRW_TD_CLIP_EMSK 0x8010 #define BRW_TD_SF_EMSK 0x8014 #define BRW_TD_WIZ_EMSK 0x8018 #define BRW_TD_0_6_EHTRG_VAL 0x801c #define BRW_TD_0_7_EHTRG_VAL 0x8020 #define BRW_TD_0_6_EHTRG_MSK 0x8024 #define BRW_TD_0_7_EHTRG_MSK 0x8028 #define BRW_TD_RDATA 0x802c #define BRW_TD_TS_EMSK 0x8030 #define BRW_EU_CTL 0x8800 #define BRW_EU_CTL_SELECT_SHIFT 16 #define BRW_EU_CTL_DATA_MUX_SHIFT 8 #define BRW_EU_ATT_0 0x8810 #define BRW_EU_ATT_1 0x8814 #define BRW_EU_ATT_DATA_0 0x8820 #define BRW_EU_ATT_DATA_1 0x8824 #define BRW_EU_ATT_CLR_0 0x8830 #define BRW_EU_ATT_CLR_1 0x8834 #define BRW_EU_RDATA 0x8840 /* End regs for broadwater */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i965_render.c000066400000000000000000002631121267532330400240630ustar00rootroot00000000000000/* * Copyright © 2006,2008 Intel Corporation * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Wang Zhenyu * Eric Anholt * Carl Worth * Keith Packard * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "xorg-server.h" #include "xf86.h" #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" #include "i965_reg.h" /* bring in brw structs */ #include "brw_defines.h" #include "brw_structs.h" // refer vol2, 3d rasterization 3.8.1 /* defined in brw_defines.h */ static const struct blendinfo { Bool dst_alpha; Bool src_alpha; uint32_t src_blend; uint32_t dst_blend; } i965_blend_op[] = { /* Clear */ {0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ZERO}, /* Src */ {0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ZERO}, /* Dst */ {0, 0, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_ONE}, /* Over */ {0, 1, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_INV_SRC_ALPHA}, /* OverReverse */ {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ONE}, /* In */ {1, 0, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_ZERO}, /* InReverse */ {0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_SRC_ALPHA}, /* Out */ {1, 0, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_ZERO}, /* OutReverse */ {0, 1, BRW_BLENDFACTOR_ZERO, BRW_BLENDFACTOR_INV_SRC_ALPHA}, /* Atop */ {1, 1, BRW_BLENDFACTOR_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA}, /* AtopReverse */ {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_SRC_ALPHA}, /* Xor */ {1, 1, BRW_BLENDFACTOR_INV_DST_ALPHA, BRW_BLENDFACTOR_INV_SRC_ALPHA}, /* Add */ {0, 0, BRW_BLENDFACTOR_ONE, BRW_BLENDFACTOR_ONE}, }; /** * Highest-valued BLENDFACTOR used in i965_blend_op. * * This leaves out BRW_BLENDFACTOR_INV_DST_COLOR, * BRW_BLENDFACTOR_INV_CONST_{COLOR,ALPHA}, * BRW_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA} */ #define BRW_BLENDFACTOR_COUNT (BRW_BLENDFACTOR_INV_DST_ALPHA + 1) /* FIXME: surface format defined in brw_defines.h, shared Sampling engine * 1.7.2 */ static const struct formatinfo { int fmt; uint32_t card_fmt; } i965_tex_formats[] = { {PICT_a8, BRW_SURFACEFORMAT_A8_UNORM}, {PICT_a8r8g8b8, BRW_SURFACEFORMAT_B8G8R8A8_UNORM}, {PICT_x8r8g8b8, BRW_SURFACEFORMAT_B8G8R8X8_UNORM}, {PICT_a8b8g8r8, BRW_SURFACEFORMAT_R8G8B8A8_UNORM}, {PICT_x8b8g8r8, BRW_SURFACEFORMAT_R8G8B8X8_UNORM}, {PICT_r8g8b8, BRW_SURFACEFORMAT_R8G8B8_UNORM}, {PICT_r5g6b5, BRW_SURFACEFORMAT_B5G6R5_UNORM}, {PICT_a1r5g5b5, BRW_SURFACEFORMAT_B5G5R5A1_UNORM}, #if XORG_VERSION_CURRENT >= 10699900 {PICT_a2r10g10b10, BRW_SURFACEFORMAT_B10G10R10A2_UNORM}, {PICT_x2r10g10b10, BRW_SURFACEFORMAT_B10G10R10X2_UNORM}, {PICT_a2b10g10r10, BRW_SURFACEFORMAT_R10G10B10A2_UNORM}, {PICT_x2r10g10b10, BRW_SURFACEFORMAT_B10G10R10X2_UNORM}, #endif {PICT_a4r4g4b4, BRW_SURFACEFORMAT_B4G4R4A4_UNORM}, }; static void i965_get_blend_cntl(int op, PicturePtr mask, uint32_t dst_format, uint32_t * sblend, uint32_t * dblend) { *sblend = i965_blend_op[op].src_blend; *dblend = i965_blend_op[op].dst_blend; /* If there's no dst alpha channel, adjust the blend op so that we'll treat * it as always 1. */ if (PICT_FORMAT_A(dst_format) == 0 && i965_blend_op[op].dst_alpha) { if (*sblend == BRW_BLENDFACTOR_DST_ALPHA) *sblend = BRW_BLENDFACTOR_ONE; else if (*sblend == BRW_BLENDFACTOR_INV_DST_ALPHA) *sblend = BRW_BLENDFACTOR_ZERO; } /* If the source alpha is being used, then we should only be in a case where * the source blend factor is 0, and the source blend value is the mask * channels multiplied by the source picture's alpha. */ if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format) && i965_blend_op[op].src_alpha) { if (*dblend == BRW_BLENDFACTOR_SRC_ALPHA) { *dblend = BRW_BLENDFACTOR_SRC_COLOR; } else if (*dblend == BRW_BLENDFACTOR_INV_SRC_ALPHA) { *dblend = BRW_BLENDFACTOR_INV_SRC_COLOR; } } } static uint32_t i965_get_dest_format(PicturePtr dest_picture) { switch (dest_picture->format) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; case PICT_a8b8g8r8: case PICT_x8b8g8r8: return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; #if XORG_VERSION_CURRENT >= 10699900 case PICT_a2r10g10b10: case PICT_x2r10g10b10: return BRW_SURFACEFORMAT_B10G10R10A2_UNORM; #endif case PICT_r5g6b5: return BRW_SURFACEFORMAT_B5G6R5_UNORM; case PICT_x1r5g5b5: case PICT_a1r5g5b5: return BRW_SURFACEFORMAT_B5G5R5A1_UNORM; case PICT_a8: return BRW_SURFACEFORMAT_A8_UNORM; case PICT_a4r4g4b4: case PICT_x4r4g4b4: return BRW_SURFACEFORMAT_B4G4R4A4_UNORM; default: return -1; } } Bool i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, int width, int height) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); /* Check for unsupported compositing operations. */ if (op >= sizeof(i965_blend_op) / sizeof(i965_blend_op[0])) { intel_uxa_debug_fallback(scrn, "Unsupported Composite op 0x%x\n", op); return FALSE; } if (mask_picture && mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (i965_blend_op[op].src_alpha && (i965_blend_op[op].src_blend != BRW_BLENDFACTOR_ZERO)) { intel_uxa_debug_fallback(scrn, "Component alpha not supported " "with source alpha and source " "value blending.\n"); return FALSE; } } if (i965_get_dest_format(dest_picture) == -1) { intel_uxa_debug_fallback(scrn, "Usupported Color buffer format 0x%x\n", (int)dest_picture->format); return FALSE; } return TRUE; } Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture) { if (picture->repeatType > RepeatReflect) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "extended repeat (%d) not supported\n", picture->repeatType); return FALSE; } if (picture->filter != PictFilterNearest && picture->filter != PictFilterBilinear) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Unsupported filter 0x%x\n", picture->filter); return FALSE; } if (picture->pDrawable) { int w, h, i; w = picture->pDrawable->width; h = picture->pDrawable->height; if ((w > 8192) || (h > 8192)) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Picture w/h too large (%dx%d)\n", w, h); return FALSE; } for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]); i++) { if (i965_tex_formats[i].fmt == picture->format) break; } if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0])) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_uxa_debug_fallback(scrn, "Unsupported picture format " "0x%x\n", (int)picture->format); return FALSE; } return TRUE; } return FALSE; } #define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) /* Set up a default static partitioning of the URB, which is supposed to * allow anything we would want to do, at potentially lower performance. */ #define URB_CS_ENTRY_SIZE 0 #define URB_CS_ENTRIES 0 #define URB_VS_ENTRY_SIZE 1 // each 512-bit row #define URB_VS_ENTRIES 8 // we needs at least 8 entries #define URB_GS_ENTRY_SIZE 0 #define URB_GS_ENTRIES 0 #define URB_CLIP_ENTRY_SIZE 0 #define URB_CLIP_ENTRIES 0 #define URB_SF_ENTRY_SIZE 2 #define URB_SF_ENTRIES 1 /* * this program computes dA/dx and dA/dy for the texture coordinates along * with the base texture coordinate. It was extracted from the Mesa driver */ #define SF_KERNEL_NUM_GRF 16 #define SF_MAX_THREADS 2 static const uint32_t sf_kernel_static[][4] = { #include "exa_sf.g4b" }; static const uint32_t sf_kernel_mask_static[][4] = { #include "exa_sf_mask.g4b" }; /* ps kernels */ #define PS_KERNEL_NUM_GRF 32 #define PS_MAX_THREADS 48 static const uint32_t ps_kernel_nomask_affine_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_nomask_projective_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_affine_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_projective_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_a.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca_srcalpha.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_a.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_argb.g4b" #include "exa_wm_ca_srcalpha.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_masknoca_affine_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_affine.g4b" #include "exa_wm_mask_sample_a.g4b" #include "exa_wm_noca.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_masknoca_projective_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_projective.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_mask_projective.g4b" #include "exa_wm_mask_sample_a.g4b" #include "exa_wm_noca.g4b" #include "exa_wm_write.g4b" }; /* new programs for Ironlake */ static const uint32_t sf_kernel_static_gen5[][4] = { #include "exa_sf.g4b.gen5" }; static const uint32_t sf_kernel_mask_static_gen5[][4] = { #include "exa_sf_mask.g4b.gen5" }; static const uint32_t ps_kernel_nomask_affine_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_nomask_projective_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_projective.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_maskca_affine_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_mask_affine.g4b.gen5" #include "exa_wm_mask_sample_argb.g4b.gen5" #include "exa_wm_ca.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_maskca_projective_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_projective.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_mask_projective.g4b.gen5" #include "exa_wm_mask_sample_argb.g4b.gen5" #include "exa_wm_ca.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_a.g4b.gen5" #include "exa_wm_mask_affine.g4b.gen5" #include "exa_wm_mask_sample_argb.g4b.gen5" #include "exa_wm_ca_srcalpha.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_projective.g4b.gen5" #include "exa_wm_src_sample_a.g4b.gen5" #include "exa_wm_mask_projective.g4b.gen5" #include "exa_wm_mask_sample_argb.g4b.gen5" #include "exa_wm_ca_srcalpha.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_masknoca_affine_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_mask_affine.g4b.gen5" #include "exa_wm_mask_sample_a.g4b.gen5" #include "exa_wm_noca.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_masknoca_projective_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_projective.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_mask_projective.g4b.gen5" #include "exa_wm_mask_sample_a.g4b.gen5" #include "exa_wm_noca.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; /* programs for GEN6 */ static const uint32_t ps_kernel_nomask_affine_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_nomask_projective_static_gen6[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_affine_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_projective_static_gen6[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca.g4b.gen5" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_a.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen6[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_a.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_argb.g6b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_masknoca_affine_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_affine.g6b" #include "exa_wm_mask_sample_a.g6b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_masknoca_projective_static_gen6[][4] = { #include "exa_wm_src_projective.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_mask_projective.g6b" #include "exa_wm_mask_sample_a.g6b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g6b" }; /* programs for GEN7 */ static const uint32_t ps_kernel_nomask_affine_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_nomask_projective_static_gen7[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_affine_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_projective_static_gen7[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca.g4b.gen5" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_srcalpha_affine_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_a.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_maskca_srcalpha_projective_static_gen7[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_a.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_argb.g7b" #include "exa_wm_ca_srcalpha.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_masknoca_affine_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_affine.g7b" #include "exa_wm_mask_sample_a.g7b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_masknoca_projective_static_gen7[][4] = { #include "exa_wm_src_projective.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_mask_projective.g7b" #include "exa_wm_mask_sample_a.g7b" #include "exa_wm_noca.g6b" #include "exa_wm_write.g7b" }; typedef enum { SS_INVALID_FILTER = -1, SS_FILTER_NEAREST, SS_FILTER_BILINEAR, FILTER_COUNT, } sampler_state_filter_t; typedef enum { SS_INVALID_EXTEND = -1, SS_EXTEND_NONE, SS_EXTEND_REPEAT, SS_EXTEND_PAD, SS_EXTEND_REFLECT, EXTEND_COUNT, } sampler_state_extend_t; typedef enum { WM_KERNEL_NOMASK_AFFINE, WM_KERNEL_NOMASK_PROJECTIVE, WM_KERNEL_MASKCA_AFFINE, WM_KERNEL_MASKCA_PROJECTIVE, WM_KERNEL_MASKCA_SRCALPHA_AFFINE, WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE, WM_KERNEL_MASKNOCA_AFFINE, WM_KERNEL_MASKNOCA_PROJECTIVE, KERNEL_COUNT } wm_kernel_t; #define KERNEL(kernel_enum, kernel, masked) \ [kernel_enum] = {&kernel, sizeof(kernel), masked} struct wm_kernel_info { const void *data; unsigned int size; Bool has_mask; }; static const struct wm_kernel_info wm_kernels_gen4[] = { KERNEL(WM_KERNEL_NOMASK_AFFINE, ps_kernel_nomask_affine_static, FALSE), KERNEL(WM_KERNEL_NOMASK_PROJECTIVE, ps_kernel_nomask_projective_static, FALSE), KERNEL(WM_KERNEL_MASKCA_AFFINE, ps_kernel_maskca_affine_static, TRUE), KERNEL(WM_KERNEL_MASKCA_PROJECTIVE, ps_kernel_maskca_projective_static, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE, ps_kernel_maskca_srcalpha_affine_static, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE, ps_kernel_maskca_srcalpha_projective_static, TRUE), KERNEL(WM_KERNEL_MASKNOCA_AFFINE, ps_kernel_masknoca_affine_static, TRUE), KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE, ps_kernel_masknoca_projective_static, TRUE), }; static const struct wm_kernel_info wm_kernels_gen5[] = { KERNEL(WM_KERNEL_NOMASK_AFFINE, ps_kernel_nomask_affine_static_gen5, FALSE), KERNEL(WM_KERNEL_NOMASK_PROJECTIVE, ps_kernel_nomask_projective_static_gen5, FALSE), KERNEL(WM_KERNEL_MASKCA_AFFINE, ps_kernel_maskca_affine_static_gen5, TRUE), KERNEL(WM_KERNEL_MASKCA_PROJECTIVE, ps_kernel_maskca_projective_static_gen5, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE, ps_kernel_maskca_srcalpha_affine_static_gen5, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE, ps_kernel_maskca_srcalpha_projective_static_gen5, TRUE), KERNEL(WM_KERNEL_MASKNOCA_AFFINE, ps_kernel_masknoca_affine_static_gen5, TRUE), KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE, ps_kernel_masknoca_projective_static_gen5, TRUE), }; static const struct wm_kernel_info wm_kernels_gen6[] = { KERNEL(WM_KERNEL_NOMASK_AFFINE, ps_kernel_nomask_affine_static_gen6, FALSE), KERNEL(WM_KERNEL_NOMASK_PROJECTIVE, ps_kernel_nomask_projective_static_gen6, FALSE), KERNEL(WM_KERNEL_MASKCA_AFFINE, ps_kernel_maskca_affine_static_gen6, TRUE), KERNEL(WM_KERNEL_MASKCA_PROJECTIVE, ps_kernel_maskca_projective_static_gen6, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE, ps_kernel_maskca_srcalpha_affine_static_gen6, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE, ps_kernel_maskca_srcalpha_projective_static_gen6, TRUE), KERNEL(WM_KERNEL_MASKNOCA_AFFINE, ps_kernel_masknoca_affine_static_gen6, TRUE), KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE, ps_kernel_masknoca_projective_static_gen6, TRUE), }; static const struct wm_kernel_info wm_kernels_gen7[] = { KERNEL(WM_KERNEL_NOMASK_AFFINE, ps_kernel_nomask_affine_static_gen7, FALSE), KERNEL(WM_KERNEL_NOMASK_PROJECTIVE, ps_kernel_nomask_projective_static_gen7, FALSE), KERNEL(WM_KERNEL_MASKCA_AFFINE, ps_kernel_maskca_affine_static_gen7, TRUE), KERNEL(WM_KERNEL_MASKCA_PROJECTIVE, ps_kernel_maskca_projective_static_gen7, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_AFFINE, ps_kernel_maskca_srcalpha_affine_static_gen7, TRUE), KERNEL(WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE, ps_kernel_maskca_srcalpha_projective_static_gen7, TRUE), KERNEL(WM_KERNEL_MASKNOCA_AFFINE, ps_kernel_masknoca_affine_static_gen7, TRUE), KERNEL(WM_KERNEL_MASKNOCA_PROJECTIVE, ps_kernel_masknoca_projective_static_gen7, TRUE), }; #undef KERNEL typedef struct _brw_cc_unit_state_padded { struct brw_cc_unit_state state; char pad[64 - sizeof(struct brw_cc_unit_state)]; } brw_cc_unit_state_padded; #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #define SURFACE_STATE_PADDED_SIZE ALIGN(MAX(sizeof(struct brw_surface_state), sizeof(struct gen7_surface_state)), 32) struct gen4_cc_unit_state { /* Index by [src_blend][dst_blend] */ brw_cc_unit_state_padded cc_state[BRW_BLENDFACTOR_COUNT][BRW_BLENDFACTOR_COUNT]; }; typedef struct gen4_composite_op { int op; sampler_state_filter_t src_filter; sampler_state_filter_t mask_filter; sampler_state_extend_t src_extend; sampler_state_extend_t mask_extend; Bool is_affine; wm_kernel_t wm_kernel; int vertex_id; } gen4_composite_op; /** Private data for gen4 render accel implementation. */ struct gen4_render_state { drm_intel_bo *vs_state_bo; drm_intel_bo *sf_state_bo; drm_intel_bo *sf_mask_state_bo; drm_intel_bo *cc_state_bo; drm_intel_bo *wm_state_bo[KERNEL_COUNT] [FILTER_COUNT] [EXTEND_COUNT] [FILTER_COUNT] [EXTEND_COUNT]; drm_intel_bo *wm_kernel_bo[KERNEL_COUNT]; drm_intel_bo *cc_vp_bo; drm_intel_bo *gen6_blend_bo; drm_intel_bo *gen6_depth_stencil_bo; drm_intel_bo *ps_sampler_state_bo[FILTER_COUNT] [EXTEND_COUNT] [FILTER_COUNT] [EXTEND_COUNT]; gen4_composite_op composite_op; }; static void gen6_emit_composite_state(struct intel_screen_private *intel); static void gen6_render_state_init(ScrnInfoPtr scrn); /** * Sets up the SF state pointing at an SF kernel. * * The SF kernel does coord interp: for each attribute, * calculate dA/dx and dA/dy. Hand these interpolation coefficients * back to SF which then hands pixels off to WM. */ static drm_intel_bo *gen4_create_sf_state(intel_screen_private *intel, drm_intel_bo * kernel_bo) { struct brw_sf_unit_state *sf_state; drm_intel_bo *sf_state_bo; int ret; sf_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 SF state", sizeof(*sf_state), 4096); assert(sf_state_bo); ret = drm_intel_bo_map(sf_state_bo, TRUE); assert(ret == 0); sf_state = memset(sf_state_bo->virtual, 0, sizeof(*sf_state)); sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF); sf_state->thread0.kernel_start_pointer = intel_uxa_emit_reloc(sf_state_bo, offsetof(struct brw_sf_unit_state, thread0), kernel_bo, sf_state->thread0.grf_reg_count << 1, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; sf_state->sf1.single_program_flow = 1; sf_state->sf1.binding_table_entry_count = 0; sf_state->sf1.thread_priority = 0; sf_state->sf1.floating_point_mode = 0; /* Mesa does this */ sf_state->sf1.illegal_op_exception_enable = 1; sf_state->sf1.mask_stack_exception_enable = 1; sf_state->sf1.sw_exception_enable = 1; sf_state->thread2.per_thread_scratch_space = 0; /* scratch space is not used in our kernel */ sf_state->thread2.scratch_space_base_pointer = 0; sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */ sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */ sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ /* don't smash vertex header, read start from dw8 */ sf_state->thread3.urb_entry_read_offset = 1; sf_state->thread3.dispatch_grf_start_reg = 3; sf_state->thread4.max_threads = SF_MAX_THREADS - 1; sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES; sf_state->sf5.viewport_transform = FALSE; /* skip viewport */ sf_state->sf6.cull_mode = BRW_CULLMODE_NONE; sf_state->sf6.scissor = 0; sf_state->sf7.trifan_pv = 2; sf_state->sf6.dest_org_vbias = 0x8; sf_state->sf6.dest_org_hbias = 0x8; drm_intel_bo_unmap(sf_state_bo); return sf_state_bo; (void)ret; } static drm_intel_bo *sampler_border_color_create(intel_screen_private *intel) { struct brw_sampler_legacy_border_color sampler_border_color; /* Set up the sampler border color (always transparent black) */ memset(&sampler_border_color, 0, sizeof(sampler_border_color)); sampler_border_color.color[0] = 0; /* R */ sampler_border_color.color[1] = 0; /* G */ sampler_border_color.color[2] = 0; /* B */ sampler_border_color.color[3] = 0; /* A */ return intel_uxa_bo_alloc_for_data(intel, &sampler_border_color, sizeof(sampler_border_color), "gen4 render sampler border color"); } static void gen4_sampler_state_init(drm_intel_bo * sampler_state_bo, struct brw_sampler_state *sampler_state, sampler_state_filter_t filter, sampler_state_extend_t extend, drm_intel_bo * border_color_bo) { uint32_t sampler_state_offset; sampler_state_offset = (char *)sampler_state - (char *)sampler_state_bo->virtual; /* PS kernel use this sampler */ memset(sampler_state, 0, sizeof(*sampler_state)); sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.border_color_mode = BRW_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SS_FILTER_NEAREST: sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST; break; case SS_FILTER_BILINEAR: sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; break; } switch (extend) { default: case SS_EXTEND_NONE: sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; break; case SS_EXTEND_REPEAT: sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; break; case SS_EXTEND_PAD: sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; break; case SS_EXTEND_REFLECT: sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_MIRROR; sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_MIRROR; sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_MIRROR; break; } sampler_state->ss2.border_color_pointer = intel_uxa_emit_reloc(sampler_state_bo, sampler_state_offset + offsetof(struct brw_sampler_state, ss2), border_color_bo, 0, I915_GEM_DOMAIN_SAMPLER, 0) >> 5; sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ } static void gen7_sampler_state_init(drm_intel_bo * sampler_state_bo, struct gen7_sampler_state *sampler_state, sampler_state_filter_t filter, sampler_state_extend_t extend, drm_intel_bo * border_color_bo) { uint32_t sampler_state_offset; sampler_state_offset = (char *)sampler_state - (char *)sampler_state_bo->virtual; /* PS kernel use this sampler */ memset(sampler_state, 0, sizeof(*sampler_state)); sampler_state->ss0.lod_preclamp = 1; /* GL mode */ /* We use the legacy mode to get the semantics specified by * the Render extension. */ sampler_state->ss0.default_color_mode = BRW_BORDER_COLOR_MODE_LEGACY; switch (filter) { default: case SS_FILTER_NEAREST: sampler_state->ss0.min_filter = BRW_MAPFILTER_NEAREST; sampler_state->ss0.mag_filter = BRW_MAPFILTER_NEAREST; break; case SS_FILTER_BILINEAR: sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR; sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR; break; } switch (extend) { default: case SS_EXTEND_NONE: sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP_BORDER; break; case SS_EXTEND_REPEAT: sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_WRAP; sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_WRAP; sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_WRAP; break; case SS_EXTEND_PAD: sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; break; case SS_EXTEND_REFLECT: sampler_state->ss3.r_wrap_mode = BRW_TEXCOORDMODE_MIRROR; sampler_state->ss3.s_wrap_mode = BRW_TEXCOORDMODE_MIRROR; sampler_state->ss3.t_wrap_mode = BRW_TEXCOORDMODE_MIRROR; break; } sampler_state->ss2.default_color_pointer = intel_uxa_emit_reloc(sampler_state_bo, sampler_state_offset + offsetof(struct gen7_sampler_state, ss2), border_color_bo, 0, I915_GEM_DOMAIN_SAMPLER, 0) >> 5; sampler_state->ss3.chroma_key_enable = 0; /* disable chromakey */ } static drm_intel_bo *gen4_create_sampler_state(intel_screen_private *intel, sampler_state_filter_t src_filter, sampler_state_extend_t src_extend, sampler_state_filter_t mask_filter, sampler_state_extend_t mask_extend, drm_intel_bo * border_color_bo) { drm_intel_bo *sampler_state_bo; struct brw_sampler_state *sampler_state; int ret; sampler_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 sampler state", sizeof(struct brw_sampler_state) * 2, 4096); assert(sampler_state_bo); ret = drm_intel_bo_map(sampler_state_bo, TRUE); assert(ret == 0); sampler_state = sampler_state_bo->virtual; gen4_sampler_state_init(sampler_state_bo, &sampler_state[0], src_filter, src_extend, border_color_bo); gen4_sampler_state_init(sampler_state_bo, &sampler_state[1], mask_filter, mask_extend, border_color_bo); drm_intel_bo_unmap(sampler_state_bo); return sampler_state_bo; (void)ret; } static drm_intel_bo * gen7_create_sampler_state(intel_screen_private *intel, sampler_state_filter_t src_filter, sampler_state_extend_t src_extend, sampler_state_filter_t mask_filter, sampler_state_extend_t mask_extend, drm_intel_bo * border_color_bo) { drm_intel_bo *sampler_state_bo; struct gen7_sampler_state *sampler_state; int ret; sampler_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen7 sampler state", sizeof(struct gen7_sampler_state) * 2, 4096); assert(sampler_state_bo); ret = drm_intel_bo_map(sampler_state_bo, TRUE); assert(ret == 0); sampler_state = sampler_state_bo->virtual; gen7_sampler_state_init(sampler_state_bo, &sampler_state[0], src_filter, src_extend, border_color_bo); gen7_sampler_state_init(sampler_state_bo, &sampler_state[1], mask_filter, mask_extend, border_color_bo); drm_intel_bo_unmap(sampler_state_bo); return sampler_state_bo; (void)ret; } static inline drm_intel_bo * i965_create_sampler_state(intel_screen_private *intel, sampler_state_filter_t src_filter, sampler_state_extend_t src_extend, sampler_state_filter_t mask_filter, sampler_state_extend_t mask_extend, drm_intel_bo * border_color_bo) { if (INTEL_INFO(intel)->gen < 070) return gen4_create_sampler_state(intel, src_filter, src_extend, mask_filter, mask_extend, border_color_bo); return gen7_create_sampler_state(intel, src_filter, src_extend, mask_filter, mask_extend, border_color_bo); } static void cc_state_init(drm_intel_bo * cc_state_bo, uint32_t cc_state_offset, int src_blend, int dst_blend, drm_intel_bo * cc_vp_bo) { struct brw_cc_unit_state *cc_state; cc_state = (struct brw_cc_unit_state *)((char *)cc_state_bo->virtual + cc_state_offset); memset(cc_state, 0, sizeof(*cc_state)); cc_state->cc0.stencil_enable = 0; /* disable stencil */ cc_state->cc2.depth_test = 0; /* disable depth test */ cc_state->cc2.logicop_enable = 0; /* disable logic op */ cc_state->cc3.ia_blend_enable = 0; /* blend alpha same as colors */ cc_state->cc3.blend_enable = 1; /* enable color blend */ cc_state->cc3.alpha_test = 0; /* disable alpha test */ cc_state->cc4.cc_viewport_state_offset = intel_uxa_emit_reloc(cc_state_bo, cc_state_offset + offsetof(struct brw_cc_unit_state, cc4), cc_vp_bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; cc_state->cc5.dither_enable = 0; /* disable dither */ cc_state->cc5.logicop_func = 0xc; /* COPY */ cc_state->cc5.statistics_enable = 1; cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD; /* Fill in alpha blend factors same as color, for the future. */ cc_state->cc5.ia_src_blend_factor = src_blend; cc_state->cc5.ia_dest_blend_factor = dst_blend; cc_state->cc6.blend_function = BRW_BLENDFUNCTION_ADD; cc_state->cc6.clamp_post_alpha_blend = 1; cc_state->cc6.clamp_pre_alpha_blend = 1; cc_state->cc6.clamp_range = 0; /* clamp range [0,1] */ cc_state->cc6.src_blend_factor = src_blend; cc_state->cc6.dest_blend_factor = dst_blend; } static drm_intel_bo *gen4_create_wm_state(intel_screen_private *intel, Bool has_mask, drm_intel_bo * kernel_bo, drm_intel_bo * sampler_bo) { struct brw_wm_unit_state *state; drm_intel_bo *wm_state_bo; int ret; wm_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 WM state", sizeof(*state), 4096); assert(wm_state_bo); ret = drm_intel_bo_map(wm_state_bo, TRUE); assert(ret == 0); state = memset(wm_state_bo->virtual, 0, sizeof(*state)); state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); state->thread0.kernel_start_pointer = intel_uxa_emit_reloc(wm_state_bo, offsetof(struct brw_wm_unit_state, thread0), kernel_bo, state->thread0.grf_reg_count << 1, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; state->thread1.single_program_flow = 0; /* scratch space is not used in our kernel */ state->thread2.scratch_space_base_pointer = 0; state->thread2.per_thread_scratch_space = 0; state->thread3.const_urb_entry_read_length = 0; state->thread3.const_urb_entry_read_offset = 0; state->thread3.urb_entry_read_offset = 0; /* wm kernel use urb from 3, see wm_program in compiler module */ state->thread3.dispatch_grf_start_reg = 3; /* must match kernel */ if (IS_GEN5(intel)) state->wm4.sampler_count = 0; /* hardware requirement */ else state->wm4.sampler_count = 1; /* 1-4 samplers used */ state->wm4.sampler_state_pointer = intel_uxa_emit_reloc(wm_state_bo, offsetof(struct brw_wm_unit_state, wm4), sampler_bo, state->wm4.sampler_count << 2, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; state->wm5.max_threads = PS_MAX_THREADS - 1; state->wm5.transposed_urb_read = 0; state->wm5.thread_dispatch_enable = 1; /* just use 16-pixel dispatch (4 subspans), don't need to change kernel * start point */ state->wm5.enable_16_pix = 1; state->wm5.enable_8_pix = 0; state->wm5.early_depth_test = 1; /* Each pair of attributes (src/mask coords) is two URB entries */ if (has_mask) { state->thread1.binding_table_entry_count = 3; /* 2 tex and fb */ state->thread3.urb_entry_read_length = 4; } else { state->thread1.binding_table_entry_count = 2; /* 1 tex and fb */ state->thread3.urb_entry_read_length = 2; } /* binding table entry count is only used for prefetching, and it has to * be set 0 for Ironlake */ if (IS_GEN5(intel)) state->thread1.binding_table_entry_count = 0; drm_intel_bo_unmap(wm_state_bo); return wm_state_bo; (void)ret; } static drm_intel_bo *gen4_create_cc_viewport(intel_screen_private *intel) { drm_intel_bo *bo; struct brw_cc_viewport vp; int ret; vp.min_depth = -1.e35; vp.max_depth = 1.e35; bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 render unit state", sizeof(vp), 4096); assert(bo); ret = drm_intel_bo_subdata(bo, 0, sizeof(vp), &vp); assert(ret == 0); return bo; (void)ret; } static drm_intel_bo *gen4_create_vs_unit_state(intel_screen_private *intel) { struct brw_vs_unit_state vs_state; memset(&vs_state, 0, sizeof(vs_state)); /* Set up the vertex shader to be disabled (passthrough) */ if (IS_GEN5(intel)) vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES >> 2; /* hardware requirement */ else vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES; vs_state.thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; vs_state.vs6.vs_enable = 0; vs_state.vs6.vert_cache_disable = 1; return intel_uxa_bo_alloc_for_data(intel, &vs_state, sizeof(vs_state), "gen4 render VS state"); } /** * Set up all combinations of cc state: each blendfactor for source and * dest. */ static drm_intel_bo *gen4_create_cc_unit_state(intel_screen_private *intel) { drm_intel_bo *cc_state_bo, *cc_vp_bo; int i, j, ret; cc_vp_bo = gen4_create_cc_viewport(intel); cc_state_bo = drm_intel_bo_alloc(intel->bufmgr, "gen4 CC state", sizeof(struct gen4_cc_unit_state), 4096); assert(cc_state_bo); ret = drm_intel_bo_map(cc_state_bo, TRUE); assert(ret == 0); for (i = 0; i < BRW_BLENDFACTOR_COUNT; i++) { for (j = 0; j < BRW_BLENDFACTOR_COUNT; j++) { cc_state_init(cc_state_bo, offsetof(struct gen4_cc_unit_state, cc_state[i][j].state), i, j, cc_vp_bo); } } drm_intel_bo_unmap(cc_state_bo); drm_intel_bo_unreference(cc_vp_bo); return cc_state_bo; (void)ret; } static uint32_t i965_get_card_format(PicturePtr picture) { unsigned i; for (i = 0; i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]); i++) if (i965_tex_formats[i].fmt == picture->format) return i965_tex_formats[i].card_fmt; assert(i != sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0])); return 0; } static sampler_state_filter_t sampler_state_filter_from_picture(int filter) { switch (filter) { case PictFilterNearest: return SS_FILTER_NEAREST; case PictFilterBilinear: return SS_FILTER_BILINEAR; default: return SS_INVALID_FILTER; } } static sampler_state_extend_t sampler_state_extend_from_picture(int repeat_type) { switch (repeat_type) { case RepeatNone: return SS_EXTEND_NONE; case RepeatNormal: return SS_EXTEND_REPEAT; case RepeatPad: return SS_EXTEND_PAD; case RepeatReflect: return SS_EXTEND_REFLECT; default: return SS_INVALID_EXTEND; } } /** * Sets up the common fields for a surface state buffer for the given * picture in the given surface state buffer. */ static int gen4_set_picture_surface_state(intel_screen_private *intel, PicturePtr picture, PixmapPtr pixmap, Bool is_dst) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); struct brw_surface_state *ss; uint32_t write_domain, read_domains; int offset; if (is_dst) { write_domain = I915_GEM_DOMAIN_RENDER; read_domains = I915_GEM_DOMAIN_RENDER; } else { write_domain = 0; read_domains = I915_GEM_DOMAIN_SAMPLER; } intel_batch_mark_pixmap_domains(intel, priv, read_domains, write_domain); ss = (struct brw_surface_state *) (intel->surface_data + intel->surface_used); memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = BRW_SURFACE_2D; if (is_dst) ss->ss0.surface_format = i965_get_dest_format(picture); else ss->ss0.surface_format = i965_get_card_format(picture); ss->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; ss->ss0.color_blend = 1; ss->ss1.base_addr = priv->bo->offset; ss->ss2.height = pixmap->drawable.height - 1; ss->ss2.width = pixmap->drawable.width - 1; ss->ss3.pitch = intel_pixmap_pitch(pixmap) - 1; ss->ss3.tile_walk = 0; /* Tiled X */ ss->ss3.tiled_surface = intel_uxa_pixmap_tiled(pixmap) ? 1 : 0; dri_bo_emit_reloc(intel->surface_bo, read_domains, write_domain, 0, intel->surface_used + offsetof(struct brw_surface_state, ss1), priv->bo); offset = intel->surface_used; intel->surface_used += SURFACE_STATE_PADDED_SIZE; return offset; } static int gen7_set_picture_surface_state(intel_screen_private *intel, PicturePtr picture, PixmapPtr pixmap, Bool is_dst) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); struct gen7_surface_state *ss; uint32_t write_domain, read_domains; int offset; if (is_dst) { write_domain = I915_GEM_DOMAIN_RENDER; read_domains = I915_GEM_DOMAIN_RENDER; } else { write_domain = 0; read_domains = I915_GEM_DOMAIN_SAMPLER; } intel_batch_mark_pixmap_domains(intel, priv, read_domains, write_domain); ss = (struct gen7_surface_state *) (intel->surface_data + intel->surface_used); memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = BRW_SURFACE_2D; if (is_dst) ss->ss0.surface_format = i965_get_dest_format(picture); else ss->ss0.surface_format = i965_get_card_format(picture); ss->ss0.tile_walk = 0; /* Tiled X */ ss->ss0.tiled_surface = intel_uxa_pixmap_tiled(pixmap) ? 1 : 0; ss->ss1.base_addr = priv->bo->offset; ss->ss2.height = pixmap->drawable.height - 1; ss->ss2.width = pixmap->drawable.width - 1; ss->ss3.pitch = intel_pixmap_pitch(pixmap) - 1; if (IS_HSW(intel)) { ss->ss7.shader_chanel_select_r = HSW_SCS_RED; ss->ss7.shader_chanel_select_g = HSW_SCS_GREEN; ss->ss7.shader_chanel_select_b = HSW_SCS_BLUE; ss->ss7.shader_chanel_select_a = HSW_SCS_ALPHA; } dri_bo_emit_reloc(intel->surface_bo, read_domains, write_domain, 0, intel->surface_used + offsetof(struct gen7_surface_state, ss1), priv->bo); offset = intel->surface_used; intel->surface_used += SURFACE_STATE_PADDED_SIZE; return offset; } static inline int i965_set_picture_surface_state(intel_screen_private *intel, PicturePtr picture, PixmapPtr pixmap, Bool is_dst) { if (INTEL_INFO(intel)->gen < 070) return gen4_set_picture_surface_state(intel, picture, pixmap, is_dst); return gen7_set_picture_surface_state(intel, picture, pixmap, is_dst); } static void gen4_composite_vertex_elements(struct intel_screen_private *intel) { struct gen4_render_state *render_state = intel->gen4_render_state; gen4_composite_op *composite_op = &render_state->composite_op; Bool has_mask = intel->render_mask != NULL; Bool is_affine = composite_op->is_affine; /* * number of extra parameters per vertex */ int nelem = has_mask ? 2 : 1; /* * size of extra parameters: * 3 for homogenous (xyzw) * 2 for cartesian (xy) */ int selem = is_affine ? 2 : 3; uint32_t w_component; uint32_t src_format; int id; id = has_mask << 1 | is_affine; if (composite_op->vertex_id == id) return; composite_op->vertex_id = id; if (is_affine) { src_format = BRW_SURFACEFORMAT_R32G32_FLOAT; w_component = BRW_VFCOMPONENT_STORE_1_FLT; } else { src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT; w_component = BRW_VFCOMPONENT_STORE_SRC; } if (IS_GEN5(intel)) { /* * The reason to add this extra vertex element in the header is that * Ironlake has different vertex header definition and origin method to * set destination element offset doesn't exist anymore, which means * hardware requires a predefined vertex element layout. * * haihao proposed this approach to fill the first vertex element, so * origin layout for Gen4 doesn't need to change, and origin shader * programs behavior is also kept. * * I think this is not bad. - zhenyu */ OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (2 + nelem)) - 1)); OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT)); } else { /* Set up our vertex elements, sourced from the single vertex buffer. * that will be set up later. */ OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (1 + nelem)) - 1)); } /* x,y */ OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); if (IS_GEN5(intel)) OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); else OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* u0, v0, w0 */ OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (src_format << VE0_FORMAT_SHIFT) | ((2 * 4) << VE0_OFFSET_SHIFT)); /* offset vb in bytes */ if (IS_GEN5(intel)) OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); else OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | ((4 + 4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* VUE offset in dwords */ /* u1, v1, w1 */ if (has_mask) { OUT_BATCH((id << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (src_format << VE0_FORMAT_SHIFT) | (((2 + selem) * 4) << VE0_OFFSET_SHIFT)); /* vb offset in bytes */ if (IS_GEN5(intel)) OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); else OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | ((4 + 4 + 4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* VUE offset in dwords */ } } static void i965_emit_composite_state(struct intel_screen_private *intel) { struct gen4_render_state *render_state = intel->gen4_render_state; gen4_composite_op *composite_op = &render_state->composite_op; int op = composite_op->op; PicturePtr mask_picture = intel->render_mask_picture; PicturePtr dest_picture = intel->render_dest_picture; PixmapPtr mask = intel->render_mask; PixmapPtr dest = intel->render_dest; sampler_state_filter_t src_filter = composite_op->src_filter; sampler_state_filter_t mask_filter = composite_op->mask_filter; sampler_state_extend_t src_extend = composite_op->src_extend; sampler_state_extend_t mask_extend = composite_op->mask_extend; uint32_t src_blend, dst_blend; intel->needs_render_state_emit = FALSE; /* Begin the long sequence of commands needed to set up the 3D * rendering pipe */ if (intel->needs_3d_invariant) { if (IS_GEN5(intel)) { /* Ironlake errata workaround: Before disabling the clipper, * you have to MI_FLUSH to get the pipeline idle. */ OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); } /* Match Mesa driver setup */ if (INTEL_INFO(intel)->gen >= 045) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); else OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); /* Set system instruction pointer */ OUT_BATCH(BRW_STATE_SIP | 0); OUT_BATCH(0); intel->needs_3d_invariant = FALSE; } if (intel->surface_reloc == 0) { /* Zero out the two base address registers so all offsets are * absolute. */ if (IS_GEN5(intel)) { OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ intel->surface_reloc = intel->batch_used; intel_batch_emit_dword(intel, intel->surface_bo->offset | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Instruction base address */ /* general state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media object state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Instruction max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); } else { OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ intel->surface_reloc = intel->batch_used; intel_batch_emit_dword(intel, intel->surface_bo->offset | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ /* general state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media object state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); } } i965_get_blend_cntl(op, mask_picture, dest_picture->format, &src_blend, &dst_blend); /* Binding table pointers */ OUT_BATCH(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4); OUT_BATCH(0); /* vs */ OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ /* Only the PS uses the binding table */ OUT_BATCH(intel->surface_table); /* The drawing rectangle clipping is always on. Set it to values that * shouldn't do any clipping. */ OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2); OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) | DRAW_XMAX(dest->drawable.width - 1)); /* ymax, xmax */ OUT_BATCH(0x00000000); /* yorigin, xorigin */ /* skip the depth buffer */ /* skip the polygon stipple */ /* skip the polygon stipple offset */ /* skip the line stipple */ /* Set the pointers to the 3d pipeline state */ OUT_BATCH(BRW_3DSTATE_PIPELINED_POINTERS | 5); OUT_RELOC(render_state->vs_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH(BRW_GS_DISABLE); /* disable GS, resulting in passthrough */ OUT_BATCH(BRW_CLIP_DISABLE); /* disable CLIP, resulting in passthrough */ if (mask) { OUT_RELOC(render_state->sf_mask_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); } else { OUT_RELOC(render_state->sf_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); } OUT_RELOC(render_state->wm_state_bo[composite_op->wm_kernel] [src_filter][src_extend] [mask_filter][mask_extend], I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_RELOC(render_state->cc_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offsetof(struct gen4_cc_unit_state, cc_state[src_blend][dst_blend])); { int urb_vs_start, urb_vs_size; int urb_gs_start, urb_gs_size; int urb_clip_start, urb_clip_size; int urb_sf_start, urb_sf_size; int urb_cs_start, urb_cs_size; urb_vs_start = 0; urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; urb_gs_start = urb_vs_start + urb_vs_size; urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE; urb_clip_start = urb_gs_start + urb_gs_size; urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE; urb_sf_start = urb_clip_start + urb_clip_size; urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE; urb_cs_start = urb_sf_start + urb_sf_size; urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; /* Erratum (Vol 1a, p32): * URB_FENCE must not cross a cache-line (64 bytes). */ if ((intel->batch_used & 15) > (16 - 3)) { int cnt = 16 - (intel->batch_used & 15); while (cnt--) OUT_BATCH(MI_NOOP); } OUT_BATCH(BRW_URB_FENCE | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) | ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) | ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT)); OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) | ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT)); /* Constant buffer state */ OUT_BATCH(BRW_CS_URB_STATE | 0); OUT_BATCH(((URB_CS_ENTRY_SIZE - 1) << 4) | (URB_CS_ENTRIES << 0)); } gen4_composite_vertex_elements(intel); } /** * Returns whether the current set of composite state plus vertex buffer is * expected to fit in the aperture. */ static Bool i965_composite_check_aperture(intel_screen_private *intel) { struct gen4_render_state *render_state = intel->gen4_render_state; gen4_composite_op *composite_op = &render_state->composite_op; drm_intel_bo *bo_table[] = { intel->batch_bo, intel->vertex_bo, intel->surface_bo, render_state->vs_state_bo, render_state->sf_state_bo, render_state->sf_mask_state_bo, render_state->wm_state_bo[composite_op->wm_kernel] [composite_op->src_filter] [composite_op->src_extend] [composite_op->mask_filter] [composite_op->mask_extend], render_state->cc_state_bo, }; drm_intel_bo *gen6_bo_table[] = { intel->batch_bo, intel->vertex_bo, intel->surface_bo, render_state->wm_kernel_bo[composite_op->wm_kernel], render_state->ps_sampler_state_bo[composite_op->src_filter] [composite_op->src_extend] [composite_op->mask_filter] [composite_op->mask_extend], render_state->cc_vp_bo, render_state->cc_state_bo, render_state->gen6_blend_bo, render_state->gen6_depth_stencil_bo, }; if (INTEL_INFO(intel)->gen >= 060) return drm_intel_bufmgr_check_aperture_space(gen6_bo_table, ARRAY_SIZE(gen6_bo_table)) == 0; else return drm_intel_bufmgr_check_aperture_space(bo_table, ARRAY_SIZE(bo_table)) == 0; } static void i965_surface_flush(struct intel_screen_private *intel) { int ret; ret = drm_intel_bo_subdata(intel->surface_bo, 0, intel->surface_used, intel->surface_data); assert(ret == 0); intel->surface_used = 0; assert (intel->surface_reloc != 0); drm_intel_bo_emit_reloc(intel->batch_bo, intel->surface_reloc * 4, intel->surface_bo, BASE_ADDRESS_MODIFY, I915_GEM_DOMAIN_INSTRUCTION, 0); intel->surface_reloc = 0; drm_intel_bo_unreference(intel->surface_bo); intel->surface_bo = drm_intel_bo_alloc(intel->bufmgr, "surface data", sizeof(intel->surface_data), 4096); assert(intel->surface_bo); return; (void)ret; } static void i965_emit_composite_primitive_identity_source(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX((srcX + w) * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX(srcY * intel->scale_units[0][1]); } static void i965_emit_composite_primitive_affine_source(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { float src_x[3], src_y[3]; if (!intel_uxa_get_transformed_coordinates(srcX, srcY, intel->transform[0], &src_x[0], &src_y[0])) return; if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h, intel->transform[0], &src_x[1], &src_y[1])) return; if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h, intel->transform[0], &src_x[2], &src_y[2])) return; OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[2] * intel->scale_units[0][0]); OUT_VERTEX(src_y[2] * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[1] * intel->scale_units[0][0]); OUT_VERTEX(src_y[1] * intel->scale_units[0][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(src_x[0] * intel->scale_units[0][0]); OUT_VERTEX(src_y[0] * intel->scale_units[0][1]); } static void i965_emit_composite_primitive_identity_source_mask(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX((srcX + w) * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX((maskX + w) * intel->scale_units[1][0]); OUT_VERTEX((maskY + h) * intel->scale_units[1][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX((srcY + h) * intel->scale_units[0][1]); OUT_VERTEX(maskX * intel->scale_units[1][0]); OUT_VERTEX((maskY + h) * intel->scale_units[1][1]); OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(srcX * intel->scale_units[0][0]); OUT_VERTEX(srcY * intel->scale_units[0][1]); OUT_VERTEX(maskX * intel->scale_units[1][0]); OUT_VERTEX(maskY * intel->scale_units[1][1]); } static void i965_emit_composite_primitive(intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3]; Bool is_affine = intel->gen4_render_state->composite_op.is_affine; if (is_affine) { if (!intel_uxa_get_transformed_coordinates(srcX, srcY, intel->transform[0], &src_x[0], &src_y[0])) return; if (!intel_uxa_get_transformed_coordinates(srcX, srcY + h, intel->transform[0], &src_x[1], &src_y[1])) return; if (!intel_uxa_get_transformed_coordinates(srcX + w, srcY + h, intel->transform[0], &src_x[2], &src_y[2])) return; } else { if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY, intel->transform[0], &src_x[0], &src_y[0], &src_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(srcX, srcY + h, intel->transform[0], &src_x[1], &src_y[1], &src_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(srcX + w, srcY + h, intel->transform[0], &src_x[2], &src_y[2], &src_w[2])) return; } if (intel->render_mask) { if (is_affine) { if (!intel_uxa_get_transformed_coordinates(maskX, maskY, intel->transform[1], &mask_x[0], &mask_y[0])) return; if (!intel_uxa_get_transformed_coordinates(maskX, maskY + h, intel->transform[1], &mask_x[1], &mask_y[1])) return; if (!intel_uxa_get_transformed_coordinates(maskX + w, maskY + h, intel->transform[1], &mask_x[2], &mask_y[2])) return; } else { if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY, intel->transform[1], &mask_x[0], &mask_y[0], &mask_w[0])) return; if (!intel_uxa_get_transformed_coordinates_3d(maskX, maskY + h, intel->transform[1], &mask_x[1], &mask_y[1], &mask_w[1])) return; if (!intel_uxa_get_transformed_coordinates_3d(maskX + w, maskY + h, intel->transform[1], &mask_x[2], &mask_y[2], &mask_w[2])) return; } } OUT_VERTEX(dstX + w); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[2] * intel->scale_units[0][0]); OUT_VERTEX(src_y[2] * intel->scale_units[0][1]); if (!is_affine) OUT_VERTEX(src_w[2]); if (intel->render_mask) { OUT_VERTEX(mask_x[2] * intel->scale_units[1][0]); OUT_VERTEX(mask_y[2] * intel->scale_units[1][1]); if (!is_affine) OUT_VERTEX(mask_w[2]); } OUT_VERTEX(dstX); OUT_VERTEX(dstY + h); OUT_VERTEX(src_x[1] * intel->scale_units[0][0]); OUT_VERTEX(src_y[1] * intel->scale_units[0][1]); if (!is_affine) OUT_VERTEX(src_w[1]); if (intel->render_mask) { OUT_VERTEX(mask_x[1] * intel->scale_units[1][0]); OUT_VERTEX(mask_y[1] * intel->scale_units[1][1]); if (!is_affine) OUT_VERTEX(mask_w[1]); } OUT_VERTEX(dstX); OUT_VERTEX(dstY); OUT_VERTEX(src_x[0] * intel->scale_units[0][0]); OUT_VERTEX(src_y[0] * intel->scale_units[0][1]); if (!is_affine) OUT_VERTEX(src_w[0]); if (intel->render_mask) { OUT_VERTEX(mask_x[0] * intel->scale_units[1][0]); OUT_VERTEX(mask_y[0] * intel->scale_units[1][1]); if (!is_affine) OUT_VERTEX(mask_w[0]); } } Bool i965_prepare_composite(int op, PicturePtr source_picture, PicturePtr mask_picture, PicturePtr dest_picture, PixmapPtr source, PixmapPtr mask, PixmapPtr dest) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); struct gen4_render_state *render_state = intel->gen4_render_state; gen4_composite_op *composite_op = &render_state->composite_op; composite_op->src_filter = sampler_state_filter_from_picture(source_picture->filter); if (composite_op->src_filter == SS_INVALID_FILTER) { intel_uxa_debug_fallback(scrn, "Bad src filter 0x%x\n", source_picture->filter); return FALSE; } composite_op->src_extend = sampler_state_extend_from_picture(source_picture->repeatType); if (composite_op->src_extend == SS_INVALID_EXTEND) { intel_uxa_debug_fallback(scrn, "Bad src repeat 0x%x\n", source_picture->repeatType); return FALSE; } if (mask_picture) { if (mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { /* Check if it's component alpha that relies on a source alpha and on * the source value. We can only get one of those into the single * source value that we get to blend with. */ if (i965_blend_op[op].src_alpha && (i965_blend_op[op].src_blend != BRW_BLENDFACTOR_ZERO)) { intel_uxa_debug_fallback(scrn, "Component alpha not supported " "with source alpha and source " "value blending.\n"); return FALSE; } } composite_op->mask_filter = sampler_state_filter_from_picture(mask_picture->filter); if (composite_op->mask_filter == SS_INVALID_FILTER) { intel_uxa_debug_fallback(scrn, "Bad mask filter 0x%x\n", mask_picture->filter); return FALSE; } composite_op->mask_extend = sampler_state_extend_from_picture(mask_picture->repeatType); if (composite_op->mask_extend == SS_INVALID_EXTEND) { intel_uxa_debug_fallback(scrn, "Bad mask repeat 0x%x\n", mask_picture->repeatType); return FALSE; } } else { composite_op->mask_filter = SS_FILTER_NEAREST; composite_op->mask_extend = SS_EXTEND_NONE; } /* Flush any pending writes prior to relocating the textures. */ if (intel_uxa_pixmap_is_dirty(source) || intel_uxa_pixmap_is_dirty(mask)) intel_batch_emit_flush(scrn); composite_op->op = op; intel->render_source_picture = source_picture; intel->render_mask_picture = mask_picture; intel->render_dest_picture = dest_picture; intel->render_source = source; intel->render_mask = mask; intel->render_dest = dest; intel->scale_units[0][0] = 1. / source->drawable.width; intel->scale_units[0][1] = 1. / source->drawable.height; intel->transform[0] = source_picture->transform; composite_op->is_affine = intel_uxa_transform_is_affine(intel->transform[0]); if (mask_picture == NULL) { intel->transform[1] = NULL; intel->scale_units[1][0] = -1; intel->scale_units[1][1] = -1; } else { assert(mask != NULL); intel->transform[1] = mask_picture->transform; intel->scale_units[1][0] = 1. / mask->drawable.width; intel->scale_units[1][1] = 1. / mask->drawable.height; composite_op->is_affine &= intel_uxa_transform_is_affine(intel->transform[1]); } if (mask) { assert(mask_picture != NULL); if (mask_picture->componentAlpha && PICT_FORMAT_RGB(mask_picture->format)) { if (i965_blend_op[op].src_alpha) { if (composite_op->is_affine) composite_op->wm_kernel = WM_KERNEL_MASKCA_SRCALPHA_AFFINE; else composite_op->wm_kernel = WM_KERNEL_MASKCA_SRCALPHA_PROJECTIVE; } else { if (composite_op->is_affine) composite_op->wm_kernel = WM_KERNEL_MASKCA_AFFINE; else composite_op->wm_kernel = WM_KERNEL_MASKCA_PROJECTIVE; } } else { if (composite_op->is_affine) composite_op->wm_kernel = WM_KERNEL_MASKNOCA_AFFINE; else composite_op->wm_kernel = WM_KERNEL_MASKNOCA_PROJECTIVE; } } else { if (composite_op->is_affine) composite_op->wm_kernel = WM_KERNEL_NOMASK_AFFINE; else composite_op->wm_kernel = WM_KERNEL_NOMASK_PROJECTIVE; } intel->prim_emit = i965_emit_composite_primitive; if (!mask) { if (intel->transform[0] == NULL) intel->prim_emit = i965_emit_composite_primitive_identity_source; else if (composite_op->is_affine) intel->prim_emit = i965_emit_composite_primitive_affine_source; } else { if (intel->transform[0] == NULL && intel->transform[1] == NULL) intel->prim_emit = i965_emit_composite_primitive_identity_source_mask; } intel->floats_per_vertex = 2 + (mask ? 2 : 1) * (composite_op->is_affine ? 2: 3); if (!i965_composite_check_aperture(intel)) { intel_batch_submit(scrn); if (!i965_composite_check_aperture(intel)) { intel_uxa_debug_fallback(scrn, "Couldn't fit render operation " "in aperture\n"); return FALSE; } } if (sizeof(intel->surface_data) - intel->surface_used < 4 * SURFACE_STATE_PADDED_SIZE) i965_surface_flush(intel); intel->needs_render_state_emit = TRUE; return TRUE; } static void i965_select_vertex_buffer(struct intel_screen_private *intel) { int id = intel->gen4_render_state->composite_op.vertex_id; int modifyenable = 0; if (intel->vertex_id & (1 << id)) return; if (INTEL_INFO(intel)->gen >= 070) modifyenable = GEN7_VB0_ADDRESS_MODIFYENABLE; /* Set up the pointer to our (single) vertex buffer */ OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3); /* XXX could use multiple vbo to reduce relocations if * frequently switching between vertex sizes, like rgb10text. */ if (INTEL_INFO(intel)->gen >= 060) { OUT_BATCH((id << GEN6_VB0_BUFFER_INDEX_SHIFT) | GEN6_VB0_VERTEXDATA | modifyenable | (4*intel->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT)); } else { OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA | (4*intel->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT)); } OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); if (INTEL_INFO(intel)->gen >= 050) OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, sizeof(intel->vertex_ptr) - 1); else OUT_BATCH(0); OUT_BATCH(0); // ignore for VERTEXDATA, but still there intel->vertex_id |= 1 << id; } static void i965_bind_surfaces(struct intel_screen_private *intel) { uint32_t *binding_table; assert(intel->surface_used + 4 * SURFACE_STATE_PADDED_SIZE <= sizeof(intel->surface_data)); binding_table = (uint32_t*) (intel->surface_data + intel->surface_used); intel->surface_table = intel->surface_used; intel->surface_used += SURFACE_STATE_PADDED_SIZE; binding_table[0] = i965_set_picture_surface_state(intel, intel->render_dest_picture, intel->render_dest, TRUE); binding_table[1] = i965_set_picture_surface_state(intel, intel->render_source_picture, intel->render_source, FALSE); if (intel->render_mask) { binding_table[2] = i965_set_picture_surface_state(intel, intel->render_mask_picture, intel->render_mask, FALSE); } } void i965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); intel_batch_start_atomic(scrn, 200); if (intel->needs_render_state_emit) { i965_bind_surfaces(intel); if (INTEL_INFO(intel)->gen >= 060) gen6_emit_composite_state(intel); else i965_emit_composite_state(intel); } if (intel->floats_per_vertex != intel->last_floats_per_vertex) { intel->vertex_index = (intel->vertex_used + intel->floats_per_vertex - 1) / intel->floats_per_vertex; intel->vertex_used = intel->vertex_index * intel->floats_per_vertex; intel->last_floats_per_vertex = intel->floats_per_vertex; } if (intel_vertex_space(intel) < 3*4*intel->floats_per_vertex) { i965_vertex_flush(intel); intel_next_vertex(intel); intel->vertex_index = 0; } i965_select_vertex_buffer(intel); if (intel->vertex_offset == 0) { if (INTEL_INFO(intel)->gen >= 070) { OUT_BATCH(BRW_3DPRIMITIVE | (7 - 2)); OUT_BATCH(BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | _3DPRIM_RECTLIST); } else { OUT_BATCH(BRW_3DPRIMITIVE | BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | 4); } intel->vertex_offset = intel->batch_used; OUT_BATCH(0); /* vertex count, to be filled in later */ OUT_BATCH(intel->vertex_index); OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ intel->vertex_count = intel->vertex_index; } intel->prim_emit(intel, srcX, srcY, maskX, maskY, dstX, dstY, w, h); intel->vertex_index += 3; if (INTEL_INFO(intel)->gen < 050) { /* XXX OMG! */ i965_vertex_flush(intel); OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); } intel_batch_end_atomic(scrn); } void i965_batch_commit_notify(intel_screen_private *intel) { intel->needs_render_state_emit = TRUE; intel->needs_3d_invariant = TRUE; intel->last_floats_per_vertex = 0; intel->vertex_index = 0; intel->gen4_render_state->composite_op.vertex_id = -1; intel->gen6_render_state.num_sf_outputs = 0; intel->gen6_render_state.samplers = NULL; intel->gen6_render_state.blend = -1; intel->gen6_render_state.kernel = NULL; intel->gen6_render_state.drawrect = -1; assert(intel->surface_reloc == 0); } /** * Called at EnterVT so we can set up our offsets into the state buffer. */ void gen4_render_state_init(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen4_render_state *render; const struct wm_kernel_info *wm_kernels; sampler_state_filter_t src_filter; sampler_state_extend_t src_extend; sampler_state_filter_t mask_filter; sampler_state_extend_t mask_extend; drm_intel_bo *sf_kernel_bo, *sf_kernel_mask_bo; drm_intel_bo *border_color_bo; int m; intel->needs_3d_invariant = TRUE; intel->surface_bo = drm_intel_bo_alloc(intel->bufmgr, "surface data", sizeof(intel->surface_data), 4096); assert(intel->surface_bo); intel->surface_used = 0; if (intel->gen4_render_state == NULL) { intel->gen4_render_state = calloc(1, sizeof(*render)); assert(intel->gen4_render_state != NULL); } if (INTEL_INFO(intel)->gen >= 060) return gen6_render_state_init(scrn); render = intel->gen4_render_state; render->composite_op.vertex_id = -1; render->vs_state_bo = gen4_create_vs_unit_state(intel); /* Set up the two SF states (one for blending with a mask, one without) */ if (IS_GEN5(intel)) { sf_kernel_bo = intel_uxa_bo_alloc_for_data(intel, sf_kernel_static_gen5, sizeof (sf_kernel_static_gen5), "sf kernel gen5"); sf_kernel_mask_bo = intel_uxa_bo_alloc_for_data(intel, sf_kernel_mask_static_gen5, sizeof(sf_kernel_mask_static_gen5), "sf mask kernel"); } else { sf_kernel_bo = intel_uxa_bo_alloc_for_data(intel, sf_kernel_static, sizeof(sf_kernel_static), "sf kernel"); sf_kernel_mask_bo = intel_uxa_bo_alloc_for_data(intel, sf_kernel_mask_static, sizeof (sf_kernel_mask_static), "sf mask kernel"); } render->sf_state_bo = gen4_create_sf_state(intel, sf_kernel_bo); render->sf_mask_state_bo = gen4_create_sf_state(intel, sf_kernel_mask_bo); drm_intel_bo_unreference(sf_kernel_bo); drm_intel_bo_unreference(sf_kernel_mask_bo); wm_kernels = IS_GEN5(intel) ? wm_kernels_gen5 : wm_kernels_gen4; for (m = 0; m < KERNEL_COUNT; m++) { render->wm_kernel_bo[m] = intel_uxa_bo_alloc_for_data(intel, wm_kernels[m].data, wm_kernels[m].size, "WM kernel"); } /* Set up the WM states: each filter/extend type for source and mask, per * kernel. */ border_color_bo = sampler_border_color_create(intel); for (src_filter = 0; src_filter < FILTER_COUNT; src_filter++) { for (src_extend = 0; src_extend < EXTEND_COUNT; src_extend++) { for (mask_filter = 0; mask_filter < FILTER_COUNT; mask_filter++) { for (mask_extend = 0; mask_extend < EXTEND_COUNT; mask_extend++) { drm_intel_bo *sampler_state_bo; sampler_state_bo = i965_create_sampler_state(intel, src_filter, src_extend, mask_filter, mask_extend, border_color_bo); for (m = 0; m < KERNEL_COUNT; m++) { render->wm_state_bo[m][src_filter][src_extend][mask_filter][mask_extend] = gen4_create_wm_state (intel, wm_kernels[m]. has_mask, render->wm_kernel_bo[m], sampler_state_bo); } drm_intel_bo_unreference(sampler_state_bo); } } } } drm_intel_bo_unreference(border_color_bo); render->cc_state_bo = gen4_create_cc_unit_state(intel); } /** * Called at LeaveVT. */ void gen4_render_state_cleanup(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen4_render_state *render_state = intel->gen4_render_state; int i, j, k, l, m; drm_intel_bo_unreference(intel->surface_bo); drm_intel_bo_unreference(render_state->vs_state_bo); drm_intel_bo_unreference(render_state->sf_state_bo); drm_intel_bo_unreference(render_state->sf_mask_state_bo); for (i = 0; i < KERNEL_COUNT; i++) drm_intel_bo_unreference(render_state->wm_kernel_bo[i]); for (i = 0; i < FILTER_COUNT; i++) for (j = 0; j < EXTEND_COUNT; j++) for (k = 0; k < FILTER_COUNT; k++) for (l = 0; l < EXTEND_COUNT; l++) for (m = 0; m < KERNEL_COUNT; m++) drm_intel_bo_unreference (render_state-> wm_state_bo[m][i][j][k] [l]); for (i = 0; i < FILTER_COUNT; i++) for (j = 0; j < EXTEND_COUNT; j++) for (k = 0; k < FILTER_COUNT; k++) for (l = 0; l < EXTEND_COUNT; l++) drm_intel_bo_unreference(render_state->ps_sampler_state_bo[i][j][k][l]); drm_intel_bo_unreference(render_state->cc_state_bo); drm_intel_bo_unreference(render_state->cc_vp_bo); drm_intel_bo_unreference(render_state->gen6_blend_bo); drm_intel_bo_unreference(render_state->gen6_depth_stencil_bo); free(intel->gen4_render_state); intel->gen4_render_state = NULL; } /* * for GEN6+ */ #define GEN6_BLEND_STATE_PADDED_SIZE ALIGN(sizeof(struct gen6_blend_state), 64) static drm_intel_bo * gen6_composite_create_cc_state(intel_screen_private *intel) { struct gen6_color_calc_state *state; drm_intel_bo *cc_bo; int ret; cc_bo = drm_intel_bo_alloc(intel->bufmgr, "gen6 CC state", sizeof(*state), 4096); assert(cc_bo); ret = drm_intel_bo_map(cc_bo, TRUE); assert(ret == 0); state = memset(cc_bo->virtual, 0, sizeof(*state)); state->constant_r = 1.0; state->constant_g = 0.0; state->constant_b = 1.0; state->constant_a = 1.0; drm_intel_bo_unmap(cc_bo); return cc_bo; (void)ret; } static drm_intel_bo * gen6_composite_create_blend_state(intel_screen_private *intel) { drm_intel_bo *blend_bo; int src, dst, ret; blend_bo = drm_intel_bo_alloc(intel->bufmgr, "gen6 BLEND state", BRW_BLENDFACTOR_COUNT * BRW_BLENDFACTOR_COUNT * GEN6_BLEND_STATE_PADDED_SIZE, 4096); assert(blend_bo); ret = drm_intel_bo_map(blend_bo, TRUE); assert(ret == 0); memset(blend_bo->virtual, 0, blend_bo->size); for (src = 0; src < BRW_BLENDFACTOR_COUNT; src++) { for (dst = 0; dst < BRW_BLENDFACTOR_COUNT; dst++) { uint32_t blend_state_offset = (src * BRW_BLENDFACTOR_COUNT + dst) * GEN6_BLEND_STATE_PADDED_SIZE; struct gen6_blend_state *blend; blend = (struct gen6_blend_state *)((char *)blend_bo->virtual + blend_state_offset); blend->blend0.dest_blend_factor = dst; blend->blend0.source_blend_factor = src; blend->blend0.blend_func = BRW_BLENDFUNCTION_ADD; blend->blend0.blend_enable = 1; blend->blend1.post_blend_clamp_enable = 1; blend->blend1.pre_blend_clamp_enable = 1; } } drm_intel_bo_unmap(blend_bo); return blend_bo; (void)ret; } static drm_intel_bo * gen6_composite_create_depth_stencil_state(intel_screen_private *intel) { drm_intel_bo *depth_stencil_bo; int ret; depth_stencil_bo = drm_intel_bo_alloc(intel->bufmgr, "gen6 DEPTH_STENCIL state", sizeof(struct gen6_depth_stencil_state), 4096); assert(depth_stencil_bo); ret = drm_intel_bo_map(depth_stencil_bo, TRUE); assert(ret == 0); memset(depth_stencil_bo->virtual, 0, sizeof(struct gen6_depth_stencil_state)); drm_intel_bo_unmap(depth_stencil_bo); return depth_stencil_bo; (void)ret; } static void gen6_composite_state_base_address(intel_screen_private *intel) { OUT_BATCH(BRW_STATE_BASE_ADDRESS | (10 - 2)); OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state base address */ intel->surface_reloc = intel->batch_used; intel_batch_emit_dword(intel, intel->surface_bo->offset | BASE_ADDRESS_MODIFY); OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction access upper bound */ } static void gen6_composite_cc_state_pointers(intel_screen_private *intel, uint32_t blend_offset) { struct gen4_render_state *render_state = intel->gen4_render_state; drm_intel_bo *cc_bo = NULL; drm_intel_bo *depth_stencil_bo = NULL; if (intel->gen6_render_state.blend == blend_offset) return; if (intel->gen6_render_state.blend == -1) { cc_bo = render_state->cc_state_bo; depth_stencil_bo = render_state->gen6_depth_stencil_bo; } if (INTEL_INFO(intel)->gen >= 070) { gen7_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset); } else { gen6_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset); } intel->gen6_render_state.blend = blend_offset; } static void gen6_composite_sampler_state_pointers(intel_screen_private *intel, drm_intel_bo *bo) { if (intel->gen6_render_state.samplers == bo) return; intel->gen6_render_state.samplers = bo; if (INTEL_INFO(intel)->gen >= 070) gen7_upload_sampler_state_pointers(intel, bo); else gen6_upload_sampler_state_pointers(intel, bo); } static void gen6_composite_wm_constants(intel_screen_private *intel) { Bool ivb = INTEL_INFO(intel)->gen >= 070; /* disable WM constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | ((ivb ? 7 : 5) - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); if (ivb) { OUT_BATCH(0); OUT_BATCH(0); } } static void gen6_composite_sf_state(intel_screen_private *intel, Bool has_mask) { int num_sf_outputs = has_mask ? 2 : 1; if (intel->gen6_render_state.num_sf_outputs == num_sf_outputs) return; intel->gen6_render_state.num_sf_outputs = num_sf_outputs; if (INTEL_INFO(intel)->gen >= 070) gen7_upload_sf_state(intel, num_sf_outputs, 1); else gen6_upload_sf_state(intel, num_sf_outputs, 1); } static void gen6_composite_wm_state(intel_screen_private *intel, Bool has_mask, drm_intel_bo *bo) { int num_surfaces = has_mask ? 3 : 2; int num_sf_outputs = has_mask ? 2 : 1; if (intel->gen6_render_state.kernel == bo) return; intel->gen6_render_state.kernel = bo; OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2)); OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) | (num_surfaces << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT)); OUT_BATCH(0); OUT_BATCH((6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT)); /* DW4 */ OUT_BATCH(((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT) | GEN6_3DSTATE_WM_DISPATCH_ENABLE | GEN6_3DSTATE_WM_16_DISPATCH_ENABLE); OUT_BATCH((num_sf_outputs << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT) | GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(0); OUT_BATCH(0); } static void gen7_composite_wm_state(intel_screen_private *intel, Bool has_mask, drm_intel_bo *bo) { int num_surfaces = has_mask ? 3 : 2; unsigned int max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_IVB; unsigned int num_samples = 0; if (IS_HSW(intel)) { max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_HSW; num_samples = 1 << GEN7_PS_SAMPLE_MASK_SHIFT_HSW; } if (intel->gen6_render_state.kernel == bo) return; intel->gen6_render_state.kernel = bo; OUT_BATCH(GEN6_3DSTATE_WM | (3 - 2)); OUT_BATCH(GEN7_WM_DISPATCH_ENABLE | GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2)); OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) | (num_surfaces << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); OUT_BATCH(0); /* scratch space base offset */ OUT_BATCH(((48 - 1) << max_threads_shift) | num_samples | GEN7_PS_ATTRIBUTE_ENABLE | GEN7_PS_16_DISPATCH_ENABLE); OUT_BATCH((6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_0)); OUT_BATCH(0); /* kernel 1 pointer */ OUT_BATCH(0); /* kernel 2 pointer */ } static void gen6_composite_drawing_rectangle(intel_screen_private *intel, PixmapPtr dest) { uint32_t dw = DRAW_YMAX(dest->drawable.height - 1) | DRAW_XMAX(dest->drawable.width - 1); /* XXX cacomposite depends upon the implicit non-pipelined flush */ if (0 && intel->gen6_render_state.drawrect == dw) return; intel->gen6_render_state.drawrect = dw; OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | (4 - 2)); OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH(dw); /* ymax, xmax */ OUT_BATCH(0x00000000); /* yorigin, xorigin */ } static void gen6_composite_vertex_element_state(intel_screen_private *intel, Bool has_mask, Bool is_affine) { /* * vertex data in vertex buffer * position: (x, y) * texture coordinate 0: (u0, v0) if (is_affine is TRUE) else (u0, v0, w0) * texture coordinate 1 if (has_mask is TRUE): same as above */ gen4_composite_op *composite_op = &intel->gen4_render_state->composite_op; int nelem = has_mask ? 2 : 1; int selem = is_affine ? 2 : 3; uint32_t w_component; uint32_t src_format; int id; id = has_mask << 1 | is_affine; if (composite_op->vertex_id == id) return; composite_op->vertex_id = id; if (is_affine) { src_format = BRW_SURFACEFORMAT_R32G32_FLOAT; w_component = BRW_VFCOMPONENT_STORE_1_FLT; } else { src_format = BRW_SURFACEFORMAT_R32G32B32_FLOAT; w_component = BRW_VFCOMPONENT_STORE_SRC; } /* The VUE layout * dword 0-3: pad (0.0, 0.0, 0.0. 0.0) * dword 4-7: position (x, y, 1.0, 1.0), * dword 8-11: texture coordinate 0 (u0, v0, w0, 1.0) * dword 12-15: texture coordinate 1 (u1, v1, w1, 1.0) * * dword 4-15 are fetched from vertex buffer */ OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | ((2 * (2 + nelem)) + 1 - 2)); OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_3_SHIFT)); /* x,y */ OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); /* offsets vb in bytes */ OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); /* u0, v0, w0 */ OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (src_format << VE0_FORMAT_SHIFT) | ((2 * 4) << VE0_OFFSET_SHIFT)); /* offset vb in bytes */ OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); /* u1, v1, w1 */ if (has_mask) { OUT_BATCH((id << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (src_format << VE0_FORMAT_SHIFT) | (((2 + selem) * 4) << VE0_OFFSET_SHIFT)); /* vb offset in bytes */ OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (w_component << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); } } static void gen6_emit_composite_state(struct intel_screen_private *intel) { struct gen4_render_state *render = intel->gen4_render_state; gen4_composite_op *composite_op = &render->composite_op; sampler_state_filter_t src_filter = composite_op->src_filter; sampler_state_filter_t mask_filter = composite_op->mask_filter; sampler_state_extend_t src_extend = composite_op->src_extend; sampler_state_extend_t mask_extend = composite_op->mask_extend; Bool is_affine = composite_op->is_affine; Bool has_mask = intel->render_mask != NULL; Bool ivb = INTEL_INFO(intel)->gen >= 070; uint32_t src, dst; drm_intel_bo *ps_sampler_state_bo = render->ps_sampler_state_bo[src_filter][src_extend][mask_filter][mask_extend]; intel->needs_render_state_emit = FALSE; if (intel->needs_3d_invariant) { gen6_upload_invariant_states(intel); if (ivb) { gen7_upload_viewport_state_pointers(intel, render->cc_vp_bo); gen7_upload_urb(intel); gen7_upload_bypass_states(intel); gen7_upload_depth_buffer_state(intel); } else { gen6_upload_invariant_states(intel); gen6_upload_viewport_state_pointers(intel, render->cc_vp_bo); gen6_upload_urb(intel); gen6_upload_gs_state(intel); gen6_upload_depth_buffer_state(intel); } gen6_composite_wm_constants(intel); gen6_upload_vs_state(intel); gen6_upload_clip_state(intel); intel->needs_3d_invariant = FALSE; } i965_get_blend_cntl(composite_op->op, intel->render_mask_picture, intel->render_dest_picture->format, &src, &dst); if (intel->surface_reloc == 0) gen6_composite_state_base_address(intel); gen6_composite_cc_state_pointers(intel, (src * BRW_BLENDFACTOR_COUNT + dst) * GEN6_BLEND_STATE_PADDED_SIZE); gen6_composite_sampler_state_pointers(intel, ps_sampler_state_bo); gen6_composite_sf_state(intel, has_mask); if (ivb) { gen7_composite_wm_state(intel, has_mask, render->wm_kernel_bo[composite_op->wm_kernel]); gen7_upload_binding_table(intel, intel->surface_table); } else { gen6_composite_wm_state(intel, has_mask, render->wm_kernel_bo[composite_op->wm_kernel]); gen6_upload_binding_table(intel, intel->surface_table); } gen6_composite_drawing_rectangle(intel, intel->render_dest); gen6_composite_vertex_element_state(intel, has_mask, is_affine); } static void gen6_render_state_init(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen4_render_state *render; sampler_state_filter_t src_filter; sampler_state_filter_t mask_filter; sampler_state_extend_t src_extend; sampler_state_extend_t mask_extend; int m; drm_intel_bo *border_color_bo; const struct wm_kernel_info *wm_kernels; render= intel->gen4_render_state; render->composite_op.vertex_id = -1; intel->gen6_render_state.num_sf_outputs = 0; intel->gen6_render_state.samplers = NULL; intel->gen6_render_state.blend = -1; intel->gen6_render_state.kernel = NULL; intel->gen6_render_state.drawrect = -1; wm_kernels = IS_GEN7(intel) ? wm_kernels_gen7 : wm_kernels_gen6; for (m = 0; m < KERNEL_COUNT; m++) { render->wm_kernel_bo[m] = intel_uxa_bo_alloc_for_data(intel, wm_kernels[m].data, wm_kernels[m].size, "WM kernel gen6/7"); } border_color_bo = sampler_border_color_create(intel); for (src_filter = 0; src_filter < FILTER_COUNT; src_filter++) { for (src_extend = 0; src_extend < EXTEND_COUNT; src_extend++) { for (mask_filter = 0; mask_filter < FILTER_COUNT; mask_filter++) { for (mask_extend = 0; mask_extend < EXTEND_COUNT; mask_extend++) { render->ps_sampler_state_bo[src_filter][src_extend][mask_filter][mask_extend] = i965_create_sampler_state(intel, src_filter, src_extend, mask_filter, mask_extend, border_color_bo); } } } } drm_intel_bo_unreference(border_color_bo); render->cc_vp_bo = gen4_create_cc_viewport(intel); render->cc_state_bo = gen6_composite_create_cc_state(intel); render->gen6_blend_bo = gen6_composite_create_blend_state(intel); render->gen6_depth_stencil_bo = gen6_composite_create_depth_stencil_state(intel); } void i965_vertex_flush(struct intel_screen_private *intel) { if (intel->vertex_offset) { intel->batch_ptr[intel->vertex_offset] = intel->vertex_index - intel->vertex_count; intel->vertex_offset = 0; } } void i965_batch_flush(struct intel_screen_private *intel) { if (intel->surface_used) i965_surface_flush(intel); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/i965_video.c000066400000000000000000001712331267532330400237140ustar00rootroot00000000000000/* * Copyright 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Eric Anholt * Keith Packard * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86xv.h" #include "fourcc.h" #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" #include "i965_reg.h" #include "brw_defines.h" #include "brw_structs.h" #include /* Make assert() work. */ #undef NDEBUG #include static const uint32_t sip_kernel_static[][4] = { /* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */ {0x00000030, 0x20000108, 0x00001220, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, /* nop (4) g0<1>UD { align1 + } */ {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, }; /* * this program computes dA/dx and dA/dy for the texture coordinates along * with the base texture coordinate. It was extracted from the Mesa driver. * It uses about 10 GRF registers. */ #define SF_KERNEL_NUM_GRF 16 #define SF_MAX_THREADS 1 static const uint32_t sf_kernel_static[][4] = { #include "exa_sf.g4b" }; /* * Ok, this kernel picks up the required data flow values in g0 and g1 * and passes those along in m0 and m1. In m2-m9, it sticks constant * values (bright pink). */ /* Our PS kernel uses less than 32 GRF registers (about 20) */ #define PS_KERNEL_NUM_GRF 32 #define PS_MAX_THREADS 32 #define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) static const uint32_t ps_kernel_packed_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_argb.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; static const uint32_t ps_kernel_planar_static[][4] = { #include "exa_wm_xy.g4b" #include "exa_wm_src_affine.g4b" #include "exa_wm_src_sample_planar.g4b" #include "exa_wm_yuv_rgb.g4b" #include "exa_wm_write.g4b" }; /* new program for Ironlake */ static const uint32_t sf_kernel_static_gen5[][4] = { #include "exa_sf.g4b.gen5" }; static const uint32_t ps_kernel_packed_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_argb.g4b.gen5" #include "exa_wm_yuv_rgb.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; static const uint32_t ps_kernel_planar_static_gen5[][4] = { #include "exa_wm_xy.g4b.gen5" #include "exa_wm_src_affine.g4b.gen5" #include "exa_wm_src_sample_planar.g4b.gen5" #include "exa_wm_yuv_rgb.g4b.gen5" #include "exa_wm_write.g4b.gen5" }; /* programs for Sandybridge */ static const uint32_t ps_kernel_packed_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_argb.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; static const uint32_t ps_kernel_planar_static_gen6[][4] = { #include "exa_wm_src_affine.g6b" #include "exa_wm_src_sample_planar.g6b" #include "exa_wm_yuv_rgb.g6b" #include "exa_wm_write.g6b" }; /* programs for Ivybridge */ static const uint32_t ps_kernel_packed_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_argb.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; static const uint32_t ps_kernel_planar_static_gen7[][4] = { #include "exa_wm_src_affine.g7b" #include "exa_wm_src_sample_planar.g7b" #include "exa_wm_yuv_rgb.g7b" #include "exa_wm_write.g7b" }; #ifndef MAX2 #define MAX2(a,b) ((a) > (b) ? (a) : (b)) #endif #define SURFACE_STATE_PADDED_SIZE_I965 ALIGN(sizeof(struct brw_surface_state), 32) #define SURFACE_STATE_PADDED_SIZE_GEN7 ALIGN(sizeof(struct gen7_surface_state), 32) #define SURFACE_STATE_PADDED_SIZE MAX2(SURFACE_STATE_PADDED_SIZE_I965, SURFACE_STATE_PADDED_SIZE_GEN7) #define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index) static uint32_t float_to_uint(float f) { union { uint32_t i; float f; } x; x.f = f; return x.i; } #if 0 static struct { uint32_t svg_ctl; char *name; } svg_ctl_bits[] = { { BRW_SVG_CTL_GS_BA, "General State Base Address"}, { BRW_SVG_CTL_SS_BA, "Surface State Base Address"}, { BRW_SVG_CTL_IO_BA, "Indirect Object Base Address"}, { BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound"}, { BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound"}, { BRW_SVG_CTL_SIP, "System Instruction Pointer"}, { 0, 0},}; static void brw_debug(ScrnInfoPtr scrn, char *when) { intel_screen_private *intel = intel_get_screen_private(scrn); int i; uint32_t v; ErrorF("brw_debug: %s\n", when); for (i = 0; svg_ctl_bits[i].name; i++) { OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl); v = INREG(BRW_SVG_RDATA); ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v); } } #endif #define WATCH_SF 0 #define WATCH_WIZ 0 #define WATCH_STATS 0 static void i965_pre_draw_debug(ScrnInfoPtr scrn) { #if 0 intel_screen_private *intel = intel_get_screen_private(scrn); #endif #if 0 ErrorF("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n", INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0), INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0)); OUTREG(BRW_VF_CTL, BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID | BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX | BRW_VF_CTL_SNAPSHOT_ENABLE); OUTREG(BRW_VF_STRG_VAL, 0); #endif #if 0 OUTREG(BRW_VS_CTL, BRW_VS_CTL_SNAPSHOT_ALL_THREADS | BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT | BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE); OUTREG(BRW_VS_STRG_VAL, 0); #endif #if WATCH_SF OUTREG(BRW_SF_CTL, BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT | BRW_SF_CTL_SNAPSHOT_ALL_THREADS | BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE); OUTREG(BRW_SF_STRG_VAL, 0); #endif #if WATCH_WIZ OUTREG(BRW_WIZ_CTL, BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE | BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS | BRW_WIZ_CTL_SNAPSHOT_ENABLE); OUTREG(BRW_WIZ_STRG_VAL, (box_x1) | (box_y1 << 16)); #endif #if 0 OUTREG(BRW_TS_CTL, BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR | BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS | BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS | BRW_TS_CTL_SNAPSHOT_ENABLE); #endif } static void i965_post_draw_debug(ScrnInfoPtr scrn) { #if 0 intel_screen_private *intel = intel_get_screen_private(scrn); #endif #if 0 for (j = 0; j < 100000; j++) { ctl = INREG(BRW_VF_CTL); if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE) break; } rdata = INREG(BRW_VF_RDATA); OUTREG(BRW_VF_CTL, 0); ErrorF("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata); #endif #if 0 for (j = 0; j < 1000000; j++) { ctl = INREG(BRW_VS_CTL); if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE) break; } rdata = INREG(BRW_VS_RDATA); for (k = 0; k <= 3; k++) { OUTREG(BRW_VS_CTL, BRW_VS_CTL_SNAPSHOT_COMPLETE | (k << 8)); rdata = INREG(BRW_VS_RDATA); ErrorF("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata); } OUTREG(BRW_VS_CTL, 0); #endif #if WATCH_SF for (j = 0; j < 1000000; j++) { ctl = INREG(BRW_SF_CTL); if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE) break; } for (k = 0; k <= 7; k++) { OUTREG(BRW_SF_CTL, BRW_SF_CTL_SNAPSHOT_COMPLETE | (k << 8)); rdata = INREG(BRW_SF_RDATA); ErrorF("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata); } OUTREG(BRW_SF_CTL, 0); #endif #if WATCH_WIZ for (j = 0; j < 100000; j++) { ctl = INREG(BRW_WIZ_CTL); if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE) break; } rdata = INREG(BRW_WIZ_RDATA); OUTREG(BRW_WIZ_CTL, 0); ErrorF("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata); #endif #if 0 for (j = 0; j < 100000; j++) { ctl = INREG(BRW_TS_CTL); if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE) break; } rdata = INREG(BRW_TS_RDATA); OUTREG(BRW_TS_CTL, 0); ErrorF("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata); ErrorF("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n", INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0), INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0)); #endif #if 0 for (j = 0; j < 256; j++) { OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT); rdata = INREG(BRW_TD_RDATA); ErrorF("TD_RDATA(%d): 0x%08x\n", j, rdata); } #endif } /* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it. * A VUE consists of a 256-bit vertex header followed by the vertex data, * which in our case is 4 floats (128 bits), thus a single 512-bit URB * entry. */ #define URB_VS_ENTRIES 8 #define URB_VS_ENTRY_SIZE 1 #define URB_GS_ENTRIES 0 #define URB_GS_ENTRY_SIZE 0 #define URB_CLIP_ENTRIES 0 #define URB_CLIP_ENTRY_SIZE 0 /* The SF kernel we use outputs only 4 256-bit registers, leading to an * entry size of 2 512-bit URBs. We don't need to have many entries to * output as we're generally working on large rectangles and don't care * about having WM threads running on different rectangles simultaneously. */ #define URB_SF_ENTRIES 1 #define URB_SF_ENTRY_SIZE 2 #define URB_CS_ENTRIES 0 #define URB_CS_ENTRY_SIZE 0 static void i965_create_dst_surface_state(ScrnInfoPtr scrn, PixmapPtr pixmap, drm_intel_bo *surf_bo, uint32_t offset) { intel_screen_private *intel = intel_get_screen_private(scrn); struct brw_surface_state dest_surf_state; drm_intel_bo *pixmap_bo = intel_uxa_get_pixmap_bo(pixmap); assert(pixmap_bo != NULL); memset(&dest_surf_state, 0, sizeof(dest_surf_state)); dest_surf_state.ss0.surface_type = BRW_SURFACE_2D; dest_surf_state.ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32; if (intel->cpp == 2) { dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; } else { dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; } dest_surf_state.ss0.writedisable_alpha = 0; dest_surf_state.ss0.writedisable_red = 0; dest_surf_state.ss0.writedisable_green = 0; dest_surf_state.ss0.writedisable_blue = 0; dest_surf_state.ss0.color_blend = 1; dest_surf_state.ss0.vert_line_stride = 0; dest_surf_state.ss0.vert_line_stride_ofs = 0; dest_surf_state.ss0.mipmap_layout_mode = 0; dest_surf_state.ss0.render_cache_read_mode = 0; dest_surf_state.ss1.base_addr = intel_uxa_emit_reloc(surf_bo, offset + offsetof(struct brw_surface_state, ss1), pixmap_bo, 0, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); dest_surf_state.ss2.height = pixmap->drawable.height - 1; dest_surf_state.ss2.width = pixmap->drawable.width - 1; dest_surf_state.ss2.mip_count = 0; dest_surf_state.ss2.render_target_rotation = 0; dest_surf_state.ss3.pitch = intel_pixmap_pitch(pixmap) - 1; dest_surf_state.ss3.tiled_surface = intel_uxa_pixmap_tiled(pixmap); dest_surf_state.ss3.tile_walk = 0; /* TileX */ dri_bo_subdata(surf_bo, offset, sizeof(dest_surf_state), &dest_surf_state); } static void i965_create_src_surface_state(ScrnInfoPtr scrn, drm_intel_bo * src_bo, uint32_t src_offset, int src_width, int src_height, int src_pitch, uint32_t src_surf_format, drm_intel_bo *surface_bo, uint32_t offset) { struct brw_surface_state src_surf_state; memset(&src_surf_state, 0, sizeof(src_surf_state)); /* Set up the source surface state buffer */ src_surf_state.ss0.surface_type = BRW_SURFACE_2D; src_surf_state.ss0.surface_format = src_surf_format; src_surf_state.ss0.writedisable_alpha = 0; src_surf_state.ss0.writedisable_red = 0; src_surf_state.ss0.writedisable_green = 0; src_surf_state.ss0.writedisable_blue = 0; src_surf_state.ss0.color_blend = 1; src_surf_state.ss0.vert_line_stride = 0; src_surf_state.ss0.vert_line_stride_ofs = 0; src_surf_state.ss0.mipmap_layout_mode = 0; src_surf_state.ss0.render_cache_read_mode = 0; src_surf_state.ss2.width = src_width - 1; src_surf_state.ss2.height = src_height - 1; src_surf_state.ss2.mip_count = 0; src_surf_state.ss2.render_target_rotation = 0; src_surf_state.ss3.pitch = src_pitch - 1; if (src_bo) { src_surf_state.ss1.base_addr = intel_uxa_emit_reloc(surface_bo, offset + offsetof(struct brw_surface_state, ss1), src_bo, src_offset, I915_GEM_DOMAIN_SAMPLER, 0); } else { src_surf_state.ss1.base_addr = src_offset; } dri_bo_subdata(surface_bo, offset, sizeof(src_surf_state), &src_surf_state); } static void gen7_create_dst_surface_state(ScrnInfoPtr scrn, PixmapPtr pixmap, drm_intel_bo *surf_bo, uint32_t offset) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen7_surface_state dest_surf_state; drm_intel_bo *pixmap_bo = intel_uxa_get_pixmap_bo(pixmap); assert(pixmap_bo != NULL); memset(&dest_surf_state, 0, sizeof(dest_surf_state)); dest_surf_state.ss0.surface_type = BRW_SURFACE_2D; dest_surf_state.ss0.tiled_surface = intel_uxa_pixmap_tiled(pixmap); dest_surf_state.ss0.tile_walk = 0; /* TileX */ if (intel->cpp == 2) { dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; } else { dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; } dest_surf_state.ss1.base_addr = intel_uxa_emit_reloc(surf_bo, offset + offsetof(struct gen7_surface_state, ss1), pixmap_bo, 0, I915_GEM_DOMAIN_SAMPLER, 0); dest_surf_state.ss2.height = pixmap->drawable.height - 1; dest_surf_state.ss2.width = pixmap->drawable.width - 1; dest_surf_state.ss3.pitch = intel_pixmap_pitch(pixmap) - 1; if (IS_HSW(intel)) { dest_surf_state.ss7.shader_chanel_select_r = HSW_SCS_RED; dest_surf_state.ss7.shader_chanel_select_g = HSW_SCS_GREEN; dest_surf_state.ss7.shader_chanel_select_b = HSW_SCS_BLUE; dest_surf_state.ss7.shader_chanel_select_a = HSW_SCS_ALPHA; } dri_bo_subdata(surf_bo, offset, sizeof(dest_surf_state), &dest_surf_state); } static void gen7_create_src_surface_state(ScrnInfoPtr scrn, drm_intel_bo * src_bo, uint32_t src_offset, int src_width, int src_height, int src_pitch, uint32_t src_surf_format, drm_intel_bo *surface_bo, uint32_t offset) { intel_screen_private * const intel = intel_get_screen_private(scrn); struct gen7_surface_state src_surf_state; memset(&src_surf_state, 0, sizeof(src_surf_state)); src_surf_state.ss0.surface_type = BRW_SURFACE_2D; src_surf_state.ss0.surface_format = src_surf_format; if (src_bo) { src_surf_state.ss1.base_addr = intel_uxa_emit_reloc(surface_bo, offset + offsetof(struct gen7_surface_state, ss1), src_bo, src_offset, I915_GEM_DOMAIN_SAMPLER, 0); } else { src_surf_state.ss1.base_addr = src_offset; } src_surf_state.ss2.width = src_width - 1; src_surf_state.ss2.height = src_height - 1; src_surf_state.ss3.pitch = src_pitch - 1; if (IS_HSW(intel)) { src_surf_state.ss7.shader_chanel_select_r = HSW_SCS_RED; src_surf_state.ss7.shader_chanel_select_g = HSW_SCS_GREEN; src_surf_state.ss7.shader_chanel_select_b = HSW_SCS_BLUE; src_surf_state.ss7.shader_chanel_select_a = HSW_SCS_ALPHA; } dri_bo_subdata(surface_bo, offset, sizeof(src_surf_state), &src_surf_state); } static void i965_create_binding_table(ScrnInfoPtr scrn, drm_intel_bo *bind_bo, int n_surf) { uint32_t binding_table[n_surf]; int i; /* Set up a binding table for our surfaces. Only the PS will use it */ for (i = 0; i < n_surf; i++) binding_table[i] = i * SURFACE_STATE_PADDED_SIZE; dri_bo_subdata(bind_bo, n_surf * SURFACE_STATE_PADDED_SIZE, sizeof(binding_table), binding_table); } static drm_intel_bo *i965_create_sampler_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct brw_sampler_state sampler_state; memset(&sampler_state, 0, sizeof(sampler_state)); sampler_state.ss0.min_filter = BRW_MAPFILTER_LINEAR; sampler_state.ss0.mag_filter = BRW_MAPFILTER_LINEAR; sampler_state.ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state.ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state.ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; return intel_uxa_bo_alloc_for_data(intel, &sampler_state, sizeof(sampler_state), "textured video sampler state"); } static drm_intel_bo *gen7_create_sampler_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen7_sampler_state sampler_state; memset(&sampler_state, 0, sizeof(sampler_state)); sampler_state.ss0.min_filter = BRW_MAPFILTER_LINEAR; sampler_state.ss0.mag_filter = BRW_MAPFILTER_LINEAR; sampler_state.ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state.ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; sampler_state.ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; return intel_uxa_bo_alloc_for_data(intel, &sampler_state, sizeof(sampler_state), "textured video sampler state"); } static drm_intel_bo *i965_create_vs_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct brw_vs_unit_state vs_state; /* Set up the vertex shader to be disabled (passthrough) */ memset(&vs_state, 0, sizeof(vs_state)); if (IS_GEN5(intel)) vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES >> 2; else vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES; vs_state.thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; vs_state.vs6.vs_enable = 0; vs_state.vs6.vert_cache_disable = 1; return intel_uxa_bo_alloc_for_data(intel, &vs_state, sizeof(vs_state), "textured video vs state"); } static drm_intel_bo *i965_create_program(ScrnInfoPtr scrn, const uint32_t * program, unsigned int program_size) { intel_screen_private *intel = intel_get_screen_private(scrn); return intel_uxa_bo_alloc_for_data(intel, program, program_size, "textured video program"); } static drm_intel_bo *i965_create_sf_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *sf_bo, *kernel_bo; struct brw_sf_unit_state sf_state; if (IS_GEN5(intel)) kernel_bo = i965_create_program(scrn, &sf_kernel_static_gen5[0][0], sizeof(sf_kernel_static_gen5)); else kernel_bo = i965_create_program(scrn, &sf_kernel_static[0][0], sizeof(sf_kernel_static)); if (!kernel_bo) return NULL; sf_bo = drm_intel_bo_alloc(intel->bufmgr, "textured video sf state", 4096, sizeof(sf_state)); if (sf_bo == NULL) { drm_intel_bo_unreference(kernel_bo); return NULL; } /* Set up the SF kernel to do coord interp: for each attribute, * calculate dA/dx and dA/dy. Hand these interpolation coefficients * back to SF which then hands pixels off to WM. */ memset(&sf_state, 0, sizeof(sf_state)); sf_state.thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF); sf_state.thread0.kernel_start_pointer = intel_uxa_emit_reloc(sf_bo, offsetof(struct brw_sf_unit_state, thread0), kernel_bo, sf_state.thread0.grf_reg_count << 1, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; sf_state.sf1.single_program_flow = 1; /* XXX */ sf_state.sf1.binding_table_entry_count = 0; sf_state.sf1.thread_priority = 0; sf_state.sf1.floating_point_mode = 0; /* Mesa does this */ sf_state.sf1.illegal_op_exception_enable = 1; sf_state.sf1.mask_stack_exception_enable = 1; sf_state.sf1.sw_exception_enable = 1; sf_state.thread2.per_thread_scratch_space = 0; /* scratch space is not used in our kernel */ sf_state.thread2.scratch_space_base_pointer = 0; sf_state.thread3.const_urb_entry_read_length = 0; /* no const URBs */ sf_state.thread3.const_urb_entry_read_offset = 0; /* no const URBs */ sf_state.thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ sf_state.thread3.urb_entry_read_offset = 0; sf_state.thread3.dispatch_grf_start_reg = 3; sf_state.thread4.max_threads = SF_MAX_THREADS - 1; sf_state.thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; sf_state.thread4.nr_urb_entries = URB_SF_ENTRIES; sf_state.thread4.stats_enable = 1; sf_state.sf5.viewport_transform = FALSE; /* skip viewport */ sf_state.sf6.cull_mode = BRW_CULLMODE_NONE; sf_state.sf6.scissor = 0; sf_state.sf7.trifan_pv = 2; sf_state.sf6.dest_org_vbias = 0x8; sf_state.sf6.dest_org_hbias = 0x8; dri_bo_subdata(sf_bo, 0, sizeof(sf_state), &sf_state); return sf_bo; } static drm_intel_bo *i965_create_wm_state(ScrnInfoPtr scrn, drm_intel_bo * sampler_bo, Bool is_packed) { intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *wm_bo, *kernel_bo; struct brw_wm_unit_state wm_state; if (is_packed) { if (IS_GEN5(intel)) kernel_bo = i965_create_program(scrn, &ps_kernel_packed_static_gen5[0] [0], sizeof (ps_kernel_packed_static_gen5)); else kernel_bo = i965_create_program(scrn, &ps_kernel_packed_static[0][0], sizeof (ps_kernel_packed_static)); } else { if (IS_GEN5(intel)) kernel_bo = i965_create_program(scrn, &ps_kernel_planar_static_gen5[0] [0], sizeof (ps_kernel_planar_static_gen5)); else kernel_bo = i965_create_program(scrn, &ps_kernel_planar_static[0][0], sizeof (ps_kernel_planar_static)); } if (!kernel_bo) return NULL; wm_bo = drm_intel_bo_alloc(intel->bufmgr, "textured video wm state", sizeof(wm_state), 0); if (wm_bo == NULL) { drm_intel_bo_unreference(kernel_bo); return NULL; } memset(&wm_state, 0, sizeof(wm_state)); wm_state.thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); wm_state.thread0.kernel_start_pointer = intel_uxa_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, thread0), kernel_bo, wm_state.thread0.grf_reg_count << 1, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; wm_state.thread1.single_program_flow = 1; /* XXX */ if (is_packed) wm_state.thread1.binding_table_entry_count = 2; else wm_state.thread1.binding_table_entry_count = 7; /* binding table entry count is only used for prefetching, and it has to * be set 0 for Ironlake */ if (IS_GEN5(intel)) wm_state.thread1.binding_table_entry_count = 0; /* Though we never use the scratch space in our WM kernel, it has to be * set, and the minimum allocation is 1024 bytes. */ wm_state.thread2.scratch_space_base_pointer = 0; wm_state.thread2.per_thread_scratch_space = 0; /* 1024 bytes */ wm_state.thread3.dispatch_grf_start_reg = 3; /* XXX */ wm_state.thread3.const_urb_entry_read_length = 0; wm_state.thread3.const_urb_entry_read_offset = 0; wm_state.thread3.urb_entry_read_length = 1; /* XXX */ wm_state.thread3.urb_entry_read_offset = 0; /* XXX */ wm_state.wm4.stats_enable = 1; wm_state.wm4.sampler_state_pointer = intel_uxa_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, wm4), sampler_bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; if (IS_GEN5(intel)) wm_state.wm4.sampler_count = 0; else wm_state.wm4.sampler_count = 1; /* 1-4 samplers used */ wm_state.wm5.max_threads = PS_MAX_THREADS - 1; wm_state.wm5.thread_dispatch_enable = 1; wm_state.wm5.enable_16_pix = 1; wm_state.wm5.enable_8_pix = 0; wm_state.wm5.early_depth_test = 1; dri_bo_subdata(wm_bo, 0, sizeof(wm_state), &wm_state); drm_intel_bo_unreference(kernel_bo); return wm_bo; } static drm_intel_bo *i965_create_cc_vp_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct brw_cc_viewport cc_viewport; memset(&cc_viewport, 0, sizeof(cc_viewport)); cc_viewport.min_depth = -1.e35; cc_viewport.max_depth = 1.e35; return intel_uxa_bo_alloc_for_data(intel, &cc_viewport, sizeof(cc_viewport), "textured video cc viewport"); } static drm_intel_bo *i965_create_cc_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *cc_bo, *cc_vp_bo; struct brw_cc_unit_state cc_state; cc_vp_bo = i965_create_cc_vp_state(scrn); if (!cc_vp_bo) return NULL; cc_bo = drm_intel_bo_alloc(intel->bufmgr, "textured video cc state", sizeof(cc_state), 0); if (cc_bo == NULL){ drm_intel_bo_unreference(cc_vp_bo); return NULL; } /* Color calculator state */ memset(&cc_state, 0, sizeof(cc_state)); cc_state.cc0.stencil_enable = 0; /* disable stencil */ cc_state.cc2.depth_test = 0; /* disable depth test */ cc_state.cc2.logicop_enable = 1; /* enable logic op */ cc_state.cc3.ia_blend_enable = 1; /* blend alpha just like colors */ cc_state.cc3.blend_enable = 0; /* disable color blend */ cc_state.cc3.alpha_test = 0; /* disable alpha test */ cc_state.cc4.cc_viewport_state_offset = intel_uxa_emit_reloc(cc_bo, offsetof(struct brw_cc_unit_state, cc4), cc_vp_bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; cc_state.cc5.dither_enable = 0; /* disable dither */ cc_state.cc5.logicop_func = 0xc; /* WHITE */ cc_state.cc5.statistics_enable = 1; cc_state.cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD; cc_state.cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE; cc_state.cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE; dri_bo_subdata(cc_bo, 0, sizeof(cc_state), &cc_state); drm_intel_bo_unreference(cc_vp_bo); return cc_bo; } static void i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); int urb_vs_start, urb_vs_size; int urb_gs_start, urb_gs_size; int urb_clip_start, urb_clip_size; int urb_sf_start, urb_sf_size; int urb_cs_start, urb_cs_size; int pipe_ctl; IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_VIDEO; intel->needs_3d_invariant = TRUE; urb_vs_start = 0; urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; urb_gs_start = urb_vs_start + urb_vs_size; urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE; urb_clip_start = urb_gs_start + urb_gs_size; urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE; urb_sf_start = urb_clip_start + urb_clip_size; urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE; urb_cs_start = urb_sf_start + urb_sf_size; urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; OUT_BATCH(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH | BRW_MI_GLOBAL_SNAPSHOT_RESET); OUT_BATCH(MI_NOOP); /* brw_debug (scrn, "before base address modify"); */ /* Match Mesa driver setup */ if (INTEL_INFO(intel)->gen >= 045) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); else OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); /* Mesa does this. Who knows... */ OUT_BATCH(BRW_CS_URB_STATE | 0); OUT_BATCH((0 << 4) | /* URB Entry Allocation Size */ (0 << 0)); /* Number of URB Entries */ /* Zero out the two base address registers so all offsets are * absolute */ if (IS_GEN5(intel)) { OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Instruction base address */ /* general state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media object state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Instruction max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); } else { OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ /* general state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media object state max addr, disabled */ OUT_BATCH(0 | BASE_ADDRESS_MODIFY); } /* Set system instruction pointer */ OUT_BATCH(BRW_STATE_SIP | 0); /* system instruction pointer */ OUT_RELOC(intel->video.gen4_sip_kernel_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); /* brw_debug (scrn, "after base address modify"); */ if (IS_GEN5(intel)) pipe_ctl = BRW_PIPE_CONTROL_NOWRITE; else pipe_ctl = BRW_PIPE_CONTROL_NOWRITE | BRW_PIPE_CONTROL_IS_FLUSH; /* Pipe control */ OUT_BATCH(BRW_PIPE_CONTROL | pipe_ctl | 2); OUT_BATCH(0); /* Destination address */ OUT_BATCH(0); /* Immediate data low DW */ OUT_BATCH(0); /* Immediate data high DW */ /* Binding table pointers */ OUT_BATCH(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4); OUT_BATCH(0); /* vs */ OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ /* Only the PS uses the binding table */ OUT_BATCH((n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); /* Blend constant color (magenta is fun) */ OUT_BATCH(BRW_3DSTATE_CONSTANT_COLOR | 3); OUT_BATCH(float_to_uint(1.0)); OUT_BATCH(float_to_uint(0.0)); OUT_BATCH(float_to_uint(1.0)); OUT_BATCH(float_to_uint(1.0)); /* The drawing rectangle clipping is always on. Set it to values that * shouldn't do any clipping. */ OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */ OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16); /* ymax, xmax */ OUT_BATCH(0x00000000); /* yorigin, xorigin */ /* skip the depth buffer */ /* skip the polygon stipple */ /* skip the polygon stipple offset */ /* skip the line stipple */ /* Set the pointers to the 3d pipeline state */ OUT_BATCH(BRW_3DSTATE_PIPELINED_POINTERS | 5); OUT_RELOC(intel->video.gen4_vs_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); /* disable GS, resulting in passthrough */ OUT_BATCH(BRW_GS_DISABLE); /* disable CLIP, resulting in passthrough */ OUT_BATCH(BRW_CLIP_DISABLE); OUT_RELOC(intel->video.gen4_sf_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); if (n_src_surf == 1) OUT_RELOC(intel->video.gen4_wm_packed_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); else OUT_RELOC(intel->video.gen4_wm_planar_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_RELOC(intel->video.gen4_cc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); /* URB fence */ OUT_BATCH(BRW_URB_FENCE | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) | ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) | ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT)); OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) | ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT)); /* Constant buffer state */ OUT_BATCH(BRW_CS_URB_STATE | 0); OUT_BATCH(((URB_CS_ENTRY_SIZE - 1) << 4) | (URB_CS_ENTRIES << 0)); /* Set up our vertex elements, sourced from the single vertex buffer. */ if (IS_GEN5(intel)) { OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | 3); /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (8 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); } else { OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | 3); /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | (0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (8 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) | (4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); } } void I965DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); BoxPtr pbox; int nbox, dxo, dyo, pix_xoff, pix_yoff; float src_scale_x, src_scale_y; int src_surf; int n_src_surf; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; drm_intel_bo *surface_state_binding_table_bo; #if 0 ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height, video_pitch); #endif #if 0 /* enable debug */ OUTREG(INST_PM, (1 << (16 + 4)) | (1 << 4)); ErrorF("INST_PM 0x%08x\n", INREG(INST_PM)); #endif src_surf_base[0] = adaptor_priv->YBufOffset; src_surf_base[1] = adaptor_priv->YBufOffset; src_surf_base[2] = adaptor_priv->VBufOffset; src_surf_base[3] = adaptor_priv->VBufOffset; src_surf_base[4] = adaptor_priv->UBufOffset; src_surf_base[5] = adaptor_priv->UBufOffset; #if 0 ErrorF("base 0 0x%x base 1 0x%x base 2 0x%x\n", src_surf_base[0], src_surf_base[1], src_surf_base[2]); #endif if (is_planar_fourcc(id)) { src_surf_format = BRW_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = width; src_height[1] = src_height[0] = height; src_pitch[1] = src_pitch[0] = video_pitch2; src_width[4] = src_width[5] = src_width[2] = src_width[3] = width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = video_pitch; n_src_surf = 6; } else { if (id == FOURCC_UYVY) src_surf_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = width; src_height[0] = height; src_pitch[0] = video_pitch; n_src_surf = 1; } #if 0 ErrorF("dst surf: 0x%08x\n", state_base_offset + dest_surf_offset); ErrorF("src surf: 0x%08x\n", state_base_offset + src_surf_offset); #endif /* We'll be poking the state buffers that could be in use by the 3d * hardware here, but we should have synced the 3D engine already in * I830PutImage. */ surface_state_binding_table_bo = drm_intel_bo_alloc(intel->bufmgr, "surface state & binding table", (n_src_surf + 1) * (SURFACE_STATE_PADDED_SIZE + sizeof(uint32_t)), 4096); if (!surface_state_binding_table_bo) return; i965_create_dst_surface_state(scrn, pixmap, surface_state_binding_table_bo, 0); for (src_surf = 0; src_surf < n_src_surf; src_surf++) { i965_create_src_surface_state(scrn, adaptor_priv->buf, src_surf_base[src_surf], src_width[src_surf], src_height[src_surf], src_pitch[src_surf], src_surf_format, surface_state_binding_table_bo, (src_surf + 1) * SURFACE_STATE_PADDED_SIZE); } i965_create_binding_table(scrn, surface_state_binding_table_bo, n_src_surf + 1); if (intel->video.gen4_sampler_bo == NULL) intel->video.gen4_sampler_bo = i965_create_sampler_state(scrn); if (intel->video.gen4_sip_kernel_bo == NULL) { intel->video.gen4_sip_kernel_bo = i965_create_program(scrn, &sip_kernel_static[0][0], sizeof(sip_kernel_static)); if (!intel->video.gen4_sip_kernel_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } if (intel->video.gen4_vs_bo == NULL) { intel->video.gen4_vs_bo = i965_create_vs_state(scrn); if (!intel->video.gen4_vs_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } if (intel->video.gen4_sf_bo == NULL) { intel->video.gen4_sf_bo = i965_create_sf_state(scrn); if (!intel->video.gen4_sf_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } if (intel->video.gen4_wm_packed_bo == NULL) { intel->video.gen4_wm_packed_bo = i965_create_wm_state(scrn, intel->video.gen4_sampler_bo, TRUE); if (!intel->video.gen4_wm_packed_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } if (intel->video.gen4_wm_planar_bo == NULL) { intel->video.gen4_wm_planar_bo = i965_create_wm_state(scrn, intel->video.gen4_sampler_bo, FALSE); if (!intel->video.gen4_wm_planar_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } if (intel->video.gen4_cc_bo == NULL) { intel->video.gen4_cc_bo = i965_create_cc_state(scrn); if (!intel->video.gen4_cc_bo) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } } /* Set up the offset for translating from the given region (in screen * coordinates) to the backing pixmap. */ #ifdef COMPOSITE pix_xoff = -pixmap->screen_x + pixmap->drawable.x; pix_yoff = -pixmap->screen_y + pixmap->drawable.y; #else pix_xoff = 0; pix_yoff = 0; #endif dxo = dstRegion->extents.x1; dyo = dstRegion->extents.y1; /* Use normalized texture coordinates */ src_scale_x = ((float)src_w / width) / (float)drw_w; src_scale_y = ((float)src_h / height) / (float)drw_h; pbox = REGION_RECTS(dstRegion); nbox = REGION_NUM_RECTS(dstRegion); while (nbox--) { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; int box_y2 = pbox->y2; int i; float vb[12]; drm_intel_bo *bo_table[] = { NULL, /* vb_bo */ intel->batch_bo, surface_state_binding_table_bo, intel->video.gen4_sampler_bo, intel->video.gen4_sip_kernel_bo, intel->video.gen4_vs_bo, intel->video.gen4_sf_bo, intel->video.gen4_wm_packed_bo, intel->video.gen4_wm_planar_bo, intel->video.gen4_cc_bo, }; pbox++; i = 0; vb[i++] = (box_x2 - dxo) * src_scale_x; vb[i++] = (box_y2 - dyo) * src_scale_y; vb[i++] = (float)box_x2 + pix_xoff; vb[i++] = (float)box_y2 + pix_yoff; vb[i++] = (box_x1 - dxo) * src_scale_x; vb[i++] = (box_y2 - dyo) * src_scale_y; vb[i++] = (float)box_x1 + pix_xoff; vb[i++] = (float)box_y2 + pix_yoff; vb[i++] = (box_x1 - dxo) * src_scale_x; vb[i++] = (box_y1 - dyo) * src_scale_y; vb[i++] = (float)box_x1 + pix_xoff; vb[i++] = (float)box_y1 + pix_yoff; bo_table[0] = intel_uxa_bo_alloc_for_data(intel, vb, sizeof(vb), "textured video vbo"); if (IS_GEN4(intel)) i965_pre_draw_debug(scrn); /* If this command won't fit in the current batch, flush. * Assume that it does after being flushed. */ if (drm_intel_bufmgr_check_aperture_space(bo_table, ARRAY_SIZE(bo_table)) < 0) { intel_batch_submit(scrn); } intel_batch_start_atomic(scrn, 150); i965_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap); /* Set up the pointer to our vertex buffer */ OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3); /* four 32-bit floats per vertex */ OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA | ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); OUT_RELOC(bo_table[0], I915_GEM_DOMAIN_VERTEX, 0, 0); if (IS_GEN5(intel)) OUT_RELOC(bo_table[0], I915_GEM_DOMAIN_VERTEX, 0, i * 4); else OUT_BATCH(3); /* four corners to our rectangle */ OUT_BATCH(0); /* reserved */ OUT_BATCH(BRW_3DPRIMITIVE | BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | /* CTG - indirect vertex count */ 4); OUT_BATCH(3); /* vertex count per instance */ OUT_BATCH(0); /* start vertex offset */ OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ OUT_BATCH(MI_NOOP); intel_batch_end_atomic(scrn); drm_intel_bo_unreference(bo_table[0]); if (IS_GEN4(intel)) i965_post_draw_debug(scrn); } /* release reference once we're finished */ drm_intel_bo_unreference(surface_state_binding_table_bo); intel_uxa_debug_flush(scrn); } void i965_free_video(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo_unreference(intel->video.gen4_vs_bo); intel->video.gen4_vs_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_sf_bo); intel->video.gen4_sf_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_cc_bo); intel->video.gen4_cc_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_wm_packed_bo); intel->video.gen4_wm_packed_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_wm_planar_bo); intel->video.gen4_wm_planar_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_cc_vp_bo); intel->video.gen4_cc_vp_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_sampler_bo); intel->video.gen4_sampler_bo = NULL; drm_intel_bo_unreference(intel->video.gen4_sip_kernel_bo); intel->video.gen4_sip_kernel_bo = NULL; drm_intel_bo_unreference(intel->video.wm_prog_packed_bo); intel->video.wm_prog_packed_bo = NULL; drm_intel_bo_unreference(intel->video.wm_prog_planar_bo); intel->video.wm_prog_planar_bo = NULL; drm_intel_bo_unreference(intel->video.gen6_blend_bo); intel->video.gen6_blend_bo = NULL; drm_intel_bo_unreference(intel->video.gen6_depth_stencil_bo); intel->video.gen6_depth_stencil_bo = NULL; } /* for GEN6+ */ static drm_intel_bo * gen6_create_cc_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen6_color_calc_state cc_state; memset(&cc_state, 0, sizeof(cc_state)); cc_state.constant_r = 1.0; cc_state.constant_g = 0.0; cc_state.constant_b = 1.0; cc_state.constant_a = 1.0; return intel_uxa_bo_alloc_for_data(intel, &cc_state, sizeof(cc_state), "textured video cc state"); } static drm_intel_bo * gen6_create_blend_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen6_blend_state blend_state; memset(&blend_state, 0, sizeof(blend_state)); blend_state.blend1.logic_op_enable = 1; blend_state.blend1.logic_op_func = 0xc; blend_state.blend1.pre_blend_clamp_enable = 1; return intel_uxa_bo_alloc_for_data(intel, &blend_state, sizeof(blend_state), "textured video blend state"); } static drm_intel_bo * gen6_create_depth_stencil_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct gen6_depth_stencil_state depth_stencil_state; memset(&depth_stencil_state, 0, sizeof(depth_stencil_state)); return intel_uxa_bo_alloc_for_data(intel, &depth_stencil_state, sizeof(depth_stencil_state), "textured video blend state"); } static Bool gen6_create_vidoe_objects(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *(*create_sampler_state)(ScrnInfoPtr); const uint32_t *packed_ps_kernel, *planar_ps_kernel; unsigned int packed_ps_size, planar_ps_size; if (INTEL_INFO(intel)->gen >= 070) { create_sampler_state = gen7_create_sampler_state; packed_ps_kernel = &ps_kernel_packed_static_gen7[0][0]; packed_ps_size = sizeof(ps_kernel_packed_static_gen7); planar_ps_kernel = &ps_kernel_planar_static_gen7[0][0]; planar_ps_size = sizeof(ps_kernel_planar_static_gen7); } else { create_sampler_state = i965_create_sampler_state; packed_ps_kernel = &ps_kernel_packed_static_gen6[0][0]; packed_ps_size = sizeof(ps_kernel_packed_static_gen6); planar_ps_kernel = &ps_kernel_planar_static_gen6[0][0]; planar_ps_size = sizeof(ps_kernel_planar_static_gen6); } if (intel->video.gen4_sampler_bo == NULL) intel->video.gen4_sampler_bo = create_sampler_state(scrn); if (intel->video.wm_prog_packed_bo == NULL) intel->video.wm_prog_packed_bo = i965_create_program(scrn, packed_ps_kernel, packed_ps_size); if (intel->video.wm_prog_planar_bo == NULL) intel->video.wm_prog_planar_bo = i965_create_program(scrn, planar_ps_kernel, planar_ps_size); if (intel->video.gen4_cc_vp_bo == NULL) intel->video.gen4_cc_vp_bo = i965_create_cc_vp_state(scrn); if (intel->video.gen4_cc_bo == NULL) intel->video.gen4_cc_bo = gen6_create_cc_state(scrn); if (intel->video.gen6_blend_bo == NULL) intel->video.gen6_blend_bo = gen6_create_blend_state(scrn); if (intel->video.gen6_depth_stencil_bo == NULL) intel->video.gen6_depth_stencil_bo = gen6_create_depth_stencil_state(scrn); return (intel->video.gen4_sampler_bo != NULL && intel->video.wm_prog_packed_bo != NULL && intel->video.wm_prog_planar_bo != NULL && intel->video.gen4_cc_vp_bo != NULL && intel->video.gen4_cc_bo != NULL && intel->video.gen6_blend_bo != NULL && intel->video.gen6_depth_stencil_bo != NULL); } static void gen6_upload_state_base_address(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo) { intel_screen_private *intel = intel_get_screen_private(scrn); OUT_BATCH(BRW_STATE_BASE_ADDRESS | (10 - 2)); OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state base address */ OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction base address */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object upper bound */ OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction access upper bound */ } static void gen6_upload_drawing_rectangle(ScrnInfoPtr scrn, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2); OUT_BATCH(0x00000000); /* ymin, xmin */ OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16); /* ymax, xmax */ OUT_BATCH(0x00000000); /* yorigin, xorigin */ } static void gen6_upload_wm_state(ScrnInfoPtr scrn, Bool is_packed) { intel_screen_private *intel = intel_get_screen_private(scrn); /* disable WM constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2)); if (is_packed) { OUT_RELOC(intel->video.wm_prog_packed_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) | (2 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT)); } else { OUT_RELOC(intel->video.wm_prog_planar_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) | (7 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT)); } OUT_BATCH(0); OUT_BATCH((6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT)); /* DW4 */ OUT_BATCH(((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT) | GEN6_3DSTATE_WM_DISPATCH_ENABLE | GEN6_3DSTATE_WM_16_DISPATCH_ENABLE); OUT_BATCH((1 << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT) | GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(0); OUT_BATCH(0); } static void gen6_upload_vertex_element_state(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); /* Set up our vertex elements, sourced from the single vertex buffer. */ OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | (5 - 2)); /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ OUT_BATCH((0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (0 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ OUT_BATCH((0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | GEN6_VE0_VALID | (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | (8 << VE0_OFFSET_SHIFT)); OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); } static void gen6_upload_vertex_buffer(ScrnInfoPtr scrn, drm_intel_bo *vertex_bo, uint32_t end_address_offset) { intel_screen_private *intel = intel_get_screen_private(scrn); /* Set up the pointer to our vertex buffer */ OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | (5 - 2)); /* four 32-bit floats per vertex */ OUT_BATCH((0 << GEN6_VB0_BUFFER_INDEX_SHIFT) | GEN6_VB0_VERTEXDATA | ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, end_address_offset); OUT_BATCH(0); /* reserved */ } static void gen6_upload_primitive(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); OUT_BATCH(BRW_3DPRIMITIVE | BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | /* Internal Vertex Count */ (6 - 2)); OUT_BATCH(3); /* vertex count per instance */ OUT_BATCH(0); /* start vertex offset */ OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); /* index buffer offset, ignored */ } static void gen6_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap, drm_intel_bo *vertex_bo, uint32_t end_address_offset) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(n_src_surf == 1 || n_src_surf == 6); IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_VIDEO; intel->needs_3d_invariant = TRUE; gen6_upload_invariant_states(intel); gen6_upload_state_base_address(scrn, surface_state_binding_table_bo); gen6_upload_viewport_state_pointers(intel, intel->video.gen4_cc_vp_bo); gen6_upload_urb(intel); gen6_upload_cc_state_pointers(intel, intel->video.gen6_blend_bo, intel->video.gen4_cc_bo, intel->video.gen6_depth_stencil_bo, 0); gen6_upload_sampler_state_pointers(intel, intel->video.gen4_sampler_bo); gen6_upload_vs_state(intel); gen6_upload_gs_state(intel); gen6_upload_clip_state(intel); gen6_upload_sf_state(intel, 1, 0); gen6_upload_wm_state(scrn, n_src_surf == 1 ? TRUE : FALSE); gen6_upload_binding_table(intel, (n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); gen6_upload_depth_buffer_state(intel); gen6_upload_drawing_rectangle(scrn, pixmap); gen6_upload_vertex_element_state(scrn); gen6_upload_vertex_buffer(scrn, vertex_bo, end_address_offset); gen6_upload_primitive(scrn); } static void gen7_upload_wm_state(ScrnInfoPtr scrn, Bool is_packed) { intel_screen_private *intel = intel_get_screen_private(scrn); unsigned int max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_IVB; unsigned int num_samples = 0; if (IS_HSW(intel)) { max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_HSW; num_samples = 1 << GEN7_PS_SAMPLE_MASK_SHIFT_HSW; } /* disable WM constant buffer */ OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (7 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(GEN6_3DSTATE_WM | (3 - 2)); OUT_BATCH(GEN7_WM_DISPATCH_ENABLE | GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); OUT_BATCH(0); OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2)); if (is_packed) { OUT_RELOC(intel->video.wm_prog_packed_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) | (2 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); } else { OUT_RELOC(intel->video.wm_prog_planar_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) | (7 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); } OUT_BATCH(0); /* scratch space base offset */ OUT_BATCH( ((48 - 1) << max_threads_shift) | num_samples | GEN7_PS_ATTRIBUTE_ENABLE | GEN7_PS_16_DISPATCH_ENABLE); OUT_BATCH( (6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_0)); OUT_BATCH(0); /* kernel 1 pointer */ OUT_BATCH(0); /* kernel 2 pointer */ } static void gen7_upload_vertex_buffer(ScrnInfoPtr scrn, drm_intel_bo *vertex_bo, uint32_t end_address_offset) { intel_screen_private *intel = intel_get_screen_private(scrn); /* Set up the pointer to our vertex buffer */ OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | (5 - 2)); /* four 32-bit floats per vertex */ OUT_BATCH((0 << GEN6_VB0_BUFFER_INDEX_SHIFT) | GEN6_VB0_VERTEXDATA | GEN7_VB0_ADDRESS_MODIFYENABLE | ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, end_address_offset); OUT_BATCH(0); /* reserved */ } static void gen7_upload_primitive(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); OUT_BATCH(BRW_3DPRIMITIVE | (7 - 2)); OUT_BATCH(_3DPRIM_RECTLIST | GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL); OUT_BATCH(3); /* vertex count per instance */ OUT_BATCH(0); /* start vertex offset */ OUT_BATCH(1); /* single instance */ OUT_BATCH(0); /* start instance location */ OUT_BATCH(0); } static void gen7_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap, drm_intel_bo *vertex_bo, uint32_t end_address_offset) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(n_src_surf == 1 || n_src_surf == 6); IntelEmitInvarientState(scrn); intel->last_3d = LAST_3D_VIDEO; intel->needs_3d_invariant = TRUE; gen6_upload_invariant_states(intel); gen6_upload_state_base_address(scrn, surface_state_binding_table_bo); gen7_upload_viewport_state_pointers(intel, intel->video.gen4_cc_vp_bo); gen7_upload_urb(intel); gen7_upload_cc_state_pointers(intel, intel->video.gen6_blend_bo, intel->video.gen4_cc_bo, intel->video.gen6_depth_stencil_bo, 0); gen7_upload_sampler_state_pointers(intel, intel->video.gen4_sampler_bo); gen7_upload_bypass_states(intel); gen6_upload_vs_state(intel); gen6_upload_clip_state(intel); gen7_upload_sf_state(intel, 1, 0); gen7_upload_wm_state(scrn, n_src_surf == 1 ? TRUE : FALSE); gen7_upload_binding_table(intel, (n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); gen7_upload_depth_buffer_state(intel); gen6_upload_drawing_rectangle(scrn, pixmap); gen6_upload_vertex_element_state(scrn); gen7_upload_vertex_buffer(scrn, vertex_bo, end_address_offset); gen7_upload_primitive(scrn); } void Gen6DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap) { intel_screen_private *intel = intel_get_screen_private(scrn); BoxPtr pbox; int nbox, dxo, dyo, pix_xoff, pix_yoff; float src_scale_x, src_scale_y; int src_surf; int n_src_surf; uint32_t src_surf_format; uint32_t src_surf_base[6]; int src_width[6]; int src_height[6]; int src_pitch[6]; drm_intel_bo *surface_state_binding_table_bo; void (*create_dst_surface_state)(ScrnInfoPtr, PixmapPtr, drm_intel_bo *, uint32_t); void (*create_src_surface_state)(ScrnInfoPtr, drm_intel_bo *, uint32_t, int, int, int, uint32_t, drm_intel_bo *, uint32_t); void (*emit_video_setup)(ScrnInfoPtr, drm_intel_bo *, int, PixmapPtr, drm_intel_bo *, uint32_t); if (INTEL_INFO(intel)->gen >= 070) { create_dst_surface_state = gen7_create_dst_surface_state; create_src_surface_state = gen7_create_src_surface_state; emit_video_setup = gen7_emit_video_setup; } else { create_dst_surface_state = i965_create_dst_surface_state; create_src_surface_state = i965_create_src_surface_state; emit_video_setup = gen6_emit_video_setup; } src_surf_base[0] = adaptor_priv->YBufOffset; src_surf_base[1] = adaptor_priv->YBufOffset; src_surf_base[2] = adaptor_priv->VBufOffset; src_surf_base[3] = adaptor_priv->VBufOffset; src_surf_base[4] = adaptor_priv->UBufOffset; src_surf_base[5] = adaptor_priv->UBufOffset; if (is_planar_fourcc(id)) { src_surf_format = BRW_SURFACEFORMAT_R8_UNORM; src_width[1] = src_width[0] = width; src_height[1] = src_height[0] = height; src_pitch[1] = src_pitch[0] = video_pitch2; src_width[4] = src_width[5] = src_width[2] = src_width[3] = width / 2; src_height[4] = src_height[5] = src_height[2] = src_height[3] = height / 2; src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = video_pitch; n_src_surf = 6; } else { if (id == FOURCC_UYVY) src_surf_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; else src_surf_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; src_width[0] = width; src_height[0] = height; src_pitch[0] = video_pitch; n_src_surf = 1; } surface_state_binding_table_bo = drm_intel_bo_alloc(intel->bufmgr, "surface state & binding table", (n_src_surf + 1) * (SURFACE_STATE_PADDED_SIZE + sizeof(uint32_t)), 4096); if (!surface_state_binding_table_bo) return; create_dst_surface_state(scrn, pixmap, surface_state_binding_table_bo, 0); for (src_surf = 0; src_surf < n_src_surf; src_surf++) { create_src_surface_state(scrn, adaptor_priv->buf, src_surf_base[src_surf], src_width[src_surf], src_height[src_surf], src_pitch[src_surf], src_surf_format, surface_state_binding_table_bo, (src_surf + 1) * SURFACE_STATE_PADDED_SIZE); } i965_create_binding_table(scrn, surface_state_binding_table_bo, n_src_surf + 1); if (!gen6_create_vidoe_objects(scrn)) { drm_intel_bo_unreference(surface_state_binding_table_bo); return; } /* Set up the offset for translating from the given region (in screen * coordinates) to the backing pixmap. */ #ifdef COMPOSITE pix_xoff = -pixmap->screen_x + pixmap->drawable.x; pix_yoff = -pixmap->screen_y + pixmap->drawable.y; #else pix_xoff = 0; pix_yoff = 0; #endif dxo = dstRegion->extents.x1; dyo = dstRegion->extents.y1; /* Use normalized texture coordinates */ src_scale_x = ((float)src_w / width) / (float)drw_w; src_scale_y = ((float)src_h / height) / (float)drw_h; pbox = REGION_RECTS(dstRegion); nbox = REGION_NUM_RECTS(dstRegion); while (nbox--) { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; int box_y2 = pbox->y2; int i; float vb[12]; drm_intel_bo *bo_table[] = { NULL, /* vb_bo */ intel->batch_bo, surface_state_binding_table_bo, intel->video.gen4_sampler_bo, intel->video.wm_prog_packed_bo, intel->video.wm_prog_planar_bo, intel->video.gen4_cc_vp_bo, intel->video.gen4_cc_bo, intel->video.gen6_blend_bo, intel->video.gen6_depth_stencil_bo, }; pbox++; i = 0; vb[i++] = (box_x2 - dxo) * src_scale_x; vb[i++] = (box_y2 - dyo) * src_scale_y; vb[i++] = (float)box_x2 + pix_xoff; vb[i++] = (float)box_y2 + pix_yoff; vb[i++] = (box_x1 - dxo) * src_scale_x; vb[i++] = (box_y2 - dyo) * src_scale_y; vb[i++] = (float)box_x1 + pix_xoff; vb[i++] = (float)box_y2 + pix_yoff; vb[i++] = (box_x1 - dxo) * src_scale_x; vb[i++] = (box_y1 - dyo) * src_scale_y; vb[i++] = (float)box_x1 + pix_xoff; vb[i++] = (float)box_y1 + pix_yoff; bo_table[0] = intel_uxa_bo_alloc_for_data(intel, vb, sizeof(vb), "video vbo"); /* If this command won't fit in the current batch, flush. * Assume that it does after being flushed. */ if (drm_intel_bufmgr_check_aperture_space(bo_table, ARRAY_SIZE(bo_table)) < 0) intel_batch_submit(scrn); intel_batch_start_atomic(scrn, 200); emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap, bo_table[0], i * 4); intel_batch_end_atomic(scrn); drm_intel_bo_unreference(bo_table[0]); } /* release reference once we're finished */ drm_intel_bo_unreference(surface_state_binding_table_bo); intel_uxa_debug_flush(scrn); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel.h000066400000000000000000000345161267532330400231540ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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: * Keith Whitwell * David Dawes * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if 0 #define I830DEBUG #endif #include #ifndef REMAP_RESERVED #define REMAP_RESERVED 0 #endif #ifndef _I830_H_ #define _I830_H_ #include "xorg-server.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Cursor.h" #include "xf86xv.h" #include "xf86Crtc.h" #include "xf86RandR12.h" #include "xorg-server.h" #include #define _XF86DRI_SERVER_ #include "drm.h" #include "dri2.h" #include "intel_bufmgr.h" #include "i915_drm.h" #include "intel_driver.h" #include "intel_options.h" #include "intel_list.h" #include "compat-api.h" #if HAVE_UDEV #include #endif #if HAVE_DRI3 #include "misync.h" #endif /* remain compatible to xorg-server 1.6 */ #ifndef MONITOR_EDID_COMPLETE_RAWDATA #define MONITOR_EDID_COMPLETE_RAWDATA EDID_COMPLETE_RAWDATA #endif #if XF86_CRTC_VERSION >= 5 #define INTEL_PIXMAP_SHARING 1 #endif #define MAX_PIPES 4 /* consider making all users dynamic */ #include "common.h" #define PITCH_NONE 0 /** enumeration of 3d consumers so some can maintain invariant state. */ enum last_3d { LAST_3D_OTHER, LAST_3D_VIDEO, LAST_3D_RENDER, LAST_3D_ROTATION }; enum dri_type { DRI_DISABLED, DRI_NONE, DRI_ACTIVE }; typedef struct intel_screen_private { ScrnInfoPtr scrn; struct intel_device *dev; int cpp; #define RENDER_BATCH I915_EXEC_RENDER #define BLT_BATCH I915_EXEC_BLT unsigned int current_batch; void *modes; drm_intel_bo *front_buffer, *back_buffer; long front_pitch, front_tiling; dri_bufmgr *bufmgr; #if USE_UXA uint32_t batch_ptr[4096]; /** Byte offset in batch_ptr for the next dword to be emitted. */ unsigned int batch_used; /** Position in batch_ptr at the start of the current BEGIN_BATCH */ unsigned int batch_emit_start; /** Number of bytes to be emitted in the current BEGIN_BATCH. */ uint32_t batch_emitting; dri_bo *batch_bo, *last_batch_bo[2]; /** Whether we're in a section of code that can't tolerate flushing */ Bool in_batch_atomic; /** Ending batch_used that was verified by intel_start_batch_atomic() */ int batch_atomic_limit; struct list batch_pixmaps; drm_intel_bo *wa_scratch_bo; OsTimerPtr cache_expire; #endif /* For Xvideo */ Bool use_overlay; #ifdef INTEL_XVMC /* For XvMC */ Bool XvMCEnabled; #endif CreateScreenResourcesProcPtr CreateScreenResources; Bool shadow_present; unsigned int tiling; #define INTEL_TILING_FB 0x1 #define INTEL_TILING_2D 0x2 #define INTEL_TILING_3D 0x4 #define INTEL_TILING_ALL (~0) Bool swapbuffers_wait; Bool has_relaxed_fencing; int Chipset; EntityInfoPtr pEnt; const struct intel_device_info *info; unsigned int BR[20]; CloseScreenProcPtr CloseScreen; void (*context_switch) (struct intel_screen_private *intel, int new_mode); void (*vertex_flush) (struct intel_screen_private *intel); void (*batch_flush) (struct intel_screen_private *intel); void (*batch_commit_notify) (struct intel_screen_private *intel); #if USE_UXA struct _UxaDriver *uxa_driver; int uxa_flags; #endif Bool need_sync; int accel_pixmap_offset_alignment; int accel_max_x; int accel_max_y; int max_bo_size; int max_gtt_map_size; int max_tiling_size; Bool XvDisabled; /* Xv disabled in PreInit. */ Bool XvEnabled; /* Xv enabled for this generation. */ Bool XvPreferOverlay; int colorKey; XF86VideoAdaptorPtr adaptor; ScreenBlockHandlerProcPtr BlockHandler; Bool overlayOn; struct { drm_intel_bo *gen4_vs_bo; drm_intel_bo *gen4_sf_bo; drm_intel_bo *gen4_wm_packed_bo; drm_intel_bo *gen4_wm_planar_bo; drm_intel_bo *gen4_cc_bo; drm_intel_bo *gen4_cc_vp_bo; drm_intel_bo *gen4_sampler_bo; drm_intel_bo *gen4_sip_kernel_bo; drm_intel_bo *wm_prog_packed_bo; drm_intel_bo *wm_prog_planar_bo; drm_intel_bo *gen6_blend_bo; drm_intel_bo *gen6_depth_stencil_bo; } video; #if USE_UXA /* Render accel state */ float scale_units[2][2]; /** Transform pointers for src/mask, or NULL if identity */ PictTransform *transform[2]; PixmapPtr render_source, render_mask, render_dest; PicturePtr render_source_picture, render_mask_picture, render_dest_picture; Bool needs_3d_invariant; Bool needs_render_state_emit; Bool needs_render_vertex_emit; /* i830 render accel state */ uint32_t render_dest_format; uint32_t cblend, ablend, s8_blendctl; /* i915 render accel state */ PixmapPtr texture[2]; uint32_t mapstate[6]; uint32_t samplerstate[6]; struct { int op; uint32_t dst_format; } i915_render_state; struct { int num_sf_outputs; int drawrect; uint32_t blend; dri_bo *samplers; dri_bo *kernel; } gen6_render_state; uint32_t prim_offset; void (*prim_emit)(struct intel_screen_private *intel, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); int floats_per_vertex; int last_floats_per_vertex; uint16_t vertex_offset; uint16_t vertex_count; uint16_t vertex_index; uint16_t vertex_used; uint32_t vertex_id; float vertex_ptr[4*1024]; dri_bo *vertex_bo; uint8_t surface_data[16*1024]; uint16_t surface_used; uint16_t surface_table; uint32_t surface_reloc; dri_bo *surface_bo; /* 965 render acceleration state */ struct gen4_render_state *gen4_render_state; #endif /* DRI enabled this generation. */ enum dri_type dri2, dri3; int drmSubFD; char *deviceName; Bool use_pageflipping; Bool use_triple_buffer; Bool force_fallback; Bool has_kernel_flush; Bool needs_flush; /* Broken-out options. */ OptionInfoPtr Options; /* Driver phase/state information */ Bool suspended; enum last_3d last_3d; /** * User option to print acceleration fallback info to the server log. */ Bool fallback_debug; unsigned debug_flush; #if HAVE_UDEV struct udev_monitor *uevent_monitor; pointer uevent_handler; #endif Bool has_prime_vmap_flush; #if HAVE_DRI3 SyncScreenFuncsRec save_sync_screen_funcs; #endif void (*flush_rendering)(struct intel_screen_private *intel); } intel_screen_private; #define INTEL_INFO(intel) ((intel)->info) #define IS_GENx(intel, X) (INTEL_INFO(intel)->gen >= 8*(X) && INTEL_INFO(intel)->gen < 8*((X)+1)) #define IS_GEN1(intel) IS_GENx(intel, 1) #define IS_GEN2(intel) IS_GENx(intel, 2) #define IS_GEN3(intel) IS_GENx(intel, 3) #define IS_GEN4(intel) IS_GENx(intel, 4) #define IS_GEN5(intel) IS_GENx(intel, 5) #define IS_GEN6(intel) IS_GENx(intel, 6) #define IS_GEN7(intel) IS_GENx(intel, 7) #define IS_HSW(intel) (INTEL_INFO(intel)->gen == 075) /* Some chips have specific errata (or limits) that we need to workaround. */ #define IS_I830(intel) (intel_get_device_id((intel)->dev) == PCI_CHIP_I830_M) #define IS_845G(intel) (intel_get_device_id((intel)->dev) == PCI_CHIP_845_G) #define IS_I865G(intel) (intel_get_device_id((intel)->dev) == PCI_CHIP_I865_G) #define IS_I915G(pI810) (intel_get_device_id((intel)->dev) == PCI_CHIP_I915_G || intel_get_device_id((intel)->dev) == PCI_CHIP_E7221_G) #define IS_I915GM(pI810) (intel_get_device_id((intel)->dev) == PCI_CHIP_I915_GM) #define IS_965_Q(pI810) (intel_get_device_id((intel)->dev) == PCI_CHIP_I965_Q) /* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */ #define SUPPORTS_YTILING(pI810) (INTEL_INFO(intel)->gen >= 040) #define HAS_BLT(pI810) (INTEL_INFO(intel)->gen >= 060) #ifndef I915_PARAM_HAS_PRIME_VMAP_FLUSH #define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 #endif enum { DEBUG_FLUSH_BATCHES = 0x1, DEBUG_FLUSH_CACHES = 0x2, DEBUG_FLUSH_WAIT = 0x4, }; extern Bool intel_mode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp); extern void intel_mode_init(struct intel_screen_private *intel); extern void intel_mode_disable_unused_functions(ScrnInfoPtr scrn); extern void intel_mode_remove_fb(intel_screen_private *intel); extern void intel_mode_close(intel_screen_private *intel); extern void intel_mode_fini(intel_screen_private *intel); extern int intel_mode_read_drm_events(intel_screen_private *intel); extern void intel_mode_hotplug(intel_screen_private *intel); typedef void (*intel_drm_handler_proc)(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t seq, uint64_t usec, void *data); typedef void (*intel_drm_abort_proc)(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data); extern uint32_t intel_drm_queue_alloc(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data, intel_drm_handler_proc handler, intel_drm_abort_proc abort); extern void intel_drm_abort(ScrnInfoPtr scrn, Bool (*match)(void *data, void *match_data), void *match_data); extern void intel_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq); extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc); extern int intel_crtc_id(xf86CrtcPtr crtc); extern int intel_output_dpms_status(xf86OutputPtr output); extern void intel_copy_fb(ScrnInfoPtr scrn); int intel_get_crtc_msc_ust(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t *msc, uint64_t *ust); uint32_t intel_crtc_msc_to_sequence(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t expect); uint64_t intel_sequence_to_crtc_msc(xf86CrtcPtr crtc, uint32_t sequence); enum DRI2FrameEventType { DRI2_SWAP, DRI2_SWAP_CHAIN, DRI2_FLIP, DRI2_WAITMSC, }; #if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1,7,99,3,0) typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, CARD64 sbc); #endif typedef void (*intel_pageflip_handler_proc) (uint64_t frame, uint64_t usec, void *data); typedef void (*intel_pageflip_abort_proc) (void *data); typedef struct _DRI2FrameEvent { struct intel_screen_private *intel; XID drawable_id; ClientPtr client; enum DRI2FrameEventType type; int frame; struct list drawable_resource, client_resource; /* for swaps & flips only */ DRI2SwapEventPtr event_complete; void *event_data; DRI2BufferPtr front; DRI2BufferPtr back; /* current scanout for triple buffer */ int old_width; int old_height; int old_pitch; int old_tiling; dri_bo *old_buffer; } DRI2FrameEventRec, *DRI2FrameEventPtr; extern Bool intel_do_pageflip(intel_screen_private *intel, dri_bo *new_front, int ref_crtc_hw_id, Bool async, void *pageflip_data, intel_pageflip_handler_proc pageflip_handler, intel_pageflip_abort_proc pageflip_abort); static inline intel_screen_private * intel_get_screen_private(ScrnInfoPtr scrn) { return (intel_screen_private *)(scrn->driverPrivate); } #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif #ifndef ALIGN #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #endif #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif extern void intel_video_init(ScreenPtr pScreen); extern void intel_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b); extern void intel_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box); extern xf86CrtcPtr intel_covering_crtc(ScrnInfoPtr scrn, BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret); Bool I830DRI2ScreenInit(ScreenPtr pScreen); void I830DRI2CloseScreen(ScreenPtr pScreen); /* intel_dri3.c */ Bool intel_dri3_screen_init(ScreenPtr screen); extern Bool intel_crtc_on(xf86CrtcPtr crtc); int intel_crtc_to_pipe(xf86CrtcPtr crtc); /* intel_memory.c */ unsigned long intel_get_fence_size(intel_screen_private *intel, unsigned long size); unsigned long intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch, uint32_t tiling_mode); Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling); void intel_set_gem_max_sizes(ScrnInfoPtr scrn); unsigned int intel_compute_size(struct intel_screen_private *intel, int w, int h, int bpp, unsigned usage, uint32_t *tiling, int *stride); drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn, int width, int height, int cpp, int *out_stride, uint32_t *out_tiling); static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) { ScreenPtr screen = drawable->pScreen; if (drawable->type == DRAWABLE_PIXMAP) return (PixmapPtr) drawable; else return screen->GetWindowPixmap((WindowPtr) drawable); } static inline Bool pixmap_is_scanout(PixmapPtr pixmap) { ScreenPtr screen = pixmap->drawable.pScreen; return pixmap == screen->GetScreenPixmap(screen); } static inline int intel_pixmap_pitch(PixmapPtr pixmap) { return (unsigned long)pixmap->devKind; } /* * intel_sync.c */ #if HAVE_DRI3 Bool intel_sync_init(ScreenPtr screen); void intel_sync_close(ScreenPtr screen); #else static inline Bool intel_sync_init(ScreenPtr screen) { return 0; } static inline void intel_sync_close(ScreenPtr screen) { } #endif /* * intel_present.c */ #if 0 #define DebugPresent(x) ErrorF x #else #define DebugPresent(x) #endif #if HAVE_PRESENT Bool intel_present_screen_init(ScreenPtr screen); #else static inline Bool intel_present_screen_init(ScreenPtr screen) { return 0; } #endif dri_bo * intel_get_pixmap_bo(PixmapPtr pixmap); void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo); void intel_flush(intel_screen_private *intel); #endif /* _I830_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_batchbuffer.c000066400000000000000000000210511267532330400254700ustar00rootroot00000000000000/* -*- c-basic-offset: 4 -*- */ /* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Eric Anholt * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "xorg-server.h" #include "xf86.h" #include "intel.h" #include "i830_reg.h" #include "i915_drm.h" #include "i965_reg.h" #include "intel_uxa.h" #define DUMP_BATCHBUFFERS NULL // "/tmp/i915-batchbuffers.dump" static void intel_end_vertex(intel_screen_private *intel) { if (intel->vertex_bo) { if (intel->vertex_used) { dri_bo_subdata(intel->vertex_bo, 0, intel->vertex_used*4, intel->vertex_ptr); intel->vertex_used = 0; } dri_bo_unreference(intel->vertex_bo); intel->vertex_bo = NULL; } intel->vertex_id = 0; } void intel_next_vertex(intel_screen_private *intel) { intel_end_vertex(intel); intel->vertex_bo = dri_bo_alloc(intel->bufmgr, "vertex", sizeof (intel->vertex_ptr), 4096); } static dri_bo *bo_alloc(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int size = 4 * 4096; /* The 865 has issues with larger-than-page-sized batch buffers. */ if (IS_I865G(intel)) size = 4096; return dri_bo_alloc(intel->bufmgr, "batch", size, 4096); } static void intel_next_batch(ScrnInfoPtr scrn, int mode) { intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *tmp; drm_intel_gem_bo_clear_relocs(intel->batch_bo, 0); tmp = intel->last_batch_bo[mode]; intel->last_batch_bo[mode] = intel->batch_bo; intel->batch_bo = tmp; intel->batch_used = 0; /* We don't know when another client has executed, so we have * to reinitialize our 3D state per batch. */ intel->last_3d = LAST_3D_OTHER; } void intel_batch_init(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); intel->batch_emit_start = 0; intel->batch_emitting = 0; intel->vertex_id = 0; intel->last_batch_bo[0] = bo_alloc(scrn); intel->last_batch_bo[1] = bo_alloc(scrn); intel->batch_bo = bo_alloc(scrn); intel->batch_used = 0; intel->last_3d = LAST_3D_OTHER; } void intel_batch_teardown(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int i; for (i = 0; i < ARRAY_SIZE(intel->last_batch_bo); i++) { if (intel->last_batch_bo[i] != NULL) { dri_bo_unreference(intel->last_batch_bo[i]); intel->last_batch_bo[i] = NULL; } } if (intel->batch_bo != NULL) { dri_bo_unreference(intel->batch_bo); intel->batch_bo = NULL; } if (intel->vertex_bo) { dri_bo_unreference(intel->vertex_bo); intel->vertex_bo = NULL; } while (!list_is_empty(&intel->batch_pixmaps)) list_del(intel->batch_pixmaps.next); } static void intel_batch_do_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; list_for_each_entry(priv, &intel->batch_pixmaps, batch) priv->dirty = 0; } static void intel_emit_post_sync_nonzero_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); /* keep this entire sequence of 3 PIPE_CONTROL cmds in one batch to * avoid upsetting the gpu. */ BEGIN_BATCH(3*4); OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_CS_STALL | BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH(0); /* address */ OUT_BATCH(0); /* write data */ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_WRITE_QWORD); OUT_RELOC(intel->wa_scratch_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0); OUT_BATCH(0); /* write data */ /* now finally the _real flush */ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH | BRW_PIPE_CONTROL_TC_FLUSH | BRW_PIPE_CONTROL_NOWRITE); OUT_BATCH(0); /* write address */ OUT_BATCH(0); /* write data */ ADVANCE_BATCH(); } void intel_batch_emit_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int flags; assert (!intel->in_batch_atomic); /* Big hammer, look to the pipelined flushes in future. */ if ((INTEL_INFO(intel)->gen >= 0100)) { /* Only BLT supported */ BEGIN_BATCH_BLT(4); OUT_BATCH(MI_FLUSH_DW | 2); OUT_BATCH(0); /* address low */ OUT_BATCH(0); /* address high */ OUT_BATCH(0); /* dword data */ ADVANCE_BATCH(); } else if ((INTEL_INFO(intel)->gen >= 060)) { if (intel->current_batch == BLT_BATCH) { BEGIN_BATCH_BLT(4); OUT_BATCH(MI_FLUSH_DW | 2); OUT_BATCH(0); /* address */ OUT_BATCH(0); /* qword low */ OUT_BATCH(0); /* qword high */ ADVANCE_BATCH(); } else { if ((INTEL_INFO(intel)->gen == 060)) { /* HW-Workaround for Sandybdrige */ intel_emit_post_sync_nonzero_flush(scrn); } else { BEGIN_BATCH(4); OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH | BRW_PIPE_CONTROL_TC_FLUSH | BRW_PIPE_CONTROL_NOWRITE); OUT_BATCH(0); /* write address */ OUT_BATCH(0); /* write data */ ADVANCE_BATCH(); } } } else { flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; if (INTEL_INFO(intel)->gen >= 040) flags = 0; BEGIN_BATCH(1); OUT_BATCH(MI_FLUSH | flags); ADVANCE_BATCH(); } intel_batch_do_flush(scrn); } void intel_batch_submit(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int ret; assert (!intel->in_batch_atomic); if (intel->vertex_flush) intel->vertex_flush(intel); intel_end_vertex(intel); if (intel->batch_flush) intel->batch_flush(intel); if (intel->batch_used == 0) return; /* Mark the end of the batchbuffer. */ OUT_BATCH(MI_BATCH_BUFFER_END); /* Emit a padding dword if we aren't going to be quad-word aligned. */ if (intel->batch_used & 1) OUT_BATCH(MI_NOOP); if (DUMP_BATCHBUFFERS) { FILE *file = fopen(DUMP_BATCHBUFFERS, "a"); if (file) { fwrite (intel->batch_ptr, intel->batch_used*4, 1, file); fclose(file); } } ret = dri_bo_subdata(intel->batch_bo, 0, intel->batch_used*4, intel->batch_ptr); if (ret == 0) { ret = drm_intel_bo_mrb_exec(intel->batch_bo, intel->batch_used*4, NULL, 0, 0xffffffff, (HAS_BLT(intel) ? intel->current_batch: I915_EXEC_DEFAULT)); } if (ret != 0) { static int once; if (!once) { if (ret == -EIO) { /* The GPU has hung and unlikely to recover by this point. */ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Detected a hung GPU, disabling acceleration.\n"); xf86DrvMsg(scrn->scrnIndex, X_ERROR, "When reporting this, please include i915_error_state from debugfs and the full dmesg.\n"); } else { /* The driver is broken. */ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to submit batch buffer, expect rendering corruption: %s.\n ", strerror(-ret)); } uxa_set_force_fallback(xf86ScrnToScreen(scrn), TRUE); intel->force_fallback = TRUE; once = 1; } } while (!list_is_empty(&intel->batch_pixmaps)) { struct intel_uxa_pixmap *entry; entry = list_first_entry(&intel->batch_pixmaps, struct intel_uxa_pixmap, batch); entry->busy = -1; entry->dirty = 0; list_del(&entry->batch); } if (intel->debug_flush & DEBUG_FLUSH_WAIT) drm_intel_bo_wait_rendering(intel->batch_bo); intel_next_batch(scrn, intel->current_batch == I915_EXEC_BLT); if (intel->batch_commit_notify) intel->batch_commit_notify(intel); intel->current_batch = 0; } void intel_uxa_debug_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->debug_flush & DEBUG_FLUSH_CACHES) intel_batch_emit_flush(scrn); if (intel->debug_flush & DEBUG_FLUSH_BATCHES) intel_batch_submit(scrn); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_batchbuffer.h000066400000000000000000000163351267532330400255060ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 David Dawes 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. **************************************************************************/ #ifndef _INTEL_BATCHBUFFER_H #define _INTEL_BATCHBUFFER_H #define BATCH_RESERVED 16 void intel_batch_init(ScrnInfoPtr scrn); void intel_batch_teardown(ScrnInfoPtr scrn); void intel_batch_emit_flush(ScrnInfoPtr scrn); void intel_batch_submit(ScrnInfoPtr scrn); static inline int intel_batch_space(intel_screen_private *intel) { return (intel->batch_bo->size - BATCH_RESERVED) - (4*intel->batch_used); } static inline int intel_vertex_space(intel_screen_private *intel) { return intel->vertex_bo ? intel->vertex_bo->size - (4*intel->vertex_used) : 0; } static inline void intel_batch_require_space(ScrnInfoPtr scrn, intel_screen_private *intel, int sz) { assert(sz < intel->batch_bo->size - 8); if (intel_batch_space(intel) < sz) intel_batch_submit(scrn); } static inline void intel_batch_start_atomic(ScrnInfoPtr scrn, int sz) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(!intel->in_batch_atomic); if (intel->current_batch != RENDER_BATCH) { if (intel->current_batch && intel->context_switch) intel->context_switch(intel, RENDER_BATCH); } intel_batch_require_space(scrn, intel, sz * 4); intel->current_batch = RENDER_BATCH; intel->in_batch_atomic = TRUE; intel->batch_atomic_limit = intel->batch_used + sz; } static inline void intel_batch_end_atomic(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); assert(intel->in_batch_atomic); assert(intel->batch_used <= intel->batch_atomic_limit); intel->in_batch_atomic = FALSE; } static inline void intel_batch_emit_dword(intel_screen_private *intel, uint32_t dword) { intel->batch_ptr[intel->batch_used++] = dword; } static inline void intel_batch_align(intel_screen_private *intel, uint32_t align) { uint32_t delta; align /= 4; assert(align); if ((delta = intel->batch_used & (align - 1))) { delta = align - delta; memset (intel->batch_ptr + intel->batch_used, 0, 4*delta); intel->batch_used += delta; } } static inline void intel_batch_emit_reloc(intel_screen_private *intel, dri_bo * bo, uint32_t read_domains, uint32_t write_domains, uint32_t delta, int needs_fence) { uint64_t offset; if (needs_fence) drm_intel_bo_emit_reloc_fence(intel->batch_bo, intel->batch_used * 4, bo, delta, read_domains, write_domains); else drm_intel_bo_emit_reloc(intel->batch_bo, intel->batch_used * 4, bo, delta, read_domains, write_domains); offset = bo->offset64 + delta; intel_batch_emit_dword(intel, offset); if (INTEL_INFO(intel)->gen >= 0100) intel_batch_emit_dword(intel, offset >> 32); } static inline void intel_batch_mark_pixmap_domains(intel_screen_private *intel, struct intel_uxa_pixmap *priv, uint32_t read_domains, uint32_t write_domain) { assert (read_domains); assert (write_domain == 0 || write_domain == read_domains); if (list_is_empty(&priv->batch)) list_add(&priv->batch, &intel->batch_pixmaps); priv->dirty |= write_domain != 0; priv->busy = 1; intel->needs_flush |= write_domain != 0; } static inline void intel_batch_emit_reloc_pixmap(intel_screen_private *intel, PixmapPtr pixmap, uint32_t read_domains, uint32_t write_domain, uint32_t delta, int needs_fence) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); intel_batch_mark_pixmap_domains(intel, priv, read_domains, write_domain); intel_batch_emit_reloc(intel, priv->bo, read_domains, write_domain, delta, needs_fence); } #define ALIGN_BATCH(align) intel_batch_align(intel, align); #define OUT_BATCH(dword) intel_batch_emit_dword(intel, dword) #define OUT_RELOC(bo, read_domains, write_domains, delta) \ intel_batch_emit_reloc(intel, bo, read_domains, write_domains, delta, 0) #define OUT_RELOC_FENCED(bo, read_domains, write_domains, delta) \ intel_batch_emit_reloc(intel, bo, read_domains, write_domains, delta, 1) #define OUT_RELOC_PIXMAP(pixmap, reads, write, delta) \ intel_batch_emit_reloc_pixmap(intel, pixmap, reads, write, delta, 0) #define OUT_RELOC_PIXMAP_FENCED(pixmap, reads, write, delta) \ intel_batch_emit_reloc_pixmap(intel, pixmap, reads, write, delta, 1) union intfloat { float f; unsigned int ui; }; #define OUT_BATCH_F(x) do { \ union intfloat tmp; \ tmp.f = (float)(x); \ OUT_BATCH(tmp.ui); \ } while(0) #define __BEGIN_BATCH(n,batch_idx) \ do { \ if (intel->batch_emitting != 0) \ FatalError("%s: BEGIN_BATCH called without closing " \ "ADVANCE_BATCH\n", __FUNCTION__); \ assert(!intel->in_batch_atomic); \ if (intel->current_batch != batch_idx) { \ if (intel->current_batch && intel->context_switch) \ intel->context_switch(intel, batch_idx); \ } \ intel_batch_require_space(scrn, intel, (n) * 4); \ intel->current_batch = batch_idx; \ intel->batch_emitting = (n); \ intel->batch_emit_start = intel->batch_used; \ } while (0) #define BEGIN_BATCH(n) __BEGIN_BATCH(n,RENDER_BATCH) #define BEGIN_BATCH_BLT(n) __BEGIN_BATCH(n,BLT_BATCH) #define ADVANCE_BATCH() do { \ if (intel->batch_emitting == 0) \ FatalError("%s: ADVANCE_BATCH called with no matching " \ "BEGIN_BATCH\n", __FUNCTION__); \ if (intel->batch_used > \ intel->batch_emit_start + intel->batch_emitting) \ FatalError("%s: ADVANCE_BATCH: exceeded allocation %d/%d\n ", \ __FUNCTION__, \ intel->batch_used - intel->batch_emit_start, \ intel->batch_emitting); \ if (intel->batch_used < intel->batch_emit_start + \ intel->batch_emitting) \ FatalError("%s: ADVANCE_BATCH: under-used allocation %d/%d\n ", \ __FUNCTION__, \ intel->batch_used - intel->batch_emit_start, \ intel->batch_emitting); \ intel->batch_emitting = 0; \ } while (0) void intel_next_vertex(intel_screen_private *intel); static inline void intel_vertex_emit(intel_screen_private *intel, float v) { intel->vertex_ptr[intel->vertex_used++] = v; } #define OUT_VERTEX(v) intel_vertex_emit(intel, v) #endif /* _INTEL_BATCHBUFFER_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_display.c000066400000000000000000002017071267532330400246720ustar00rootroot00000000000000/* * Copyright © 2007 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Dave Airlie * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "xorg-server.h" #include "xorgVersion.h" #include "intel.h" #include "intel_bufmgr.h" #include "intel_options.h" #include "backlight.h" #include "xf86drm.h" #include "xf86drmMode.h" #include "X11/Xatom.h" #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H) #include #else #define DPMSModeOn 0 #define DPMSModeOff 3 #endif #include "xf86DDC.h" #include "fb.h" #if USE_UXA #include "intel_uxa.h" #endif #define KNOWN_MODE_FLAGS ((1<<14)-1) struct intel_drm_queue { struct list list; xf86CrtcPtr crtc; uint32_t seq; void *data; ScrnInfoPtr scrn; intel_drm_handler_proc handler; intel_drm_abort_proc abort; }; static uint32_t intel_drm_seq; static struct list intel_drm_queue; struct intel_mode { int fd; uint32_t fb_id; int cpp; drmEventContext event_context; int old_fb_id; int flip_count; uint64_t fe_msc; uint64_t fe_usec; struct list outputs; struct list crtcs; struct { intel_pageflip_handler_proc handler; intel_pageflip_abort_proc abort; void *data; } pageflip; }; struct intel_pageflip { struct intel_mode *mode; Bool dispatch_me; }; struct intel_crtc { struct intel_mode *mode; drmModeModeInfo kmode; drmModeCrtcPtr mode_crtc; int pipe; dri_bo *cursor; dri_bo *rotate_bo; uint32_t rotate_pitch; uint32_t rotate_fb_id; xf86CrtcPtr crtc; struct list link; PixmapPtr scanout_pixmap; uint32_t scanout_fb_id; uint32_t msc_prev; uint64_t msc_high; }; struct intel_property { drmModePropertyPtr mode_prop; uint64_t value; int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */ Atom *atoms; }; struct intel_output { struct intel_mode *mode; int output_id; drmModeConnectorPtr mode_output; drmModeEncoderPtr *mode_encoders; drmModePropertyBlobPtr edid_blob; int num_props; struct intel_property *props; void *private_data; Bool has_panel_limits; int panel_hdisplay; int panel_vdisplay; int dpms_mode; struct backlight backlight; int backlight_active_level; xf86OutputPtr output; struct list link; int enc_mask; int enc_clone_mask; }; static void intel_output_dpms(xf86OutputPtr output, int mode); static void intel_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode); static inline int crtc_id(struct intel_crtc *crtc) { return crtc->mode_crtc->crtc_id; } static void intel_output_backlight_set(xf86OutputPtr output, int level) { struct intel_output *intel_output = output->driver_private; if (backlight_set(&intel_output->backlight, level) < 0) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "failed to set backlight %s to brightness level %d, disabling\n", intel_output->backlight.iface, level); backlight_disable(&intel_output->backlight); } } static int intel_output_backlight_get(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; return backlight_get(&intel_output->backlight); } static void intel_output_backlight_init(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; intel_screen_private *intel = intel_get_screen_private(output->scrn); const char *str; #if !USE_BACKLIGHT return; #endif str = xf86GetOptValString(intel->Options, OPTION_BACKLIGHT); if (str != NULL) { if (backlight_exists(str)) { intel_output->backlight_active_level = backlight_open(&intel_output->backlight, strdup(str)); if (intel_output->backlight_active_level != -1) { xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG, "found backlight control interface %s\n", str); return; } } xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "unrecognised backlight control interface %s\n", str); } intel_output->backlight_active_level = backlight_open(&intel_output->backlight, NULL); if (intel_output->backlight_active_level != -1) { xf86DrvMsg(output->scrn->scrnIndex, X_PROBED, "found backlight control interface %s\n", intel_output->backlight.iface); return; } } static void mode_from_kmode(ScrnInfoPtr scrn, drmModeModeInfoPtr kmode, DisplayModePtr mode) { memset(mode, 0, sizeof(DisplayModeRec)); mode->status = MODE_OK; mode->Clock = kmode->clock; mode->HDisplay = kmode->hdisplay; mode->HSyncStart = kmode->hsync_start; mode->HSyncEnd = kmode->hsync_end; mode->HTotal = kmode->htotal; mode->HSkew = kmode->hskew; mode->VDisplay = kmode->vdisplay; mode->VSyncStart = kmode->vsync_start; mode->VSyncEnd = kmode->vsync_end; mode->VTotal = kmode->vtotal; mode->VScan = kmode->vscan; mode->Flags = kmode->flags; mode->name = strdup(kmode->name); if (kmode->type & DRM_MODE_TYPE_DRIVER) mode->type = M_T_DRIVER; if (kmode->type & DRM_MODE_TYPE_PREFERRED) mode->type |= M_T_PREFERRED; if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS) mode->status = MODE_BAD; /* unknown flags => unhandled */ xf86SetModeCrtc (mode, scrn->adjustFlags); } static void mode_to_kmode(ScrnInfoPtr scrn, drmModeModeInfoPtr kmode, DisplayModePtr mode) { memset(kmode, 0, sizeof(*kmode)); kmode->clock = mode->Clock; kmode->hdisplay = mode->HDisplay; kmode->hsync_start = mode->HSyncStart; kmode->hsync_end = mode->HSyncEnd; kmode->htotal = mode->HTotal; kmode->hskew = mode->HSkew; kmode->vdisplay = mode->VDisplay; kmode->vsync_start = mode->VSyncStart; kmode->vsync_end = mode->VSyncEnd; kmode->vtotal = mode->VTotal; kmode->vscan = mode->VScan; kmode->flags = mode->Flags; if (mode->name) strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; } static void intel_crtc_dpms(xf86CrtcPtr crtc, int mode) { } void intel_mode_disable_unused_functions(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct intel_mode *mode = intel_get_screen_private(scrn)->modes; int i; /* Force off for consistency between kernel and ddx */ for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; if (!crtc->enabled) drmModeSetCrtc(mode->fd, crtc_id(crtc->driver_private), 0, 0, 0, NULL, 0, NULL); } } static Bool intel_crtc_apply(xf86CrtcPtr crtc) { ScrnInfoPtr scrn = crtc->scrn; struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); uint32_t *output_ids; int output_count = 0; int fb_id, x, y; int i, ret = FALSE; output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); if (!output_ids) return FALSE; for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; struct intel_output *intel_output; /* Make sure we mark the output as off (and save the backlight) * before the kernel turns it off due to changing the pipe. * This is necessary as the kernel may turn off the backlight * and we lose track of the user settings. */ if (output->crtc == NULL) output->funcs->dpms(output, DPMSModeOff); if (output->crtc != crtc) continue; intel_output = output->driver_private; if (!intel_output->mode_output) return FALSE; output_ids[output_count] = intel_output->mode_output->connector_id; output_count++; } if (!intel_crtc->scanout_fb_id) { #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,5,99,0,0) if (!xf86CrtcRotate(crtc, mode, rotation)) goto done; #else if (!xf86CrtcRotate(crtc)) goto done; #endif } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,0,0,0) crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, crtc->gamma_blue, crtc->gamma_size); #endif x = crtc->x; y = crtc->y; fb_id = mode->fb_id; if (intel_crtc->rotate_fb_id) { fb_id = intel_crtc->rotate_fb_id; x = 0; y = 0; } else if (intel_crtc->scanout_fb_id && intel_crtc->scanout_pixmap->drawable.width >= crtc->mode.HDisplay && intel_crtc->scanout_pixmap->drawable.height >= crtc->mode.VDisplay) { fb_id = intel_crtc->scanout_fb_id; x = 0; y = 0; } ret = drmModeSetCrtc(mode->fd, crtc_id(intel_crtc), fb_id, x, y, output_ids, output_count, &intel_crtc->kmode); if (ret) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set mode: %s\n", strerror(-ret)); ret = FALSE; } else { ret = TRUE; /* Force DPMS to On for all outputs, which the kernel will have done * with the mode set. Also, restore the backlight level */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; struct intel_output *intel_output; if (output->crtc != crtc) continue; intel_output = output->driver_private; intel_output_dpms_backlight(output, intel_output->dpms_mode, DPMSModeOn); intel_output->dpms_mode = DPMSModeOn; } } if (scrn->pScreen) xf86_reload_cursors(scrn->pScreen); done: free(output_ids); return ret; } static Bool intel_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *intel_mode = intel_crtc->mode; int saved_x, saved_y; Rotation saved_rotation; DisplayModeRec saved_mode; int ret = TRUE; unsigned int pitch = scrn->displayWidth * intel->cpp; if (intel_mode->fb_id == 0) { ret = drmModeAddFB(intel_mode->fd, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, pitch, intel->front_buffer->handle, &intel_mode->fb_id); if (ret < 0) { ErrorF("failed to add fb\n"); return FALSE; } drm_intel_bo_disable_reuse(intel->front_buffer); } saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; saved_rotation = crtc->rotation; crtc->mode = *mode; crtc->x = x; crtc->y = y; crtc->rotation = rotation; intel_flush(intel); mode_to_kmode(crtc->scrn, &intel_crtc->kmode, mode); ret = intel_crtc_apply(crtc); if (!ret) { crtc->x = saved_x; crtc->y = saved_y; crtc->rotation = saved_rotation; crtc->mode = saved_mode; } return ret; } static void intel_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) { } static void intel_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) { struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; drmModeMoveCursor(mode->fd, crtc_id(intel_crtc), x, y); } static int __intel_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) { struct intel_crtc *intel_crtc = crtc->driver_private; int ret; ret = dri_bo_subdata(intel_crtc->cursor, 0, 64*64*4, image); if (ret) xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "failed to set cursor: %s\n", strerror(-ret)); return ret; } #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2) static Bool intel_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) { return __intel_crtc_load_cursor_argb(crtc, image) == 0; } #else static void intel_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) { __intel_crtc_load_cursor_argb(crtc, image); } #endif static void intel_crtc_hide_cursor(xf86CrtcPtr crtc) { struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; drmModeSetCursor(mode->fd, crtc_id(intel_crtc), 0, 64, 64); } static void intel_crtc_show_cursor(xf86CrtcPtr crtc) { struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; drmModeSetCursor(mode->fd, crtc_id(intel_crtc), intel_crtc->cursor->handle, 64, 64); } static void * intel_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { ScrnInfoPtr scrn = crtc->scrn; struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; int rotate_pitch; uint32_t tiling; int ret; intel_crtc->rotate_bo = intel_allocate_framebuffer(scrn, width, height, mode->cpp, &rotate_pitch, &tiling); if (!intel_crtc->rotate_bo) { xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "Couldn't allocate shadow memory for rotated CRTC\n"); return NULL; } ret = drmModeAddFB(mode->fd, width, height, crtc->scrn->depth, crtc->scrn->bitsPerPixel, rotate_pitch, intel_crtc->rotate_bo->handle, &intel_crtc->rotate_fb_id); if (ret) { ErrorF("failed to add rotate fb\n"); drm_intel_bo_unreference(intel_crtc->rotate_bo); return NULL; } intel_crtc->rotate_pitch = rotate_pitch; return intel_crtc->rotate_bo; } static PixmapPtr intel_create_pixmap_header(ScreenPtr pScreen, int width, int height, int depth, int bitsPerPixel, int devKind, void *pPixData) { PixmapPtr pixmap; /* width and height of 0 means don't allocate any pixmap data */ pixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0); if (pixmap) { if ((*pScreen->ModifyPixmapHeader) (pixmap, width, height, depth, bitsPerPixel, devKind, pPixData)) { return pixmap; } (*pScreen->DestroyPixmap) (pixmap); } return NullPixmap; } static PixmapPtr intel_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_crtc *intel_crtc = crtc->driver_private; PixmapPtr rotate_pixmap; if (!data) { data = intel_crtc_shadow_allocate (crtc, width, height); if (!data) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); return NULL; } } if (intel_crtc->rotate_bo == NULL) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); return NULL; } rotate_pixmap = intel_create_pixmap_header(scrn->pScreen, width, height, scrn->depth, scrn->bitsPerPixel, intel_crtc->rotate_pitch, NULL); if (rotate_pixmap == NULL) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate shadow pixmap for rotated CRTC\n"); return NULL; } intel_set_pixmap_bo(rotate_pixmap, intel_crtc->rotate_bo); intel->shadow_present = TRUE; return rotate_pixmap; } static void intel_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; if (rotate_pixmap) { intel_set_pixmap_bo(rotate_pixmap, NULL); rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap); } if (data) { /* Be sure to sync acceleration before the memory gets * unbound. */ drmModeRmFB(mode->fd, intel_crtc->rotate_fb_id); intel_crtc->rotate_fb_id = 0; dri_bo_unreference(intel_crtc->rotate_bo); intel_crtc->rotate_bo = NULL; } intel->shadow_present = FALSE; } static void intel_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size) { struct intel_crtc *intel_crtc = crtc->driver_private; struct intel_mode *mode = intel_crtc->mode; drmModeCrtcSetGamma(mode->fd, crtc_id(intel_crtc), size, red, green, blue); } static void intel_crtc_destroy(xf86CrtcPtr crtc) { struct intel_crtc *intel_crtc = crtc->driver_private; if (intel_crtc->cursor) { drmModeSetCursor(intel_crtc->mode->fd, crtc_id(intel_crtc), 0, 64, 64); drm_intel_bo_unreference(intel_crtc->cursor); intel_crtc->cursor = NULL; } list_del(&intel_crtc->link); free(intel_crtc); crtc->driver_private = NULL; } #ifdef INTEL_PIXMAP_SHARING static Bool intel_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) { struct intel_crtc *intel_crtc = crtc->driver_private; ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *bo; if (ppix == intel_crtc->scanout_pixmap) return TRUE; if (!ppix) { intel_crtc->scanout_pixmap = NULL; if (intel_crtc->scanout_fb_id) { drmModeRmFB(intel->drmSubFD, intel_crtc->scanout_fb_id); intel_crtc->scanout_fb_id = 0; } return TRUE; } bo = intel_get_pixmap_bo(ppix); if (!bo) return FALSE; if (intel->front_buffer) return FALSE; drm_intel_bo_disable_reuse(bo); intel_crtc->scanout_pixmap = ppix; return drmModeAddFB(intel->drmSubFD, ppix->drawable.width, ppix->drawable.height, ppix->drawable.depth, ppix->drawable.bitsPerPixel, ppix->devKind, bo->handle, &intel_crtc->scanout_fb_id) == 0; } #endif static const xf86CrtcFuncsRec intel_crtc_funcs = { .dpms = intel_crtc_dpms, .set_mode_major = intel_crtc_set_mode_major, .set_cursor_colors = intel_crtc_set_cursor_colors, .set_cursor_position = intel_crtc_set_cursor_position, .show_cursor = intel_crtc_show_cursor, .hide_cursor = intel_crtc_hide_cursor, #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3) .load_cursor_argb_check = intel_crtc_load_cursor_argb, #else .load_cursor_argb = intel_crtc_load_cursor_argb, #endif .shadow_create = intel_crtc_shadow_create, .shadow_allocate = intel_crtc_shadow_allocate, .shadow_destroy = intel_crtc_shadow_destroy, .gamma_set = intel_crtc_gamma_set, .destroy = intel_crtc_destroy, #ifdef INTEL_PIXMAP_SHARING .set_scanout_pixmap = intel_set_scanout_pixmap, #endif }; static void intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num) { intel_screen_private *intel = intel_get_screen_private(scrn); xf86CrtcPtr crtc; struct intel_crtc *intel_crtc; intel_crtc = calloc(sizeof(struct intel_crtc), 1); if (intel_crtc == NULL) return; crtc = xf86CrtcCreate(scrn, &intel_crtc_funcs); if (crtc == NULL) { free(intel_crtc); return; } intel_crtc->mode_crtc = drmModeGetCrtc(mode->fd, mode_res->crtcs[num]); if (intel_crtc->mode_crtc == NULL) { free(intel_crtc); return; } intel_crtc->mode = mode; crtc->driver_private = intel_crtc; intel_crtc->pipe = drm_intel_get_pipe_from_crtc_id(intel->bufmgr, crtc_id(intel_crtc)); intel_crtc->cursor = drm_intel_bo_alloc(intel->bufmgr, "ARGB cursor", 4*64*64, 4096); intel_crtc->crtc = crtc; list_add(&intel_crtc->link, &mode->crtcs); } static Bool is_panel(int type) { return (type == DRM_MODE_CONNECTOR_LVDS || type == DRM_MODE_CONNECTOR_eDP); } static xf86OutputStatus intel_output_detect(xf86OutputPtr output) { /* go to the hw and retrieve a new output struct */ struct intel_output *intel_output = output->driver_private; struct intel_mode *mode = intel_output->mode; xf86OutputStatus status; drmModeFreeConnector(intel_output->mode_output); intel_output->mode_output = drmModeGetConnector(mode->fd, intel_output->output_id); if (intel_output->mode_output == NULL) { /* and hope we are safe everywhere else */ xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "drmModeGetConnector failed, reporting output disconnected\n"); return XF86OutputStatusDisconnected; } switch (intel_output->mode_output->connection) { case DRM_MODE_CONNECTED: status = XF86OutputStatusConnected; break; case DRM_MODE_DISCONNECTED: status = XF86OutputStatusDisconnected; break; default: case DRM_MODE_UNKNOWNCONNECTION: status = XF86OutputStatusUnknown; break; } return status; } static Bool intel_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) { struct intel_output *intel_output = output->driver_private; /* * If the connector type is a panel, we will use the panel limit to * verfiy whether the mode is valid. */ if (intel_output->has_panel_limits) { if (pModes->HDisplay > intel_output->panel_hdisplay || pModes->VDisplay > intel_output->panel_vdisplay) return MODE_PANEL; } return MODE_OK; } static void intel_output_attach_edid(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; drmModeConnectorPtr koutput = intel_output->mode_output; struct intel_mode *mode = intel_output->mode; xf86MonPtr mon = NULL; int i; if (!koutput) { xf86OutputSetEDID(output, mon); return; } /* look for an EDID property */ for (i = 0; i < koutput->count_props; i++) { drmModePropertyPtr props; props = drmModeGetProperty(mode->fd, koutput->props[i]); if (!props) continue; if (!(props->flags & DRM_MODE_PROP_BLOB)) { drmModeFreeProperty(props); continue; } if (!strcmp(props->name, "EDID")) { drmModeFreePropertyBlob(intel_output->edid_blob); intel_output->edid_blob = drmModeGetPropertyBlob(mode->fd, koutput->prop_values[i]); } drmModeFreeProperty(props); } if (intel_output->edid_blob) { mon = xf86InterpretEDID(output->scrn->scrnIndex, intel_output->edid_blob->data); if (mon && intel_output->edid_blob->length > 128) mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; } xf86OutputSetEDID(output, mon); } static void intel_output_attach_tile(xf86OutputPtr output) { #if XF86_OUTPUT_VERSION >= 3 struct intel_output *intel_output = output->driver_private; drmModeConnectorPtr koutput = intel_output->mode_output; struct intel_mode *mode = intel_output->mode; drmModePropertyBlobPtr blob = NULL; struct xf86CrtcTileInfo tile_info, *set = NULL; int i; for (i = 0; koutput && i < koutput->count_props; i++) { drmModePropertyPtr props; props = drmModeGetProperty(mode->fd, koutput->props[i]); if (!props) continue; if (!(props->flags & DRM_MODE_PROP_BLOB)) { drmModeFreeProperty(props); continue; } if (!strcmp(props->name, "TILE")) { blob = drmModeGetPropertyBlob(mode->fd, koutput->prop_values[i]); } drmModeFreeProperty(props); } if (blob) { if (xf86OutputParseKMSTile(blob->data, blob->length, &tile_info)) set = &tile_info; drmModeFreePropertyBlob(blob); } xf86OutputSetTile(output, set); #endif } static DisplayModePtr intel_output_panel_edid(xf86OutputPtr output, DisplayModePtr modes) { xf86MonPtr mon = output->MonInfo; if (!mon || !GTF_SUPPORTED(mon->features.msc)) { DisplayModePtr i, m, p = NULL; int max_x = 0, max_y = 0; float max_vrefresh = 0.0; for (m = modes; m; m = m->next) { if (m->type & M_T_PREFERRED) p = m; max_x = max(max_x, m->HDisplay); max_y = max(max_y, m->VDisplay); max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); } max_vrefresh = max(max_vrefresh, 60.0); max_vrefresh *= (1 + SYNC_TOLERANCE); #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,0,0) m = xf86GetDefaultModes(); #else m = xf86GetDefaultModes(0,0); #endif xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); for (i = m; i; i = i->next) { if (xf86ModeVRefresh(i) > max_vrefresh) i->status = MODE_VSYNC; if (p && i->HDisplay >= p->HDisplay && i->VDisplay >= p->VDisplay && xf86ModeVRefresh(i) >= xf86ModeVRefresh(p)) i->status = MODE_VSYNC; } xf86PruneInvalidModes(output->scrn, &m, FALSE); modes = xf86ModesAdd(modes, m); } return modes; } static DisplayModePtr intel_output_get_modes(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; drmModeConnectorPtr koutput = intel_output->mode_output; DisplayModePtr Modes = NULL; int i; intel_output_attach_edid(output); intel_output_attach_tile(output); if (!koutput) return Modes; /* modes should already be available */ for (i = 0; i < koutput->count_modes; i++) { DisplayModePtr Mode; Mode = calloc(1, sizeof(DisplayModeRec)); if (Mode) { mode_from_kmode(output->scrn, &koutput->modes[i], Mode); Modes = xf86ModesAdd(Modes, Mode); } } /* * If the connector type is a panel, we will traverse the kernel mode to * get the panel limit. And then add all the standard modes to fake * the fullscreen experience. * If it is incorrect, please fix me. */ intel_output->has_panel_limits = FALSE; if (is_panel(koutput->connector_type)) { for (i = 0; i < koutput->count_modes; i++) { drmModeModeInfo *mode_ptr; mode_ptr = &koutput->modes[i]; if (mode_ptr->hdisplay > intel_output->panel_hdisplay) intel_output->panel_hdisplay = mode_ptr->hdisplay; if (mode_ptr->vdisplay > intel_output->panel_vdisplay) intel_output->panel_vdisplay = mode_ptr->vdisplay; } intel_output->has_panel_limits = intel_output->panel_hdisplay && intel_output->panel_vdisplay; Modes = intel_output_panel_edid(output, Modes); } return Modes; } static void intel_output_destroy(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; int i; drmModeFreePropertyBlob(intel_output->edid_blob); for (i = 0; i < intel_output->num_props; i++) { drmModeFreeProperty(intel_output->props[i].mode_prop); free(intel_output->props[i].atoms); } free(intel_output->props); for (i = 0; i < intel_output->mode_output->count_encoders; i++) { drmModeFreeEncoder(intel_output->mode_encoders[i]); } free(intel_output->mode_encoders); drmModeFreeConnector(intel_output->mode_output); intel_output->mode_output = NULL; list_del(&intel_output->link); backlight_close(&intel_output->backlight); free(intel_output); output->driver_private = NULL; } static void intel_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode) { struct intel_output *intel_output = output->driver_private; if (!intel_output->backlight.iface) return; if (mode == DPMSModeOn) { /* If we're going from off->on we may need to turn on the backlight. */ if (oldmode != DPMSModeOn) intel_output_backlight_set(output, intel_output->backlight_active_level); } else { /* Only save the current backlight value if we're going from on to off. */ if (oldmode == DPMSModeOn) intel_output->backlight_active_level = intel_output_backlight_get(output); intel_output_backlight_set(output, 0); } } static void intel_output_dpms(xf86OutputPtr output, int dpms) { struct intel_output *intel_output = output->driver_private; drmModeConnectorPtr koutput = intel_output->mode_output; struct intel_mode *mode = intel_output->mode; int i; if (!koutput) return; for (i = 0; i < koutput->count_props; i++) { drmModePropertyPtr props; props = drmModeGetProperty(mode->fd, koutput->props[i]); if (!props) continue; if (!strcmp(props->name, "DPMS")) { /* Make sure to reverse the order between on and off. */ if (dpms != DPMSModeOn) intel_output_dpms_backlight(output, intel_output->dpms_mode, dpms); drmModeConnectorSetProperty(mode->fd, intel_output->output_id, props->prop_id, dpms); if (dpms == DPMSModeOn) intel_output_dpms_backlight(output, intel_output->dpms_mode, dpms); intel_output->dpms_mode = dpms; drmModeFreeProperty(props); return; } drmModeFreeProperty(props); } } int intel_output_dpms_status(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; return intel_output->dpms_mode; } static Bool intel_property_ignore(drmModePropertyPtr prop) { if (!prop) return TRUE; /* ignore blob prop */ if (prop->flags & DRM_MODE_PROP_BLOB) return TRUE; /* ignore standard property */ if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) return TRUE; return FALSE; } static void intel_output_create_ranged_atom(xf86OutputPtr output, Atom *atom, const char *name, INT32 min, INT32 max, uint64_t value, Bool immutable) { int err; INT32 atom_range[2]; atom_range[0] = min; atom_range[1] = max; *atom = MakeAtom(name, strlen(name), TRUE); err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE, TRUE, immutable, 2, atom_range); if (err != 0) xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRConfigureOutputProperty error, %d\n", err); err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER, 32, PropModeReplace, 1, &value, FALSE, FALSE); if (err != 0) xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRChangeOutputProperty error, %d\n", err); } #define BACKLIGHT_NAME "Backlight" #define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT" static Atom backlight_atom, backlight_deprecated_atom; static void intel_output_create_resources(xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private; drmModeConnectorPtr mode_output = intel_output->mode_output; struct intel_mode *mode = intel_output->mode; int i, j, err; intel_output->props = calloc(mode_output->count_props, sizeof(struct intel_property)); if (!intel_output->props) return; intel_output->num_props = 0; for (i = j = 0; i < mode_output->count_props; i++) { drmModePropertyPtr drmmode_prop; drmmode_prop = drmModeGetProperty(mode->fd, mode_output->props[i]); if (intel_property_ignore(drmmode_prop)) { drmModeFreeProperty(drmmode_prop); continue; } intel_output->props[j].mode_prop = drmmode_prop; intel_output->props[j].value = mode_output->prop_values[i]; j++; } intel_output->num_props = j; for (i = 0; i < intel_output->num_props; i++) { struct intel_property *p = &intel_output->props[i]; drmModePropertyPtr drmmode_prop = p->mode_prop; if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { p->num_atoms = 1; p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; intel_output_create_ranged_atom(output, &p->atoms[0], drmmode_prop->name, drmmode_prop->values[0], drmmode_prop->values[1], p->value, drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE); } else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { p->num_atoms = drmmode_prop->count_enums + 1; p->atoms = calloc(p->num_atoms, sizeof(Atom)); if (!p->atoms) continue; p->atoms[0] = MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); for (j = 1; j <= drmmode_prop->count_enums; j++) { struct drm_mode_property_enum *e = &drmmode_prop->enums[j-1]; p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); } err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], FALSE, FALSE, drmmode_prop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE, p->num_atoms - 1, (INT32 *)&p->atoms[1]); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRConfigureOutputProperty error, %d\n", err); } for (j = 0; j < drmmode_prop->count_enums; j++) if (drmmode_prop->enums[j].value == p->value) break; /* there's always a matching value */ err = RRChangeOutputProperty(output->randr_output, p->atoms[0], XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1], FALSE, FALSE); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRChangeOutputProperty error, %d\n", err); } } } if (intel_output->backlight.iface) { /* Set up the backlight property, which takes effect * immediately and accepts values only within the * backlight_range. */ intel_output_create_ranged_atom(output, &backlight_atom, BACKLIGHT_NAME, 0, intel_output->backlight.max, intel_output->backlight_active_level, FALSE); intel_output_create_ranged_atom(output, &backlight_deprecated_atom, BACKLIGHT_DEPRECATED_NAME, 0, intel_output->backlight.max, intel_output->backlight_active_level, FALSE); } } static Bool intel_output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) { struct intel_output *intel_output = output->driver_private; struct intel_mode *mode = intel_output->mode; int i; if (property == backlight_atom || property == backlight_deprecated_atom) { INT32 val; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) { return FALSE; } val = *(INT32 *)value->data; if (val < 0 || val > intel_output->backlight.max) return FALSE; if (intel_output->dpms_mode == DPMSModeOn) intel_output_backlight_set(output, val); intel_output->backlight_active_level = val; return TRUE; } for (i = 0; i < intel_output->num_props; i++) { struct intel_property *p = &intel_output->props[i]; if (p->atoms[0] != property) continue; if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { uint32_t val; if (value->type != XA_INTEGER || value->format != 32 || value->size != 1) return FALSE; val = *(uint32_t *)value->data; drmModeConnectorSetProperty(mode->fd, intel_output->output_id, p->mode_prop->prop_id, (uint64_t)val); return TRUE; } else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { Atom atom; const char *name; int j; if (value->type != XA_ATOM || value->format != 32 || value->size != 1) return FALSE; memcpy(&atom, value->data, 4); name = NameForAtom(atom); if (name == NULL) return FALSE; /* search for matching name string, then set its value down */ for (j = 0; j < p->mode_prop->count_enums; j++) { if (!strcmp(p->mode_prop->enums[j].name, name)) { drmModeConnectorSetProperty(mode->fd, intel_output->output_id, p->mode_prop->prop_id, p->mode_prop->enums[j].value); return TRUE; } } return FALSE; } } /* We didn't recognise this property, just report success in order * to allow the set to continue, otherwise we break setting of * common properties like EDID. */ return TRUE; } static Bool intel_output_get_property(xf86OutputPtr output, Atom property) { struct intel_output *intel_output = output->driver_private; int err; if (property == backlight_atom || property == backlight_deprecated_atom) { INT32 val; if (!intel_output->backlight.iface) return FALSE; if (intel_output->dpms_mode == DPMSModeOn) { val = intel_output_backlight_get(output); if (val < 0) return FALSE; } else { val = intel_output->backlight_active_level; } err = RRChangeOutputProperty(output->randr_output, property, XA_INTEGER, 32, PropModeReplace, 1, &val, FALSE, FALSE); if (err != 0) { xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "RRChangeOutputProperty error, %d\n", err); return FALSE; } return TRUE; } return FALSE; } static const xf86OutputFuncsRec intel_output_funcs = { .create_resources = intel_output_create_resources, #ifdef RANDR_12_INTERFACE .set_property = intel_output_set_property, .get_property = intel_output_get_property, #endif .dpms = intel_output_dpms, #if 0 .save = drmmode_crt_save, .restore = drmmode_crt_restore, .mode_fixup = drmmode_crt_mode_fixup, .prepare = intel_output_prepare, .mode_set = drmmode_crt_mode_set, .commit = intel_output_commit, #endif .detect = intel_output_detect, .mode_valid = intel_output_mode_valid, .get_modes = intel_output_get_modes, .destroy = intel_output_destroy }; static const int subpixel_conv_table[7] = { 0, SubPixelUnknown, SubPixelHorizontalRGB, SubPixelHorizontalBGR, SubPixelVerticalRGB, SubPixelVerticalBGR, SubPixelNone }; static const char *output_names[] = { "None", "VGA", "DVI", "DVI", "DVI", "Composite", "TV", "LVDS", "CTV", "DIN", "DP", "HDMI", "HDMI", "TV", "eDP", }; static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int i; for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; struct intel_output *intel_output; intel_output = output->driver_private; if (intel_output->output_id == id) return output; } return NULL; } static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) { char *conn; char conn_id[5]; int id, len; char *blob_data; if (!path_blob) return -1; blob_data = path_blob->data; /* we only handle MST paths for now */ if (strncmp(blob_data, "mst:", 4)) return -1; conn = strchr(blob_data + 4, '-'); if (!conn) return -1; len = conn - (blob_data + 4); if (len + 1 > 5) return -1; memcpy(conn_id, blob_data + 4, len); conn_id[len] = '\0'; id = strtoul(conn_id, NULL, 10); *conn_base_id = id; *path = conn + 1; return 0; } static void drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, drmModePropertyBlobPtr path_blob) { xf86OutputPtr output; int conn_id; char *extra_path; output = NULL; if (parse_path_blob(path_blob, &conn_id, &extra_path) == 0) output = find_output(pScrn, conn_id); if (output) { snprintf(name, 32, "%s-%s", output->name, extra_path); } else { const char *output_name; if (koutput->connector_type < ARRAY_SIZE(output_names)) output_name = output_names[koutput->connector_type]; else output_name = "UNKNOWN"; snprintf(name, 32, "%s%d", output_name, koutput->connector_type_id); } } static void intel_output_init(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res, int num, int dynamic) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86OutputPtr output; drmModeConnectorPtr koutput; drmModeEncoderPtr *kencoders = NULL; struct intel_output *intel_output; char name[32]; drmModePropertyPtr props; drmModePropertyBlobPtr path_blob = NULL; int i; koutput = drmModeGetConnector(mode->fd, mode_res->connectors[num]); if (!koutput) return; for (i = 0; i < koutput->count_props; i++) { props = drmModeGetProperty(mode->fd, koutput->props[i]); if (props && (props->flags & DRM_MODE_PROP_BLOB)) { if (!strcmp(props->name, "PATH")) { path_blob = drmModeGetPropertyBlob(mode->fd, koutput->prop_values[i]); drmModeFreeProperty(props); break; } drmModeFreeProperty(props); } } drmmode_create_name(scrn, koutput, name, path_blob); if (path_blob) drmModeFreePropertyBlob(path_blob); if (path_blob && dynamic) { /* See if we have an output with this name already * and hook stuff up. */ for (i = 0; i < xf86_config->num_output; i++) { output = xf86_config->output[i]; if (strncmp(output->name, name, 32)) continue; intel_output = output->driver_private; intel_output->output_id = mode_res->connectors[num]; intel_output->mode_output = koutput; RROutputChanged(output->randr_output, TRUE); return; } } kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); if (!kencoders) { goto out_free_encoders; } for (i = 0; i < koutput->count_encoders; i++) { kencoders[i] = drmModeGetEncoder(mode->fd, koutput->encoders[i]); if (!kencoders[i]) goto out_free_encoders; } output = xf86OutputCreate (scrn, &intel_output_funcs, name); if (!output) { goto out_free_encoders; } intel_output = calloc(sizeof(struct intel_output), 1); if (!intel_output) { xf86OutputDestroy(output); goto out_free_encoders; } intel_output->output_id = mode_res->connectors[num]; intel_output->mode_output = koutput; intel_output->mode_encoders = kencoders; intel_output->mode = mode; output->mm_width = koutput->mmWidth; output->mm_height = koutput->mmHeight; output->subpixel_order = subpixel_conv_table[koutput->subpixel]; output->driver_private = intel_output; if (is_panel(koutput->connector_type)) intel_output_backlight_init(output); output->possible_crtcs = 0x7f; for (i = 0; i < koutput->count_encoders; i++) { output->possible_crtcs &= kencoders[i]->possible_crtcs; } output->interlaceAllowed = TRUE; intel_output->output = output; if (dynamic) { output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), output->name, strlen(output->name), output); intel_output_create_resources(output); } list_add(&intel_output->link, &mode->outputs); return; out_free_encoders: if (kencoders) { for (i = 0; i < koutput->count_encoders; i++) drmModeFreeEncoder(kencoders[i]); free(kencoders); } drmModeFreeConnector(koutput); } static Bool intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); struct intel_crtc *intel_crtc = xf86_config->crtc[0]->driver_private; struct intel_mode *mode = intel_crtc->mode; intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *old_front = NULL; Bool ret; uint32_t old_fb_id; int i, old_width, old_height, old_pitch; int pitch; uint32_t tiling; if (scrn->virtualX == width && scrn->virtualY == height) return TRUE; intel_flush(intel); old_width = scrn->virtualX; old_height = scrn->virtualY; old_pitch = scrn->displayWidth; old_fb_id = mode->fb_id; old_front = intel->front_buffer; if (intel->back_buffer) { drm_intel_bo_unreference(intel->back_buffer); intel->back_buffer = NULL; } intel->front_buffer = intel_allocate_framebuffer(scrn, width, height, intel->cpp, &pitch, &tiling); if (!intel->front_buffer) goto fail; ret = drmModeAddFB(mode->fd, width, height, scrn->depth, scrn->bitsPerPixel, pitch, intel->front_buffer->handle, &mode->fb_id); if (ret) goto fail; intel->front_pitch = pitch; intel->front_tiling = tiling; scrn->virtualX = width; scrn->virtualY = height; if (!intel_uxa_create_screen_resources(scrn->pScreen)) goto fail; for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; if (!crtc->enabled) continue; if (!intel_crtc_apply(crtc)) goto fail; } if (old_fb_id) drmModeRmFB(mode->fd, old_fb_id); if (old_front) drm_intel_bo_unreference(old_front); return TRUE; fail: if (intel->front_buffer) drm_intel_bo_unreference(intel->front_buffer); intel->front_buffer = old_front; scrn->virtualX = old_width; scrn->virtualY = old_height; scrn->displayWidth = old_pitch; if (old_fb_id != mode->fb_id) drmModeRmFB(mode->fd, mode->fb_id); mode->fb_id = old_fb_id; return FALSE; } static void intel_pageflip_handler(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t frame, uint64_t usec, void *data); static void intel_pageflip_abort(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data); static void intel_pageflip_complete(struct intel_mode *mode); Bool intel_do_pageflip(intel_screen_private *intel, dri_bo *new_front, int ref_crtc_hw_id, Bool async, void *pageflip_data, intel_pageflip_handler_proc pageflip_handler, intel_pageflip_abort_proc pageflip_abort) { ScrnInfoPtr scrn = intel->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); struct intel_crtc *crtc = config->crtc[0]->driver_private; struct intel_mode *mode = crtc->mode; unsigned int pitch = scrn->displayWidth * intel->cpp; struct intel_pageflip *flip; uint32_t new_fb_id; uint32_t flags; uint32_t seq; int err = 0; int i; /* * We only have a single length queue in the kernel, so any * attempts to schedule a second flip before processing the first * is a bug. Punt it back to the caller. */ if (mode->flip_count) return FALSE; /* * Create a new handle for the back buffer */ if (drmModeAddFB(mode->fd, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, pitch, new_front->handle, &new_fb_id)) { err = errno; goto error_out; } drm_intel_bo_disable_reuse(new_front); intel_flush(intel); /* * Queue flips on all enabled CRTCs * Note that if/when we get per-CRTC buffers, we'll have to update this. * Right now it assumes a single shared fb across all CRTCs, with the * kernel fixing up the offset of each CRTC as necessary. * * Also, flips queued on disabled or incorrectly configured displays * may never complete; this is a configuration error. */ mode->fe_msc = 0; mode->fe_usec = 0; memset(&mode->pageflip, 0, sizeof(mode->pageflip)); flags = DRM_MODE_PAGE_FLIP_EVENT; if (async) flags |= DRM_MODE_PAGE_FLIP_ASYNC; for (i = 0; i < config->num_crtc; i++) { if (!intel_crtc_on(config->crtc[i])) continue; crtc = config->crtc[i]->driver_private; flip = calloc(1, sizeof(struct intel_pageflip)); if (flip == NULL) { err = errno; goto error_undo; } /* Only the reference crtc will finally deliver its page flip * completion event. All other crtc's events will be discarded. */ flip->dispatch_me = (intel_crtc_to_pipe(crtc->crtc) == ref_crtc_hw_id); flip->mode = mode; seq = intel_drm_queue_alloc(scrn, config->crtc[i], flip, intel_pageflip_handler, intel_pageflip_abort); if (!seq) { err = errno; free(flip); goto error_undo; } mode->flip_count++; if (drmModePageFlip(mode->fd, crtc_id(crtc), new_fb_id, flags, (void *)(uintptr_t)seq)) { err = errno; intel_drm_abort_seq(scrn, seq); goto error_undo; } } mode->old_fb_id = mode->fb_id; mode->fb_id = new_fb_id; mode->pageflip.data = pageflip_data; mode->pageflip.handler = pageflip_handler; mode->pageflip.abort = pageflip_abort; if (!mode->flip_count) intel_pageflip_complete(mode); return TRUE; error_undo: drmModeRmFB(mode->fd, new_fb_id); for (i = 0; i < config->num_crtc; i++) { if (config->crtc[i]->enabled) intel_crtc_apply(config->crtc[i]); } error_out: xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n", strerror(err)); mode->flip_count = 0; return FALSE; } static const xf86CrtcConfigFuncsRec intel_xf86crtc_config_funcs = { intel_xf86crtc_resize }; /* * Enqueue a potential drm response; when the associated response * appears, we've got data to pass to the handler from here */ uint32_t intel_drm_queue_alloc(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data, intel_drm_handler_proc handler, intel_drm_abort_proc abort) { struct intel_drm_queue *q; q = calloc(1, sizeof(struct intel_drm_queue)); if (!q) return 0; if (!intel_drm_seq) ++intel_drm_seq; q->seq = intel_drm_seq++; q->scrn = scrn; q->crtc = crtc; q->data = data; q->handler = handler; q->abort = abort; list_add(&q->list, &intel_drm_queue); return q->seq; } /* * Abort one queued DRM entry, removing it * from the list, calling the abort function and * freeing the memory */ static void intel_drm_abort_one(struct intel_drm_queue *q) { list_del(&q->list); q->abort(q->scrn, q->crtc, q->data); free(q); } /* * Externally usable abort function that uses a callback to match a single queued * entry to abort */ void intel_drm_abort(ScrnInfoPtr scrn, Bool (*match)(void *data, void *match_data), void *match_data) { struct intel_drm_queue *q; list_for_each_entry(q, &intel_drm_queue, list) { if (match(q->data, match_data)) { intel_drm_abort_one(q); break; } } } /* * Abort by drm queue sequence number */ void intel_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq) { struct intel_drm_queue *q; list_for_each_entry(q, &intel_drm_queue, list) { if (q->seq == seq) { intel_drm_abort_one(q); break; } } } /* * Abort all queued entries on a specific scrn, used * when resetting the X server */ static void intel_drm_abort_scrn(ScrnInfoPtr scrn) { struct intel_drm_queue *q, *tmp; list_for_each_entry_safe(q, tmp, &intel_drm_queue, list) { if (q->scrn == scrn) intel_drm_abort_one(q); } } static uint32_t pipe_select(int pipe) { if (pipe > 1) return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT; else if (pipe > 0) return DRM_VBLANK_SECONDARY; else return 0; } /* * Get the current msc/ust value from the kernel */ static int intel_get_msc_ust(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint32_t *msc, uint64_t *ust) { intel_screen_private *intel = intel_get_screen_private(scrn); drmVBlank vbl; /* Get current count */ vbl.request.type = DRM_VBLANK_RELATIVE | pipe_select(intel_crtc_to_pipe(crtc)); vbl.request.sequence = 0; vbl.request.signal = 0; if (drmWaitVBlank(intel->drmSubFD, &vbl)) { *msc = 0; *ust = 0; return BadMatch; } else { *msc = vbl.reply.sequence; *ust = (CARD64) vbl.reply.tval_sec * 1000000 + vbl.reply.tval_usec; return Success; } } /* * Convert a 32-bit kernel MSC sequence number to a 64-bit local sequence * number, adding in the vblank_offset and high 32 bits, and dealing * with 64-bit wrapping */ uint64_t intel_sequence_to_crtc_msc(xf86CrtcPtr crtc, uint32_t sequence) { struct intel_crtc *intel_crtc = crtc->driver_private; if ((int32_t) (sequence - intel_crtc->msc_prev) < -0x40000000) intel_crtc->msc_high += 0x100000000L; intel_crtc->msc_prev = sequence; return intel_crtc->msc_high + sequence; } /* * Get the current 64-bit adjust MSC and UST value */ int intel_get_crtc_msc_ust(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t *msc, uint64_t *ust) { uint32_t sequence; int ret; ret = intel_get_msc_ust(scrn, crtc, &sequence, ust); if (ret) return ret; *msc = intel_sequence_to_crtc_msc(crtc, sequence); return 0; } uint32_t intel_crtc_msc_to_sequence(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t expect) { return (uint32_t)expect; } /* * General DRM kernel handler. Looks for the matching sequence number in the * drm event queue and calls the handler for it. */ static void intel_drm_handler(int fd, uint32_t frame, uint32_t sec, uint32_t usec, void *user_ptr) { uint32_t user_data = (intptr_t)user_ptr; struct intel_drm_queue *q; list_for_each_entry(q, &intel_drm_queue, list) { if (q->seq == user_data) { list_del(&q->list); q->handler(q->scrn, q->crtc, intel_sequence_to_crtc_msc(q->crtc, frame), (uint64_t)sec * 1000000 + usec, q->data); free(q); break; } } } /* * Notify the page flip caller that the flip is * complete */ static void intel_pageflip_complete(struct intel_mode *mode) { if (!mode->pageflip.handler) return; /* Release framebuffer */ drmModeRmFB(mode->fd, mode->old_fb_id); mode->pageflip.handler(mode->fe_msc, mode->fe_usec, mode->pageflip.data); } /* * One pageflip event has completed. Update the saved msc/ust values * as needed, then check to see if the whole set of events are * complete and notify the application at that point */ static struct intel_mode * intel_handle_pageflip(struct intel_pageflip *flip, uint64_t msc, uint64_t usec) { struct intel_mode *mode = flip->mode; if (flip->dispatch_me) { /* Yes: Cache msc, ust for later delivery. */ mode->fe_msc = msc; mode->fe_usec = usec; } free(flip); /* Last crtc completed flip? */ mode->flip_count--; if (mode->flip_count > 0) return NULL; return mode; } /* * Called from the DRM event queue when a single flip has completed */ static void intel_pageflip_handler(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t msc, uint64_t usec, void *data) { struct intel_pageflip *flip = data; struct intel_mode *mode = intel_handle_pageflip(flip, msc, usec); if (!mode) return; intel_pageflip_complete(mode); } /* * Called from the DRM queue abort code when a flip has been aborted */ static void intel_pageflip_abort(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data) { struct intel_pageflip *flip = data; struct intel_mode *mode = intel_handle_pageflip(flip, 0, 0); if (!mode) return; if (!mode->pageflip.abort) return; /* Release framebuffer */ drmModeRmFB(mode->fd, mode->old_fb_id); mode->pageflip.abort(mode->pageflip.data); } /* * Check for pending DRM events and process them. */ static void drm_wakeup_handler(pointer data, int err, pointer p) { struct intel_mode *mode; fd_set *read_mask; if (data == NULL || err < 0) return; mode = data; read_mask = p; if (FD_ISSET(mode->fd, read_mask)) drmHandleEvent(mode->fd, &mode->event_context); } /* * If there are any available, read drm_events */ int intel_mode_read_drm_events(struct intel_screen_private *intel) { struct intel_mode *mode = intel->modes; struct pollfd p = { .fd = mode->fd, .events = POLLIN }; int r; do { r = poll(&p, 1, 0); } while (r == -1 && (errno == EINTR || errno == EAGAIN)); if (r <= 0) return 0; return drmHandleEvent(mode->fd, &mode->event_context); } /* * Libdrm's possible_clones is a mask of encoders, Xorg's possible_clones is a * mask of outputs. This function sets Xorg's possible_clones based on the * values read from libdrm. */ static uint32_t find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) { struct intel_output *intel_output = output->driver_private, *clone_drmout; int i; xf86OutputPtr clone_output; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int index_mask = 0; if (intel_output->enc_clone_mask == 0) return index_mask; for (i = 0; i < xf86_config->num_output; i++) { clone_output = xf86_config->output[i]; clone_drmout = clone_output->driver_private; if (output == clone_output) continue; if (clone_drmout->enc_mask == 0) continue; if (intel_output->enc_clone_mask == clone_drmout->enc_mask) index_mask |= (1 << i); } return index_mask; } static void intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode, drmModeResPtr mode_res) { int i, j; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; struct intel_output *intel_output; intel_output = output->driver_private; intel_output->enc_clone_mask = 0xff; /* and all the possible encoder clones for this output together */ for (j = 0; j < intel_output->mode_output->count_encoders; j++) { int k; for (k = 0; k < mode_res->count_encoders; k++) { if (mode_res->encoders[k] == intel_output->mode_encoders[j]->encoder_id) intel_output->enc_mask |= (1 << k); } intel_output->enc_clone_mask &= intel_output->mode_encoders[j]->possible_clones; } } for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; output->possible_clones = find_clones(scrn, output); } } Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) { intel_screen_private *intel = intel_get_screen_private(scrn); struct drm_i915_getparam gp; struct intel_mode *mode; unsigned int i; int has_flipping; drmModeResPtr mode_res; mode = calloc(1, sizeof *mode); if (!mode) return FALSE; mode->fd = fd; list_init(&mode->crtcs); list_init(&mode->outputs); xf86CrtcConfigInit(scrn, &intel_xf86crtc_config_funcs); mode->cpp = cpp; mode_res = drmModeGetResources(mode->fd); if (!mode_res) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "failed to get resources: %s\n", strerror(errno)); free(mode); return FALSE; } xf86CrtcSetSizeRange(scrn, 320, 200, mode_res->max_width, mode_res->max_height); for (i = 0; i < mode_res->count_crtcs; i++) intel_crtc_init(scrn, mode, mode_res, i); for (i = 0; i < mode_res->count_connectors; i++) intel_output_init(scrn, mode, mode_res, i, 0); intel_compute_possible_clones(scrn, mode, mode_res); #ifdef INTEL_PIXMAP_SHARING xf86ProviderSetup(scrn, NULL, "Intel"); #endif xf86InitialConfiguration(scrn, TRUE); mode->event_context.version = DRM_EVENT_CONTEXT_VERSION; mode->event_context.vblank_handler = intel_drm_handler; mode->event_context.page_flip_handler = intel_drm_handler; /* XXX assumes only one intel screen */ list_init(&intel_drm_queue); intel_drm_seq = 0; has_flipping = 0; gp.param = I915_PARAM_HAS_PAGEFLIPPING; gp.value = &has_flipping; (void)drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, sizeof(gp)); if (has_flipping && intel->swapbuffers_wait) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Kernel page flipping support detected, enabling\n"); intel->use_pageflipping = TRUE; } intel->modes = mode; drmModeFreeResources(mode_res); return TRUE; } void intel_mode_init(struct intel_screen_private *intel) { struct intel_mode *mode = intel->modes; /* We need to re-register the mode->fd for the synchronisation * feedback on every server generation, so perform the * registration within ScreenInit and not PreInit. */ mode->flip_count = 0; AddGeneralSocket(mode->fd); RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, mode); } void intel_mode_remove_fb(intel_screen_private *intel) { struct intel_mode *mode = intel->modes; if (mode->fb_id) { drmModeRmFB(mode->fd, mode->fb_id); mode->fb_id = 0; } } void intel_mode_close(intel_screen_private *intel) { struct intel_mode *mode = intel->modes; if (mode == NULL) return; intel_drm_abort_scrn(intel->scrn); RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, drm_wakeup_handler, mode); RemoveGeneralSocket(mode->fd); } void intel_mode_fini(intel_screen_private *intel) { struct intel_mode *mode = intel->modes; if (mode == NULL) return; while(!list_is_empty(&mode->crtcs)) { xf86CrtcDestroy(list_first_entry(&mode->crtcs, struct intel_crtc, link)->crtc); } while(!list_is_empty(&mode->outputs)) { xf86OutputDestroy(list_first_entry(&mode->outputs, struct intel_output, link)->output); } if (mode->fb_id) drmModeRmFB(mode->fd, mode->fb_id); /* mode->rotate_fb_id should have been destroyed already */ free(mode); intel->modes = NULL; } /* for the mode overlay */ int intel_crtc_id(xf86CrtcPtr crtc) { return crtc_id(crtc->driver_private); } int intel_crtc_to_pipe(xf86CrtcPtr crtc) { struct intel_crtc *intel_crtc = crtc->driver_private; return intel_crtc->pipe; } Bool intel_crtc_on(xf86CrtcPtr crtc) { struct intel_crtc *intel_crtc = crtc->driver_private; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); drmModeCrtcPtr drm_crtc; Bool ret; int i; if (!crtc->enabled) return FALSE; /* Kernel manages CRTC status based on output config */ ret = FALSE; for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc == crtc && intel_output_dpms_status(output) == DPMSModeOn) { ret = TRUE; break; } } if (!ret) return FALSE; /* And finally check with the kernel that the fb is bound */ drm_crtc = drmModeGetCrtc(intel_crtc->mode->fd, crtc_id(intel_crtc)); if (drm_crtc == NULL) return FALSE; ret = (drm_crtc->mode_valid && (intel_crtc->mode->fb_id == drm_crtc->buffer_id || intel_crtc->mode->old_fb_id == drm_crtc->buffer_id)); free(drm_crtc); return ret; } static PixmapPtr intel_create_pixmap_for_bo(ScreenPtr pScreen, dri_bo *bo, int width, int height, int depth, int bpp, int pitch) { PixmapPtr pixmap; pixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, 0); if (pixmap == NullPixmap) return pixmap; if (!pScreen->ModifyPixmapHeader(pixmap, width, height, depth, bpp, pitch, NULL)) { pScreen->DestroyPixmap(pixmap); return NullPixmap; } intel_set_pixmap_bo(pixmap, bo); return pixmap; } static PixmapPtr intel_create_pixmap_for_fbcon(ScrnInfoPtr scrn, int fbcon_id) { ScreenPtr pScreen = xf86ScrnToScreen(scrn); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_mode *mode = intel->modes; int fd = mode->fd; drmModeFBPtr fbcon; struct drm_gem_flink flink; drm_intel_bo *bo; PixmapPtr pixmap = NullPixmap; fbcon = drmModeGetFB(fd, fbcon_id); if (fbcon == NULL) return NULL; if (fbcon->depth != scrn->depth || fbcon->width != scrn->virtualX || fbcon->height != scrn->virtualY) goto out_free_fb; flink.handle = fbcon->handle; if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n"); goto out_free_fb; } bo = drm_intel_bo_gem_create_from_name(intel->bufmgr, "fbcon", flink.name); if (bo == NULL) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate bo for fbcon handle\n"); goto out_free_fb; } pixmap = intel_create_pixmap_for_bo(pScreen, bo, fbcon->width, fbcon->height, fbcon->depth, fbcon->bpp, fbcon->pitch); if (pixmap == NullPixmap) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate pixmap fbcon contents\n"); drm_intel_bo_unreference(bo); out_free_fb: drmModeFreeFB(fbcon); return pixmap; } void intel_copy_fb(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); ScreenPtr pScreen = xf86ScrnToScreen(scrn); intel_screen_private *intel = intel_get_screen_private(scrn); PixmapPtr src, dst; unsigned int pitch = scrn->displayWidth * intel->cpp; struct intel_crtc *intel_crtc; int i, fbcon_id; if (intel->force_fallback) return; fbcon_id = 0; for (i = 0; i < xf86_config->num_crtc; i++) { intel_crtc = xf86_config->crtc[i]->driver_private; if (intel_crtc->mode_crtc->buffer_id) fbcon_id = intel_crtc->mode_crtc->buffer_id; } if (!fbcon_id) return; src = intel_create_pixmap_for_fbcon(scrn, fbcon_id); if (src == NULL) return; /* We dont have a screen Pixmap yet */ dst = intel_create_pixmap_for_bo(pScreen, intel->front_buffer, scrn->virtualX, scrn->virtualY, scrn->depth, scrn->bitsPerPixel, pitch); if (dst == NullPixmap) goto cleanup_src; if (!intel->uxa_driver->prepare_copy(src, dst, -1, -1, GXcopy, FB_ALLONES)) goto cleanup_dst; intel->uxa_driver->copy(dst, 0, 0, 0, 0, scrn->virtualX, scrn->virtualY); intel->uxa_driver->done_copy(dst); #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0) pScreen->canDoBGNoneRoot = TRUE; #endif cleanup_dst: (*pScreen->DestroyPixmap)(dst); cleanup_src: (*pScreen->DestroyPixmap)(src); } void intel_mode_hotplug(struct intel_screen_private *intel) { ScrnInfoPtr scrn = intel->scrn; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); drmModeResPtr mode_res; int i, j; Bool found; Bool changed = FALSE; mode_res = drmModeGetResources(intel->drmSubFD); if (!mode_res) goto out; for (i = 0; i < config->num_output; i++) { xf86OutputPtr output = config->output[i]; struct intel_output *intel_output; intel_output = output->driver_private; found = FALSE; for (j = 0; j < mode_res->count_connectors; j++) { if (mode_res->connectors[j] == intel_output->output_id) { found = TRUE; break; } } if (found) continue; drmModeFreeConnector(intel_output->mode_output); intel_output->mode_output = NULL; intel_output->output_id = -1; RROutputChanged(output->randr_output, TRUE); changed = TRUE; } /* find new output ids we don't have outputs for */ for (i = 0; i < mode_res->count_connectors; i++) { found = FALSE; for (j = 0; j < config->num_output; j++) { xf86OutputPtr output = config->output[j]; struct intel_output *intel_output; intel_output = output->driver_private; if (mode_res->connectors[i] == intel_output->output_id) { found = TRUE; break; } } if (found) continue; changed = TRUE; intel_output_init(scrn, intel->modes, mode_res, i, 1); } if (changed) RRTellChanged(xf86ScrnToScreen(scrn)); drmModeFreeResources(mode_res); out: RRGetInfo(xf86ScrnToScreen(scrn), TRUE); } void intel_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b) { dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1; dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2; if (dest->x1 >= dest->x2) { dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; return; } dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1; dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2; if (dest->y1 >= dest->y2) dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0; } void intel_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box) { if (crtc->enabled) { crtc_box->x1 = crtc->x; crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation); crtc_box->y1 = crtc->y; crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation); } else crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0; } static int intel_box_area(BoxPtr box) { return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1); } /* * Return the crtc covering 'box'. If two crtcs cover a portion of * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc * with greater coverage */ xf86CrtcPtr intel_covering_crtc(ScrnInfoPtr scrn, BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc, best_crtc; int coverage, best_coverage; int c; BoxRec crtc_box, cover_box; best_crtc = NULL; best_coverage = 0; crtc_box_ret->x1 = 0; crtc_box_ret->x2 = 0; crtc_box_ret->y1 = 0; crtc_box_ret->y2 = 0; for (c = 0; c < xf86_config->num_crtc; c++) { crtc = xf86_config->crtc[c]; /* If the CRTC is off, treat it as not covering */ if (!intel_crtc_on(crtc)) continue; intel_crtc_box(crtc, &crtc_box); intel_box_intersect(&cover_box, &crtc_box, box); coverage = intel_box_area(&cover_box); if (coverage && crtc == desired) { *crtc_box_ret = crtc_box; return crtc; } if (coverage > best_coverage) { *crtc_box_ret = crtc_box; best_crtc = crtc; best_coverage = coverage; } } return best_crtc; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_dri.c000066400000000000000000001241141267532330400237770ustar00rootroot00000000000000/************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. Copyright © 2002 by David Dawes 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 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 ATI, VA LINUX SYSTEMS AND/OR THEIR 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: Jeff Hartmann * David Dawes * Keith Whitwell */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "xf86drm.h" #include "windowstr.h" #include "shadow.h" #include "fb.h" #include "intel.h" #include "i830_reg.h" #include "i915_drm.h" #include "dri2.h" #if USE_UXA #include "intel_uxa.h" #endif typedef struct { int refcnt; PixmapPtr pixmap; } I830DRI2BufferPrivateRec, *I830DRI2BufferPrivatePtr; #if HAS_DEVPRIVATEKEYREC static DevPrivateKeyRec i830_client_key; #else static int i830_client_key; #endif static void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, DRI2FrameEventPtr flip_info); static void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, DRI2FrameEventPtr swap_info); static void i830_dri2_del_frame_event(DRI2FrameEventPtr info); static uint32_t pipe_select(int pipe) { if (pipe > 1) return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT; else if (pipe > 0) return DRM_VBLANK_SECONDARY; else return 0; } static void intel_dri2_vblank_handler(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t msc, uint64_t usec, void *data) { I830DRI2FrameEventHandler((uint32_t) msc, usec / 1000000, usec % 1000000, data); } static void intel_dri2_vblank_abort(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data) { i830_dri2_del_frame_event(data); } static uint32_t pixmap_flink(PixmapPtr pixmap) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); uint32_t name; if (priv == NULL || priv->bo == NULL) return 0; if (dri_bo_flink(priv->bo, &name) != 0) return 0; priv->pinned |= PIN_DRI2; return name; } static PixmapPtr get_front_buffer(DrawablePtr drawable) { PixmapPtr pixmap; pixmap = get_drawable_pixmap(drawable); if (!intel_get_pixmap_bo(pixmap)) return NULL; pixmap->refcnt++; return pixmap; } #if DRI2INFOREC_VERSION < 2 static DRI2BufferPtr I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments, int count) { ScreenPtr screen = drawable->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DRI2BufferPtr buffers; I830DRI2BufferPrivatePtr privates; PixmapPtr pixmap, pDepthPixmap; int i; buffers = calloc(count, sizeof *buffers); if (buffers == NULL) return NULL; privates = calloc(count, sizeof *privates); if (privates == NULL) { free(buffers); return NULL; } pDepthPixmap = NULL; for (i = 0; i < count; i++) { pixmap = NULL; if (attachments[i] == DRI2BufferFrontLeft) { pixmap = get_front_buffer(drawable); } else if (attachments[i] == DRI2BufferStencil && pDepthPixmap) { pixmap = pDepthPixmap; pixmap->refcnt++; } if (pixmap == NULL) { unsigned int hint = INTEL_CREATE_PIXMAP_DRI2; if (intel->tiling & INTEL_TILING_3D) { switch (attachments[i]) { case DRI2BufferDepth: if (SUPPORTS_YTILING(intel)) hint |= INTEL_CREATE_PIXMAP_TILING_Y; else hint |= INTEL_CREATE_PIXMAP_TILING_X; break; case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontRight: case DRI2BufferBackLeft: case DRI2BufferBackRight: hint |= INTEL_CREATE_PIXMAP_TILING_X; break; } } pixmap = screen->CreatePixmap(screen, drawable->width, drawable->height, drawable->depth, hint); if (pixmap == NULL || intel_get_pixmap_bo(pixmap) == NULL) { if (pixmap) screen->DestroyPixmap(pixmap); goto unwind; } } if (attachments[i] == DRI2BufferDepth) pDepthPixmap = pixmap; buffers[i].attachment = attachments[i]; buffers[i].pitch = pixmap->devKind; buffers[i].cpp = pixmap->drawable.bitsPerPixel / 8; buffers[i].driverPrivate = &privates[i]; buffers[i].flags = 0; /* not tiled */ privates[i].refcnt = 1; privates[i].pixmap = pixmap; if ((buffers[i].name = pixmap_flink(pixmap)) == 0) { /* failed to name buffer */ screen->DestroyPixmap(pixmap); goto unwind; } } return buffers; unwind: while (i--) screen->DestroyPixmap(privates[i].pixmap); free(privates); free(buffers); return NULL; } static void I830DRI2DestroyBuffers(DrawablePtr drawable, DRI2BufferPtr buffers, int count) { ScreenPtr screen = drawable->pScreen; I830DRI2BufferPrivatePtr private; int i; for (i = 0; i < count; i++) { private = buffers[i].driverPrivate; screen->DestroyPixmap(private->pixmap); } if (buffers) { free(buffers[0].driverPrivate); free(buffers); } } #else static DRI2Buffer2Ptr I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment, unsigned int format) { ScreenPtr screen = drawable->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DRI2Buffer2Ptr buffer; I830DRI2BufferPrivatePtr privates; PixmapPtr pixmap; buffer = calloc(1, sizeof *buffer); if (buffer == NULL) return NULL; privates = calloc(1, sizeof *privates); if (privates == NULL) { free(buffer); return NULL; } pixmap = NULL; if (attachment == DRI2BufferFrontLeft) pixmap = get_front_buffer(drawable); if (pixmap == NULL) { unsigned int hint = INTEL_CREATE_PIXMAP_DRI2; int pixmap_width = drawable->width; int pixmap_height = drawable->height; int pixmap_cpp = (format != 0) ? format : drawable->depth; if (intel->tiling & INTEL_TILING_3D) { switch (attachment) { case DRI2BufferDepth: case DRI2BufferDepthStencil: case DRI2BufferHiz: if (SUPPORTS_YTILING(intel)) { hint |= INTEL_CREATE_PIXMAP_TILING_Y; break; } case DRI2BufferAccum: case DRI2BufferBackLeft: case DRI2BufferBackRight: case DRI2BufferFakeFrontLeft: case DRI2BufferFakeFrontRight: case DRI2BufferFrontLeft: case DRI2BufferFrontRight: hint |= INTEL_CREATE_PIXMAP_TILING_X; break; case DRI2BufferStencil: /* * The stencil buffer is W tiled. However, we * request from the kernel a non-tiled buffer * because the GTT is incapable of W fencing. */ hint |= INTEL_CREATE_PIXMAP_TILING_NONE; break; default: free(privates); free(buffer); return NULL; } } /* * The stencil buffer has quirky pitch requirements. From Vol * 2a, 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface * Pitch": * The pitch must be set to 2x the value computed based on * width, as the stencil buffer is stored with two rows * interleaved. * To accomplish this, we resort to the nasty hack of doubling * the drm region's cpp and halving its height. * * If we neglect to double the pitch, then render corruption * occurs. */ if (attachment == DRI2BufferStencil) { pixmap_width = ALIGN(pixmap_width, 64); pixmap_height = ALIGN((pixmap_height + 1) / 2, 64); pixmap_cpp *= 2; } pixmap = screen->CreatePixmap(screen, pixmap_width, pixmap_height, pixmap_cpp, hint); if (pixmap == NULL || intel_get_pixmap_bo(pixmap) == NULL) { if (pixmap) screen->DestroyPixmap(pixmap); free(privates); free(buffer); return NULL; } } buffer->attachment = attachment; buffer->pitch = pixmap->devKind; buffer->cpp = pixmap->drawable.bitsPerPixel / 8; buffer->driverPrivate = privates; buffer->format = format; buffer->flags = 0; /* not tiled */ privates->refcnt = 1; privates->pixmap = pixmap; if ((buffer->name = pixmap_flink(pixmap)) == 0) { /* failed to name buffer */ screen->DestroyPixmap(pixmap); free(privates); free(buffer); return NULL; } return buffer; } static void I830DRI2DestroyBuffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer) { if (buffer && buffer->driverPrivate) { I830DRI2BufferPrivatePtr private = buffer->driverPrivate; if (--private->refcnt == 0) { ScreenPtr screen = private->pixmap->drawable.pScreen; screen->DestroyPixmap(private->pixmap); free(private); free(buffer); } } else free(buffer); } #endif static void I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion, DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer) { I830DRI2BufferPrivatePtr srcPrivate = sourceBuffer->driverPrivate; I830DRI2BufferPrivatePtr dstPrivate = destBuffer->driverPrivate; ScreenPtr screen = drawable->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft) ? drawable : &srcPrivate->pixmap->drawable; DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft) ? drawable : &dstPrivate->pixmap->drawable; RegionPtr pCopyClip; GCPtr gc; gc = GetScratchGC(dst->depth, screen); if (!gc) return; pCopyClip = REGION_CREATE(screen, NULL, 0); REGION_COPY(screen, pCopyClip, pRegion); (*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0); ValidateGC(dst, gc); /* Wait for the scanline to be outside the region to be copied */ if (scrn->vtSema && pixmap_is_scanout(get_drawable_pixmap(dst)) && intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) { BoxPtr box; BoxRec crtcbox; int y1, y2; int event, load_scan_lines_pipe; xf86CrtcPtr crtc; Bool full_height = FALSE; box = REGION_EXTENTS(unused, gc->pCompositeClip); crtc = intel_covering_crtc(scrn, box, NULL, &crtcbox); /* * Make sure the CRTC is valid and this is the real front * buffer */ if (crtc != NULL && !crtc->rotatedData) { int pipe = intel_crtc_to_pipe(crtc); /* * Make sure we don't wait for a scanline that will * never occur */ y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0; y2 = (box->y2 <= crtcbox.y2) ? box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1; if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1)) full_height = TRUE; /* * Pre-965 doesn't have SVBLANK, so we need a bit * of extra time for the blitter to start up and * do its job for a full height blit */ if (full_height && INTEL_INFO(intel)->gen < 040) y2 -= 2; if (pipe == 0) { event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; if (full_height && INTEL_INFO(intel)->gen >= 040) event = MI_WAIT_FOR_PIPEA_SVBLANK; } else { event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; if (full_height && INTEL_INFO(intel)->gen >= 040) event = MI_WAIT_FOR_PIPEB_SVBLANK; } if (crtc->mode.Flags & V_INTERLACE) { /* DSL count field lines */ y1 /= 2; y2 /= 2; } BEGIN_BATCH(5); /* * The documentation says that the LOAD_SCAN_LINES * command always comes in pairs. Don't ask me why. */ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); OUT_BATCH((y1 << 16) | (y2-1)); OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); OUT_BATCH((y1 << 16) | (y2-1)); OUT_BATCH(MI_WAIT_FOR_EVENT | event); ADVANCE_BATCH(); } } /* It's important that this copy gets submitted before the * direct rendering client submits rendering for the next * frame, but we don't actually need to submit right now. The * client will wait for the DRI2CopyRegion reply or the swap * buffer event before rendering, and we'll hit the flush * callback chain before those messages are sent. We submit * our batch buffers from the flush callback chain so we know * that will happen before the client tries to render * again. */ gc->ops->CopyArea(src, dst, gc, 0, 0, drawable->width, drawable->height, 0, 0); FreeScratchGC(gc); /* And make sure the WAIT_FOR_EVENT is queued before any * modesetting/dpms operations on the pipe. */ intel_batch_submit(scrn); } static void I830DRI2FallbackBlitSwap(DrawablePtr drawable, DRI2BufferPtr dst, DRI2BufferPtr src) { BoxRec box; RegionRec region; box.x1 = 0; box.y1 = 0; box.x2 = drawable->width; box.y2 = drawable->height; REGION_INIT(pScreen, ®ion, &box, 0); I830DRI2CopyRegion(drawable, ®ion, dst, src); } #if DRI2INFOREC_VERSION >= 4 static void I830DRI2ReferenceBuffer(DRI2Buffer2Ptr buffer) { if (buffer) { I830DRI2BufferPrivatePtr private = buffer->driverPrivate; private->refcnt++; } } static xf86CrtcPtr I830DRI2DrawableCrtc(DrawablePtr pDraw) { ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); BoxRec box, crtcbox; xf86CrtcPtr crtc = NULL; box.x1 = pDraw->x; box.y1 = pDraw->y; box.x2 = box.x1 + pDraw->width; box.y2 = box.y1 + pDraw->height; if (pDraw->type != DRAWABLE_PIXMAP) crtc = intel_covering_crtc(pScrn, &box, NULL, &crtcbox); /* Make sure the CRTC is valid and this is the real front buffer */ if (crtc != NULL && !crtc->rotatedData) return crtc; return NULL; } static RESTYPE frame_event_client_type, frame_event_drawable_type; struct i830_dri2_resource { XID id; RESTYPE type; struct list list; }; static struct i830_dri2_resource * get_resource(XID id, RESTYPE type) { struct i830_dri2_resource *resource; void *ptr; ptr = NULL; dixLookupResourceByType(&ptr, id, type, NULL, DixWriteAccess); if (ptr) return ptr; resource = malloc(sizeof(*resource)); if (resource == NULL) return NULL; if (!AddResource(id, type, resource)) { free(resource); return NULL; } resource->id = id; resource->type = type; list_init(&resource->list); return resource; } static int i830_dri2_frame_event_client_gone(void *data, XID id) { struct i830_dri2_resource *resource = data; while (!list_is_empty(&resource->list)) { DRI2FrameEventPtr info = list_first_entry(&resource->list, DRI2FrameEventRec, client_resource); list_del(&info->client_resource); info->client = NULL; } free(resource); return Success; } static int i830_dri2_frame_event_drawable_gone(void *data, XID id) { struct i830_dri2_resource *resource = data; while (!list_is_empty(&resource->list)) { DRI2FrameEventPtr info = list_first_entry(&resource->list, DRI2FrameEventRec, drawable_resource); list_del(&info->drawable_resource); info->drawable_id = None; } free(resource); return Success; } static Bool i830_dri2_register_frame_event_resource_types(void) { frame_event_client_type = CreateNewResourceType(i830_dri2_frame_event_client_gone, "Frame Event Client"); if (!frame_event_client_type) return FALSE; frame_event_drawable_type = CreateNewResourceType(i830_dri2_frame_event_drawable_gone, "Frame Event Drawable"); if (!frame_event_drawable_type) return FALSE; return TRUE; } static XID get_client_id(ClientPtr client) { #if HAS_DIXREGISTERPRIVATEKEY XID *ptr = dixGetPrivateAddr(&client->devPrivates, &i830_client_key); #else XID *ptr = dixLookupPrivate(&client->devPrivates, &i830_client_key); #endif if (*ptr == 0) *ptr = FakeClientID(client->index); return *ptr; } /* * Hook this frame event into the server resource * database so we can clean it up if the drawable or * client exits while the swap is pending */ static Bool i830_dri2_add_frame_event(DRI2FrameEventPtr info) { struct i830_dri2_resource *resource; resource = get_resource(get_client_id(info->client), frame_event_client_type); if (resource == NULL) return FALSE; list_add(&info->client_resource, &resource->list); resource = get_resource(info->drawable_id, frame_event_drawable_type); if (resource == NULL) { list_del(&info->client_resource); return FALSE; } list_add(&info->drawable_resource, &resource->list); return TRUE; } static void i830_dri2_del_frame_event(DRI2FrameEventPtr info) { list_del(&info->client_resource); list_del(&info->drawable_resource); if (info->front) I830DRI2DestroyBuffer(NULL, info->front); if (info->back) I830DRI2DestroyBuffer(NULL, info->back); if (info->old_buffer) { /* Check that the old buffer still matches the front buffer * in case a mode change occurred before we woke up. */ if (info->intel->back_buffer == NULL && info->old_width == info->intel->scrn->virtualX && info->old_height == info->intel->scrn->virtualY && info->old_pitch == info->intel->front_pitch && info->old_tiling == info->intel->front_tiling) info->intel->back_buffer = info->old_buffer; else dri_bo_unreference(info->old_buffer); } free(info); } static struct intel_uxa_pixmap * intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr front, PixmapPtr back) { struct intel_uxa_pixmap *new_front = NULL, *new_back; RegionRec region; /* Post damage on the front buffer so that listeners, such * as DisplayLink know take a copy and shove it over the USB. * also for sw cursors. */ region.extents.x1 = region.extents.y1 = 0; region.extents.x2 = front->drawable.width; region.extents.y2 = front->drawable.height; region.data = NULL; DamageRegionAppend(&front->drawable, ®ion); new_front = intel_uxa_get_pixmap_private(back); new_back = intel_uxa_get_pixmap_private(front); intel_uxa_set_pixmap_private(front, new_front); intel_uxa_set_pixmap_private(back, new_back); new_front->busy = 1; new_back->busy = -1; DamageRegionProcessPending(&front->drawable); return new_front; } static void I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front, DRI2BufferPtr back) { I830DRI2BufferPrivatePtr front_priv, back_priv; struct intel_uxa_pixmap *new_front; front_priv = front->driverPrivate; back_priv = back->driverPrivate; /* Swap BO names so DRI works */ front->name = back->name; back->name = pixmap_flink(front_priv->pixmap); /* Swap pixmap bos */ new_front = intel_exchange_pixmap_buffers(intel, front_priv->pixmap, back_priv->pixmap); dri_bo_unreference (intel->front_buffer); intel->front_buffer = new_front->bo; dri_bo_reference (intel->front_buffer); } static drm_intel_bo *get_pixmap_bo(I830DRI2BufferPrivatePtr priv) { drm_intel_bo *bo = intel_get_pixmap_bo(priv->pixmap); assert(bo != NULL); /* guaranteed by construction of the DRI2 buffer */ return bo; } static void I830DRI2FlipComplete(uint64_t frame, uint64_t usec, void *pageflip_data) { DRI2FrameEventPtr info = pageflip_data; I830DRI2FlipEventHandler((uint32_t) frame, usec / 1000000, usec % 1000000, info); } static void I830DRI2FlipAbort(void *pageflip_data) { DRI2FrameEventPtr info = pageflip_data; i830_dri2_del_frame_event(info); } static Bool allocate_back_buffer(struct intel_screen_private *intel) { drm_intel_bo *bo; int pitch; uint32_t tiling; if (intel->back_buffer) return TRUE; bo = intel_allocate_framebuffer(intel->scrn, intel->scrn->virtualX, intel->scrn->virtualY, intel->cpp, &pitch, &tiling); if (bo == NULL) return FALSE; if (pitch != intel->front_pitch || tiling != intel->front_tiling) { drm_intel_bo_unreference(bo); return FALSE; } intel->back_buffer = bo; return TRUE; } static Bool can_exchange(DrawablePtr drawable, DRI2BufferPtr front, DRI2BufferPtr back) { ScrnInfoPtr pScrn = xf86ScreenToScrn(drawable->pScreen); struct intel_screen_private *intel = intel_get_screen_private(pScrn); I830DRI2BufferPrivatePtr front_priv = front->driverPrivate; I830DRI2BufferPrivatePtr back_priv = back->driverPrivate; PixmapPtr front_pixmap = front_priv->pixmap; PixmapPtr back_pixmap = back_priv->pixmap; struct intel_uxa_pixmap *front_intel = intel_uxa_get_pixmap_private(front_pixmap); struct intel_uxa_pixmap *back_intel = intel_uxa_get_pixmap_private(back_pixmap); if (!pScrn->vtSema) return FALSE; if (I830DRI2DrawableCrtc(drawable) == NULL) return FALSE; if (!DRI2CanFlip(drawable)) return FALSE; if (intel->shadow_present) return FALSE; if (!intel->use_pageflipping) return FALSE; if (front_pixmap->drawable.width != back_pixmap->drawable.width) return FALSE; if (front_pixmap->drawable.height != back_pixmap->drawable.height) return FALSE; /* XXX should we be checking depth instead of bpp? */ #if 0 if (front_pixmap->drawable.depth != back_pixmap->drawable.depth) return FALSE; #else if (front_pixmap->drawable.bitsPerPixel != back_pixmap->drawable.bitsPerPixel) return FALSE; #endif /* prevent an implicit tiling mode change */ if (front_intel->tiling != back_intel->tiling) return FALSE; if (front_intel->pinned & ~(PIN_SCANOUT | PIN_DRI2)) return FALSE; return TRUE; } static Bool queue_flip(struct intel_screen_private *intel, DrawablePtr draw, DRI2FrameEventPtr info) { xf86CrtcPtr crtc = I830DRI2DrawableCrtc(draw); I830DRI2BufferPrivatePtr priv = info->back->driverPrivate; drm_intel_bo *old_back = get_pixmap_bo(priv); if (crtc == NULL) return FALSE; if (!can_exchange(draw, info->front, info->back)) return FALSE; if (!intel_do_pageflip(intel, old_back, intel_crtc_to_pipe(crtc), FALSE, info, I830DRI2FlipComplete, I830DRI2FlipAbort)) return FALSE; #if DRI2INFOREC_VERSION >= 6 if (intel->use_triple_buffer && allocate_back_buffer(intel)) { info->old_width = intel->scrn->virtualX; info->old_height = intel->scrn->virtualY; info->old_pitch = intel->front_pitch; info->old_tiling = intel->front_tiling; info->old_buffer = intel->front_buffer; dri_bo_reference(info->old_buffer); priv = info->front->driverPrivate; intel_set_pixmap_bo(priv->pixmap, intel->back_buffer); dri_bo_unreference(intel->back_buffer); intel->back_buffer = NULL; DRI2SwapLimit(draw, 2); } else DRI2SwapLimit(draw, 1); #endif /* Then flip DRI2 pointers and update the screen pixmap */ I830DRI2ExchangeBuffers(intel, info->front, info->back); return TRUE; } static Bool queue_swap(struct intel_screen_private *intel, DrawablePtr draw, DRI2FrameEventPtr info) { xf86CrtcPtr crtc = I830DRI2DrawableCrtc(draw); drmVBlank vbl; if (crtc == NULL) return FALSE; vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT | pipe_select(intel_crtc_to_pipe(crtc)); vbl.request.sequence = 1; vbl.request.signal = intel_drm_queue_alloc(intel->scrn, crtc, info, intel_dri2_vblank_handler, intel_dri2_vblank_abort); if (vbl.request.signal == 0) return FALSE; info->type = DRI2_SWAP; if (drmWaitVBlank(intel->drmSubFD, &vbl)) { intel_drm_abort_seq(intel->scrn, vbl.request.signal); return FALSE; } return TRUE; } static void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, DRI2FrameEventPtr swap_info) { intel_screen_private *intel = swap_info->intel; DrawablePtr drawable; int status; if (!swap_info->drawable_id) status = BadDrawable; else status = dixLookupDrawable(&drawable, swap_info->drawable_id, serverClient, M_ANY, DixWriteAccess); if (status != Success) { i830_dri2_del_frame_event(swap_info); return; } switch (swap_info->type) { case DRI2_FLIP: /* If we can still flip... */ if (!queue_flip(intel, drawable, swap_info) && !queue_swap(intel, drawable, swap_info)) { case DRI2_SWAP: I830DRI2FallbackBlitSwap(drawable, swap_info->front, swap_info->back); DRI2SwapComplete(swap_info->client, drawable, frame, tv_sec, tv_usec, DRI2_BLIT_COMPLETE, swap_info->client ? swap_info->event_complete : NULL, swap_info->event_data); break; } return; case DRI2_WAITMSC: if (swap_info->client) DRI2WaitMSCComplete(swap_info->client, drawable, frame, tv_sec, tv_usec); break; default: xf86DrvMsg(intel->scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); /* Unknown type */ break; } i830_dri2_del_frame_event(swap_info); } static void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, DRI2FrameEventPtr flip_info) { struct intel_screen_private *intel = flip_info->intel; DrawablePtr drawable; drawable = NULL; if (flip_info->drawable_id) dixLookupDrawable(&drawable, flip_info->drawable_id, serverClient, M_ANY, DixWriteAccess); /* We assume our flips arrive in order, so we don't check the frame */ switch (flip_info->type) { case DRI2_FLIP: case DRI2_SWAP: if (!drawable) break; /* Check for too small vblank count of pageflip completion, taking wraparound * into account. This usually means some defective kms pageflip completion, * causing wrong (msc, ust) return values and possible visual corruption. */ if ((frame < flip_info->frame) && (flip_info->frame - frame < 5)) { static int limit = 5; /* XXX we are currently hitting this path with older * kernels, so make it quieter. */ if (limit) { xf86DrvMsg(intel->scrn->scrnIndex, X_WARNING, "%s: Pageflip completion has impossible msc %d < target_msc %d\n", __func__, frame, flip_info->frame); limit--; } /* All-0 values signal timestamping failure. */ frame = tv_sec = tv_usec = 0; } DRI2SwapComplete(flip_info->client, drawable, frame, tv_sec, tv_usec, DRI2_FLIP_COMPLETE, flip_info->client ? flip_info->event_complete : NULL, flip_info->event_data); break; default: xf86DrvMsg(intel->scrn->scrnIndex, X_WARNING, "%s: unknown vblank event received\n", __func__); /* Unknown type */ break; } i830_dri2_del_frame_event(flip_info); } /* * ScheduleSwap is responsible for requesting a DRM vblank event for the * appropriate frame. * * In the case of a blit (e.g. for a windowed swap) or buffer exchange, * the vblank requested can simply be the last queued swap frame + the swap * interval for the drawable. * * In the case of a page flip, we request an event for the last queued swap * frame + swap interval - 1, since we'll need to queue the flip for the frame * immediately following the received event. * * The client will be blocked if it tries to perform further GL commands * after queueing a swap, though in the Intel case after queueing a flip, the * client is free to queue more commands; they'll block in the kernel if * they access buffers busy with the flip. * * When the swap is complete, the driver should call into the server so it * can send any swap complete events that have been requested. */ static int I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back, CARD64 *target_msc, CARD64 divisor, CARD64 remainder, DRI2SwapEventPtr func, void *data) { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); drmVBlank vbl; int ret; xf86CrtcPtr crtc = I830DRI2DrawableCrtc(draw); int pipe = crtc ? intel_crtc_to_pipe(crtc) : -1; int flip = 0; DRI2FrameEventPtr swap_info = NULL; uint64_t current_msc, current_ust; uint64_t request_msc; uint32_t seq; /* Drawable not displayed... just complete the swap */ if (pipe == -1) goto blit_fallback; swap_info = calloc(1, sizeof(DRI2FrameEventRec)); if (!swap_info) goto blit_fallback; swap_info->intel = intel; swap_info->drawable_id = draw->id; swap_info->client = client; swap_info->event_complete = func; swap_info->event_data = data; swap_info->front = front; swap_info->back = back; swap_info->type = DRI2_SWAP; if (!i830_dri2_add_frame_event(swap_info)) { free(swap_info); swap_info = NULL; goto blit_fallback; } I830DRI2ReferenceBuffer(front); I830DRI2ReferenceBuffer(back); ret = intel_get_crtc_msc_ust(scrn, crtc, ¤t_msc, ¤t_ust); if (ret) goto blit_fallback; /* * If we can, schedule the flip directly from here rather * than waiting for an event from the kernel for the current * (or a past) MSC. */ if (divisor == 0 && current_msc >= *target_msc && queue_flip(intel, draw, swap_info)) return TRUE; if (can_exchange(draw, front, back)) { swap_info->type = DRI2_FLIP; /* Flips need to be submitted one frame before */ if (*target_msc > 0) --*target_msc; flip = 1; } #if DRI2INFOREC_VERSION >= 6 DRI2SwapLimit(draw, 1); #endif /* * If divisor is zero, or current_msc is smaller than target_msc * we just need to make sure target_msc passes before initiating * the swap. */ if (divisor == 0 || current_msc < *target_msc) { vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe); /* If non-pageflipping, but blitting/exchanging, we need to use * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later * on. */ if (flip == 0) vbl.request.type |= DRM_VBLANK_NEXTONMISS; /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back * to the caller. This makes swap_interval logic more robust. */ if (current_msc > *target_msc) *target_msc = current_msc; seq = intel_drm_queue_alloc(scrn, crtc, swap_info, intel_dri2_vblank_handler, intel_dri2_vblank_abort); if (!seq) goto blit_fallback; vbl.request.sequence = intel_crtc_msc_to_sequence(scrn, crtc, *target_msc); vbl.request.signal = seq; ret = drmWaitVBlank(intel->drmSubFD, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "divisor 0 get vblank counter failed: %s\n", strerror(errno)); intel_drm_abort_seq(intel->scrn, seq); swap_info = NULL; goto blit_fallback; } *target_msc = intel_sequence_to_crtc_msc(crtc, vbl.reply.sequence + flip); swap_info->frame = *target_msc; return TRUE; } /* * If we get here, target_msc has already passed or we don't have one, * and we need to queue an event that will satisfy the divisor/remainder * equation. */ vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe); if (flip == 0) vbl.request.type |= DRM_VBLANK_NEXTONMISS; request_msc = current_msc - (current_msc % divisor) + remainder; /* * If the calculated deadline vbl.request.sequence is smaller than * or equal to current_msc, it means we've passed the last point * when effective onset frame seq could satisfy * seq % divisor == remainder, so we need to wait for the next time * this will happen. * This comparison takes the 1 frame swap delay in pageflipping mode * into account, as well as a potential DRM_VBLANK_NEXTONMISS delay * if we are blitting/exchanging instead of flipping. */ if (request_msc <= current_msc) request_msc += divisor; seq = intel_drm_queue_alloc(scrn, crtc, swap_info, intel_dri2_vblank_handler, intel_dri2_vblank_abort); if (!seq) goto blit_fallback; /* Account for 1 frame extra pageflip delay if flip > 0 */ vbl.request.sequence = intel_crtc_msc_to_sequence(scrn, crtc, request_msc) - flip; vbl.request.signal = seq; ret = drmWaitVBlank(intel->drmSubFD, &vbl); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "final get vblank counter failed: %s\n", strerror(errno)); goto blit_fallback; } /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ *target_msc = intel_sequence_to_crtc_msc(crtc, vbl.reply.sequence + flip); swap_info->frame = *target_msc; return TRUE; blit_fallback: I830DRI2FallbackBlitSwap(draw, front, back); DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data); if (swap_info) i830_dri2_del_frame_event(swap_info); *target_msc = 0; /* offscreen, so zero out target vblank count */ return TRUE; } static uint64_t gettime_us(void) { struct timespec tv; if (clock_gettime(CLOCK_MONOTONIC, &tv)) return 0; return (uint64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000; } /* * Get current frame count and frame count timestamp, based on drawable's * crtc. */ static int I830DRI2GetMSC(DrawablePtr draw, CARD64 *ust, CARD64 *msc) { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); int ret; xf86CrtcPtr crtc = I830DRI2DrawableCrtc(draw); /* Drawable not displayed, make up a *monotonic* value */ if (crtc == NULL) { fail: *ust = gettime_us(); *msc = 0; return TRUE; } ret = intel_get_crtc_msc_ust(scrn, crtc, msc, ust); if (ret) { static int limit = 5; if (limit) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s:%d get vblank counter failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); limit--; } goto fail; } return TRUE; } /* * Request a DRM event when the requested conditions will be satisfied. * * We need to handle the event and ask the server to wake up the client when * we receive it. */ static int I830DRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc, CARD64 divisor, CARD64 remainder) { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DRI2FrameEventPtr wait_info; drmVBlank vbl; int ret; xf86CrtcPtr crtc = I830DRI2DrawableCrtc(draw); int pipe = crtc ? intel_crtc_to_pipe(crtc) : -1; CARD64 current_msc, current_ust, request_msc; uint32_t seq; /* Drawable not visible, return immediately */ if (pipe == -1) goto out_complete; wait_info = calloc(1, sizeof(DRI2FrameEventRec)); if (!wait_info) goto out_complete; wait_info->intel = intel; wait_info->drawable_id = draw->id; wait_info->client = client; wait_info->type = DRI2_WAITMSC; if (!i830_dri2_add_frame_event(wait_info)) { free(wait_info); goto out_complete; } /* Get current count */ ret = intel_get_crtc_msc_ust(scrn, crtc, ¤t_msc, ¤t_ust); if (ret) goto out_free; /* * If divisor is zero, or current_msc is smaller than target_msc, * we just need to make sure target_msc passes before waking up the * client. */ if (divisor == 0 || current_msc < target_msc) { /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back * to the caller. This keeps the client from continually * sending us MSC targets from the past by forcibly updating * their count on this call. */ seq = intel_drm_queue_alloc(scrn, crtc, wait_info, intel_dri2_vblank_handler, intel_dri2_vblank_abort); if (!seq) goto out_free; if (current_msc >= target_msc) target_msc = current_msc; vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe); vbl.request.sequence = intel_crtc_msc_to_sequence(scrn, crtc, target_msc); vbl.request.signal = seq; ret = drmWaitVBlank(intel->drmSubFD, &vbl); if (ret) { static int limit = 5; if (limit) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s:%d get vblank counter failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); limit--; } intel_drm_abort_seq(intel->scrn, seq); goto out_complete; } wait_info->frame = intel_sequence_to_crtc_msc(crtc, vbl.reply.sequence); DRI2BlockClient(client, draw); return TRUE; } /* * If we get here, target_msc has already passed or we don't have one, * so we queue an event that will satisfy the divisor/remainder equation. */ vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe); request_msc = current_msc - (current_msc % divisor) + remainder; /* * If calculated remainder is larger than requested remainder, * it means we've passed the last point where * seq % divisor == remainder, so we need to wait for the next time * that will happen. */ if ((current_msc % divisor) >= remainder) request_msc += divisor; seq = intel_drm_queue_alloc(scrn, crtc, wait_info, intel_dri2_vblank_handler, intel_dri2_vblank_abort); if (!seq) goto out_free; vbl.request.sequence = intel_crtc_msc_to_sequence(scrn, crtc, request_msc); vbl.request.signal = seq; ret = drmWaitVBlank(intel->drmSubFD, &vbl); if (ret) { static int limit = 5; if (limit) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s:%d get vblank counter failed: %s\n", __FUNCTION__, __LINE__, strerror(errno)); limit--; } intel_drm_abort_seq(intel->scrn, seq); goto out_complete; } wait_info->frame = intel_sequence_to_crtc_msc(crtc, vbl.reply.sequence); DRI2BlockClient(client, draw); return TRUE; out_free: i830_dri2_del_frame_event(wait_info); out_complete: DRI2WaitMSCComplete(client, draw, target_msc, 0, 0); return TRUE; } static int dri2_server_generation; #endif static int has_i830_dri(void) { return access(DRI_DRIVER_PATH "/i830_dri.so", R_OK) == 0; } static int namecmp(const char *s1, const char *s2) { char c1, c2; if (!s1 || *s1 == 0) { if (!s2 || *s2 == 0) return 0; else return 1; } while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; while (c1 == c2) { if (c1 == '\0') return 0; s1++; while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') s1++; s2++; while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') s2++; c1 = isupper(*s1) ? tolower(*s1) : *s1; c2 = isupper(*s2) ? tolower(*s2) : *s2; } return c1 - c2; } static Bool is_level(const char **str) { const char *s = *str; char *end; unsigned val; if (s == NULL || *s == '\0') return TRUE; if (namecmp(s, "on") == 0) return TRUE; if (namecmp(s, "true") == 0) return TRUE; if (namecmp(s, "yes") == 0) return TRUE; if (namecmp(s, "0") == 0) return TRUE; if (namecmp(s, "off") == 0) return TRUE; if (namecmp(s, "false") == 0) return TRUE; if (namecmp(s, "no") == 0) return TRUE; val = strtoul(s, &end, 0); if (val && *end == '\0') return TRUE; if (val && *end == ':') *str = end + 1; return FALSE; } static const char *options_get_dri(intel_screen_private *intel) { #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) return xf86GetOptValString(intel->Options, OPTION_DRI); #else return NULL; #endif } static const char *dri_driver_name(intel_screen_private *intel) { const char *s = options_get_dri(intel); if (is_level(&s)) { if (INTEL_INFO(intel)->gen < 030) return has_i830_dri() ? "i830" : "i915"; else if (INTEL_INFO(intel)->gen < 040) return "i915"; else return "i965"; } return s; } Bool I830DRI2ScreenInit(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DRI2InfoRec info; int dri2scr_major = 1; int dri2scr_minor = 0; #if DRI2INFOREC_VERSION >= 4 const char *driverNames[2]; #endif if (intel->force_fallback) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "cannot enable DRI2 whilst forcing software fallbacks\n"); return FALSE; } if (xf86LoaderCheckSymbol("DRI2Version")) DRI2Version(&dri2scr_major, &dri2scr_minor); if (dri2scr_minor < 1) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "DRI2 requires DRI2 module version 1.1.0 or later\n"); return FALSE; } #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&i830_client_key, PRIVATE_CLIENT, sizeof(XID))) return FALSE; #else if (!dixRequestPrivate(&i830_client_key, sizeof(XID))) return FALSE; #endif #if DRI2INFOREC_VERSION >= 4 if (serverGeneration != dri2_server_generation) { dri2_server_generation = serverGeneration; if (!i830_dri2_register_frame_event_resource_types()) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Cannot register DRI2 frame event resources\n"); return FALSE; } } #endif intel->deviceName = drmGetDeviceNameFromFd(intel->drmSubFD); memset(&info, '\0', sizeof(info)); info.fd = intel->drmSubFD; info.driverName = dri_driver_name(intel); info.deviceName = intel->deviceName; #if DRI2INFOREC_VERSION == 1 info.version = 1; info.CreateBuffers = I830DRI2CreateBuffers; info.DestroyBuffers = I830DRI2DestroyBuffers; #elif DRI2INFOREC_VERSION == 2 /* The ABI between 2 and 3 was broken so we could get rid of * the multi-buffer alloc functions. Make sure we indicate the * right version so DRI2 can reject us if it's version 3 or above. */ info.version = 2; info.CreateBuffer = I830DRI2CreateBuffer; info.DestroyBuffer = I830DRI2DestroyBuffer; #else info.version = 3; info.CreateBuffer = I830DRI2CreateBuffer; info.DestroyBuffer = I830DRI2DestroyBuffer; #endif info.CopyRegion = I830DRI2CopyRegion; #if DRI2INFOREC_VERSION >= 4 info.version = 4; info.ScheduleSwap = I830DRI2ScheduleSwap; info.GetMSC = I830DRI2GetMSC; info.ScheduleWaitMSC = I830DRI2ScheduleWaitMSC; info.numDrivers = 2; info.driverNames = driverNames; driverNames[0] = info.driverName; driverNames[1] = "va_gl"; #endif return DRI2ScreenInit(screen, &info); } void I830DRI2CloseScreen(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); DRI2CloseScreen(screen); drmFree(intel->deviceName); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_dri3.c000066400000000000000000000070211267532330400240570ustar00rootroot00000000000000/* * Copyright © 2013-2014 Intel Corporation * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include "xf86.h" #include "fb.h" #include "intel.h" #if USE_UXA #include "intel_uxa.h" #endif #include "dri3.h" static int intel_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); int fd; fd = intel_get_client_fd(intel->dev); if (fd < 0) return -fd; *out = fd; return Success; } static PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; PixmapPtr pixmap; dri_bo *bo; if (depth < 8) return NULL; switch (bpp) { case 8: case 16: case 32: break; default: return NULL; } pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); if (!pixmap) return NULL; if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) goto free_pixmap; bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, fd, (uint32_t)height * stride); if (bo == NULL) goto free_pixmap; intel_uxa_set_pixmap_bo(pixmap, bo); dri_bo_unreference(bo); priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL) goto free_pixmap; priv->pinned |= PIN_DRI3; return pixmap; free_pixmap: fbDestroyPixmap(pixmap); return NULL; } static int intel_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) { struct intel_uxa_pixmap *priv; int fd; priv = intel_uxa_get_pixmap_private(pixmap); if (!priv) return -1; if (intel_pixmap_pitch(pixmap) > UINT16_MAX) return -1; if (drm_intel_bo_gem_export_to_prime(priv->bo, &fd) < 0) return -1; priv->pinned |= PIN_DRI3; *stride = intel_pixmap_pitch(pixmap); *size = priv->bo->size; return fd; } static dri3_screen_info_rec intel_dri3_screen_info = { .version = DRI3_SCREEN_INFO_VERSION, .open = intel_dri3_open, .pixmap_from_fd = intel_dri3_pixmap_from_fd, .fd_from_pixmap = intel_dri3_fd_from_pixmap }; Bool intel_dri3_screen_init(ScreenPtr screen) { return dri3_screen_init(screen, &intel_dri3_screen_info); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_driver.c000066400000000000000000000762741267532330400245310ustar00rootroot00000000000000/************************************************************************** Copyright 2001 VA Linux Systems Inc., Fremont, California. Copyright © 2002 by David Dawes 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 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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: Jeff Hartmann * Abraham van der Merwe * David Dawes * Alan Hourihane */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86cmap.h" #include "xf86drm.h" #include "compiler.h" #include "mipointer.h" #include "micmap.h" #include #include "fb.h" #include "miscstruct.h" #include "dixstruct.h" #include "xf86xv.h" #include "shadow.h" #include "intel.h" #include "intel_video.h" #include "uxa_module.h" #ifdef INTEL_XVMC #define _INTEL_XVMC_SERVER_ #include "intel_xvmc.h" #endif #if USE_UXA #include "intel_uxa.h" #endif #include "intel_options.h" #include "i915_drm.h" static void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL); static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL); static Bool I830EnterVT(VT_FUNC_ARGS_DECL); /* temporary */ extern void xf86SetCursor(ScreenPtr screen, CursorPtr pCurs, int x, int y); /* Export I830 options to i830 driver where necessary */ static void I830LoadPalette(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int i, j, index; int p; uint16_t lut_r[256], lut_g[256], lut_b[256]; for (p = 0; p < xf86_config->num_crtc; p++) { xf86CrtcPtr crtc = xf86_config->crtc[p]; switch (scrn->depth) { case 15: for (i = 0; i < numColors; i++) { index = indices[i]; for (j = 0; j < 8; j++) { lut_r[index * 8 + j] = colors[index].red << 8; lut_g[index * 8 + j] = colors[index].green << 8; lut_b[index * 8 + j] = colors[index].blue << 8; } } break; case 16: for (i = 0; i < numColors; i++) { index = indices[i]; if (index <= 31) { for (j = 0; j < 8; j++) { lut_r[index * 8 + j] = colors[index].red << 8; lut_b[index * 8 + j] = colors[index].blue << 8; } } for (j = 0; j < 4; j++) { lut_g[index * 4 + j] = colors[index].green << 8; } } break; default: for (i = 0; i < numColors; i++) { index = indices[i]; lut_r[index] = colors[index].red << 8; lut_g[index] = colors[index].green << 8; lut_b[index] = colors[index].blue << 8; } break; } /* Make the change through RandR */ #ifdef RANDR_12_INTERFACE RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); #else crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); #endif } } /** * Adjust the screen pixmap for the current location of the front buffer. * This is done at EnterVT when buffers are bound as long as the resources * have already been created, but the first EnterVT happens before * CreateScreenResources. */ static Bool i830CreateScreenResources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); screen->CreateScreenResources = intel->CreateScreenResources; if (!(*screen->CreateScreenResources) (screen)) return FALSE; if (!intel_uxa_create_screen_resources(screen)) return FALSE; intel_copy_fb(scrn); return TRUE; } void intel_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo) { intel_uxa_set_pixmap_bo(pixmap, bo); } dri_bo * intel_get_pixmap_bo(PixmapPtr pixmap) { return intel_uxa_get_pixmap_bo(pixmap); } void intel_flush(intel_screen_private *intel) { intel_batch_submit(intel->scrn); } static void PreInitCleanup(ScrnInfoPtr scrn) { if (!scrn || !scrn->driverPrivate) return; free(scrn->driverPrivate); scrn->driverPrivate = NULL; } static void intel_check_chipset_option(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); intel_detect_chipset(scrn, intel->dev); } static Bool I830GetEarlyOptions(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); /* Process the options */ intel->Options = intel_options_get(scrn); if (!intel->Options) return FALSE; #if USE_UXA intel->fallback_debug = xf86ReturnOptValBool(intel->Options, OPTION_FALLBACKDEBUG, FALSE); intel->debug_flush = 0; if (xf86ReturnOptValBool(intel->Options, OPTION_DEBUG_FLUSH_BATCHES, FALSE)) intel->debug_flush |= DEBUG_FLUSH_BATCHES; if (xf86ReturnOptValBool(intel->Options, OPTION_DEBUG_FLUSH_CACHES, FALSE)) intel->debug_flush |= DEBUG_FLUSH_CACHES; if (xf86ReturnOptValBool(intel->Options, OPTION_DEBUG_WAIT, FALSE)) intel->debug_flush |= DEBUG_FLUSH_WAIT; #endif return TRUE; } static void intel_check_dri_option(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); unsigned level; intel->dri2 = intel->dri3 = DRI_NONE; level = intel_option_cast_to_unsigned(intel->Options, OPTION_DRI, DEFAULT_DRI_LEVEL); if (level < 3) intel->dri3 = DRI_DISABLED; if (level < 2) intel->dri2 = DRI_DISABLED; if (scrn->depth != 16 && scrn->depth != 24 && scrn->depth != 30) { xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "DRI is disabled because it " "runs only at depths 16, 24, and 30.\n"); intel->dri2 = intel->dri3 = DRI_DISABLED; } } static Bool intel_open_drm_master(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); intel->dev = intel_get_device(scrn, &intel->drmSubFD); return intel->dev != NULL; } static int intel_init_bufmgr(intel_screen_private *intel) { int batch_size; batch_size = 4096 * 4; if (IS_I865G(intel)) /* The 865 has issues with larger-than-page-sized batch buffers. */ batch_size = 4096; intel->bufmgr = drm_intel_bufmgr_gem_init(intel->drmSubFD, batch_size); if (!intel->bufmgr) return FALSE; if (xf86ReturnOptValBool(intel->Options, OPTION_BUFFER_CACHE, TRUE)) drm_intel_bufmgr_gem_enable_reuse(intel->bufmgr); drm_intel_bufmgr_gem_set_vma_cache_size(intel->bufmgr, 512); drm_intel_bufmgr_gem_enable_fenced_relocs(intel->bufmgr); list_init(&intel->batch_pixmaps); if ((INTEL_INFO(intel)->gen == 060)) { intel->wa_scratch_bo = drm_intel_bo_alloc(intel->bufmgr, "wa scratch", 4096, 4096); } return TRUE; } static void intel_bufmgr_fini(intel_screen_private *intel) { if (intel->bufmgr == NULL) return; drm_intel_bo_unreference(intel->wa_scratch_bo); drm_intel_bufmgr_destroy(intel->bufmgr); } static void I830XvInit(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); MessageType from = X_PROBED; intel->XvPreferOverlay = xf86ReturnOptValBool(intel->Options, OPTION_PREFER_OVERLAY, FALSE); if (xf86GetOptValInteger(intel->Options, OPTION_VIDEO_KEY, &(intel->colorKey))) { from = X_CONFIG; } else if (xf86GetOptValInteger(intel->Options, OPTION_COLOR_KEY, &(intel->colorKey))) { from = X_CONFIG; } else { intel->colorKey = (1 << scrn->offset.red) | (1 << scrn->offset.green) | (((scrn->mask.blue >> scrn->offset.blue) - 1) << scrn->offset.blue); from = X_DEFAULT; } xf86DrvMsg(scrn->scrnIndex, from, "video overlay key set to 0x%x\n", intel->colorKey); } static Bool drm_has_boolean_param(struct intel_screen_private *intel, int param) { drm_i915_getparam_t gp; int value; gp.value = &value; gp.param = param; if (drmIoctl(intel->drmSubFD, DRM_IOCTL_I915_GETPARAM, &gp)) return FALSE; return value; } static Bool has_kernel_flush(struct intel_screen_private *intel) { /* The BLT ring was introduced at the same time as the * automatic flush for the busy-ioctl. */ return drm_has_boolean_param(intel, I915_PARAM_HAS_BLT); } static Bool has_relaxed_fencing(struct intel_screen_private *intel) { return drm_has_boolean_param(intel, I915_PARAM_HAS_RELAXED_FENCING); } static Bool has_prime_vmap_flush(struct intel_screen_private *intel) { return drm_has_boolean_param(intel, I915_PARAM_HAS_PRIME_VMAP_FLUSH); } static Bool can_accelerate_blt(struct intel_screen_private *intel) { if (INTEL_INFO(intel)->gen == -1) return FALSE; if (!xf86ReturnOptValBool(intel->Options, OPTION_ACCEL_ENABLE, TRUE) || !intel_option_cast_to_bool(intel->Options, OPTION_ACCEL_METHOD, TRUE)) { xf86DrvMsg(intel->scrn->scrnIndex, X_CONFIG, "Disabling hardware acceleration.\n"); return FALSE; } if (INTEL_INFO(intel)->gen == 060) { struct pci_device *const device = xf86GetPciInfoForEntity(intel->pEnt->index); /* Sandybridge rev07 locks up easily, even with the * BLT ring workaround in place. * Thus use shadowfb by default. */ if (device->revision < 8) { xf86DrvMsg(intel->scrn->scrnIndex, X_WARNING, "Disabling hardware acceleration on this pre-production hardware.\n"); return FALSE; } } if (INTEL_INFO(intel)->gen >= 060) { drm_i915_getparam_t gp; int value; /* On Sandybridge we need the BLT in order to do anything since * it so frequently used in the acceleration code paths. */ gp.value = &value; gp.param = I915_PARAM_HAS_BLT; if (drmIoctl(intel->drmSubFD, DRM_IOCTL_I915_GETPARAM, &gp)) return FALSE; } return TRUE; } static void intel_setup_capabilities(ScrnInfoPtr scrn) { #ifdef INTEL_PIXMAP_SHARING intel_screen_private *intel = intel_get_screen_private(scrn); uint64_t value; int ret; scrn->capabilities = 0; ret = drmGetCap(intel->drmSubFD, DRM_CAP_PRIME, &value); if (ret == 0) { if (value & DRM_PRIME_CAP_EXPORT) scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; if (value & DRM_PRIME_CAP_IMPORT) scrn->capabilities |= RR_Capability_SinkOutput; } #endif } /** * This is called before ScreenInit to do any require probing of screen * configuration. * * This code generally covers probing, module loading, option handling * card mapping, and RandR setup. * * Since xf86InitialConfiguration ends up requiring that we set video modes * in order to detect configuration, we end up having to do a lot of driver * setup (talking to the DRM, mapping the device, etc.) in this function. * As a result, we want to set up that server initialization once rather * that doing it per generation. */ static Bool I830PreInit(ScrnInfoPtr scrn, int flags) { intel_screen_private *intel; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; int flags24; Gamma zeros = { 0.0, 0.0, 0.0 }; if (scrn->numEntities != 1) return FALSE; pEnt = xf86GetEntityInfo(scrn->entityList[0]); if (pEnt == NULL) return FALSE; if (pEnt->location.type != BUS_PCI #ifdef XSERVER_PLATFORM_BUS && pEnt->location.type != BUS_PLATFORM #endif ) return FALSE; if (flags & PROBE_DETECT) return TRUE; if (((uintptr_t)scrn->driverPrivate) & 3) { intel = xnfcalloc(sizeof(*intel), 1); if (intel == NULL) return FALSE; intel->info = (void *)((uintptr_t)scrn->driverPrivate & ~3); scrn->driverPrivate = intel; } intel = intel_get_screen_private(scrn); intel->scrn = scrn; intel->pEnt = pEnt; scrn->displayWidth = 640; /* default it */ if (!intel_open_drm_master(scrn)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to become DRM master.\n"); return FALSE; } scrn->monitor = scrn->confScreen->monitor; scrn->progClock = TRUE; scrn->rgbBits = 8; flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; if (!xf86SetDepthBpp(scrn, 0, 0, 0, flags24)) return FALSE; switch (scrn->depth) { case 15: case 16: case 24: case 30: break; case 8: default: xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Given depth (%d) is not supported by intel driver\n", scrn->depth); return FALSE; } xf86PrintDepthBpp(scrn); if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) return FALSE; if (!xf86SetDefaultVisual(scrn, -1)) return FALSE; intel->cpp = scrn->bitsPerPixel / 8; if (!I830GetEarlyOptions(scrn)) return FALSE; intel_setup_capabilities(scrn); intel_check_chipset_option(scrn); intel_check_dri_option(scrn); if (!intel_init_bufmgr(intel)) { PreInitCleanup(scrn); return FALSE; } intel->force_fallback = drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE) != 0; /* Enable tiling by default */ intel->tiling = INTEL_TILING_ALL; /* Allow user override if they set a value */ if (!xf86ReturnOptValBool(intel->Options, OPTION_TILING_2D, TRUE)) intel->tiling &= ~INTEL_TILING_2D; if (xf86ReturnOptValBool(intel->Options, OPTION_TILING_FB, FALSE)) intel->tiling &= ~INTEL_TILING_FB; if (!can_accelerate_blt(intel)) { intel->force_fallback = TRUE; intel->tiling &= ~INTEL_TILING_FB; } intel->has_kernel_flush = has_kernel_flush(intel); intel->has_prime_vmap_flush = has_prime_vmap_flush(intel); intel->has_relaxed_fencing = INTEL_INFO(intel)->gen >= 033; /* And override the user if there is no kernel support */ if (intel->has_relaxed_fencing) intel->has_relaxed_fencing = has_relaxed_fencing(intel); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Relaxed fencing %s\n", intel->has_relaxed_fencing ? "enabled" : "disabled"); /* SwapBuffers delays to avoid tearing */ intel->swapbuffers_wait = xf86ReturnOptValBool(intel->Options, OPTION_SWAPBUFFERS_WAIT, TRUE); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Wait on SwapBuffers? %s\n", intel->swapbuffers_wait ? "enabled" : "disabled"); intel->use_triple_buffer = xf86ReturnOptValBool(intel->Options, OPTION_TRIPLE_BUFFER, TRUE); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Triple buffering? %s\n", intel->use_triple_buffer ? "enabled" : "disabled"); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s\n", intel->tiling & INTEL_TILING_FB ? "tiled" : "linear"); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Pixmaps %s\n", intel->tiling & INTEL_TILING_2D ? "tiled" : "linear"); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "3D buffers %s\n", intel->tiling & INTEL_TILING_3D ? "tiled" : "linear"); xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "SwapBuffers wait %sabled\n", intel->swapbuffers_wait ? "en" : "dis"); I830XvInit(scrn); if (!intel_mode_pre_init(scrn, intel->drmSubFD, intel->cpp)) { PreInitCleanup(scrn); return FALSE; } if (!xf86SetGamma(scrn, zeros)) { PreInitCleanup(scrn); return FALSE; } if (scrn->modes == NULL) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "No modes.\n"); PreInitCleanup(scrn); return FALSE; } scrn->currentMode = scrn->modes; /* Set display resolution */ xf86SetDpi(scrn, 0, 0); /* Load the required sub modules */ if (!xf86LoadSubModule(scrn, "fb")) { PreInitCleanup(scrn); return FALSE; } /* Load the dri modules if requested. */ #if HAVE_DRI2 if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2")) intel->dri2 = DRI_DISABLED; #endif #if HAVE_DRI3 if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3")) intel->dri3 = DRI_DISABLED; #endif return TRUE; } #ifdef INTEL_PIXMAP_SHARING static void redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); RegionRec pixregion; int was_blocked; PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); RegionTranslate(&pixregion, dirty->x, dirty->y); RegionIntersect(&pixregion, &pixregion, DamageRegion(dirty->damage)); RegionTranslate(&pixregion, -dirty->x, -dirty->y); was_blocked = RegionNil(&pixregion); DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); RegionUninit(&pixregion); if (was_blocked) return; PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); PixmapSyncDirtyHelper(dirty, &pixregion); RegionUninit(&pixregion); intel_flush(intel); if (!intel->has_prime_vmap_flush) { drm_intel_bo *bo = intel_uxa_get_pixmap_bo(dirty->slave_dst->master_pixmap); was_blocked = xf86BlockSIGIO(); drm_intel_bo_map(bo, FALSE); drm_intel_bo_unmap(bo); xf86UnblockSIGIO(was_blocked); } DamageRegionProcessPending(&dirty->slave_dst->drawable); return; } static void intel_dirty_update(ScreenPtr screen) { RegionPtr region; PixmapDirtyUpdatePtr ent; if (xorg_list_is_empty(&screen->pixmap_dirty_list)) return; xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { region = DamageRegion(ent->damage); if (RegionNotEmpty(region)) { redisplay_dirty(screen, ent); DamageEmpty(ent->damage); } } } #endif static void I830BlockHandler(BLOCKHANDLER_ARGS_DECL) { SCREEN_PTR(arg); ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); screen->BlockHandler = intel->BlockHandler; (*screen->BlockHandler) (BLOCKHANDLER_ARGS); intel->BlockHandler = screen->BlockHandler; screen->BlockHandler = I830BlockHandler; intel_uxa_block_handler(intel); intel_video_block_handler(intel); #ifdef INTEL_PIXMAP_SHARING intel_dirty_update(screen); #endif } static Bool intel_init_initial_framebuffer(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int width = scrn->virtualX; int height = scrn->virtualY; int pitch; uint32_t tiling; intel->front_buffer = intel_allocate_framebuffer(scrn, width, height, intel->cpp, &pitch, &tiling); if (!intel->front_buffer) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Couldn't allocate initial framebuffer.\n"); return FALSE; } intel->front_pitch = pitch; intel->front_tiling = tiling; scrn->displayWidth = pitch / intel->cpp; return TRUE; } static void intel_flush_callback(CallbackListPtr *list, pointer user_data, pointer call_data) { ScrnInfoPtr scrn = user_data; if (scrn->vtSema) intel_flush(intel_get_screen_private(scrn)); } #if HAVE_UDEV #include static void I830HandleUEvents(int fd, void *closure) { ScrnInfoPtr scrn = closure; intel_screen_private *intel = intel_get_screen_private(scrn); struct udev_device *dev; const char *hotplug; struct stat s; dev_t udev_devnum; dev = udev_monitor_receive_device(intel->uevent_monitor); if (!dev) return; udev_devnum = udev_device_get_devnum(dev); if (fstat(intel->drmSubFD, &s)) { udev_device_unref(dev); return; } /* * Check to make sure this event is directed at our * device (by comparing dev_t values), then make * sure it's a hotplug event (HOTPLUG=1) */ hotplug = udev_device_get_property_value(dev, "HOTPLUG"); if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 && hotplug && atoi(hotplug) == 1) { intel_mode_hotplug(intel); } udev_device_unref(dev); } static int has_randr(void) { #if HAS_DIXREGISTERPRIVATEKEY return dixPrivateKeyRegistered(rrPrivKey); #else return *rrPrivKey; #endif } static void I830UeventInit(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct udev *u; struct udev_monitor *mon; Bool hotplug; MessageType from = X_CONFIG; /* Without RR, nothing we can do here */ if (!has_randr()) return; if (!xf86GetOptValBool(intel->Options, OPTION_HOTPLUG, &hotplug)) { from = X_DEFAULT; hotplug = TRUE; } xf86DrvMsg(scrn->scrnIndex, from, "hotplug detection: \"%s\"\n", hotplug ? "enabled" : "disabled"); if (!hotplug) return; u = udev_new(); if (!u) return; mon = udev_monitor_new_from_netlink(u, "udev"); if (!mon) { udev_unref(u); return; } if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") < 0 || udev_monitor_enable_receiving(mon) < 0) { udev_monitor_unref(mon); udev_unref(u); return; } intel->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), I830HandleUEvents, scrn); if (!intel->uevent_handler) { udev_monitor_unref(mon); udev_unref(u); return; } intel->uevent_monitor = mon; } static void I830UeventFini(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->uevent_handler) { struct udev *u = udev_monitor_get_udev(intel->uevent_monitor); xf86RemoveGeneralHandler(intel->uevent_handler); udev_monitor_unref(intel->uevent_monitor); udev_unref(u); intel->uevent_handler = NULL; intel->uevent_monitor = NULL; } } #endif /* HAVE_UDEV */ static Bool I830ScreenInit(SCREEN_INIT_ARGS_DECL) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); VisualPtr visual; #ifdef INTEL_XVMC MessageType from; #endif struct pci_device *const device = xf86GetPciInfoForEntity(intel->pEnt->index); int fb_bar = IS_GEN2(intel) ? 0 : 2; scrn->videoRam = device->regions[fb_bar].size / 1024; intel->last_3d = LAST_3D_OTHER; intel->overlayOn = FALSE; /* * Set this so that the overlay allocation is factored in when * appropriate. */ intel->XvEnabled = TRUE; if (!intel_init_initial_framebuffer(scrn)) return FALSE; miClearVisualTypes(); if (!miSetVisualTypes(scrn->depth, miGetDefaultVisualMask(scrn->depth), scrn->rgbBits, scrn->defaultVisual)) return FALSE; if (!miSetPixmapDepths()) return FALSE; /* Must be first, before anything else installs screen callbacks. */ if (!fbScreenInit(screen, NULL, scrn->virtualX, scrn->virtualY, scrn->xDpi, scrn->yDpi, scrn->displayWidth, scrn->bitsPerPixel)) return FALSE; if (scrn->bitsPerPixel > 8) { /* Fixup RGB ordering */ visual = screen->visuals + screen->numVisuals; while (--visual >= screen->visuals) { if ((visual->class | DynamicClass) == DirectColor) { visual->offsetRed = scrn->offset.red; visual->offsetGreen = scrn->offset.green; visual->offsetBlue = scrn->offset.blue; visual->redMask = scrn->mask.red; visual->greenMask = scrn->mask.green; visual->blueMask = scrn->mask.blue; } } } fbPictureInit(screen, NULL, 0); xf86SetBlackWhitePixels(screen); if (!intel_uxa_init(screen)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Hardware acceleration initialization failed\n"); return FALSE; } #if HAVE_DRI2 if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen)) intel->dri2 = DRI_ACTIVE; #endif #if HAVE_DRI3 if (!intel_sync_init(screen)) intel->dri3 = DRI_DISABLED; if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen)) intel->dri3 = DRI_ACTIVE; #endif if (xf86ReturnOptValBool(intel->Options, OPTION_PRESENT, TRUE)) intel_present_screen_init(screen); xf86SetBackingStore(screen); xf86SetSilkenMouse(screen); miDCInitialize(screen, xf86GetPointerScreenFuncs()); xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); if (!xf86_cursors_init(screen, 64, 64, (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | HARDWARE_CURSOR_INVERT_MASK | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | HARDWARE_CURSOR_UPDATE_UNHIDDEN | HARDWARE_CURSOR_ARGB))) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); } intel->BlockHandler = screen->BlockHandler; screen->BlockHandler = I830BlockHandler; #ifdef INTEL_PIXMAP_SHARING screen->StartPixmapTracking = PixmapStartDirtyTracking; screen->StopPixmapTracking = PixmapStopDirtyTracking; #endif if (!AddCallback(&FlushCallback, intel_flush_callback, scrn)) return FALSE; screen->SaveScreen = xf86SaveScreen; intel->CloseScreen = screen->CloseScreen; screen->CloseScreen = I830CloseScreen; intel->CreateScreenResources = screen->CreateScreenResources; screen->CreateScreenResources = i830CreateScreenResources; if (!xf86CrtcScreenInit(screen)) return FALSE; if (!miCreateDefColormap(screen)) return FALSE; if (!xf86HandleColormaps(screen, 256, 8, I830LoadPalette, NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) { return FALSE; } xf86DPMSInit(screen, xf86DPMSSet, 0); #ifdef INTEL_XVMC if (INTEL_INFO(intel)->gen >= 040) intel->XvMCEnabled = TRUE; from = (intel->dri2 == DRI_ACTIVE && xf86GetOptValBool(intel->Options, OPTION_XVMC, &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT); xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", intel->XvMCEnabled ? "en" : "dis"); #endif /* Init video */ if (intel->XvEnabled) intel_video_init(screen); #if HAVE_DRI2 switch (intel->dri2) { case DRI_ACTIVE: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI2: Enabled\n"); break; case DRI_DISABLED: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI2: Disabled\n"); break; case DRI_NONE: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI2: Failed\n"); break; } #else xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI2: Not available\n"); #endif #if HAVE_DRI3 switch (intel->dri3) { case DRI_ACTIVE: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI3: Enabled\n"); break; case DRI_DISABLED: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI3: Disabled\n"); break; case DRI_NONE: xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI3: Failed\n"); break; } #else xf86DrvMsg(scrn->scrnIndex, X_INFO, "DRI3: Not available\n"); #endif if (serverGeneration == 1) xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); intel_mode_init(intel); intel->suspended = FALSE; #if HAVE_UDEV I830UeventInit(scrn); #endif /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ scrn->vtSema = TRUE; return I830EnterVT(VT_FUNC_ARGS(0)); } static void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL) { } static void I830FreeScreen(FREE_SCREEN_ARGS_DECL) { SCRN_INFO_PTR(arg); intel_screen_private *intel = intel_get_screen_private(scrn); if (intel && !((uintptr_t)intel & 3)) { intel_mode_fini(intel); intel_bufmgr_fini(intel); intel_put_device(intel->dev); free(intel); scrn->driverPrivate = NULL; } } static void I830LeaveVT(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); intel_screen_private *intel = intel_get_screen_private(scrn); xf86RotateFreeShadow(scrn); xf86_hide_cursors(scrn); if (intel_put_master(intel->dev)) xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmDropMaster failed: %s\n", strerror(errno)); } /* * This gets called when gaining control of the VT, and from ScreenInit(). */ static Bool I830EnterVT(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); intel_screen_private *intel = intel_get_screen_private(scrn); if (intel_get_master(intel->dev)) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmSetMaster failed: %s\n", strerror(errno)); return FALSE; } if (!xf86SetDesiredModes(scrn)) return FALSE; intel_mode_disable_unused_functions(scrn); return TRUE; } static Bool I830SwitchMode(SWITCH_MODE_ARGS_DECL) { SCRN_INFO_PTR(arg); return xf86SetSingleMode(scrn, mode, RR_Rotate_0); } static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); #if HAVE_UDEV I830UeventFini(scrn); #endif intel_mode_close(intel); DeleteCallback(&FlushCallback, intel_flush_callback, scrn); TimerFree(intel->cache_expire); intel->cache_expire = NULL; if (intel->uxa_driver) { uxa_driver_fini(screen); free(intel->uxa_driver); intel->uxa_driver = NULL; } if (intel->back_buffer) { drm_intel_bo_unreference(intel->back_buffer); intel->back_buffer = NULL; } if (intel->front_buffer) { intel_mode_remove_fb(intel); drm_intel_bo_unreference(intel->front_buffer); intel->front_buffer = NULL; } if (scrn->vtSema == TRUE) { I830LeaveVT(VT_FUNC_ARGS(0)); } intel_batch_teardown(scrn); if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100) gen4_render_state_cleanup(scrn); xf86_cursors_fini(screen); i965_free_video(scrn); screen->CloseScreen = intel->CloseScreen; (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); if (intel->dri2 == DRI_ACTIVE) { I830DRI2CloseScreen(screen); intel->dri2 = DRI_NONE; } if (intel->dri3 == DRI_ACTIVE) { /* nothing to do here? */ intel->dri3 = DRI_NONE; } intel_sync_close(screen); xf86GARTCloseScreen(scrn->scrnIndex); scrn->vtSema = FALSE; return TRUE; } static ModeStatus I830ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { SCRN_INFO_PTR(arg); if (mode->Flags & V_INTERLACE) { if (verbose) { xf86DrvMsg(scrn->scrnIndex, X_PROBED, "Removing interlaced mode \"%s\"\n", mode->name); } return MODE_BAD; } return MODE_OK; } #ifndef SUSPEND_SLEEP #define SUSPEND_SLEEP 0 #endif #ifndef RESUME_SLEEP #define RESUME_SLEEP 0 #endif /* * This function is only required if we need to do anything differently from * DoApmEvent() in common/xf86PM.c, including if we want to see events other * than suspend/resume. */ static Bool I830PMEvent(SCRN_ARG_TYPE arg, pmEvent event, Bool undo) { SCRN_INFO_PTR(arg); intel_screen_private *intel = intel_get_screen_private(scrn); switch (event) { case XF86_APM_SYS_SUSPEND: case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ case XF86_APM_USER_SUSPEND: case XF86_APM_SYS_STANDBY: case XF86_APM_USER_STANDBY: if (!undo && !intel->suspended) { scrn->LeaveVT(VT_FUNC_ARGS(0)); intel->suspended = TRUE; sleep(SUSPEND_SLEEP); } else if (undo && intel->suspended) { sleep(RESUME_SLEEP); scrn->EnterVT(VT_FUNC_ARGS(0)); intel->suspended = FALSE; } break; case XF86_APM_STANDBY_RESUME: case XF86_APM_NORMAL_RESUME: case XF86_APM_CRITICAL_RESUME: if (intel->suspended) { sleep(RESUME_SLEEP); scrn->EnterVT(VT_FUNC_ARGS(0)); intel->suspended = FALSE; /* * Turn the screen saver off when resuming. This seems to be * needed to stop xscreensaver kicking in (when used). * * XXX DoApmEvent() should probably call this just like * xf86VTSwitch() does. Maybe do it here only in 4.2 * compatibility mode. */ SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); } break; /* This is currently used for ACPI */ case XF86_APM_CAPABILITY_CHANGED: ErrorF("I830PMEvent: Capability change\n"); SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); break; default: ErrorF("I830PMEvent: received APM event %d\n", event); } return TRUE; } Bool intel_init_scrn(ScrnInfoPtr scrn) { scrn->PreInit = I830PreInit; scrn->ScreenInit = I830ScreenInit; scrn->SwitchMode = I830SwitchMode; scrn->AdjustFrame = i830AdjustFrame; scrn->EnterVT = I830EnterVT; scrn->LeaveVT = I830LeaveVT; scrn->FreeScreen = I830FreeScreen; scrn->ValidMode = I830ValidMode; scrn->PMEvent = I830PMEvent; return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_hwmc.c000066400000000000000000000146511267532330400241630ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define _INTEL_XVMC_SERVER_ #include "intel.h" #include "intel_xvmc.h" #include #include #include static int create_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture, int *num_priv, CARD32 ** priv) { return Success; } static void destroy_subpicture(ScrnInfoPtr scrn, XvMCSubpicturePtr subpicture) { } static int create_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface, int *num_priv, CARD32 ** priv) { return Success; } static void destroy_surface(ScrnInfoPtr scrn, XvMCSurfacePtr surface) { } static int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext, int *num_priv, CARD32 **priv) { intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_xvmc_hw_context *contextRec; *priv = calloc(1, sizeof(struct intel_xvmc_hw_context)); contextRec = (struct intel_xvmc_hw_context *) *priv; if (!contextRec) { *num_priv = 0; return BadAlloc; } *num_priv = sizeof(struct intel_xvmc_hw_context) >> 2; if (IS_GEN3(intel)) { contextRec->type = XVMC_I915_MPEG2_MC; contextRec->i915.use_phys_addr = 0; } else { if (INTEL_INFO(intel)->gen >= 045) contextRec->type = XVMC_I965_MPEG2_VLD; else contextRec->type = XVMC_I965_MPEG2_MC; contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 045; contextRec->i965.is_965_q = IS_965_Q(intel); contextRec->i965.is_igdng = IS_GEN5(intel); } return Success; } static void destroy_context(ScrnInfoPtr scrn, XvMCContextPtr context) { } /* i915 hwmc support */ static XF86MCSurfaceInfoRec i915_YV12_mpg2_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_2, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 0, /* &yv12_subpicture_list */ NULL, }; static XF86MCSurfaceInfoRec i915_YV12_mpg1_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 720, 576, 720, 576, XVMC_MPEG_1, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ 0, NULL, }; static XF86MCSurfaceInfoPtr surface_info_i915[2] = { (XF86MCSurfaceInfoPtr) & i915_YV12_mpg2_surface, (XF86MCSurfaceInfoPtr) & i915_YV12_mpg1_surface }; /* i965 and later hwmc support */ #ifndef XVMC_VLD #define XVMC_VLD 0x00020000 #endif static XF86MCSurfaceInfoRec yv12_mpeg2_vld_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1936, 1096, 1920, 1080, XVMC_MPEG_2 | XVMC_VLD, XVMC_INTRA_UNSIGNED, NULL }; static XF86MCSurfaceInfoRec yv12_mpeg2_i965_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1936, 1096, 1920, 1080, XVMC_MPEG_2 | XVMC_MOCOMP, /* XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING, */ XVMC_INTRA_UNSIGNED, /* &yv12_subpicture_list */ NULL }; static XF86MCSurfaceInfoRec yv12_mpeg1_i965_surface = { FOURCC_YV12, XVMC_CHROMA_FORMAT_420, 0, 1920, 1080, 1920, 1080, XVMC_MPEG_1 | XVMC_MOCOMP, /*XVMC_OVERLAID_SURFACE | XVMC_SUBPICTURE_INDEPENDENT_SCALING | XVMC_INTRA_UNSIGNED, */ XVMC_INTRA_UNSIGNED, /*&yv12_subpicture_list */ NULL }; static XF86MCSurfaceInfoPtr surface_info_i965[] = { &yv12_mpeg2_i965_surface, &yv12_mpeg1_i965_surface }; static XF86MCSurfaceInfoPtr surface_info_vld[] = { &yv12_mpeg2_vld_surface, &yv12_mpeg2_i965_surface, }; /* check chip type and load xvmc driver */ Bool intel_xvmc_adaptor_init(ScreenPtr pScreen) { ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); struct pci_device *pci; static XF86MCAdaptorRec *pAdapt; const char *name; char buf[64]; if (!intel->XvMCEnabled) return FALSE; /* Needs KMS support. */ if (IS_I915G(intel) || IS_I915GM(intel)) return FALSE; if (IS_GEN2(intel)) { ErrorF("Your chipset doesn't support XvMC.\n"); return FALSE; } pci = xf86GetPciInfoForEntity(intel->pEnt->index); if (pci == NULL) return FALSE; pAdapt = calloc(1, sizeof(XF86MCAdaptorRec)); if (!pAdapt) { ErrorF("Allocation error.\n"); return FALSE; } pAdapt->name = "Intel(R) Textured Video"; pAdapt->num_subpictures = 0; pAdapt->subpictures = NULL; pAdapt->CreateContext = create_context; pAdapt->DestroyContext = destroy_context; pAdapt->CreateSurface = create_surface; pAdapt->DestroySurface = destroy_surface; pAdapt->CreateSubpicture = create_subpicture; pAdapt->DestroySubpicture = destroy_subpicture; if (IS_GEN3(intel)) { name = "i915_xvmc", pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915); pAdapt->surfaces = surface_info_i915; } else if (INTEL_INFO(intel)->gen >= 045) { name = "xvmc_vld", pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld); pAdapt->surfaces = surface_info_vld; } else { name = "i965_xvmc", pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965); pAdapt->surfaces = surface_info_i965; } if (xf86XvMCScreenInit(pScreen, 1, &pAdapt)) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "[XvMC] %s driver initialized.\n", name); } else { intel->XvMCEnabled = FALSE; xf86DrvMsg(scrn->scrnIndex, X_INFO, "[XvMC] Failed to initialize XvMC.\n"); return FALSE; } sprintf(buf, "pci:%04x:%02x:%02x.%d", pci->domain, pci->bus, pci->dev, pci->func); xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME, buf, INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, INTEL_XVMC_PATCHLEVEL); return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_memory.c000066400000000000000000000230621267532330400245310ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright © 2002 by David Dawes. 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 COPYRIGHT HOLDERS AND/OR THEIR 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: * Keith Whitwell * David Dawes * * Updated for Dual Head capabilities: * Alan Hourihane */ /** * @file intel_memory.c * * This is the video memory allocator. Our memory allocation is different from * other graphics chips, where you have a fixed amount of graphics memory * available that you want to put to the best use. Instead, we have almost no * memory pre-allocated, and we have to choose an appropriate amount of system * memory to use. * * The allocations we might do: * * - Ring buffer * - HW cursor block (either one block or four) * - Overlay registers * - Front buffer (screen 1) * - Front buffer (screen 2, only in zaphod mode) * - Back/depth buffer (3D only) * - Compatibility texture pool (optional, more is always better) * - New texture pool (optional, more is always better. aperture allocation * only) * * The user may request a specific amount of memory to be used * (intel->pEnt->videoRam != 0), in which case allocations have to fit within * that much aperture. If not, the individual allocations will be * automatically sized, and will be fit within the maximum aperture size. * Only the actual memory used (not alignment padding) will get actual AGP * memory allocated. * * Given that the allocations listed are generally a page or more than a page, * our allocator will only return page-aligned offsets, simplifying the memory * binding process. For smaller allocations, the acceleration architecture's * linear allocator is preferred. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "intel.h" #include "i915_drm.h" /** * Returns the fence size for a tiled area of the given size. */ unsigned long intel_get_fence_size(intel_screen_private *intel, unsigned long size) { unsigned long i; unsigned long start; if (INTEL_INFO(intel)->gen >= 040 || intel->has_relaxed_fencing) { /* The 965 can have fences at any page boundary. */ return ALIGN(size, 4096); } else { /* Align the size to a power of two greater than the smallest fence * size. */ if (IS_GEN3(intel)) start = MB(1); else start = KB(512); for (i = start; i < size; i <<= 1) ; return i; } } /** * On some chips, pitch width has to be a power of two tile width, so * calculate that here. */ unsigned long intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch, uint32_t tiling_mode) { unsigned long i; unsigned long tile_width = (tiling_mode == I915_TILING_Y) ? 128 : 512; if (tiling_mode == I915_TILING_NONE) return pitch; /* 965+ is flexible */ if (INTEL_INFO(intel)->gen >= 040) return ALIGN(pitch, tile_width); /* Pre-965 needs power of two tile width */ for (i = tile_width; i < pitch; i <<= 1) ; return i; } Bool intel_check_display_stride(ScrnInfoPtr scrn, int stride, Bool tiling) { intel_screen_private *intel = intel_get_screen_private(scrn); int limit; /* 8xx spec has always 8K limit, but tests show larger limit in non-tiling mode, which makes large monitor work. */ if (tiling) { if (IS_GEN2(intel)) limit = KB(8); else if (IS_GEN3(intel)) limit = KB(8); else if (IS_GEN4(intel)) limit = KB(16); else limit = KB(32); } else limit = KB(32); return stride <= limit; } static size_t agp_aperture_size(struct pci_device *dev, int gen) { return dev->regions[gen < 030 ? 0 : 2].size; } void intel_set_gem_max_sizes(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); size_t agp_size = agp_aperture_size(xf86GetPciInfoForEntity(intel->pEnt->index), INTEL_INFO(intel)->gen); /* The chances of being able to mmap an object larger than * agp_size/2 are slim. Moreover, we may be forced to fallback * using a gtt mapping as both the source and a mask, as well * as a destination and all need to fit into the aperture. */ intel->max_gtt_map_size = agp_size / 4; /* Let objects be tiled up to the size where only 4 would fit in * the aperture, presuming best case alignment. Also if we * cannot mmap it using the GTT we will be stuck. */ intel->max_tiling_size = intel->max_gtt_map_size; /* Large BOs will tend to hit SW fallbacks frequently, and also will * tend to fail to successfully map when doing SW fallbacks because we * overcommit address space for BO access, or worse cause aperture * thrashing. */ intel->max_bo_size = intel->max_gtt_map_size; } unsigned int intel_compute_size(struct intel_screen_private *intel, int w, int h, int bpp, unsigned usage, uint32_t *tiling, int *stride) { int pitch, size; if (*tiling != I915_TILING_NONE) { /* First check whether tiling is necessary. */ pitch = (w * bpp + 7) / 8; pitch = ALIGN(pitch, 64); size = pitch * ALIGN (h, 2); if (INTEL_INFO(intel)->gen < 040) { /* Gen 2/3 has a maximum stride for tiling of * 8192 bytes. */ if (pitch > KB(8)) *tiling = I915_TILING_NONE; /* Narrower than half a tile? */ if (pitch < 256) *tiling = I915_TILING_NONE; /* Older hardware requires fences to be pot size * aligned with a minimum of 1 MiB, so causes * massive overallocation for small textures. */ if (size < 1024*1024/2 && !intel->has_relaxed_fencing) *tiling = I915_TILING_NONE; } else if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && size <= 4096) { /* Disable tiling beneath a page size, we will not see * any benefit from reducing TLB misses and instead * just incur extra cost when we require a fence. */ *tiling = I915_TILING_NONE; } } pitch = (w * bpp + 7) / 8; if (!(usage & INTEL_CREATE_PIXMAP_DRI2) && pitch <= 256) *tiling = I915_TILING_NONE; if (*tiling != I915_TILING_NONE) { int aligned_h, tile_height; if (IS_GEN2(intel)) tile_height = 16; else if (*tiling == I915_TILING_X) tile_height = 8; else tile_height = 32; aligned_h = ALIGN(h, tile_height); *stride = intel_get_fence_pitch(intel, ALIGN(pitch, 512), *tiling); /* Round the object up to the size of the fence it will live in * if necessary. We could potentially make the kernel allocate * a larger aperture space and just bind the subset of pages in, * but this is easier and also keeps us out of trouble (as much) * with drm_intel_bufmgr_check_aperture(). */ size = intel_get_fence_size(intel, *stride * aligned_h); if (size > intel->max_tiling_size) *tiling = I915_TILING_NONE; } if (*tiling == I915_TILING_NONE) { /* We only require a 64 byte alignment for scanouts, but * a 256 byte alignment for sharing with PRIME. */ *stride = ALIGN(pitch, 256); /* Round the height up so that the GPU's access to a 2x2 aligned * subspan doesn't address an invalid page offset beyond the * end of the GTT. */ size = *stride * ALIGN(h, 2); } return size; } drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn, int width, int height, int cpp, int *out_stride, uint32_t *out_tiling) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t tiling; int stride, size; drm_intel_bo *bo; intel_set_gem_max_sizes(scrn); if (intel->tiling & INTEL_TILING_FB) tiling = I915_TILING_X; else tiling = I915_TILING_NONE; retry: size = intel_compute_size(intel, width, height, intel->cpp*8, 0, &tiling, &stride); if (!intel_check_display_stride(scrn, stride, tiling)) { if (tiling != I915_TILING_NONE) { tiling = I915_TILING_NONE; goto retry; } xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Front buffer stride %d kB " "exceeds display limit\n", stride / 1024); return NULL; } bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0); if (bo == NULL) return FALSE; if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(bo, &tiling, stride); xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocated new frame buffer %dx%d stride %d, %s\n", width, height, stride, tiling == I915_TILING_NONE ? "untiled" : "tiled"); drm_intel_bo_disable_reuse(bo); *out_stride = stride; *out_tiling = tiling; return bo; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_present.c000066400000000000000000000265201267532330400247030ustar00rootroot00000000000000/* * Copyright © 2014 Intel Corporation * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "xf86drm.h" #include "windowstr.h" #include "shadow.h" #include "fb.h" #include "intel.h" #include "i830_reg.h" #include "i915_drm.h" #include "present.h" struct intel_present_vblank_event { uint64_t event_id; }; static uint32_t pipe_select(int pipe) { if (pipe > 1) return pipe << DRM_VBLANK_HIGH_CRTC_SHIFT; else if (pipe > 0) return DRM_VBLANK_SECONDARY; else return 0; } static RRCrtcPtr intel_present_get_crtc(WindowPtr window) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr pScrn = xf86ScreenToScrn(screen); BoxRec box, crtcbox; xf86CrtcPtr crtc; RRCrtcPtr randr_crtc = NULL; box.x1 = window->drawable.x; box.y1 = window->drawable.y; box.x2 = box.x1 + window->drawable.width; box.y2 = box.y1 + window->drawable.height; crtc = intel_covering_crtc(pScrn, &box, NULL, &crtcbox); /* Make sure the CRTC is valid and this is the real front buffer */ if (crtc != NULL && !crtc->rotatedData) randr_crtc = crtc->randr_crtc; return randr_crtc; } static int intel_present_crtc_pipe(ScreenPtr screen, RRCrtcPtr randr_crtc) { xf86CrtcPtr crtc; if (randr_crtc == NULL) return 0; crtc = randr_crtc->devPrivate; return intel_crtc_to_pipe(crtc); } static int intel_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); return intel_get_crtc_msc_ust(scrn, xf86_crtc, msc, ust); } /* * Flush the DRM event queue when full; this * makes space for new requests */ static Bool intel_present_flush_drm_events(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); return intel_mode_read_drm_events(intel) >= 0; } /* * Called when the queued vblank event has occurred */ static void intel_present_vblank_handler(ScrnInfoPtr scrn, xf86CrtcPtr crtc, uint64_t msc, uint64_t usec, void *data) { struct intel_present_vblank_event *event = data; present_event_notify(event->event_id, usec, msc); free(event); } /* * Called when the queued vblank is aborted */ static void intel_present_vblank_abort(ScrnInfoPtr scrn, xf86CrtcPtr crtc, void *data) { struct intel_present_vblank_event *event = data; free(event); } /* * Queue an event to report back to the Present extension when the specified * MSC has past */ static int intel_present_queue_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { xf86CrtcPtr xf86_crtc = crtc->devPrivate; ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); int pipe = intel_present_crtc_pipe(screen, crtc); struct intel_present_vblank_event *event; drmVBlank vbl; int ret; uint32_t seq; event = calloc(sizeof(struct intel_present_vblank_event), 1); if (!event) return BadAlloc; event->event_id = event_id; seq = intel_drm_queue_alloc(scrn, xf86_crtc, event, intel_present_vblank_handler, intel_present_vblank_abort); if (!seq) { free(event); return BadAlloc; } vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | pipe_select(pipe); vbl.request.sequence = intel_crtc_msc_to_sequence(scrn, xf86_crtc, msc); vbl.request.signal = seq; for (;;) { ret = drmWaitVBlank(intel->drmSubFD, &vbl); if (!ret) break; if (errno != EBUSY || !intel_present_flush_drm_events(screen)) return BadAlloc; } DebugPresent(("\t\tiq %lld seq %u msc %llu (hw msc %u)\n", (long long) event_id, seq, (long long) msc, vbl.request.sequence)); return Success; } static Bool intel_present_event_match(void *data, void *match_data) { struct intel_present_vblank_event *event = data; uint64_t *match = match_data; return *match == event->event_id; } /* * Remove a pending vblank event from the DRM queue so that it is not reported * to the extension */ static void intel_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc) { ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_drm_abort(scrn, intel_present_event_match, &event_id); } /* * Flush our batch buffer when requested by the Present extension. */ static void intel_present_flush(WindowPtr window) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->flush_rendering) intel->flush_rendering(intel); } /* * Test to see if page flipping is possible on the target crtc */ static Bool intel_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *bo; if (!scrn->vtSema) return FALSE; if (intel->shadow_present) return FALSE; if (!intel->use_pageflipping) return FALSE; if (crtc && !intel_crtc_on(crtc->devPrivate)) return FALSE; /* Check stride, can't change that on flip */ if (pixmap->devKind != intel->front_pitch) return FALSE; /* Make sure there's a bo we can get to */ bo = intel_get_pixmap_bo(pixmap); if (!bo) return FALSE; return TRUE; } /* * Once the flip has been completed on all pipes, notify the * extension code telling it when that happened */ static void intel_present_flip_event(uint64_t msc, uint64_t ust, void *pageflip_data) { struct intel_present_vblank_event *event = pageflip_data; present_event_notify(event->event_id, ust, msc); free(event); } /* * The flip has been aborted, free the structure */ static void intel_present_flip_abort(void *pageflip_data) { struct intel_present_vblank_event *event = pageflip_data; free(event); } /* * Queue a flip on 'crtc' to 'pixmap' at 'target_msc'. If 'sync_flip' is true, * then wait for vblank. Otherwise, flip immediately */ static Bool intel_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, PixmapPtr pixmap, Bool sync_flip) { ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_present_vblank_event *event; int pipe = intel_present_crtc_pipe(screen, crtc); dri_bo *bo; Bool ret; if (!intel_present_check_flip(crtc, screen->root, pixmap, sync_flip)) return FALSE; bo = intel_get_pixmap_bo(pixmap); if (!bo) return FALSE; event = calloc(1, sizeof(struct intel_present_vblank_event)); if (!event) return FALSE; event->event_id = event_id; ret = intel_do_pageflip(intel, bo, pipe, !sync_flip, event, intel_present_flip_event, intel_present_flip_abort); if (!ret) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n"); return ret; } /* * Queue a flip back to the normal frame buffer */ static void intel_present_unflip(ScreenPtr screen, uint64_t event_id) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); PixmapPtr pixmap = screen->GetScreenPixmap(screen); struct intel_present_vblank_event *event = NULL; dri_bo *bo; if (!intel_present_check_flip(NULL, screen->root, pixmap, true)) goto fail; bo = intel_get_pixmap_bo(pixmap); if (!bo) goto fail; event = calloc(1, sizeof(struct intel_present_vblank_event)); if (!event) goto fail; event->event_id = event_id; if (!intel_do_pageflip(intel, bo, -1, FALSE, event, intel_present_flip_event, intel_present_flip_abort)) goto fail; return; fail: xf86SetDesiredModes(scrn); present_event_notify(event_id, 0, 0); free(event); } static present_screen_info_rec intel_present_screen_info = { .version = PRESENT_SCREEN_INFO_VERSION, .get_crtc = intel_present_get_crtc, .get_ust_msc = intel_present_get_ust_msc, .queue_vblank = intel_present_queue_vblank, .abort_vblank = intel_present_abort_vblank, .flush = intel_present_flush, .capabilities = PresentCapabilityNone, .check_flip = intel_present_check_flip, .flip = intel_present_flip, .unflip = intel_present_unflip, }; static Bool intel_present_has_async_flip(ScreenPtr screen) { #ifdef DRM_CAP_ASYNC_PAGE_FLIP ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); int ret; uint64_t value; ret = drmGetCap(intel->drmSubFD, DRM_CAP_ASYNC_PAGE_FLIP, &value); if (ret == 0) return value == 1; #endif return FALSE; } Bool intel_present_screen_init(ScreenPtr screen) { if (intel_present_has_async_flip(screen)) intel_present_screen_info.capabilities |= PresentCapabilityAsync; return present_screen_init(screen, &intel_present_screen_info); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_sync.c000066400000000000000000000100671267532330400241760ustar00rootroot00000000000000/* * Copyright © 2013-2014 Intel Corporation * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "intel.h" #include "misyncshm.h" #include "misyncstr.h" /* * This whole file exists to wrap a sync fence trigger operation * so that we can flush the batch buffer to provide serialization * between the server and the shm fence client */ static DevPrivateKeyRec intel_sync_fence_private_key; typedef struct _intel_sync_fence_private { SyncFenceSetTriggeredFunc set_triggered; } intel_sync_fence_private; #define SYNC_FENCE_PRIV(pFence) \ (intel_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &intel_sync_fence_private_key) static void intel_sync_fence_set_triggered (SyncFence *fence) { ScreenPtr screen = fence->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence); /* Flush pending rendering operations */ if (intel->flush_rendering) intel->flush_rendering(intel); fence->funcs.SetTriggered = private->set_triggered; fence->funcs.SetTriggered(fence); private->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = intel_sync_fence_set_triggered; } static void intel_sync_create_fence(ScreenPtr screen, SyncFence *fence, Bool initially_triggered) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence); screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence; screen_funcs->CreateFence(screen, fence, initially_triggered); intel->save_sync_screen_funcs.CreateFence = screen_funcs->CreateFence; screen_funcs->CreateFence = intel_sync_create_fence; private->set_triggered = fence->funcs.SetTriggered; fence->funcs.SetTriggered = intel_sync_fence_set_triggered; } Bool intel_sync_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); SyncScreenFuncsPtr screen_funcs; if (!miSyncShmScreenInit(screen)) return FALSE; if (!dixPrivateKeyRegistered(&intel_sync_fence_private_key)) { if (!dixRegisterPrivateKey(&intel_sync_fence_private_key, PRIVATE_SYNC_FENCE, sizeof (intel_sync_fence_private))) return FALSE; } screen_funcs = miSyncGetScreenFuncs(screen); intel->save_sync_screen_funcs.CreateFence = screen_funcs->CreateFence; screen_funcs->CreateFence = intel_sync_create_fence; return TRUE; } void intel_sync_close(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); if (screen_funcs) screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_uxa.c000066400000000000000000001112161267532330400240150ustar00rootroot00000000000000/************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. All Rights Reserved. Copyright (c) 2005 Jesse Barnes Based on code from i830_xaa.c. 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. **************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xorg-server.h" #include #include #include #include #include #include #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" #include "i915_drm.h" #include "brw_defines.h" static const int I830CopyROP[16] = { ROP_0, /* GXclear */ ROP_DSa, /* GXand */ ROP_SDna, /* GXandReverse */ ROP_S, /* GXcopy */ ROP_DSna, /* GXandInverted */ ROP_D, /* GXnoop */ ROP_DSx, /* GXxor */ ROP_DSo, /* GXor */ ROP_DSon, /* GXnor */ ROP_DSxn, /* GXequiv */ ROP_Dn, /* GXinvert */ ROP_SDno, /* GXorReverse */ ROP_Sn, /* GXcopyInverted */ ROP_DSno, /* GXorInverted */ ROP_DSan, /* GXnand */ ROP_1 /* GXset */ }; static const int I830PatternROP[16] = { ROP_0, ROP_DPa, ROP_PDna, ROP_P, ROP_DPna, ROP_D, ROP_DPx, ROP_DPo, ROP_DPon, ROP_PDxn, ROP_Dn, ROP_PDno, ROP_Pn, ROP_DPno, ROP_DPan, ROP_1 }; #if HAS_DEVPRIVATEKEYREC DevPrivateKeyRec uxa_pixmap_index; #else int uxa_pixmap_index; #endif static void gen6_context_switch(intel_screen_private *intel, int new_mode) { intel_batch_submit(intel->scrn); } static void gen5_context_switch(intel_screen_private *intel, int new_mode) { /* Ironlake has a limitation that a 3D or Media command can't * be the first command after a BLT, unless it's * non-pipelined. Instead of trying to track it and emit a * command at the right time, we just emit a dummy * non-pipelined 3D instruction after each blit. */ if (new_mode == I915_EXEC_BLT) { OUT_BATCH(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); } else { OUT_BATCH(CMD_POLY_STIPPLE_OFFSET << 16); OUT_BATCH(0); } } static void gen4_context_switch(intel_screen_private *intel, int new_mode) { if (new_mode == I915_EXEC_BLT) { OUT_BATCH(MI_FLUSH | MI_STATE_INSTRUCTION_CACHE_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); } } Bool intel_uxa_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, int num_bos) { intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->batch_bo == NULL) { intel_uxa_debug_fallback(scrn, "VT inactive\n"); return FALSE; } bo_table[0] = intel->batch_bo; if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) { intel_batch_submit(scrn); bo_table[0] = intel->batch_bo; if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) { intel_uxa_debug_fallback(scrn, "Couldn't get aperture " "space for BOs\n"); return FALSE; } } return TRUE; } static Bool intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask) { ScrnInfoPtr scrn = xf86ScreenToScrn(drawable->pScreen); if (!UXA_PM_IS_SOLID(drawable, planemask)) { intel_uxa_debug_fallback(scrn, "planemask is not solid\n"); return FALSE; } switch (drawable->bitsPerPixel) { case 8: case 16: case 32: break; default: return FALSE; } return TRUE; } /** * Sets up hardware state for a series of solid fills. */ static Bool intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ intel_uxa_get_pixmap_bo(pixmap), }; if (!intel_uxa_check_pitch_2d(pixmap)) return FALSE; if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) return FALSE; intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16; switch (pixmap->drawable.bitsPerPixel) { case 8: break; case 16: /* RGB565 */ intel->BR[13] |= (1 << 24); break; case 32: /* RGB8888 */ intel->BR[13] |= ((1 << 24) | (1 << 25)); break; } intel->BR[16] = fg; return TRUE; } static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); unsigned long pitch; uint32_t cmd; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > pixmap->drawable.width) x2 = pixmap->drawable.width; if (y2 > pixmap->drawable.height) y2 = pixmap->drawable.height; if (x2 <= x1 || y2 <= y1) return; pitch = intel_pixmap_pitch(pixmap); { int len = INTEL_INFO(intel)->gen >= 0100 ? 7 : 6; BEGIN_BATCH_BLT(len); cmd = XY_COLOR_BLT_CMD | (len - 2); if (pixmap->drawable.bitsPerPixel == 32) cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; if (INTEL_INFO(intel)->gen >= 040 && intel_uxa_pixmap_tiled(pixmap)) { assert((pitch % 512) == 0); pitch >>= 2; cmd |= XY_COLOR_BLT_TILED; } OUT_BATCH(cmd); OUT_BATCH(intel->BR[13] | pitch); OUT_BATCH((y1 << 16) | (x1 & 0xffff)); OUT_BATCH((y2 << 16) | (x2 & 0xffff)); OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(intel->BR[16]); ADVANCE_BATCH(); } } /** * TODO: * - support planemask using FULL_BLT_CMD? */ static Bool intel_uxa_check_copy(PixmapPtr source, PixmapPtr dest, int alu, Pixel planemask) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) { intel_uxa_debug_fallback(scrn, "planemask is not solid"); return FALSE; } if (source->drawable.bitsPerPixel != dest->drawable.bitsPerPixel) { intel_uxa_debug_fallback(scrn, "mixed bpp copies unsupported\n"); return FALSE; } switch (source->drawable.bitsPerPixel) { case 8: case 16: case 32: break; default: return FALSE; } if (!intel_uxa_check_pitch_2d(source)) return FALSE; if (!intel_uxa_check_pitch_2d(dest)) return FALSE; return TRUE; } static Bool intel_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, int ydir, int alu, Pixel planemask) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ intel_uxa_get_pixmap_bo(source), intel_uxa_get_pixmap_bo(dest), }; if (!intel_uxa_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) return FALSE; intel->render_source = source; intel->BR[13] = I830CopyROP[alu] << 16; switch (source->drawable.bitsPerPixel) { case 8: break; case 16: intel->BR[13] |= (1 << 24); break; case 32: intel->BR[13] |= ((1 << 25) | (1 << 24)); break; } return TRUE; } static void intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1, int dst_y1, int w, int h) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t cmd; int dst_x2, dst_y2, src_x2, src_y2; unsigned int dst_pitch, src_pitch; dst_x2 = dst_x1 + w; dst_y2 = dst_y1 + h; /* XXX Fixup extents as a lamentable workaround for missing * source clipping in the upper layers. */ if (dst_x1 < 0) src_x1 -= dst_x1, dst_x1 = 0; if (dst_y1 < 0) src_y1 -= dst_y1, dst_y1 = 0; if (dst_x2 > dest->drawable.width) dst_x2 = dest->drawable.width; if (dst_y2 > dest->drawable.height) dst_y2 = dest->drawable.height; src_x2 = src_x1 + (dst_x2 - dst_x1); src_y2 = src_y1 + (dst_y2 - dst_y1); if (src_x1 < 0) dst_x1 -= src_x1, src_x1 = 0; if (src_y1 < 0) dst_y1 -= src_y1, src_y1 = 0; if (src_x2 > intel->render_source->drawable.width) dst_x2 -= src_x2 - intel->render_source->drawable.width; if (src_y2 > intel->render_source->drawable.height) dst_y2 -= src_y2 - intel->render_source->drawable.height; if (dst_x2 <= dst_x1 || dst_y2 <= dst_y1) return; dst_pitch = intel_pixmap_pitch(dest); src_pitch = intel_pixmap_pitch(intel->render_source); { int len = INTEL_INFO(intel)->gen >= 0100 ? 10 : 8; BEGIN_BATCH_BLT(len); cmd = XY_SRC_COPY_BLT_CMD | (len - 2); if (dest->drawable.bitsPerPixel == 32) cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; if (INTEL_INFO(intel)->gen >= 040) { if (intel_uxa_pixmap_tiled(dest)) { assert((dst_pitch % 512) == 0); dst_pitch >>= 2; cmd |= XY_SRC_COPY_BLT_DST_TILED; } if (intel_uxa_pixmap_tiled(intel->render_source)) { assert((src_pitch % 512) == 0); src_pitch >>= 2; cmd |= XY_SRC_COPY_BLT_SRC_TILED; } } OUT_BATCH(cmd); OUT_BATCH(intel->BR[13] | dst_pitch); OUT_BATCH((dst_y1 << 16) | (dst_x1 & 0xffff)); OUT_BATCH((dst_y2 << 16) | (dst_x2 & 0xffff)); OUT_RELOC_PIXMAP_FENCED(dest, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH((src_y1 << 16) | (src_x1 & 0xffff)); OUT_BATCH(src_pitch); OUT_RELOC_PIXMAP_FENCED(intel->render_source, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); } } static void intel_uxa_done(PixmapPtr pixmap) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); if (INTEL_INFO(intel)->gen >= 060) { /* workaround a random BLT hang */ BEGIN_BATCH_BLT(3); OUT_BATCH(XY_SETUP_CLIP_BLT_CMD | (3 - 2)); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } intel_uxa_debug_flush(scrn); } /** * Do any cleanup from the Composite operation. * * This is shared between i830 through i965. */ static void i830_done_composite(PixmapPtr dest) { ScrnInfoPtr scrn = xf86ScreenToScrn(dest->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->vertex_flush) intel->vertex_flush(intel); intel_uxa_debug_flush(scrn); } #define xFixedToFloat(val) \ ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)) static Bool _intel_transform_point(PictTransformPtr transform, float x, float y, float result[3]) { int j; for (j = 0; j < 3; j++) { result[j] = (xFixedToFloat(transform->matrix[j][0]) * x + xFixedToFloat(transform->matrix[j][1]) * y + xFixedToFloat(transform->matrix[j][2])); } if (!result[2]) return FALSE; return TRUE; } /** * Returns the floating-point coordinates transformed by the given transform. * * transform may be null. */ Bool intel_uxa_get_transformed_coordinates(int x, int y, PictTransformPtr transform, float *x_out, float *y_out) { if (transform == NULL) { *x_out = x; *y_out = y; } else { float result[3]; if (!_intel_transform_point(transform, x, y, result)) return FALSE; *x_out = result[0] / result[2]; *y_out = result[1] / result[2]; } return TRUE; } /** * Returns the un-normalized floating-point coordinates transformed by the given transform. * * transform may be null. */ Bool intel_uxa_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, float *x_out, float *y_out, float *w_out) { if (transform == NULL) { *x_out = x; *y_out = y; *w_out = 1; } else { float result[3]; if (!_intel_transform_point(transform, x, y, result)) return FALSE; *x_out = result[0]; *y_out = result[1]; *w_out = result[2]; } return TRUE; } /** * Returns whether the provided transform is affine. * * transform may be null. */ Bool intel_uxa_transform_is_affine(PictTransformPtr t) { if (t == NULL) return TRUE; return t->matrix[2][0] == 0 && t->matrix[2][1] == 0; } dri_bo *intel_uxa_get_pixmap_bo(PixmapPtr pixmap) { struct intel_uxa_pixmap *intel; intel = intel_uxa_get_pixmap_private(pixmap); if (intel == NULL) return NULL; return intel->bo; } static unsigned intel_get_tile_width(intel_screen_private *intel, int tiling, int pitch) { unsigned long tile_width; if (tiling == I915_TILING_NONE) return 4; tile_width = (tiling == I915_TILING_Y) ? 128 : 512; if (INTEL_INFO(intel)->gen >= 040) return tile_width; while (tile_width < pitch) tile_width <<= 1; return tile_width; } void intel_uxa_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL && bo == NULL) return; if (priv != NULL) { if (priv->bo == bo) return; free_priv: dri_bo_unreference(priv->bo); list_del(&priv->batch); free(priv); priv = NULL; } if (bo != NULL) { uint32_t tiling, swizzle_mode; unsigned tile_width; int size, stride; priv = calloc(1, sizeof (struct intel_uxa_pixmap)); if (priv == NULL) goto BAIL; list_init(&priv->batch); dri_bo_reference(bo); priv->bo = bo; if (drm_intel_bo_get_tiling(bo, &tiling, &swizzle_mode)) { bo = NULL; goto free_priv; } priv->tiling = tiling; priv->busy = -1; priv->offscreen = 1; stride = (pixmap->drawable.width * pixmap->drawable.bitsPerPixel + 7) / 8; tile_width = intel_get_tile_width(intel, tiling, stride); stride = ALIGN(stride, tile_width); if (intel_pixmap_pitch(pixmap) < stride || intel_pixmap_pitch(pixmap) & (tile_width - 1) || intel_pixmap_pitch(pixmap) >= KB(32)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s: stride on buffer object does not match constraints: stride=%d, must be greater than %d, but less than %d, and have alignment at least %d\n", __FUNCTION__, intel_pixmap_pitch(pixmap), stride, KB(32), tile_width); bo = NULL; goto free_priv; } if (tiling != I915_TILING_NONE) { int height; if (IS_GEN2(intel)) height = 16; else if (tiling == I915_TILING_X) height = 8; else height = 32; height = ALIGN(pixmap->drawable.height, height); size = intel_get_fence_size(intel, intel_pixmap_pitch(pixmap) * height); } else size = intel_pixmap_pitch(pixmap) * pixmap->drawable.height; if (bo->size < size || bo->size > intel->max_bo_size) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "%s: size of buffer object does not match constraints: size=%ld, must be greater than %d, but less than %d\n", __FUNCTION__, (long)bo->size, size, intel->max_bo_size); bo = NULL; goto free_priv; } } BAIL: intel_uxa_set_pixmap_private(pixmap, priv); } static Bool intel_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); dri_bo *bo = priv->bo; int ret; /* When falling back to swrast, flush all pending operations */ if (access == UXA_ACCESS_RW || priv->dirty) intel_batch_submit(scrn); assert(bo->size <= intel->max_gtt_map_size); ret = drm_intel_gem_bo_map_gtt(bo); if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: bo map (use gtt? %d, access %d) failed: %s\n", __FUNCTION__, priv->tiling || bo->size <= intel->max_gtt_map_size, access, strerror(-ret)); return FALSE; } pixmap->devPrivate.ptr = bo->virtual; priv->busy = 0; return TRUE; } static void intel_uxa_finish_access(PixmapPtr pixmap, uxa_access_t access) { struct intel_uxa_pixmap *priv; priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL) return; drm_intel_gem_bo_unmap_gtt(priv->bo); pixmap->devPrivate.ptr = NULL; } static Bool intel_uxa_pixmap_put_image(PixmapPtr pixmap, char *src, int src_pitch, int x, int y, int w, int h) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); int stride = intel_pixmap_pitch(pixmap); int cpp = pixmap->drawable.bitsPerPixel/8; int ret = FALSE; if (priv == NULL || priv->bo == NULL) return FALSE; if (priv->tiling == I915_TILING_NONE && (h == 1 || (src_pitch == stride && w == pixmap->drawable.width))) { return drm_intel_bo_subdata(priv->bo, y*stride + x*cpp, stride*(h-1) + w*cpp, src) == 0; } else if (drm_intel_gem_bo_map_gtt(priv->bo) == 0) { char *dst = priv->bo->virtual; int row_length = w * cpp; int num_rows = h; if (row_length == src_pitch && src_pitch == stride) num_rows = 1, row_length *= h; dst += y * stride + x * cpp; do { memcpy (dst, src, row_length); src += src_pitch; dst += stride; } while (--num_rows); drm_intel_gem_bo_unmap_gtt(priv->bo); ret = TRUE; } return ret; } static Bool intel_uxa_put_image(PixmapPtr pixmap, int x, int y, int w, int h, char *src, int src_pitch) { struct intel_uxa_pixmap *priv; priv = intel_uxa_get_pixmap_private(pixmap); if (!intel_uxa_pixmap_is_busy(priv)) { /* bo is not busy so can be replaced without a stall, upload in-place. */ return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, x, y, w, h); } else { ScreenPtr screen = pixmap->drawable.pScreen; if (!priv->pinned && x == 0 && y == 0 && w == pixmap->drawable.width && h == pixmap->drawable.height) { intel_screen_private *intel = intel_get_screen_private(xf86ScreenToScrn(screen)); uint32_t tiling = priv->tiling; int size, stride; dri_bo *bo; /* Replace busy bo. */ size = intel_compute_size(intel, w, h, pixmap->drawable.bitsPerPixel, pixmap->usage_hint, &tiling, &stride); if (size > intel->max_gtt_map_size) return FALSE; bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0); if (bo == NULL) return FALSE; if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(bo, &tiling, stride); priv->tiling = tiling; screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); intel_uxa_set_pixmap_bo(pixmap, bo); dri_bo_unreference(bo); return intel_uxa_pixmap_put_image(pixmap, src, src_pitch, 0, 0, w, h); } else { PixmapPtr scratch; Bool ret; /* Upload to a linear buffer and queue a blit. */ scratch = (*screen->CreatePixmap)(screen, w, h, pixmap->drawable.depth, UXA_CREATE_PIXMAP_FOR_MAP); if (!scratch) return FALSE; if (!intel_uxa_pixmap_is_offscreen(scratch)) { screen->DestroyPixmap(scratch); return FALSE; } ret = intel_uxa_pixmap_put_image(scratch, src, src_pitch, 0, 0, w, h); if (ret) { GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen); if (gc) { ValidateGC(&pixmap->drawable, gc); (*gc->ops->CopyArea)(&scratch->drawable, &pixmap->drawable, gc, 0, 0, w, h, x, y); FreeScratchGC(gc); } else ret = FALSE; } (*screen->DestroyPixmap)(scratch); return ret; } } } static Bool intel_uxa_pixmap_get_image(PixmapPtr pixmap, int x, int y, int w, int h, char *dst, int dst_pitch) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); int stride = intel_pixmap_pitch(pixmap); int cpp = pixmap->drawable.bitsPerPixel/8; /* assert(priv->tiling == I915_TILING_NONE); */ if (h == 1 || (dst_pitch == stride && w == pixmap->drawable.width)) { return drm_intel_bo_get_subdata(priv->bo, y*stride + x*cpp, (h-1)*stride + w*cpp, dst) == 0; } else { char *src; if (drm_intel_gem_bo_map_gtt(priv->bo)) return FALSE; src = (char *) priv->bo->virtual + y * stride + x * cpp; w *= cpp; do { memcpy(dst, src, w); src += stride; dst += dst_pitch; } while (--h); drm_intel_gem_bo_unmap_gtt(priv->bo); return TRUE; } } static Bool intel_uxa_get_image(PixmapPtr pixmap, int x, int y, int w, int h, char *dst, int dst_pitch) { struct intel_uxa_pixmap *priv; PixmapPtr scratch = NULL; Bool ret; /* The presumption is that we wish to keep the target hot, so * copy to a new bo and move that to the CPU in preference to * causing ping-pong of the original. * * Also the gpu is much faster at detiling. */ priv = intel_uxa_get_pixmap_private(pixmap); if (intel_uxa_pixmap_is_busy(priv) || priv->tiling != I915_TILING_NONE) { ScreenPtr screen = pixmap->drawable.pScreen; GCPtr gc; /* Copy to a linear buffer and pull. */ scratch = screen->CreatePixmap(screen, w, h, pixmap->drawable.depth, INTEL_CREATE_PIXMAP_TILING_NONE); if (!scratch) return FALSE; if (!intel_uxa_pixmap_is_offscreen(scratch)) { screen->DestroyPixmap(scratch); return FALSE; } gc = GetScratchGC(pixmap->drawable.depth, screen); if (!gc) { screen->DestroyPixmap(scratch); return FALSE; } ValidateGC(&pixmap->drawable, gc); gc->ops->CopyArea(&pixmap->drawable, &scratch->drawable, gc, x, y, w, h, 0, 0); FreeScratchGC(gc); intel_batch_submit(xf86ScreenToScrn(screen)); x = y = 0; pixmap = scratch; } ret = intel_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch); if (scratch) scratch->drawable.pScreen->DestroyPixmap(scratch); return ret; } static CARD32 intel_cache_expire(OsTimerPtr timer, CARD32 now, pointer data) { intel_screen_private *intel = data; /* We just want to create and destroy a bo as this causes libdrm * to reap its caches. However, since we can't remove that buffer * from the cache due to its own activity, we want to use something * that we know we will reuse later. The most frequently reused buffer * we have is the batchbuffer, and the best way to trigger its * reallocation is to submit a flush. */ intel_batch_emit_flush(intel->scrn); intel_batch_submit(intel->scrn); return 0; } static void intel_flush_rendering(intel_screen_private *intel) { if (intel->needs_flush == 0) return; if (intel->has_kernel_flush) { intel_batch_submit(intel->scrn); drm_intel_bo_busy(intel->front_buffer); } else { intel_batch_emit_flush(intel->scrn); intel_batch_submit(intel->scrn); } intel->cache_expire = TimerSet(intel->cache_expire, 0, 3000, intel_cache_expire, intel); intel->needs_flush = 0; } static void intel_throttle(intel_screen_private *intel) { drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE); } void intel_uxa_block_handler(intel_screen_private *intel) { /* Emit a flush of the rendering cache, or on the 965 * and beyond rendering results may not hit the * framebuffer until significantly later. */ intel_flush_rendering(intel); intel_throttle(intel); } static PixmapPtr intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth, unsigned usage) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; PixmapPtr pixmap, new_pixmap = NULL; if (w > 32767 || h > 32767) return NullPixmap; if (depth == 1 || intel->force_fallback) return fbCreatePixmap(screen, w, h, depth, usage); if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32) return fbCreatePixmap(screen, w, h, depth, usage); pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); if (pixmap == NullPixmap) return pixmap; if (w && h) { unsigned int size, tiling; int stride; /* Always attempt to tile, compute_size() will remove the * tiling for pixmaps that are either too large or too small * to be effectively tiled. */ tiling = I915_TILING_X; if (usage & INTEL_CREATE_PIXMAP_TILING_Y) tiling = I915_TILING_Y; if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage & INTEL_CREATE_PIXMAP_TILING_NONE) tiling = I915_TILING_NONE; #ifdef CREATE_PIXMAP_USAGE_SHARED if (usage == CREATE_PIXMAP_USAGE_SHARED) tiling = I915_TILING_NONE; #endif /* if tiling is off force to none */ if (!intel->tiling) tiling = I915_TILING_NONE; if (tiling != I915_TILING_NONE && !(usage & INTEL_CREATE_PIXMAP_DRI2)) { if (h <= 4) tiling = I915_TILING_NONE; if (h <= 16 && tiling == I915_TILING_Y) tiling = I915_TILING_X; } size = intel_compute_size(intel, w, h, pixmap->drawable.bitsPerPixel, usage, &tiling, &stride); /* Fail very large allocations. Large BOs will tend to hit SW fallbacks * frequently, and also will tend to fail to successfully map when doing * SW fallbacks because we overcommit address space for BO access. */ if (size > intel->max_bo_size || stride >= KB(32)) goto fallback_pixmap; priv = calloc(1, sizeof (struct intel_uxa_pixmap)); if (priv == NULL) goto fallback_pixmap; if (usage == UXA_CREATE_PIXMAP_FOR_MAP) { priv->busy = 0; priv->bo = drm_intel_bo_alloc(intel->bufmgr, "pixmap", size, 0); } else { priv->busy = -1; priv->bo = drm_intel_bo_alloc_for_render(intel->bufmgr, "pixmap", size, 0); } if (!priv->bo) goto fallback_priv; if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(priv->bo, &tiling, stride); priv->tiling = tiling; priv->offscreen = 1; list_init(&priv->batch); intel_uxa_set_pixmap_private(pixmap, priv); screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL); } return pixmap; fallback_priv: free(priv); fallback_pixmap: fbDestroyPixmap(pixmap); if (new_pixmap) return new_pixmap; else return fbCreatePixmap(screen, w, h, depth, usage); } static Bool intel_uxa_destroy_pixmap(PixmapPtr pixmap) { if (pixmap->refcnt == 1) intel_uxa_set_pixmap_bo(pixmap, NULL); fbDestroyPixmap(pixmap); return TRUE; } Bool intel_uxa_create_screen_resources(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); PixmapPtr pixmap; intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *bo = intel->front_buffer, *old_bo; int old_width, old_height, old_pitch; if (!uxa_resources_init(screen)) return FALSE; if (drm_intel_gem_bo_map_gtt(bo)) return FALSE; pixmap = screen->GetScreenPixmap(screen); old_width = pixmap->drawable.width; old_height = pixmap->drawable.height; old_pitch = pixmap->devKind; old_bo = intel_uxa_get_pixmap_bo(pixmap); if (!screen->ModifyPixmapHeader(pixmap, scrn->virtualX, scrn->virtualY, -1, -1, intel->front_pitch, NULL)) return FALSE; intel_uxa_set_pixmap_bo(pixmap, bo); if (intel_uxa_get_pixmap_private(pixmap) == NULL) goto err; intel_uxa_get_pixmap_private(pixmap)->pinned |= PIN_SCANOUT; scrn->displayWidth = intel->front_pitch / intel->cpp; return TRUE; err: screen->ModifyPixmapHeader(pixmap, old_width, old_height, -1, -1, old_pitch, NULL); if (old_bo) intel_uxa_set_pixmap_bo(pixmap, old_bo); return FALSE; } #ifdef CREATE_PIXMAP_USAGE_SHARED static Bool intel_uxa_share_pixmap_backing(PixmapPtr ppix, ScreenPtr slave, void **fd_handle) { ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(ppix); unsigned int size, tiling, swizzle; dri_bo *bo = intel_uxa_get_pixmap_bo(ppix), *newbo; int stride; int handle; if (drm_intel_bo_references(intel->batch_bo, bo)) intel_batch_submit(intel->scrn); drm_intel_bo_get_tiling(bo, &tiling, &swizzle); if (tiling == I915_TILING_X) { if (priv->pinned) return FALSE; tiling = I915_TILING_NONE; size = intel_compute_size(intel, ppix->drawable.width, ppix->drawable.height, ppix->drawable.bitsPerPixel, INTEL_CREATE_PIXMAP_DRI2, &tiling, &stride); newbo = drm_intel_bo_alloc_for_render(intel->bufmgr, "pixmap", size, 0); if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(newbo, &tiling, stride); priv->tiling = tiling; intel_uxa_set_pixmap_bo(ppix, newbo); ppix->drawable.pScreen->ModifyPixmapHeader(ppix, ppix->drawable.width, ppix->drawable.height, 0, 0, stride, NULL); bo = newbo; } drm_intel_bo_get_tiling(bo, &tiling, &swizzle); drm_intel_bo_gem_export_to_prime(bo, &handle); priv->pinned |= PIN_PRIME; *fd_handle = (void *)(long)handle; return TRUE; } static Bool intel_uxa_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle) { ScrnInfoPtr scrn = xf86ScreenToScrn(ppix->drawable.pScreen); intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *bo; int ihandle = (int)(long)fd_handle; /* force untiled for now */ bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, ihandle, 0); if (!bo) return FALSE; intel_uxa_set_pixmap_bo(ppix, bo); close(ihandle); return TRUE; } #endif static void intel_limits_init(intel_screen_private *intel) { /* Limits are described in the BLT engine chapter under Graphics Data Size * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO, * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO. * * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768. * * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled. * i965 limits 3D surface to 4kB-aligned offset if tiled. * i965 limits 3D surfaces to w,h of ?,8192. * i965 limits 3D surface to pitch of 1B - 128kB. * i965 limits 3D surface pitch alignment to 1 or 2 times the element size. * i965 limits 3D surface pitch alignment to 512B if tiled. * i965 limits 3D destination drawing rect to w,h of 8192,8192. * * i915 limits 3D textures to 4B-aligned offset if un-tiled. * i915 limits 3D textures to ~4kB-aligned offset if tiled. * i915 limits 3D textures to width,height of 2048,2048. * i915 limits 3D textures to pitch of 16B - 8kB, in dwords. * i915 limits 3D destination to ~4kB-aligned offset if tiled. * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled. * i915 limits 3D destination to pitch 64B-aligned if used with depth. * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled. * i915 limits 3D destination to POT aligned pitch if tiled. * i915 limits 3D destination drawing rect to w,h of 2048,2048. * * i845 limits 3D textures to 4B-aligned offset if un-tiled. * i845 limits 3D textures to ~4kB-aligned offset if tiled. * i845 limits 3D textures to width,height of 2048,2048. * i845 limits 3D textures to pitch of 4B - 8kB, in dwords. * i845 limits 3D destination to 4B-aligned offset if un-tiled. * i845 limits 3D destination to ~4kB-aligned offset if tiled. * i845 limits 3D destination to pitch of 8B - 8kB, in dwords. * i845 limits 3D destination drawing rect to w,h of 2048,2048. * * For the tiled issues, the only tiled buffer we draw to should be * the front, which will have an appropriate pitch/offset already set up, * so UXA doesn't need to worry. */ if (INTEL_INFO(intel)->gen >= 040) { intel->accel_pixmap_offset_alignment = 4 * 2; intel->accel_max_x = 8192; intel->accel_max_y = 8192; } else { intel->accel_pixmap_offset_alignment = 4; intel->accel_max_x = 2048; intel->accel_max_y = 2048; } } static Bool intel_option_accel_none(intel_screen_private *intel) { const char *s; s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD); if (s == NULL) return IS_DEFAULT_ACCEL_METHOD(NOACCEL); return strcasecmp(s, "none") == 0; } static Bool intel_option_accel_blt(intel_screen_private *intel) { const char *s; s = xf86GetOptValString(intel->Options, OPTION_ACCEL_METHOD); if (s == NULL) return FALSE; return strcasecmp(s, "blt") == 0; } /** * Intialiazes the hardware for the 3D pipeline use in the 2D driver. * * Some state caching is performed to avoid redundant state emits. This * function is also responsible for marking the state as clobbered for DRI * clients. */ void IntelEmitInvarientState(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); /* If we've emitted our state since the last clobber by another client, * skip it. */ if (intel->last_3d != LAST_3D_OTHER) return; if (IS_GEN2(intel)) I830EmitInvarientState(scrn); else if IS_GEN3(intel) I915EmitInvarientState(scrn); } Bool intel_uxa_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); intel_batch_init(scrn); if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100) gen4_render_state_init(scrn); #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&uxa_pixmap_index, PRIVATE_PIXMAP, 0)) #else if (!dixRequestPrivate(&uxa_pixmap_index, 0)) #endif return FALSE; intel_limits_init(intel); intel->uxa_driver = uxa_driver_alloc(); if (intel->uxa_driver == NULL) return FALSE; memset(intel->uxa_driver, 0, sizeof(*intel->uxa_driver)); intel->uxa_driver->uxa_major = 1; intel->uxa_driver->uxa_minor = 0; intel->prim_offset = 0; intel->vertex_count = 0; intel->vertex_offset = 0; intel->vertex_used = 0; intel->floats_per_vertex = 0; intel->last_floats_per_vertex = 0; intel->vertex_bo = NULL; intel->surface_used = 0; intel->surface_reloc = 0; /* Solid fill */ intel->uxa_driver->check_solid = intel_uxa_check_solid; intel->uxa_driver->prepare_solid = intel_uxa_prepare_solid; intel->uxa_driver->solid = intel_uxa_solid; intel->uxa_driver->done_solid = intel_uxa_done; /* Copy */ intel->uxa_driver->check_copy = intel_uxa_check_copy; intel->uxa_driver->prepare_copy = intel_uxa_prepare_copy; intel->uxa_driver->copy = intel_uxa_copy; intel->uxa_driver->done_copy = intel_uxa_done; /* Composite */ if (intel_option_accel_blt(intel)) { } else if (INTEL_INFO(intel)->gen < 030) { intel->uxa_driver->check_composite = i830_check_composite; intel->uxa_driver->check_composite_target = i830_check_composite_target; intel->uxa_driver->check_composite_texture = i830_check_composite_texture; intel->uxa_driver->prepare_composite = i830_prepare_composite; intel->uxa_driver->composite = i830_composite; intel->uxa_driver->done_composite = i830_done_composite; intel->vertex_flush = i830_vertex_flush; intel->batch_commit_notify = i830_batch_commit_notify; } else if (INTEL_INFO(intel)->gen < 040) { intel->uxa_driver->check_composite = i915_check_composite; intel->uxa_driver->check_composite_target = i915_check_composite_target; intel->uxa_driver->check_composite_texture = i915_check_composite_texture; intel->uxa_driver->prepare_composite = i915_prepare_composite; intel->uxa_driver->composite = i915_composite; intel->uxa_driver->done_composite = i830_done_composite; intel->vertex_flush = i915_vertex_flush; intel->batch_commit_notify = i915_batch_commit_notify; } else if (INTEL_INFO(intel)->gen < 0100) { intel->uxa_driver->check_composite = i965_check_composite; intel->uxa_driver->check_composite_texture = i965_check_composite_texture; intel->uxa_driver->prepare_composite = i965_prepare_composite; intel->uxa_driver->composite = i965_composite; intel->uxa_driver->done_composite = i830_done_composite; intel->vertex_flush = i965_vertex_flush; intel->batch_flush = i965_batch_flush; intel->batch_commit_notify = i965_batch_commit_notify; if (INTEL_INFO(intel)->gen < 050) { intel->context_switch = gen4_context_switch; } else if (INTEL_INFO(intel)->gen < 060) { intel->context_switch = gen5_context_switch; } else { intel->context_switch = gen6_context_switch; } } /* PutImage */ intel->uxa_driver->put_image = intel_uxa_put_image; intel->uxa_driver->get_image = intel_uxa_get_image; intel->uxa_driver->prepare_access = intel_uxa_prepare_access; intel->uxa_driver->finish_access = intel_uxa_finish_access; intel->uxa_driver->pixmap_is_offscreen = intel_uxa_pixmap_is_offscreen; screen->CreatePixmap = intel_uxa_create_pixmap; screen->DestroyPixmap = intel_uxa_destroy_pixmap; #ifdef CREATE_PIXMAP_USAGE_SHARED screen->SharePixmapBacking = intel_uxa_share_pixmap_backing; screen->SetSharedPixmapBacking = intel_uxa_set_shared_pixmap_backing; #endif if (!uxa_driver_init(screen, intel->uxa_driver)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "UXA initialization failed\n"); free(intel->uxa_driver); return FALSE; } if (intel_option_accel_none(intel)) intel->force_fallback = 1; uxa_set_fallback_debug(screen, intel->fallback_debug); uxa_set_force_fallback(screen, intel->force_fallback); intel->flush_rendering = intel_flush_rendering; return TRUE; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_uxa.h000066400000000000000000000246331267532330400240300ustar00rootroot00000000000000/* * Copyright © 2014 Keith Packard * * 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, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _INTEL_UXA_H_ #define _INTEL_UXA_H_ #include "intel_video.h" #include "uxa.h" struct intel_uxa_pixmap { dri_bo *bo; struct list batch; uint8_t tiling; int8_t busy :2; uint8_t dirty :1; uint8_t offscreen :1; uint8_t pinned :5; #define PIN_SCANOUT 0x1 #define PIN_DRI2 0x2 #define PIN_DRI3 0x4 #define PIN_PRIME 0x8 }; #if HAS_DEVPRIVATEKEYREC extern DevPrivateKeyRec uxa_pixmap_index; #else extern int uxa_pixmap_index; #endif static inline struct intel_uxa_pixmap *intel_uxa_get_pixmap_private(PixmapPtr pixmap) { #if HAS_DEVPRIVATEKEYREC return dixGetPrivate(&pixmap->devPrivates, &uxa_pixmap_index); #else return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index); #endif } static inline Bool intel_uxa_pixmap_is_busy(struct intel_uxa_pixmap *priv) { if (priv->busy == -1) priv->busy = drm_intel_bo_busy(priv->bo); return priv->busy; } static inline void intel_uxa_set_pixmap_private(PixmapPtr pixmap, struct intel_uxa_pixmap *intel) { dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel); } static inline Bool intel_uxa_pixmap_is_dirty(PixmapPtr pixmap) { return pixmap && intel_uxa_get_pixmap_private(pixmap)->dirty; } static inline Bool intel_uxa_pixmap_tiled(PixmapPtr pixmap) { return intel_uxa_get_pixmap_private(pixmap)->tiling != I915_TILING_NONE; } dri_bo *intel_uxa_get_pixmap_bo(PixmapPtr pixmap); void intel_uxa_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo); Bool intel_uxa_init(ScreenPtr pScreen); Bool intel_uxa_create_screen_resources(ScreenPtr pScreen); void intel_uxa_block_handler(intel_screen_private *intel); static inline Bool intel_uxa_pixmap_is_offscreen(PixmapPtr pixmap) { struct intel_uxa_pixmap *priv = intel_uxa_get_pixmap_private(pixmap); return priv && priv->offscreen; } /* Batchbuffer support macros and functions */ #include "intel_batchbuffer.h" /* I830 specific functions */ extern void IntelEmitInvarientState(ScrnInfoPtr scrn); extern void I830EmitInvarientState(ScrnInfoPtr scrn); extern void I915EmitInvarientState(ScrnInfoPtr scrn); extern void I830EmitFlush(ScrnInfoPtr scrn); /* i830_render.c */ Bool i830_check_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, int width, int height); Bool i830_check_composite_target(PixmapPtr pixmap); Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture); Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, PixmapPtr sourcecPixmap, PixmapPtr maskPixmap, PixmapPtr destPixmap); void i830_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); void i830_vertex_flush(intel_screen_private *intel); /* i915_render.c */ Bool i915_check_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, int width, int height); Bool i915_check_composite_target(PixmapPtr pixmap); Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture); Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, PixmapPtr sourcecPixmap, PixmapPtr maskPixmap, PixmapPtr destPixmap); void i915_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); void i915_vertex_flush(intel_screen_private *intel); void i915_batch_commit_notify(intel_screen_private *intel); void i830_batch_commit_notify(intel_screen_private *intel); /* i965_render.c */ unsigned int gen4_render_state_size(ScrnInfoPtr scrn); void gen4_render_state_init(ScrnInfoPtr scrn); void gen4_render_state_cleanup(ScrnInfoPtr scrn); Bool i965_check_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, int width, int height); Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture); Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask, PicturePtr dest, PixmapPtr sourcecPixmap, PixmapPtr maskPixmap, PixmapPtr destPixmap); void i965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h); void i965_vertex_flush(intel_screen_private *intel); void i965_batch_flush(intel_screen_private *intel); void i965_batch_commit_notify(intel_screen_private *intel); /* i965_3d.c */ void gen6_upload_invariant_states(intel_screen_private *intel); void gen6_upload_viewport_state_pointers(intel_screen_private *intel, drm_intel_bo *cc_vp_bo); void gen7_upload_viewport_state_pointers(intel_screen_private *intel, drm_intel_bo *cc_vp_bo); void gen6_upload_urb(intel_screen_private *intel); void gen7_upload_urb(intel_screen_private *intel); void gen6_upload_cc_state_pointers(intel_screen_private *intel, drm_intel_bo *blend_bo, drm_intel_bo *cc_bo, drm_intel_bo *depth_stencil_bo, uint32_t blend_offset); void gen7_upload_cc_state_pointers(intel_screen_private *intel, drm_intel_bo *blend_bo, drm_intel_bo *cc_bo, drm_intel_bo *depth_stencil_bo, uint32_t blend_offset); void gen6_upload_sampler_state_pointers(intel_screen_private *intel, drm_intel_bo *sampler_bo); void gen7_upload_sampler_state_pointers(intel_screen_private *intel, drm_intel_bo *sampler_bo); void gen7_upload_bypass_states(intel_screen_private *intel); void gen6_upload_gs_state(intel_screen_private *intel); void gen6_upload_vs_state(intel_screen_private *intel); void gen6_upload_clip_state(intel_screen_private *intel); void gen6_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset); void gen7_upload_sf_state(intel_screen_private *intel, int num_sf_outputs, int read_offset); void gen6_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset); void gen7_upload_binding_table(intel_screen_private *intel, uint32_t ps_binding_table_offset); void gen6_upload_depth_buffer_state(intel_screen_private *intel); void gen7_upload_depth_buffer_state(intel_screen_private *intel); Bool intel_uxa_transform_is_affine(PictTransformPtr t); Bool intel_uxa_get_transformed_coordinates(int x, int y, PictTransformPtr transform, float *x_out, float *y_out); Bool intel_uxa_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, float *x_out, float *y_out, float *z_out); static inline void intel_uxa_debug_fallback(ScrnInfoPtr scrn, const char *format, ...) _X_ATTRIBUTE_PRINTF(2, 3); static inline void intel_uxa_debug_fallback(ScrnInfoPtr scrn, const char *format, ...) { intel_screen_private *intel = intel_get_screen_private(scrn); va_list ap; va_start(ap, format); if (intel->fallback_debug) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "fallback: "); LogVMessageVerb(X_INFO, 1, format, ap); } va_end(ap); } static inline Bool intel_uxa_check_pitch_2d(PixmapPtr pixmap) { uint32_t pitch = intel_pixmap_pitch(pixmap); if (pitch > KB(32)) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_uxa_debug_fallback(scrn, "pitch exceeds 2d limit 32K\n"); return FALSE; } return TRUE; } /* For pre-965 chip only, as they have 8KB limit for 3D */ static inline Bool intel_uxa_check_pitch_3d(PixmapPtr pixmap) { uint32_t pitch = intel_pixmap_pitch(pixmap); if (pitch > KB(8)) { ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen); intel_uxa_debug_fallback(scrn, "pitch exceeds 3d limit 8K\n"); return FALSE; } return TRUE; } /** * Little wrapper around drm_intel_bo_reloc to return the initial value you * should stuff into the relocation entry. * * If only we'd done this before settling on the library API. */ static inline uint32_t intel_uxa_emit_reloc(drm_intel_bo * bo, uint32_t offset, drm_intel_bo * target_bo, uint32_t target_offset, uint32_t read_domains, uint32_t write_domain) { drm_intel_bo_emit_reloc(bo, offset, target_bo, target_offset, read_domains, write_domain); return target_bo->offset + target_offset; } static inline drm_intel_bo *intel_uxa_bo_alloc_for_data(intel_screen_private *intel, const void *data, unsigned int size, const char *name) { drm_intel_bo *bo; int ret; bo = drm_intel_bo_alloc(intel->bufmgr, name, size, 4096); assert(bo); ret = drm_intel_bo_subdata(bo, 0, size, data); assert(ret == 0); return bo; (void)ret; } void intel_uxa_debug_flush(ScrnInfoPtr scrn); Bool intel_uxa_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table, int num_bos); XF86VideoAdaptorPtr intel_uxa_video_setup_image_textured(ScreenPtr screen); void I915DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap); void I965DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap); void Gen6DisplayVideoTextured(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int id, RegionPtr dstRegion, short width, short height, int video_pitch, int video_pitch2, short src_w, short src_h, short drw_w, short drw_h, PixmapPtr pixmap); void i965_free_video(ScrnInfoPtr scrn); #endif /* _INTEL_UXA_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_uxa_video.c000066400000000000000000000265261267532330400252140ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane * David Dawes * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian * Offscreen Images: * Matt Sottek */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "xf86drm.h" #include "regionstr.h" #include "randrstr.h" #include "windowstr.h" #include "damage.h" #include "intel.h" #include "intel_uxa.h" #include "i830_reg.h" #include "xf86xv.h" #include #include "dixstruct.h" #include "fourcc.h" #ifdef INTEL_XVMC #define _INTEL_XVMC_SERVER_ #include "intel_xvmc.h" #endif /* overlay debugging printf function */ #if 0 #define UXA_VIDEO_DEBUG ErrorF #else #define UXA_VIDEO_DEBUG if (0) ErrorF #endif static int intel_uxa_video_put_image_textured(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char *, short, short, Bool, RegionPtr, pointer, DrawablePtr); static int intel_uxa_video_set_port_attribute(ScrnInfoPtr scrn, Atom attribute, INT32 value, pointer data) { intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; if (attribute == intel_xv_Brightness) { if ((value < -128) || (value > 127)) return BadValue; adaptor_priv->brightness = value; return Success; } else if (attribute == intel_xv_Contrast) { if ((value < 0) || (value > 255)) return BadValue; adaptor_priv->contrast = value; return Success; } else if (attribute == intel_xv_SyncToVblank) { if ((value < -1) || (value > 1)) return BadValue; adaptor_priv->SyncToVblank = value; return Success; } else { return BadMatch; } } static int xvmc_passthrough(int id) { #ifdef INTEL_XVMC return id == FOURCC_XVMC; #else return 0; #endif } static void intel_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap, xf86CrtcPtr crtc, RegionPtr clipBoxes) { intel_screen_private *intel = intel_get_screen_private(scrn); pixman_box16_t box, crtc_box; int pipe, event; Bool full_height; int y1, y2; pipe = -1; if (scrn->vtSema && pixmap_is_scanout(pixmap)) pipe = intel_crtc_to_pipe(crtc); if (pipe < 0) return; box = *REGION_EXTENTS(unused, clipBoxes); if (crtc->transform_in_use) pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, &box); /* We could presume the clip was correctly computed... */ intel_crtc_box(crtc, &crtc_box); intel_box_intersect(&box, &crtc_box, &box); /* * Make sure we don't wait for a scanline that will * never occur */ y1 = (crtc_box.y1 <= box.y1) ? box.y1 - crtc_box.y1 : 0; y2 = (box.y2 <= crtc_box.y2) ? box.y2 - crtc_box.y1 : crtc_box.y2 - crtc_box.y1; if (y2 <= y1) return; full_height = FALSE; if (y1 == 0 && y2 == (crtc_box.y2 - crtc_box.y1)) full_height = TRUE; /* * Pre-965 doesn't have SVBLANK, so we need a bit * of extra time for the blitter to start up and * do its job for a full height blit */ if (full_height && INTEL_INFO(intel)->gen < 040) y2 -= 2; if (pipe == 0) { pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; if (full_height && INTEL_INFO(intel)->gen >= 040) event = MI_WAIT_FOR_PIPEA_SVBLANK; } else { pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; if (full_height && INTEL_INFO(intel)->gen >= 040) event = MI_WAIT_FOR_PIPEB_SVBLANK; } if (crtc->mode.Flags & V_INTERLACE) { /* DSL count field lines */ y1 /= 2; y2 /= 2; } BEGIN_BATCH(5); /* The documentation says that the LOAD_SCAN_LINES command * always comes in pairs. Don't ask me why. */ OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe); OUT_BATCH((y1 << 16) | (y2-1)); OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | pipe); OUT_BATCH((y1 << 16) | (y2-1)); OUT_BATCH(MI_WAIT_FOR_EVENT | event); ADVANCE_BATCH(); } /* * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h). * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h). * id is a fourcc code for the format of the video. * buf is the pointer to the source data in system memory. * width and height are the w/h of the source data. * If "sync" is TRUE, then we must be finished with *buf at the point of return * (which we always are). * clipBoxes is the clipping region in screen space. * data is a pointer to our port private. * drawable is some Drawable, which might not be the screen in the case of * compositing. It's a new argument to the function in the 1.1 server. */ static int intel_uxa_video_put_image_textured(ScrnInfoPtr scrn, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr drawable) { intel_screen_private *intel = intel_get_screen_private(scrn); intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; PixmapPtr pixmap = get_drawable_pixmap(drawable); int dstPitch, dstPitch2; BoxRec dstBox; xf86CrtcPtr crtc; int top, left, npixels, nlines; if (!intel_uxa_pixmap_is_offscreen(pixmap)) return BadAlloc; #if 0 ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height); #endif if (!intel_clip_video_helper(scrn, adaptor_priv, &crtc, &dstBox, src_x, src_y, drw_x, drw_y, src_w, src_h, drw_w, drw_h, id, &top, &left, &npixels, &nlines, clipBoxes, width, height)) return Success; if (xvmc_passthrough(id)) { uint32_t *gem_handle = (uint32_t *)buf; int size; intel_setup_dst_params(scrn, adaptor_priv, width, height, &dstPitch, &dstPitch2, &size, id); if (IS_I915G(intel) || IS_I915GM(intel)) { /* XXX: i915 is not support and needs some * serious care. grep for KMS in i915_hwmc.c */ return BadAlloc; } if (adaptor_priv->buf) drm_intel_bo_unreference(adaptor_priv->buf); adaptor_priv->buf = drm_intel_bo_gem_create_from_name(intel->bufmgr, "xvmc surface", *gem_handle); if (adaptor_priv->buf == NULL) return BadAlloc; adaptor_priv->reusable = FALSE; } else { if (!intel_video_copy_data(scrn, adaptor_priv, width, height, &dstPitch, &dstPitch2, top, left, npixels, nlines, id, buf)) return BadAlloc; } if (crtc && adaptor_priv->SyncToVblank != 0 && INTEL_INFO(intel)->gen < 060) { intel_wait_for_scanline(scrn, pixmap, crtc, clipBoxes); } if (INTEL_INFO(intel)->gen >= 060) { Gen6DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, width, height, dstPitch, dstPitch2, src_w, src_h, drw_w, drw_h, pixmap); } else if (INTEL_INFO(intel)->gen >= 040) { I965DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, width, height, dstPitch, dstPitch2, src_w, src_h, drw_w, drw_h, pixmap); } else { I915DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes, width, height, dstPitch, dstPitch2, src_w, src_h, drw_w, drw_h, pixmap); } intel_get_screen_private(scrn)->needs_flush = TRUE; DamageDamageRegion(drawable, clipBoxes); /* And make sure the WAIT_FOR_EVENT is queued before any * modesetting/dpms operations on the pipe. */ intel_batch_submit(scrn); return Success; } XF86VideoAdaptorPtr intel_uxa_video_setup_image_textured(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); XF86VideoAdaptorPtr adapt; intel_adaptor_private *adaptor_privs; DevUnion *devUnions; int nports = 16, i; UXA_VIDEO_DEBUG("intel_video_overlay_setup_image\n"); adapt = calloc(1, sizeof(XF86VideoAdaptorRec)); adaptor_privs = calloc(nports, sizeof(intel_adaptor_private)); devUnions = calloc(nports, sizeof(DevUnion)); if (adapt == NULL || adaptor_privs == NULL || devUnions == NULL) { free(adapt); free(adaptor_privs); free(devUnions); return NULL; } adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = 0; adapt->name = "Intel(R) Textured Video"; adapt->nEncodings = 1; adapt->pEncodings = xnfalloc(sizeof(intel_xv_dummy_encoding)); memcpy(adapt->pEncodings, intel_xv_dummy_encoding, sizeof(intel_xv_dummy_encoding)); adapt->nFormats = NUM_FORMATS; adapt->pFormats = intel_xv_formats; adapt->nPorts = nports; adapt->pPortPrivates = devUnions; adapt->nAttributes = 0; adapt->pAttributes = NULL; if (IS_I915G(intel) || IS_I915GM(intel)) adapt->nImages = NUM_IMAGES - XVMC_IMAGE; else adapt->nImages = NUM_IMAGES; adapt->pImages = intel_xv_images; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; adapt->GetStill = NULL; adapt->StopVideo = intel_video_stop_video; adapt->SetPortAttribute = intel_uxa_video_set_port_attribute; adapt->GetPortAttribute = intel_video_get_port_attribute; adapt->QueryBestSize = intel_video_query_best_size; adapt->PutImage = intel_uxa_video_put_image_textured; adapt->QueryImageAttributes = intel_video_query_image_attributes; for (i = 0; i < nports; i++) { intel_adaptor_private *adaptor_priv = &adaptor_privs[i]; adaptor_priv->textured = TRUE; adaptor_priv->videoStatus = 0; adaptor_priv->buf = NULL; adaptor_priv->old_buf[0] = NULL; adaptor_priv->old_buf[1] = NULL; adaptor_priv->rotation = RR_Rotate_0; adaptor_priv->SyncToVblank = 1; /* gotta uninit this someplace, XXX: shouldn't be necessary for textured */ REGION_NULL(screen, &adaptor_priv->clip); adapt->pPortPrivates[i].ptr = (pointer) (adaptor_priv); } intel_xv_SyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); return adapt; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_video.c000066400000000000000000000570271267532330400243370ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane * David Dawes * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian * Offscreen Images: * Matt Sottek */ /* * XXX Could support more formats. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "xf86drm.h" #include "regionstr.h" #include "randrstr.h" #include "windowstr.h" #include "damage.h" #include "intel.h" #include "intel_video.h" #include "i830_reg.h" #include "xf86xv.h" #include #include "dixstruct.h" #include "fourcc.h" #ifdef INTEL_XVMC #define _INTEL_XVMC_SERVER_ #include "intel_xvmc.h" #endif #include "intel_uxa.h" #include "intel_video_overlay.h" Atom intel_xv_Brightness, intel_xv_Contrast, intel_xv_Saturation, intel_xv_ColorKey, intel_xv_Pipe; Atom intel_xv_Gamma0, intel_xv_Gamma1, intel_xv_Gamma2, intel_xv_Gamma3, intel_xv_Gamma4, intel_xv_Gamma5; Atom intel_xv_SyncToVblank; /* client libraries expect an encoding */ const XF86VideoEncodingRec intel_xv_dummy_encoding[1] = { { 0, "XV_IMAGE", IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, {1, 1} } }; XF86VideoFormatRec intel_xv_formats[NUM_FORMATS] = { {15, TrueColor}, {16, TrueColor}, {24, TrueColor} }; XF86AttributeRec intel_xv_attributes[NUM_ATTRIBUTES] = { {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"}, {XvSettable | XvGettable, -1, 1, "XV_PIPE"} }; #define GAMMA_ATTRIBUTES 6 XF86AttributeRec intel_xv_gamma_attributes[GAMMA_ATTRIBUTES] = { {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA0"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA1"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA2"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA3"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA4"}, {XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"} }; #ifdef INTEL_XVMC #define NUM_IMAGES 5 #define XVMC_IMAGE 1 #else #define NUM_IMAGES 4 #define XVMC_IMAGE 0 #endif XF86ImageRec intel_xv_images[NUM_IMAGES] = { XVIMAGE_YUY2, XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_UYVY, #ifdef INTEL_XVMC { /* * Below, a dummy picture type that is used in XvPutImage only to do * an overlay update. Introduced for the XvMC client lib. * Defined to have a zero data size. */ FOURCC_XVMC, XvYUV, LSBFirst, {'X', 'V', 'M', 'C', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, 12, XvPlanar, 3, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, {'Y', 'V', 'U', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, XvTopToBottom}, #endif }; void intel_video_init(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); XF86VideoAdaptorPtr *adaptors = NULL, *newAdaptors = NULL; XF86VideoAdaptorPtr overlayAdaptor = NULL, texturedAdaptor = NULL; int num_adaptors = xf86XVListGenericAdaptors(scrn, &adaptors); /* Give our adaptor list enough space for the overlay and/or texture video * adaptors. */ newAdaptors = realloc(adaptors, (num_adaptors + 3) * sizeof(XF86VideoAdaptorPtr)); if (newAdaptors == NULL) { free(adaptors); return; } adaptors = newAdaptors; /* Add the adaptors supported by our hardware. First, set up the atoms * that will be used by both output adaptors. */ intel_xv_Brightness = MAKE_ATOM("XV_BRIGHTNESS"); intel_xv_Contrast = MAKE_ATOM("XV_CONTRAST"); /* Set up textured video if we can do it at this depth and we are on * supported hardware. */ if (!intel->force_fallback && scrn->bitsPerPixel >= 16 && INTEL_INFO(intel)->gen >= 030 && INTEL_INFO(intel)->gen < 0100) { texturedAdaptor = intel_uxa_video_setup_image_textured(screen); if (texturedAdaptor != NULL) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Set up textured video\n"); } else { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to set up textured video\n"); } } overlayAdaptor = intel_video_overlay_setup_image(screen); if (intel->use_overlay) { if (overlayAdaptor != NULL) { xf86DrvMsg(scrn->scrnIndex, X_INFO, "Set up overlay video\n"); } else { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to set up overlay video\n"); } } if (overlayAdaptor && intel->XvPreferOverlay) adaptors[num_adaptors++] = overlayAdaptor; if (texturedAdaptor) adaptors[num_adaptors++] = texturedAdaptor; if (overlayAdaptor && !intel->XvPreferOverlay) adaptors[num_adaptors++] = overlayAdaptor; if (num_adaptors) { xf86XVScreenInit(screen, adaptors, num_adaptors); } else { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Disabling Xv because no adaptors could be initialized.\n"); intel->XvEnabled = FALSE; } #ifdef INTEL_XVMC if (texturedAdaptor) intel_xvmc_adaptor_init(screen); #endif free(adaptors); } void intel_free_video_buffers(intel_adaptor_private *adaptor_priv) { int i; for (i = 0; i < 2; i++) { if (adaptor_priv->old_buf[i]) { drm_intel_bo_disable_reuse(adaptor_priv->old_buf[i]); drm_intel_bo_unreference(adaptor_priv->old_buf[i]); adaptor_priv->old_buf[i] = NULL; } } if (adaptor_priv->buf) { drm_intel_bo_unreference(adaptor_priv->buf); adaptor_priv->buf = NULL; } } int intel_video_get_port_attribute(ScrnInfoPtr scrn, Atom attribute, INT32 * value, pointer data) { intel_screen_private *intel = intel_get_screen_private(scrn); intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; if (attribute == intel_xv_Brightness) { *value = adaptor_priv->brightness; } else if (attribute == intel_xv_Contrast) { *value = adaptor_priv->contrast; } else if (attribute == intel_xv_Saturation) { *value = adaptor_priv->saturation; } else if (attribute == intel_xv_Pipe) { int c; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); for (c = 0; c < xf86_config->num_crtc; c++) if (xf86_config->crtc[c] == adaptor_priv->desired_crtc) break; if (c == xf86_config->num_crtc) c = -1; *value = c; } else if (attribute == intel_xv_Gamma0 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma0; } else if (attribute == intel_xv_Gamma1 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma1; } else if (attribute == intel_xv_Gamma2 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma2; } else if (attribute == intel_xv_Gamma3 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma3; } else if (attribute == intel_xv_Gamma4 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma4; } else if (attribute == intel_xv_Gamma5 && (INTEL_INFO(intel)->gen >= 030)) { *value = adaptor_priv->gamma5; } else if (attribute == intel_xv_ColorKey) { *value = adaptor_priv->colorKey; } else if (attribute == intel_xv_SyncToVblank) { *value = adaptor_priv->SyncToVblank; } else return BadMatch; return Success; } void intel_video_query_best_size(ScrnInfoPtr scrn, Bool motion, short vid_w, short vid_h, short drw_w, short drw_h, unsigned int *p_w, unsigned int *p_h, pointer data) { if (vid_w > (drw_w << 1)) drw_w = vid_w >> 1; if (vid_h > (drw_h << 1)) drw_h = vid_h >> 1; *p_w = drw_w; *p_h = drw_h; } static Bool intel_video_copy_packed_data(intel_adaptor_private *adaptor_priv, unsigned char *buf, int srcPitch, int dstPitch, int top, int left, int h, int w) { unsigned char *src, *dst, *dst_base; int i, j; unsigned char *s; #if 0 ErrorF("intel_video_copy_packed_data: (%d,%d) (%d,%d)\n" "srcPitch: %d, dstPitch: %d\n", top, left, h, w, srcPitch, dstPitch); #endif src = buf + (top * srcPitch) + (left << 1); if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf)) return FALSE; dst_base = adaptor_priv->buf->virtual; dst = dst_base + adaptor_priv->YBufOffset; switch (adaptor_priv->rotation) { case RR_Rotate_0: w <<= 1; for (i = 0; i < h; i++) { memcpy(dst, src, w); src += srcPitch; dst += dstPitch; } break; case RR_Rotate_90: h <<= 1; for (i = 0; i < h; i += 2) { s = src; for (j = 0; j < w; j++) { /* Copy Y */ dst[(i + 0) + ((w - j - 1) * dstPitch)] = *s++; (void)*s++; } src += srcPitch; } h >>= 1; src = buf + (top * srcPitch) + (left << 1); for (i = 0; i < h; i += 2) { for (j = 0; j < w; j += 2) { /* Copy U */ dst[((i * 2) + 1) + ((w - j - 1) * dstPitch)] = src[(j * 2) + 1 + (i * srcPitch)]; dst[((i * 2) + 1) + ((w - j - 2) * dstPitch)] = src[(j * 2) + 1 + ((i + 1) * srcPitch)]; /* Copy V */ dst[((i * 2) + 3) + ((w - j - 1) * dstPitch)] = src[(j * 2) + 3 + (i * srcPitch)]; dst[((i * 2) + 3) + ((w - j - 2) * dstPitch)] = src[(j * 2) + 3 + ((i + 1) * srcPitch)]; } } break; case RR_Rotate_180: w <<= 1; for (i = 0; i < h; i++) { s = src; for (j = 0; j < w; j += 4) { dst[(w - j - 4) + ((h - i - 1) * dstPitch)] = *s++; dst[(w - j - 3) + ((h - i - 1) * dstPitch)] = *s++; dst[(w - j - 2) + ((h - i - 1) * dstPitch)] = *s++; dst[(w - j - 1) + ((h - i - 1) * dstPitch)] = *s++; } src += srcPitch; } break; case RR_Rotate_270: h <<= 1; for (i = 0; i < h; i += 2) { s = src; for (j = 0; j < w; j++) { /* Copy Y */ dst[(h - i - 2) + (j * dstPitch)] = *s++; (void)*s++; } src += srcPitch; } h >>= 1; src = buf + (top * srcPitch) + (left << 1); for (i = 0; i < h; i += 2) { for (j = 0; j < w; j += 2) { /* Copy U */ dst[(((h - i) * 2) - 3) + (j * dstPitch)] = src[(j * 2) + 1 + (i * srcPitch)]; dst[(((h - i) * 2) - 3) + ((j + 1) * dstPitch)] = src[(j * 2) + 1 + ((i + 1) * srcPitch)]; /* Copy V */ dst[(((h - i) * 2) - 1) + (j * dstPitch)] = src[(j * 2) + 3 + (i * srcPitch)]; dst[(((h - i) * 2) - 1) + ((j + 1) * dstPitch)] = src[(j * 2) + 3 + ((i + 1) * srcPitch)]; } } break; } drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf); return TRUE; } static void intel_memcpy_plane(unsigned char *dst, unsigned char *src, int height, int width, int dstPitch, int srcPitch, Rotation rotation) { int i, j = 0; unsigned char *s; switch (rotation) { case RR_Rotate_0: /* optimise for the case of no clipping */ if (srcPitch == dstPitch && srcPitch == width) memcpy(dst, src, srcPitch * height); else for (i = 0; i < height; i++) { memcpy(dst, src, width); src += srcPitch; dst += dstPitch; } break; case RR_Rotate_90: for (i = 0; i < height; i++) { s = src; for (j = 0; j < width; j++) { dst[(i) + ((width - j - 1) * dstPitch)] = *s++; } src += srcPitch; } break; case RR_Rotate_180: for (i = 0; i < height; i++) { s = src; for (j = 0; j < width; j++) { dst[(width - j - 1) + ((height - i - 1) * dstPitch)] = *s++; } src += srcPitch; } break; case RR_Rotate_270: for (i = 0; i < height; i++) { s = src; for (j = 0; j < width; j++) { dst[(height - i - 1) + (j * dstPitch)] = *s++; } src += srcPitch; } break; } } static Bool intel_video_copy_planar_data(intel_adaptor_private *adaptor_priv, unsigned char *buf, int srcPitch, int srcPitch2, int dstPitch, int dstPitch2, int srcH, int top, int left, int h, int w, int id) { unsigned char *src1, *src2, *src3, *dst_base, *dst1, *dst2, *dst3; #if 0 ErrorF("intel_video_copy_planar_data: srcPitch %d, srcPitch %d, dstPitch %d\n" "nlines %d, npixels %d, top %d, left %d\n", srcPitch, srcPitch2, dstPitch, h, w, top, left); #endif /* Copy Y data */ src1 = buf + (top * srcPitch) + left; #if 0 ErrorF("src1 is %p, offset is %ld\n", src1, (unsigned long)src1 - (unsigned long)buf); #endif if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf)) return FALSE; dst_base = adaptor_priv->buf->virtual; dst1 = dst_base + adaptor_priv->YBufOffset; intel_memcpy_plane(dst1, src1, h, w, dstPitch2, srcPitch, adaptor_priv->rotation); /* Copy V data for YV12, or U data for I420 */ src2 = buf + /* start of YUV data */ (srcH * srcPitch) + /* move over Luma plane */ ((top >> 1) * srcPitch2) + /* move down from by top lines */ (left >> 1); /* move left by left pixels */ #if 0 ErrorF("src2 is %p, offset is %ld\n", src2, (unsigned long)src2 - (unsigned long)buf); #endif if (id == FOURCC_I420) dst2 = dst_base + adaptor_priv->UBufOffset; else dst2 = dst_base + adaptor_priv->VBufOffset; intel_memcpy_plane(dst2, src2, h / 2, w / 2, dstPitch, srcPitch2, adaptor_priv->rotation); /* Copy U data for YV12, or V data for I420 */ src3 = buf + /* start of YUV data */ (srcH * srcPitch) + /* move over Luma plane */ ((srcH >> 1) * srcPitch2) + /* move over Chroma plane */ ((top >> 1) * srcPitch2) + /* move down from by top lines */ (left >> 1); /* move left by left pixels */ #if 0 ErrorF("src3 is %p, offset is %ld\n", src3, (unsigned long)src3 - (unsigned long)buf); #endif if (id == FOURCC_I420) dst3 = dst_base + adaptor_priv->VBufOffset; else dst3 = dst_base + adaptor_priv->UBufOffset; intel_memcpy_plane(dst3, src3, h / 2, w / 2, dstPitch, srcPitch2, adaptor_priv->rotation); drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf); return TRUE; } void intel_setup_dst_params(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, short width, short height, int *dstPitch, int *dstPitch2, int *size, int id) { intel_screen_private *intel = intel_get_screen_private(scrn); int pitchAlign; /* Only needs to be DWORD-aligned for textured on i915, but overlay has * stricter requirements. */ if (adaptor_priv->textured) { pitchAlign = 4; } else { if (INTEL_INFO(intel)->gen >= 040) /* Actually the alignment is 64 bytes, too. But the * stride must be at least 512 bytes. Take the easy fix * and align on 512 bytes unconditionally. */ pitchAlign = 512; else if (IS_I830(intel) || IS_845G(intel)) /* Harsh, errata on these chipsets limit the stride to be * a multiple of 256 bytes. */ pitchAlign = 256; else pitchAlign = 64; } #if INTEL_XVMC /* for i915 xvmc, hw requires 1kb aligned surfaces */ if ((id == FOURCC_XVMC) && IS_GEN3(intel)) pitchAlign = 1024; #endif /* Determine the desired destination pitch (representing the chroma's pitch, * in the planar case. */ if (is_planar_fourcc(id)) { if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { *dstPitch = ALIGN((height / 2), pitchAlign); *dstPitch2 = ALIGN(height, pitchAlign); *size = *dstPitch * width * 3; } else { *dstPitch = ALIGN((width / 2), pitchAlign); *dstPitch2 = ALIGN(width, pitchAlign); *size = *dstPitch * height * 3; } } else { if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { *dstPitch = ALIGN((height << 1), pitchAlign); *size = *dstPitch * width; } else { *dstPitch = ALIGN((width << 1), pitchAlign); *size = *dstPitch * height; } *dstPitch2 = 0; } #if 0 ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, *dstPitch, size); #endif adaptor_priv->YBufOffset = 0; if (adaptor_priv->rotation & (RR_Rotate_90 | RR_Rotate_270)) { adaptor_priv->UBufOffset = adaptor_priv->YBufOffset + (*dstPitch2 * width); adaptor_priv->VBufOffset = adaptor_priv->UBufOffset + (*dstPitch * width / 2); } else { adaptor_priv->UBufOffset = adaptor_priv->YBufOffset + (*dstPitch2 * height); adaptor_priv->VBufOffset = adaptor_priv->UBufOffset + (*dstPitch * height / 2); } } static Bool intel_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, int alloc_size, int id, unsigned char *buf) { intel_screen_private *intel = intel_get_screen_private(scrn); /* Free the current buffer if we're going to have to reallocate */ if (adaptor_priv->buf && adaptor_priv->buf->size < alloc_size) intel_free_video_buffers(adaptor_priv); if (adaptor_priv->buf == NULL) { adaptor_priv->buf = drm_intel_bo_alloc(intel->bufmgr, "xv buffer", alloc_size, 4096); if (adaptor_priv->buf == NULL) return FALSE; adaptor_priv->reusable = TRUE; } return TRUE; } Bool intel_video_copy_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, short width, short height, int *dstPitch, int *dstPitch2, int top, int left, int npixels, int nlines, int id, unsigned char *buf) { int srcPitch = 0, srcPitch2 = 0; int size; if (is_planar_fourcc(id)) { srcPitch = ALIGN(width, 0x4); srcPitch2 = ALIGN((width >> 1), 0x4); } else { srcPitch = width << 1; } intel_setup_dst_params(scrn, adaptor_priv, width, height, dstPitch, dstPitch2, &size, id); if (!intel_setup_video_buffer(scrn, adaptor_priv, size, id, buf)) return FALSE; /* copy data */ if (is_planar_fourcc(id)) { return intel_video_copy_planar_data(adaptor_priv, buf, srcPitch, srcPitch2, *dstPitch, *dstPitch2, height, top, left, nlines, npixels, id); } else { return intel_video_copy_packed_data(adaptor_priv, buf, srcPitch, *dstPitch, top, left, nlines, npixels); } } int is_planar_fourcc(int id) { switch (id) { case FOURCC_YV12: case FOURCC_I420: #ifdef INTEL_XVMC case FOURCC_XVMC: #endif return 1; case FOURCC_UYVY: case FOURCC_YUY2: return 0; default: ErrorF("Unknown format 0x%x\n", id); return 0; } } Bool intel_clip_video_helper(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, xf86CrtcPtr * crtc_ret, BoxPtr dst, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, int *top, int* left, int* npixels, int *nlines, RegionPtr reg, INT32 width, INT32 height) { Bool ret; RegionRec crtc_region_local; RegionPtr crtc_region = reg; BoxRec crtc_box; INT32 x1, x2, y1, y2; xf86CrtcPtr crtc; x1 = src_x; x2 = src_x + src_w; y1 = src_y; y2 = src_y + src_h; dst->x1 = drw_x; dst->x2 = drw_x + drw_w; dst->y1 = drw_y; dst->y2 = drw_y + drw_h; /* * For overlay video, compute the relevant CRTC and * clip video to that */ crtc = intel_covering_crtc(scrn, dst, adaptor_priv->desired_crtc, &crtc_box); /* For textured video, we don't actually want to clip at all. */ if (crtc && !adaptor_priv->textured) { REGION_INIT(screen, &crtc_region_local, &crtc_box, 1); crtc_region = &crtc_region_local; REGION_INTERSECT(screen, crtc_region, crtc_region, reg); } *crtc_ret = crtc; ret = xf86XVClipVideoHelper(dst, &x1, &x2, &y1, &y2, crtc_region, width, height); if (crtc_region != reg) REGION_UNINIT(screen, &crtc_region_local); *top = y1 >> 16; *left = (x1 >> 16) & ~1; *npixels = ALIGN(((x2 + 0xffff) >> 16), 2) - *left; if (is_planar_fourcc(id)) { *top &= ~1; *nlines = ALIGN(((y2 + 0xffff) >> 16), 2) - *top; } else *nlines = ((y2 + 0xffff) >> 16) - *top; return ret; } int intel_video_query_image_attributes(ScrnInfoPtr scrn, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) { intel_screen_private *intel = intel_get_screen_private(scrn); int size, tmp; #if 0 ErrorF("intel_video_query_image_attributes: w is %d, h is %d\n", *w, *h); #endif if (IS_845G(intel) || IS_I830(intel)) { if (*w > IMAGE_MAX_WIDTH_LEGACY) *w = IMAGE_MAX_WIDTH_LEGACY; if (*h > IMAGE_MAX_HEIGHT_LEGACY) *h = IMAGE_MAX_HEIGHT_LEGACY; } else { if (*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; if (*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; } *w = (*w + 1) & ~1; if (offsets) offsets[0] = 0; switch (id) { /* IA44 is for XvMC only */ case FOURCC_IA44: case FOURCC_AI44: if (pitches) pitches[0] = *w; size = *w * *h; break; case FOURCC_YV12: case FOURCC_I420: *h = (*h + 1) & ~1; size = (*w + 3) & ~3; if (pitches) pitches[0] = size; size *= *h; if (offsets) offsets[1] = size; tmp = ((*w >> 1) + 3) & ~3; if (pitches) pitches[1] = pitches[2] = tmp; tmp *= (*h >> 1); size += tmp; if (offsets) offsets[2] = size; size += tmp; #if 0 if (pitches) ErrorF("pitch 0 is %d, pitch 1 is %d, pitch 2 is %d\n", pitches[0], pitches[1], pitches[2]); if (offsets) ErrorF("offset 1 is %d, offset 2 is %d\n", offsets[1], offsets[2]); if (offsets) ErrorF("size is %d\n", size); #endif break; #ifdef INTEL_XVMC case FOURCC_XVMC: *h = (*h + 1) & ~1; size = sizeof(struct intel_xvmc_command); if (pitches) pitches[0] = size; break; #endif case FOURCC_UYVY: case FOURCC_YUY2: default: size = *w << 1; if (pitches) pitches[0] = size; size *= *h; break; } return size; } void intel_video_stop_video(ScrnInfoPtr scrn, pointer data, Bool shutdown) { intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; if (adaptor_priv->textured) return; REGION_EMPTY(scrn->pScreen, &adaptor_priv->clip); if (shutdown) { if (adaptor_priv->videoStatus & CLIENT_VIDEO_ON) intel_video_overlay_off(intel_get_screen_private(scrn)); intel_free_video_buffers(adaptor_priv); adaptor_priv->videoStatus = 0; } else { if (adaptor_priv->videoStatus & CLIENT_VIDEO_ON) { adaptor_priv->videoStatus |= OFF_TIMER; adaptor_priv->offTime = currentTime.milliseconds + OFF_DELAY; } } } void intel_video_block_handler(intel_screen_private *intel) { intel_adaptor_private *adaptor_priv; /* no overlay */ if (intel->adaptor == NULL) return; adaptor_priv = intel_get_adaptor_private(intel); if (adaptor_priv->videoStatus & OFF_TIMER) { Time now = currentTime.milliseconds; if (adaptor_priv->offTime < now) { /* Turn off the overlay */ intel_video_overlay_off(intel); intel_free_video_buffers(adaptor_priv); adaptor_priv->videoStatus = 0; } } } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_video.h000066400000000000000000000116061267532330400243350ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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 _INTEL_VIDEO_H_ #define _INTEL_VIDEO_H_ #include "xf86.h" #include "xf86_OSproc.h" typedef struct { uint32_t YBufOffset; uint32_t UBufOffset; uint32_t VBufOffset; int brightness; int contrast; int saturation; xf86CrtcPtr desired_crtc; RegionRec clip; uint32_t colorKey; uint32_t gamma0; uint32_t gamma1; uint32_t gamma2; uint32_t gamma3; uint32_t gamma4; uint32_t gamma5; /* only used by the overlay */ uint32_t videoStatus; Time offTime; Time freeTime; /** YUV data buffers */ drm_intel_bo *buf, *old_buf[2]; Bool reusable; Bool textured; Rotation rotation; /* should remove intel->rotation later */ int SyncToVblank; /* -1: auto, 0: off, 1: on */ } intel_adaptor_private; #define OFF_DELAY 250 /* milliseconds */ #define OFF_TIMER 0x01 #define CLIENT_VIDEO_ON 0x02 static inline intel_adaptor_private * intel_get_adaptor_private(intel_screen_private *intel) { return intel->adaptor->pPortPrivates[0].ptr; } int is_planar_fourcc(int id); void intel_video_block_handler(intel_screen_private *intel); int intel_video_query_image_attributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); Bool intel_video_copy_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, short width, short height, int *dstPitch, int *dstPitch2, int top, int left, int npixels, int nlines, int id, unsigned char *buf); Bool intel_clip_video_helper(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, xf86CrtcPtr * crtc_ret, BoxPtr dst, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, int *top, int* left, int* npixels, int *nlines, RegionPtr reg, INT32 width, INT32 height); void intel_free_video_buffers(intel_adaptor_private *adaptor_priv); int intel_video_get_port_attribute(ScrnInfoPtr scrn, Atom attribute, INT32 * value, pointer data); void intel_video_query_best_size(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer); void intel_setup_dst_params(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, short width, short height, int *dstPitch, int *dstPitch2, int *size, int id); void intel_video_stop_video(ScrnInfoPtr scrn, pointer data, Bool shutdown); extern Atom intel_xv_Brightness, intel_xv_Contrast, intel_xv_Saturation, intel_xv_ColorKey, intel_xv_Pipe; extern Atom intel_xv_Gamma0, intel_xv_Gamma1, intel_xv_Gamma2, intel_xv_Gamma3, intel_xv_Gamma4, intel_xv_Gamma5; extern Atom intel_xv_SyncToVblank; #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) /* Limits for the overlay/textured video source sizes. The documented hardware * limits are 2048x2048 or better for overlay and both of our textured video * implementations. Additionally, on the 830 and 845, larger sizes resulted in * the card hanging, so we keep the limits lower there. */ #define IMAGE_MAX_WIDTH 2048 #define IMAGE_MAX_HEIGHT 2048 #define IMAGE_MAX_WIDTH_LEGACY 1024 #define IMAGE_MAX_HEIGHT_LEGACY 1088 extern const XF86VideoEncodingRec intel_xv_dummy_encoding[1]; #define NUM_FORMATS 3 extern XF86VideoFormatRec intel_xv_formats[NUM_FORMATS]; #define NUM_ATTRIBUTES 5 extern XF86AttributeRec intel_xv_attributes[NUM_ATTRIBUTES]; #define GAMMA_ATTRIBUTES 6 extern XF86AttributeRec intel_xv_gamma_attributes[GAMMA_ATTRIBUTES]; #ifdef INTEL_XVMC #define NUM_IMAGES 5 #define XVMC_IMAGE 1 #else #define NUM_IMAGES 4 #define XVMC_IMAGE 0 #endif extern XF86ImageRec intel_xv_images[NUM_IMAGES]; #endif /* _INTEL_VIDEO_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_video_overlay.c000066400000000000000000000410701267532330400260670ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane * David Dawes * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian * Offscreen Images: * Matt Sottek */ /* * XXX Could support more formats. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" #include "compiler.h" #include "xf86Pci.h" #include "xf86fbman.h" #include "xf86drm.h" #include "regionstr.h" #include "randrstr.h" #include "windowstr.h" #include "damage.h" #include "intel.h" #include "intel_video.h" #include "i830_reg.h" #include "xf86xv.h" #include #include "dixstruct.h" #include "fourcc.h" #include "intel_video_overlay.h" /* overlay debugging printf function */ #if 0 #define OVERLAY_DEBUG ErrorF #else #define OVERLAY_DEBUG if (0) ErrorF #endif /* kernel modesetting overlay functions */ static Bool intel_has_overlay(intel_screen_private *intel) { struct drm_i915_getparam gp; int has_overlay = 0; int ret; gp.param = I915_PARAM_HAS_OVERLAY; gp.value = &has_overlay; ret = drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, sizeof(gp)); return ret == 0 && !! has_overlay; } static Bool intel_overlay_update_attrs(intel_screen_private *intel) { intel_adaptor_private *adaptor_priv = intel_get_adaptor_private(intel); struct drm_intel_overlay_attrs attrs; attrs.flags = I915_OVERLAY_UPDATE_ATTRS; attrs.brightness = adaptor_priv->brightness; attrs.contrast = adaptor_priv->contrast; attrs.saturation = adaptor_priv->saturation; attrs.color_key = adaptor_priv->colorKey; attrs.gamma0 = adaptor_priv->gamma0; attrs.gamma1 = adaptor_priv->gamma1; attrs.gamma2 = adaptor_priv->gamma2; attrs.gamma3 = adaptor_priv->gamma3; attrs.gamma4 = adaptor_priv->gamma4; attrs.gamma5 = adaptor_priv->gamma5; return drmCommandWriteRead(intel->drmSubFD, DRM_I915_OVERLAY_ATTRS, &attrs, sizeof(attrs)) == 0; } void intel_video_overlay_off(intel_screen_private *intel) { struct drm_intel_overlay_put_image request; int ret; request.flags = 0; ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE, &request, sizeof(request)); (void) ret; } static int intel_video_overlay_set_port_attribute(ScrnInfoPtr scrn, Atom attribute, INT32 value, pointer data) { intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; intel_screen_private *intel = intel_get_screen_private(scrn); if (attribute == intel_xv_Brightness) { if ((value < -128) || (value > 127)) return BadValue; adaptor_priv->brightness = value; OVERLAY_DEBUG("BRIGHTNESS\n"); } else if (attribute == intel_xv_Contrast) { if ((value < 0) || (value > 255)) return BadValue; adaptor_priv->contrast = value; OVERLAY_DEBUG("CONTRAST\n"); } else if (attribute == intel_xv_Saturation) { if ((value < 0) || (value > 1023)) return BadValue; adaptor_priv->saturation = value; } else if (attribute == intel_xv_Pipe) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); if ((value < -1) || (value >= xf86_config->num_crtc)) return BadValue; if (value < 0) adaptor_priv->desired_crtc = NULL; else adaptor_priv->desired_crtc = xf86_config->crtc[value]; } else if (attribute == intel_xv_Gamma0 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma0 = value; } else if (attribute == intel_xv_Gamma1 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma1 = value; } else if (attribute == intel_xv_Gamma2 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma2 = value; } else if (attribute == intel_xv_Gamma3 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma3 = value; } else if (attribute == intel_xv_Gamma4 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma4 = value; } else if (attribute == intel_xv_Gamma5 && (INTEL_INFO(intel)->gen >= 030)) { adaptor_priv->gamma5 = value; } else if (attribute == intel_xv_ColorKey) { adaptor_priv->colorKey = value; OVERLAY_DEBUG("COLORKEY\n"); } else return BadMatch; if ((attribute == intel_xv_Gamma0 || attribute == intel_xv_Gamma1 || attribute == intel_xv_Gamma2 || attribute == intel_xv_Gamma3 || attribute == intel_xv_Gamma4 || attribute == intel_xv_Gamma5) && (INTEL_INFO(intel)->gen >= 030)) { OVERLAY_DEBUG("GAMMA\n"); } if (!intel_overlay_update_attrs(intel)) return BadValue; if (attribute == intel_xv_ColorKey) REGION_EMPTY(scrn->pScreen, &adaptor_priv->clip); return Success; } static Bool intel_overlay_put_image(intel_screen_private *intel, xf86CrtcPtr crtc, int id, short width, short height, int dstPitch, int dstPitch2, BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) { intel_adaptor_private *adaptor_priv = intel_get_adaptor_private(intel); struct drm_intel_overlay_put_image request; int ret; int planar = is_planar_fourcc(id); float scale; dri_bo *tmp; request.flags = I915_OVERLAY_ENABLE; request.bo_handle = adaptor_priv->buf->handle; if (planar) { request.stride_Y = dstPitch2; request.stride_UV = dstPitch; } else { request.stride_Y = dstPitch; request.stride_UV = 0; } request.offset_Y = adaptor_priv->YBufOffset; request.offset_U = adaptor_priv->UBufOffset; request.offset_V = adaptor_priv->VBufOffset; OVERLAY_DEBUG("off_Y: %i, off_U: %i, off_V: %i\n", request.offset_Y, request.offset_U, request.offset_V); request.crtc_id = intel_crtc_id(crtc); request.dst_x = dstBox->x1; request.dst_y = dstBox->y1; request.dst_width = dstBox->x2 - dstBox->x1; request.dst_height = dstBox->y2 - dstBox->y1; request.src_width = width; request.src_height = height; /* adjust src dimensions */ if (request.dst_height > 1) { scale = ((float)request.dst_height - 1) / ((float)drw_h - 1); request.src_scan_height = src_h * scale; } else request.src_scan_height = 1; if (request.dst_width > 1) { scale = ((float)request.dst_width - 1) / ((float)drw_w - 1); request.src_scan_width = src_w * scale; } else request.src_scan_width = 1; if (planar) { request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420; } else { request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422; if (id == FOURCC_UYVY) request.flags |= I915_OVERLAY_Y_SWAP; } ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE, &request, sizeof(request)); if (ret) return FALSE; if (!adaptor_priv->reusable) { drm_intel_bo_unreference(adaptor_priv->buf); adaptor_priv->buf = NULL; adaptor_priv->reusable = TRUE; } tmp = adaptor_priv->old_buf[1]; adaptor_priv->old_buf[1] = adaptor_priv->old_buf[0]; adaptor_priv->old_buf[0] = adaptor_priv->buf; adaptor_priv->buf = tmp; return TRUE; } static void intel_update_dst_box_to_crtc_coords(ScrnInfoPtr scrn, xf86CrtcPtr crtc, BoxPtr dstBox) { int tmp; /* for overlay, we should take it from crtc's screen * coordinate to current crtc's display mode. * yeah, a bit confusing. */ switch (crtc->rotation & 0xf) { case RR_Rotate_0: dstBox->x1 -= crtc->x; dstBox->x2 -= crtc->x; dstBox->y1 -= crtc->y; dstBox->y2 -= crtc->y; break; case RR_Rotate_90: tmp = dstBox->x1; dstBox->x1 = dstBox->y1 - crtc->x; dstBox->y1 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = dstBox->y2 - crtc->x; dstBox->y2 = scrn->virtualX - tmp - crtc->y; tmp = dstBox->y1; dstBox->y1 = dstBox->y2; dstBox->y2 = tmp; break; case RR_Rotate_180: tmp = dstBox->x1; dstBox->x1 = scrn->virtualX - dstBox->x2 - crtc->x; dstBox->x2 = scrn->virtualX - tmp - crtc->x; tmp = dstBox->y1; dstBox->y1 = scrn->virtualY - dstBox->y2 - crtc->y; dstBox->y2 = scrn->virtualY - tmp - crtc->y; break; case RR_Rotate_270: tmp = dstBox->x1; dstBox->x1 = scrn->virtualY - dstBox->y1 - crtc->x; dstBox->y1 = tmp - crtc->y; tmp = dstBox->x2; dstBox->x2 = scrn->virtualY - dstBox->y2 - crtc->x; dstBox->y2 = tmp - crtc->y; tmp = dstBox->x1; dstBox->x1 = dstBox->x2; dstBox->x2 = tmp; break; } return; } static Bool intel_video_overlay_display(ScrnInfoPtr scrn, xf86CrtcPtr crtc, int id, short width, short height, int dstPitch, int dstPitch2, BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) { intel_screen_private *intel = intel_get_screen_private(scrn); int tmp; OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height, dstPitch); /* * If the video isn't visible on any CRTC, turn it off */ if (!crtc) { intel_video_overlay_off(intel); return TRUE; } intel_update_dst_box_to_crtc_coords(scrn, crtc, dstBox); if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) { tmp = width; width = height; height = tmp; tmp = drw_w; drw_w = drw_h; drw_h = tmp; tmp = src_w; src_w = src_h; src_h = tmp; } return intel_overlay_put_image(intel, crtc, id, width, height, dstPitch, dstPitch2, dstBox, src_w, src_h, drw_w, drw_h); } static int intel_video_overlay_put_image(ScrnInfoPtr scrn, short src_x, short src_y, short drw_x, short drw_y, short src_w, short src_h, short drw_w, short drw_h, int id, unsigned char *buf, short width, short height, Bool sync, RegionPtr clipBoxes, pointer data, DrawablePtr drawable) { intel_adaptor_private *adaptor_priv = (intel_adaptor_private *) data; int dstPitch, dstPitch2; BoxRec dstBox; xf86CrtcPtr crtc; int top, left, npixels, nlines; #if 0 ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height); #endif /* If dst width and height are less than 1/8th the src size, the * src/dst scale factor becomes larger than 8 and doesn't fit in * the scale register. */ if (src_w >= (drw_w * 8)) drw_w = src_w / 7; if (src_h >= (drw_h * 8)) drw_h = src_h / 7; if (!intel_clip_video_helper(scrn, adaptor_priv, &crtc, &dstBox, src_x, src_y, drw_x, drw_y, src_w, src_h, drw_w, drw_h, id, &top, &left, &npixels, &nlines, clipBoxes, width, height)) return Success; /* overlay can't handle rotation natively, store it for the copy func */ if (crtc) adaptor_priv->rotation = crtc->rotation; else { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Fail to clip video to any crtc!\n"); return Success; } if (!intel_video_copy_data(scrn, adaptor_priv, width, height, &dstPitch, &dstPitch2, top, left, npixels, nlines, id, buf)) return BadAlloc; if (!intel_video_overlay_display (scrn, crtc, id, width, height, dstPitch, dstPitch2, &dstBox, src_w, src_h, drw_w, drw_h)) return BadAlloc; /* update cliplist */ if (!REGION_EQUAL(scrn->pScreen, &adaptor_priv->clip, clipBoxes)) { REGION_COPY(scrn->pScreen, &adaptor_priv->clip, clipBoxes); xf86XVFillKeyHelperDrawable(drawable, adaptor_priv->colorKey, clipBoxes); } adaptor_priv->videoStatus = CLIENT_VIDEO_ON; return Success; } XF86VideoAdaptorPtr intel_video_overlay_setup_image(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); XF86VideoAdaptorPtr adapt; intel_adaptor_private *adaptor_priv; XF86AttributePtr att; /* Set up overlay video if it is available */ intel->use_overlay = intel_has_overlay(intel); if (!intel->use_overlay) return NULL; OVERLAY_DEBUG("intel_video_overlay_setup_image\n"); if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + sizeof(intel_adaptor_private) + sizeof(DevUnion)))) return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT */ ; adapt->name = "Intel(R) Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = xnfalloc(sizeof(intel_xv_dummy_encoding)); memcpy(adapt->pEncodings, intel_xv_dummy_encoding, sizeof(intel_xv_dummy_encoding)); if (IS_845G(intel) || IS_I830(intel)) { adapt->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY; adapt->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY; } adapt->nFormats = NUM_FORMATS; adapt->pFormats = intel_xv_formats; adapt->nPorts = 1; adapt->pPortPrivates = (DevUnion *) (&adapt[1]); adaptor_priv = (intel_adaptor_private *)&adapt->pPortPrivates[1]; adapt->pPortPrivates[0].ptr = (pointer) (adaptor_priv); adapt->nAttributes = NUM_ATTRIBUTES; if (INTEL_INFO(intel)->gen >= 030) adapt->nAttributes += GAMMA_ATTRIBUTES; /* has gamma */ adapt->pAttributes = xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes); /* Now copy the attributes */ att = adapt->pAttributes; memcpy((char *)att, (char *)intel_xv_attributes, sizeof(XF86AttributeRec) * NUM_ATTRIBUTES); att += NUM_ATTRIBUTES; if (INTEL_INFO(intel)->gen >= 030) { memcpy((char *)att, (char *)intel_xv_gamma_attributes, sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES); } adapt->nImages = NUM_IMAGES - XVMC_IMAGE; adapt->pImages = intel_xv_images; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; adapt->GetStill = NULL; adapt->StopVideo = intel_video_stop_video; adapt->SetPortAttribute = intel_video_overlay_set_port_attribute; adapt->GetPortAttribute = intel_video_get_port_attribute; adapt->QueryBestSize = intel_video_query_best_size; adapt->PutImage = intel_video_overlay_put_image; adapt->QueryImageAttributes = intel_video_query_image_attributes; adaptor_priv->textured = FALSE; adaptor_priv->colorKey = intel->colorKey & ((1 << scrn->depth) - 1); adaptor_priv->videoStatus = 0; adaptor_priv->brightness = -19; /* (255/219) * -16 */ adaptor_priv->contrast = 75; /* 255/219 * 64 */ adaptor_priv->saturation = 146; /* 128/112 * 128 */ adaptor_priv->desired_crtc = NULL; adaptor_priv->buf = NULL; adaptor_priv->old_buf[0] = NULL; adaptor_priv->old_buf[1] = NULL; adaptor_priv->gamma5 = 0xc0c0c0; adaptor_priv->gamma4 = 0x808080; adaptor_priv->gamma3 = 0x404040; adaptor_priv->gamma2 = 0x202020; adaptor_priv->gamma1 = 0x101010; adaptor_priv->gamma0 = 0x080808; adaptor_priv->rotation = RR_Rotate_0; /* gotta uninit this someplace */ REGION_NULL(screen, &adaptor_priv->clip); intel->adaptor = adapt; intel_xv_ColorKey = MAKE_ATOM("XV_COLORKEY"); intel_xv_Brightness = MAKE_ATOM("XV_BRIGHTNESS"); intel_xv_Contrast = MAKE_ATOM("XV_CONTRAST"); intel_xv_Saturation = MAKE_ATOM("XV_SATURATION"); /* Allow the pipe to be switched from pipe A to B when in clone mode */ intel_xv_Pipe = MAKE_ATOM("XV_PIPE"); if (INTEL_INFO(intel)->gen >= 030) { intel_xv_Gamma0 = MAKE_ATOM("XV_GAMMA0"); intel_xv_Gamma1 = MAKE_ATOM("XV_GAMMA1"); intel_xv_Gamma2 = MAKE_ATOM("XV_GAMMA2"); intel_xv_Gamma3 = MAKE_ATOM("XV_GAMMA3"); intel_xv_Gamma4 = MAKE_ATOM("XV_GAMMA4"); intel_xv_Gamma5 = MAKE_ATOM("XV_GAMMA5"); } intel_overlay_update_attrs(intel); return adapt; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/intel_video_overlay.h000066400000000000000000000035471267532330400261030ustar00rootroot00000000000000/*************************************************************************** Copyright 2000 Intel Corporation. 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 INTEL, 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. **************************************************************************/ /* * i830_video.c: i830/i845 Xv driver. * * Copyright © 2002 by Alan Hourihane and David Dawes * * Authors: * Alan Hourihane * David Dawes * * Derived from i810 Xv driver: * * Authors of i810 code: * Jonathan Bian * Offscreen Images: * Matt Sottek */ #ifndef _INTEL_VIDEO_OVERLAY_H_ #define _INTEL_VIDEO_OVERLAY_H_ XF86VideoAdaptorPtr intel_video_overlay_setup_image(ScreenPtr); void intel_video_overlay_off(intel_screen_private *intel); #endif /* _INTEL_VIDEO_OVERLAY_H_ */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa-accel.c000066400000000000000000000665331267532330400237020ustar00rootroot00000000000000 /* * Copyright ® 2001 Keith Packard * * Partly based on code that is Copyright ® The XFree86 Project Inc. * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: * Eric Anholt * Michel Dänzer * */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include "uxa-priv.h" #include #include "dixfontstr.h" #include "uxa.h" static void uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr dst_pixmap; BoxPtr pbox; int nbox; int x1, x2, y; int off_x, off_y; if (uxa_screen->force_fallback) goto fallback; if (pGC->fillStyle != FillSolid) goto fallback; dst_pixmap = uxa_get_offscreen_pixmap(pDrawable, &off_x, &off_y); if (!dst_pixmap) goto fallback; if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask)) goto fallback; if (!(*uxa_screen->info->prepare_solid) (dst_pixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) goto fallback; while (n--) { x1 = ppt->x; y = ppt->y; x2 = x1 + (int)*pwidth; ppt++; pwidth++; nbox = REGION_NUM_RECTS(pClip); pbox = REGION_RECTS(pClip); while (nbox--) { int X1 = x1, X2 = x2; if (X1 < pbox->x1) X1 = pbox->x1; if (X2 > pbox->x2) X2 = pbox->x2; if (X2 > X1 && pbox->y1 <= y && pbox->y2 > y) (*uxa_screen->info->solid) (dst_pixmap, X1 + off_x, y + off_y, X2 + off_x, y + 1 + off_y); pbox++; } } (*uxa_screen->info->done_solid) (dst_pixmap); return; fallback: uxa_check_fill_spans(pDrawable, pGC, n, ppt, pwidth, fSorted); } static Bool uxa_do_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int format, char *bits, int src_stride) { uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); PixmapPtr pPix; RegionPtr pClip; BoxPtr pbox; int nbox; int xoff, yoff; int bpp = pDrawable->bitsPerPixel; /* Don't bother with under 8bpp, XYPixmaps. */ if (format != ZPixmap || bpp < 8) return FALSE; if (uxa_screen->force_fallback) return FALSE; if (!uxa_screen->info->put_image) return FALSE; /* Only accelerate copies: no rop or planemask. */ if (!UXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) return FALSE; pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff); if (!pPix) return FALSE; x += pDrawable->x; y += pDrawable->y; pClip = fbGetCompositeClip(pGC); for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); nbox--; pbox++) { int x1 = x; int y1 = y; int x2 = x + w; int y2 = y + h; char *src; Bool ok; if (x1 < pbox->x1) x1 = pbox->x1; if (y1 < pbox->y1) y1 = pbox->y1; if (x2 > pbox->x2) x2 = pbox->x2; if (y2 > pbox->y2) y2 = pbox->y2; if (x1 >= x2 || y1 >= y2) continue; src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); ok = uxa_screen->info->put_image(pPix, x1 + xoff, y1 + yoff, x2 - x1, y2 - y1, src, src_stride); /* If we fail to accelerate the upload, fall back to using * unaccelerated fb calls. */ if (!ok) { FbStip *dst; FbStride dst_stride; int dstBpp; int dstXoff, dstYoff; if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) return FALSE; fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, dstXoff, dstYoff); fbBltStip((FbStip *) bits + (y1 - y) * (src_stride / sizeof(FbStip)), src_stride / sizeof(FbStip), (x1 - x) * dstBpp, dst + (y1 + dstYoff) * dst_stride, dst_stride, (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp, y2 - y1, GXcopy, FB_ALLONES, dstBpp); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } return TRUE; } static void uxa_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { if (!uxa_do_put_image(pDrawable, pGC, depth, x, y, w, h, format, bits, PixmapBytePad(w, pDrawable->depth))) { uxa_check_put_image(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); } } static inline Bool uxa_copy_n_to_n_two_dir(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) { uxa_screen_t *uxa_screen = uxa_get_screen(pDstDrawable->pScreen); PixmapPtr pSrcPixmap, pDstPixmap; int src_off_x, src_off_y, dst_off_x, dst_off_y; int dirsetup; /* Need to get both pixmaps to call the driver routines */ pSrcPixmap = uxa_get_offscreen_pixmap(pSrcDrawable, &src_off_x, &src_off_y); pDstPixmap = uxa_get_offscreen_pixmap(pDstDrawable, &dst_off_x, &dst_off_y); if (!pSrcPixmap || !pDstPixmap) return FALSE; /* * Now the case of a chip that only supports xdir = ydir = 1 or * xdir = ydir = -1, but we have xdir != ydir. */ dirsetup = 0; /* No direction set up yet. */ for (; nbox; pbox++, nbox--) { if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { /* Do a xdir = ydir = -1 blit instead. */ if (dirsetup != -1) { if (dirsetup != 0) uxa_screen->info->done_copy(pDstPixmap); dirsetup = -1; if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap, -1, -1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } (*uxa_screen->info->copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy, dst_off_x + pbox->x1, dst_off_y + pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { /* Do a xdir = ydir = 1 blit instead. */ if (dirsetup != 1) { if (dirsetup != 0) uxa_screen->info->done_copy(pDstPixmap); dirsetup = 1; if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap, 1, 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } (*uxa_screen->info->copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy, dst_off_x + pbox->x1, dst_off_y + pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); } else if (dx >= 0) { /* * xdir = 1, ydir = -1. * Perform line-by-line xdir = ydir = 1 blits, going up. */ int i; if (dirsetup != 1) { if (dirsetup != 0) uxa_screen->info->done_copy(pDstPixmap); dirsetup = 1; if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap, 1, 1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--) (*uxa_screen->info->copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy + i, dst_off_x + pbox->x1, dst_off_y + pbox->y1 + i, pbox->x2 - pbox->x1, 1); } else { /* * xdir = -1, ydir = 1. * Perform line-by-line xdir = ydir = -1 blits, * going down. */ int i; if (dirsetup != -1) { if (dirsetup != 0) uxa_screen->info->done_copy(pDstPixmap); dirsetup = -1; if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap, -1, -1, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) return FALSE; } for (i = 0; i < pbox->y2 - pbox->y1; i++) (*uxa_screen->info->copy) (pDstPixmap, src_off_x + pbox->x1 + dx, src_off_y + pbox->y1 + dy + i, dst_off_x + pbox->x1, dst_off_y + pbox->y1 + i, pbox->x2 - pbox->x1, 1); } } if (dirsetup != 0) uxa_screen->info->done_copy(pDstPixmap); return TRUE; } void uxa_copy_n_to_n(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = pDstDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); int src_off_x, src_off_y; int dst_off_x, dst_off_y; PixmapPtr pSrcPixmap, pDstPixmap; if (uxa_screen->force_fallback) goto fallback; pSrcPixmap = uxa_get_drawable_pixmap(pSrcDrawable); pDstPixmap = uxa_get_drawable_pixmap(pDstDrawable); if (!pSrcPixmap || !pDstPixmap) goto fallback; if (uxa_screen->info->check_copy && !uxa_screen->info->check_copy(pSrcPixmap, pDstPixmap, pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) goto fallback; uxa_get_drawable_deltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); uxa_get_drawable_deltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); /* Mixed directions must be handled specially if the card is lame */ if ((uxa_screen->info->flags & UXA_TWO_BITBLT_DIRECTIONS) && reverse != upsidedown) { if (uxa_copy_n_to_n_two_dir (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy)) return; goto fallback; } if (!uxa_pixmap_is_offscreen(pDstPixmap)) { int stride, bpp; char *dst; if (!uxa_pixmap_is_offscreen(pSrcPixmap)) goto fallback; if (!uxa_screen->info->get_image) goto fallback; /* Don't bother with under 8bpp, XYPixmaps. */ bpp = pSrcPixmap->drawable.bitsPerPixel; if (bpp != pDstDrawable->bitsPerPixel || bpp < 8) goto fallback; /* Only accelerate copies: no rop or planemask. */ if (pGC && (!UXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask) || pGC->alu != GXcopy)) goto fallback; dst = pDstPixmap->devPrivate.ptr; stride = pDstPixmap->devKind; bpp /= 8; while (nbox--) { if (!uxa_screen->info->get_image(pSrcPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) dst + (pbox->y1 + dst_off_y) * stride + (pbox->x1 + dst_off_x) * bpp, stride)) goto fallback; pbox++; } return; } if (uxa_pixmap_is_offscreen(pSrcPixmap)) { if (!(*uxa_screen->info->prepare_copy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1, pGC ? pGC->alu : GXcopy, pGC ? pGC-> planemask : FB_ALLONES)) goto fallback; while (nbox--) { (*uxa_screen->info->copy) (pDstPixmap, pbox->x1 + dx + src_off_x, pbox->y1 + dy + src_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*uxa_screen->info->done_copy) (pDstPixmap); } else { int stride, bpp; char *src; if (!uxa_screen->info->put_image) goto fallback; /* Don't bother with under 8bpp, XYPixmaps. */ bpp = pSrcPixmap->drawable.bitsPerPixel; if (bpp != pDstDrawable->bitsPerPixel || bpp < 8) goto fallback; /* Only accelerate copies: no rop or planemask. */ if (pGC && (!UXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask) || pGC->alu != GXcopy)) goto fallback; src = pSrcPixmap->devPrivate.ptr; stride = pSrcPixmap->devKind; bpp /= 8; while (nbox--) { if (!uxa_screen->info->put_image(pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, (char *) src + (pbox->y1 + dy + src_off_y) * stride + (pbox->x1 + dx + src_off_x) * bpp, stride)) goto fallback; pbox++; } } return; fallback: UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable, uxa_drawable_location(pSrcDrawable), uxa_drawable_location(pDstDrawable))); if (uxa_prepare_access(pDstDrawable, UXA_ACCESS_RW)) { if (pSrcDrawable == pDstDrawable || uxa_prepare_access(pSrcDrawable, UXA_ACCESS_RO)) { fbCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure); if (pSrcDrawable != pDstDrawable) uxa_finish_access(pSrcDrawable, UXA_ACCESS_RO); } uxa_finish_access(pDstDrawable, UXA_ACCESS_RW); } } RegionPtr uxa_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty) { uxa_screen_t *uxa_screen = uxa_get_screen(pDstDrawable->pScreen); if (uxa_screen->force_fallback) { return uxa_check_copy_area(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty); } return miDoCopy(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, uxa_copy_n_to_n, 0, NULL); } static void uxa_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { int i; xRectangle *prect; /* If we can't reuse the current GC as is, don't bother accelerating the * points. */ if (pGC->fillStyle != FillSolid) { uxa_check_poly_point(pDrawable, pGC, mode, npt, ppt); return; } prect = malloc(sizeof(xRectangle) * npt); if (!prect) return; for (i = 0; i < npt; i++) { prect[i].x = ppt[i].x; prect[i].y = ppt[i].y; if (i > 0 && mode == CoordModePrevious) { prect[i].x += prect[i - 1].x; prect[i].y += prect[i - 1].y; } prect[i].width = 1; prect[i].height = 1; } pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect); free(prect); } /** * uxa_poly_lines() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void uxa_poly_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { xRectangle *prect; int x1, x2, y1, y2; int i; /* Don't try to do wide lines or non-solid fill style. */ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { uxa_check_poly_lines(pDrawable, pGC, mode, npt, ppt); return; } prect = malloc(sizeof(xRectangle) * (npt - 1)); if (!prect) return; x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; } else { x2 = ppt[i + 1].x; y2 = ppt[i + 1].y; } if (x1 != x2 && y1 != y2) { free(prect); uxa_check_poly_lines(pDrawable, pGC, mode, npt, ppt); return; } if (x1 < x2) { prect[i].x = x1; prect[i].width = x2 - x1 + 1; } else { prect[i].x = x2; prect[i].width = x1 - x2 + 1; } if (y1 < y2) { prect[i].y = y1; prect[i].height = y2 - y1 + 1; } else { prect[i].y = y2; prect[i].height = y1 - y2 + 1; } x1 = x2; y1 = y2; } pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect); free(prect); } static BoxRec box_from_seg(const xSegment *seg, GCPtr gc) { BoxRec b; if (seg->x1 == seg->x2) { if (seg->y1 > seg->y2) { b.y2 = seg->y1 + 1; b.y1 = seg->y2 + 1; if (gc->capStyle != CapNotLast) b.y1--; } else { b.y1 = seg->y1; b.y2 = seg->y2; if (gc->capStyle != CapNotLast) b.y2++; } b.x1 = seg->x1; b.x2 = seg->x1 + 1; } else { if (seg->x1 > seg->x2) { b.x2 = seg->x1 + 1; b.x1 = seg->x2 + 1; if (gc->capStyle != CapNotLast) b.x1--; } else { b.x1 = seg->x1; b.x2 = seg->x2; if (gc->capStyle != CapNotLast) b.x2++; } b.y1 = seg->y1; b.y2 = seg->y1 + 1; } return b; } /** * uxa_poly_segment() checks if it can accelerate the lines as a group of * horizontal or vertical lines (rectangles), and uses existing rectangle fill * acceleration if so. */ static void uxa_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg) { xRectangle *prect; int i; /* Don't try to do wide lines or non-solid fill style. */ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) { uxa_check_poly_segment(pDrawable, pGC, nseg, pSeg); return; } /* If we have any non-horizontal/vertical, fall back. */ for (i = 0; i < nseg; i++) { if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { uxa_check_poly_segment(pDrawable, pGC, nseg, pSeg); return; } } prect = malloc(sizeof(xRectangle) * nseg); if (!prect) return; for (i = 0; i < nseg; i++) { BoxRec b = box_from_seg(&pSeg[i], pGC); prect[i].x = b.x1; prect[i].y = b.y1; prect[i].width = b.x2 - b.x1; prect[i].height = b.y2 - b.y1; } pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); free(prect); } static Bool uxa_fill_region_solid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, CARD32 planemask, CARD32 alu); static void uxa_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle * prect) { uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); RegionPtr pClip = fbGetCompositeClip(pGC); PixmapPtr pPixmap; RegionPtr pReg; BoxPtr pbox; int fullX1, fullX2, fullY1, fullY2; int xoff, yoff; int xorg, yorg; int n; /* Compute intersection of rects and clip region */ pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); REGION_INTERSECT(pScreen, pReg, pClip, pReg); if (!REGION_NUM_RECTS(pReg)) goto out; if (uxa_screen->force_fallback) goto fallback; pPixmap = uxa_get_offscreen_pixmap (pDrawable, &xoff, &yoff); if (!pPixmap) goto fallback; /* For ROPs where overlaps don't matter, convert rectangles to region * and call uxa_fill_region_{solid,tiled}. */ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop || pGC->alu == GXcopyInverted || pGC->alu == GXset)) { if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && uxa_fill_region_solid(pDrawable, pReg, pGC->fillStyle == FillSolid ? pGC->fgPixel : pGC->tile. pixel, pGC->planemask, pGC->alu)) || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && uxa_fill_region_tiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu))) { goto out; } } if (pGC->fillStyle != FillSolid && !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) { goto fallback; } if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask)) { goto fallback; } if (!(*uxa_screen->info->prepare_solid) (pPixmap, pGC->alu, pGC->planemask, pGC->fgPixel)) { fallback: uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect); goto out; } xorg = pDrawable->x; yorg = pDrawable->y; while (nrect--) { fullX1 = prect->x + xorg; fullY1 = prect->y + yorg; fullX2 = fullX1 + (int)prect->width; fullY2 = fullY1 + (int)prect->height; prect++; n = REGION_NUM_RECTS(pClip); pbox = REGION_RECTS(pClip); /* * clip the rectangle to each box in the clip region * this is logically equivalent to calling Intersect(), * but rectangles may overlap each other here. */ while (n--) { int x1 = fullX1; int x2 = fullX2; int y1 = fullY1; int y2 = fullY2; if (pbox->x1 > x1) x1 = pbox->x1; if (pbox->x2 < x2) x2 = pbox->x2; if (pbox->y1 > y1) y1 = pbox->y1; if (pbox->y2 < y2) y2 = pbox->y2; pbox++; if (x1 >= x2 || y1 >= y2) continue; (*uxa_screen->info->solid) (pPixmap, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); } } (*uxa_screen->info->done_solid) (pPixmap); out: REGION_UNINIT(pScreen, pReg); REGION_DESTROY(pScreen, pReg); } void uxa_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { uxa_check_get_spans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); } static void uxa_set_spans(DrawablePtr pDrawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int n, int sorted) { uxa_check_set_spans(pDrawable, gc, src, points, widths, n, sorted); } static RegionPtr uxa_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { return uxa_check_copy_plane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); } static void uxa_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { uxa_check_image_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); } static void uxa_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { uxa_check_poly_glyph_blt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); } static void uxa_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { uxa_check_push_pixels(pGC, pBitmap, pDrawable, w, h, x, y); } const GCOps uxa_ops = { uxa_fill_spans, uxa_set_spans, uxa_put_image, uxa_copy_area, uxa_copy_plane, uxa_poly_point, uxa_poly_lines, uxa_poly_segment, miPolyRectangle, uxa_check_poly_arc, miFillPolygon, uxa_poly_fill_rect, miPolyFillArc, miPolyText8, miPolyText16, miImageText8, miImageText16, uxa_image_glyph_blt, uxa_poly_glyph_blt, uxa_push_pixels, }; void uxa_copy_window(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { RegionRec rgnDst; int dx, dy; PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); dx = ptOldOrg.x - pWin->drawable.x; dy = ptOldOrg.y - pWin->drawable.y; REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0); REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); #ifdef COMPOSITE if (pPixmap->screen_x || pPixmap->screen_y) REGION_TRANSLATE(pWin->drawable.pScreen, &rgnDst, -pPixmap->screen_x, -pPixmap->screen_y); #endif miCopyRegion(&pPixmap->drawable, &pPixmap->drawable, NULL, &rgnDst, dx, dy, uxa_copy_n_to_n, 0, NULL); REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); } static Bool uxa_fill_region_solid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, CARD32 planemask, CARD32 alu) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); PixmapPtr pixmap; int xoff, yoff; int nbox; BoxPtr pBox; Bool ret = FALSE; pixmap = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff); if (!pixmap) return FALSE; REGION_TRANSLATE(screen, pRegion, xoff, yoff); nbox = REGION_NUM_RECTS(pRegion); pBox = REGION_RECTS(pRegion); if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(&pixmap->drawable, alu, planemask)) goto err; if (!uxa_screen->info->prepare_solid(pixmap, alu, planemask, pixel)) goto err; while (nbox--) { uxa_screen->info->solid(pixmap, pBox->x1, pBox->y1, pBox->x2, pBox->y2); pBox++; } uxa_screen->info->done_solid(pixmap); ret = TRUE; err: REGION_TRANSLATE(screen, pRegion, -xoff, -yoff); return ret; } /* Try to do an accelerated tile of the pTile into pRegion of pDrawable. * Based on fbFillRegionTiled(), fbTile(). */ Bool uxa_fill_region_tiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu) { uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen); PixmapPtr pPixmap; int xoff, yoff; int tileWidth, tileHeight; int nbox = REGION_NUM_RECTS(pRegion); BoxPtr pBox = REGION_RECTS(pRegion); Bool ret = FALSE; tileWidth = pTile->drawable.width; tileHeight = pTile->drawable.height; /* If we're filling with a solid color, grab it out and go to * FillRegionsolid, saving numerous copies. */ if (tileWidth == 1 && tileHeight == 1) return uxa_fill_region_solid(pDrawable, pRegion, uxa_get_pixmap_first_pixel(pTile), planemask, alu); pPixmap = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff); if (!pPixmap || !uxa_pixmap_is_offscreen(pTile)) goto out; if (uxa_screen->info->check_copy && !uxa_screen->info->check_copy(pTile, pPixmap, alu, planemask)) return FALSE; REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); if ((*uxa_screen->info->prepare_copy) (pTile, pPixmap, 1, 1, alu, planemask)) { while (nbox--) { int height = pBox->y2 - pBox->y1; int dstY = pBox->y1; int tileY; modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); while (height > 0) { int width = pBox->x2 - pBox->x1; int dstX = pBox->x1; int tileX; int h = tileHeight - tileY; if (h > height) h = height; height -= h; modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth, tileX); while (width > 0) { int w = tileWidth - tileX; if (w > width) w = width; width -= w; (*uxa_screen->info->copy) (pPixmap, tileX, tileY, dstX, dstY, w, h); dstX += w; tileX = 0; } dstY += h; tileY = 0; } pBox++; } (*uxa_screen->info->done_copy) (pPixmap); ret = TRUE; } out: REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); return ret; } /** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); BoxRec Box; PixmapPtr pPix = uxa_get_drawable_pixmap(pDrawable); int xoff, yoff; Bool ok; uxa_get_drawable_deltas(pDrawable, pPix, &xoff, &yoff); Box.x1 = pDrawable->y + x + xoff; Box.y1 = pDrawable->y + y + yoff; Box.x2 = Box.x1 + w; Box.y2 = Box.y1 + h; if (uxa_screen->force_fallback) goto fallback; pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff); if (pPix == NULL || uxa_screen->info->get_image == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !UXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to * think about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = uxa_screen->info->get_image(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) return; fallback: UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) { fbGetImage(pDrawable, x, y, w, h, format, planeMask, d); uxa_finish_access(pDrawable, UXA_ACCESS_RO); } return; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa-glyphs.c000066400000000000000000000627261267532330400241410ustar00rootroot00000000000000/* * Copyright © 2010 Intel Corporation * Partly based on code Copyright © 2008 Red Hat, Inc. * Partly based on code Copyright © 2000 SuSE, Inc. * * 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, and that the name of Intel not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Intel makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL INTEL * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * 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, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * 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, and that the name of SuSE not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. SuSE makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Chris Wilson * Based on code by: Keith Packard and Owen Taylor */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "uxa-priv.h" #include "common.h" /* Width of the pixmaps we use for the caches; this should be less than * max texture size of the driver; this may need to actually come from * the driver. */ #define CACHE_PICTURE_SIZE 1024 #define GLYPH_MIN_SIZE 8 #define GLYPH_MAX_SIZE 64 #define GLYPH_CACHE_SIZE (CACHE_PICTURE_SIZE * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE)) struct uxa_glyph { uxa_glyph_cache_t *cache; uint16_t x, y; uint16_t size, pos; }; #if HAS_DEVPRIVATEKEYREC static DevPrivateKeyRec uxa_glyph_key; #else static int uxa_glyph_key; #endif static inline struct uxa_glyph *uxa_glyph_get_private(GlyphPtr glyph) { #if HAS_DEVPRIVATEKEYREC return dixGetPrivate(&glyph->devPrivates, &uxa_glyph_key); #else return dixLookupPrivate(&glyph->devPrivates, &uxa_glyph_key); #endif } static inline void uxa_glyph_set_private(GlyphPtr glyph, struct uxa_glyph *priv) { dixSetPrivate(&glyph->devPrivates, &uxa_glyph_key, priv); } #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) static void uxa_unrealize_glyph_caches(ScreenPtr pScreen) { uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); int i; if (!uxa_screen->glyph_cache_initialized) return; for (i = 0; i < UXA_NUM_GLYPH_CACHE_FORMATS; i++) { uxa_glyph_cache_t *cache = &uxa_screen->glyphCaches[i]; if (cache->picture) FreePicture(cache->picture, 0); if (cache->glyphs) free(cache->glyphs); } uxa_screen->glyph_cache_initialized = FALSE; } void uxa_glyphs_fini(ScreenPtr pScreen) { uxa_unrealize_glyph_caches(pScreen); } /* All caches for a single format share a single pixmap for glyph storage, * allowing mixing glyphs of different sizes without paying a penalty * for switching between source pixmaps. (Note that for a size of font * right at the border between two sizes, we might be switching for almost * every glyph.) * * This function allocates the storage pixmap, and then fills in the * rest of the allocated structures for all caches with the given format. */ static Bool uxa_realize_glyph_caches(ScreenPtr pScreen) { uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); unsigned int formats[] = { PIXMAN_a8, PIXMAN_a8r8g8b8, }; unsigned i; if (uxa_screen->glyph_cache_initialized) return TRUE; uxa_screen->glyph_cache_initialized = TRUE; memset(uxa_screen->glyphCaches, 0, sizeof(uxa_screen->glyphCaches)); for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) { uxa_glyph_cache_t *cache = &uxa_screen->glyphCaches[i]; PixmapPtr pixmap; PicturePtr picture; CARD32 component_alpha; int depth = PIXMAN_FORMAT_DEPTH(formats[i]); int error; PictFormatPtr pPictFormat = PictureMatchFormat(pScreen, depth, formats[i]); if (!pPictFormat) goto bail; /* Now allocate the pixmap and picture */ pixmap = pScreen->CreatePixmap(pScreen, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, depth, INTEL_CREATE_PIXMAP_TILING_X); if (!pixmap) goto bail; if (!uxa_pixmap_is_offscreen(pixmap)) { /* Presume shadow is in-effect */ pScreen->DestroyPixmap(pixmap); uxa_unrealize_glyph_caches(pScreen); return TRUE; } component_alpha = NeedsComponent(pPictFormat->format); picture = CreatePicture(0, &pixmap->drawable, pPictFormat, CPComponentAlpha, &component_alpha, serverClient, &error); pScreen->DestroyPixmap(pixmap); if (!picture) goto bail; ValidatePicture(picture); cache->picture = picture; cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE); if (!cache->glyphs) goto bail; cache->evict = rand() % GLYPH_CACHE_SIZE; } assert(i == UXA_NUM_GLYPH_CACHE_FORMATS); return TRUE; bail: uxa_unrealize_glyph_caches(pScreen); return FALSE; } Bool uxa_glyphs_init(ScreenPtr pScreen) { #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&uxa_glyph_key, PRIVATE_GLYPH, 0)) return FALSE; #else if (!dixRequestPrivate(&uxa_glyph_key, 0)) return FALSE; #endif /* Skip pixmap creation if we don't intend to use it. */ if (uxa_get_screen(pScreen)->force_fallback) return TRUE; return uxa_realize_glyph_caches(pScreen); } /* The most efficient thing to way to upload the glyph to the screen * is to use CopyArea; uxa pixmaps are always offscreen. */ static void uxa_glyph_cache_upload_glyph(ScreenPtr screen, uxa_glyph_cache_t * cache, GlyphPtr glyph, int x, int y) { PicturePtr pGlyphPicture = GetGlyphPicture(glyph, screen); PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; PixmapPtr scratch; GCPtr gc; gc = GetScratchGC(pCachePixmap->drawable.depth, screen); if (!gc) return; ValidateGC(&pCachePixmap->drawable, gc); scratch = pGlyphPixmap; /* Create a temporary bo to stream the updates to the cache */ if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth || !uxa_pixmap_is_offscreen(scratch)) { scratch = screen->CreatePixmap(screen, glyph->info.width, glyph->info.height, pCachePixmap->drawable.depth, UXA_CREATE_PIXMAP_FOR_MAP); if (scratch) { if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) { PicturePtr picture; int error; picture = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, pCachePixmap->drawable.depth, cache->picture->format), 0, NULL, serverClient, &error); if (picture) { ValidatePicture(picture); uxa_composite(PictOpSrc, pGlyphPicture, NULL, picture, 0, 0, 0, 0, 0, 0, glyph->info.width, glyph->info.height); FreePicture(picture, 0); } } else { uxa_copy_area(&pGlyphPixmap->drawable, &scratch->drawable, gc, 0, 0, glyph->info.width, glyph->info.height, 0, 0); } } else { scratch = pGlyphPixmap; } } uxa_copy_area(&scratch->drawable, &pCachePixmap->drawable, gc, 0, 0, glyph->info.width, glyph->info.height, x, y); if (scratch != pGlyphPixmap) screen->DestroyPixmap(scratch); FreeScratchGC(gc); } void uxa_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) { struct uxa_glyph *priv; /* Use Lookup in case we have not attached to this glyph. */ priv = dixLookupPrivate(&glyph->devPrivates, &uxa_glyph_key); if (priv == NULL) return; priv->cache->glyphs[priv->pos] = NULL; uxa_glyph_set_private(glyph, NULL); free(priv); } /* Cut and paste from render/glyph.c - probably should export it instead */ static void uxa_glyph_extents(int nlist, GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents) { int x1, x2, y1, y2; int x, y, n; x1 = y1 = MAXSHORT; x2 = y2 = MINSHORT; x = y = 0; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; list++; while (n--) { GlyphPtr glyph = *glyphs++; int v; v = x - glyph->info.x; if (v < x1) x1 = v; v += glyph->info.width; if (v > x2) x2 = v; v = y - glyph->info.y; if (v < y1) y1 = v; v += glyph->info.height; if (v > y2) y2 = v; x += glyph->info.xOff; y += glyph->info.yOff; } } extents->x1 = x1 < MINSHORT ? MINSHORT : x1; extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2; extents->y1 = y1 < MINSHORT ? MINSHORT : y1; extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2; } /** * Returns TRUE if the glyphs in the lists intersect. Only checks based on * bounding box, which appears to be good enough to catch most cases at least. */ static Bool uxa_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs) { int x1, x2, y1, y2; int n; int x, y; BoxRec extents; Bool first = TRUE; x = 0; y = 0; extents.x1 = 0; extents.y1 = 0; extents.x2 = 0; extents.y2 = 0; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; list++; while (n--) { GlyphPtr glyph = *glyphs++; if (glyph->info.width == 0 || glyph->info.height == 0) { x += glyph->info.xOff; y += glyph->info.yOff; continue; } x1 = x - glyph->info.x; if (x1 < MINSHORT) x1 = MINSHORT; y1 = y - glyph->info.y; if (y1 < MINSHORT) y1 = MINSHORT; x2 = x1 + glyph->info.width; if (x2 > MAXSHORT) x2 = MAXSHORT; y2 = y1 + glyph->info.height; if (y2 > MAXSHORT) y2 = MAXSHORT; if (first) { extents.x1 = x1; extents.y1 = y1; extents.x2 = x2; extents.y2 = y2; first = FALSE; } else { if (x1 < extents.x2 && x2 > extents.x1 && y1 < extents.y2 && y2 > extents.y1) { return TRUE; } if (x1 < extents.x1) extents.x1 = x1; if (x2 > extents.x2) extents.x2 = x2; if (y1 < extents.y1) extents.y1 = y1; if (y2 > extents.y2) extents.y2 = y2; } x += glyph->info.xOff; y += glyph->info.yOff; } } return FALSE; } static void uxa_check_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { pixman_image_t *image; PixmapPtr scratch; PicturePtr mask, mask_src = NULL, mask_dst = NULL, white = NULL; int width = 0, height = 0; int x, y, n; int xDst = list->xOff, yDst = list->yOff; BoxRec extents = { 0, 0, 0, 0 }; CARD8 mask_op = 0; if (maskFormat) { pixman_format_code_t format; CARD32 component_alpha; xRenderColor color; int error; uxa_glyph_extents(nlist, list, glyphs, &extents); if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) return; width = extents.x2 - extents.x1; height = extents.y2 - extents.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; scratch = GetScratchPixmapHeader(dst->pDrawable->pScreen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!scratch) { pixman_image_unref(image); return; } component_alpha = NeedsComponent(maskFormat->format); mask = CreatePicture(0, &scratch->drawable, maskFormat, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) { FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } ValidatePicture(mask); x = -extents.x1; y = -extents.y1; color.red = color.green = color.blue = color.alpha = 0xffff; white = CreateSolidPicture(0, &color, &error); mask_op = op; op = PictOpAdd; mask_src = src; src = white; mask_dst = dst; dst = mask; } else { mask = dst; x = 0; y = 0; } while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { GlyphPtr glyph = *glyphs++; PicturePtr g = GetGlyphPicture(glyph, dst->pDrawable->pScreen); if (g) { CompositePicture(op, src, g, dst, xSrc + (x - glyph->info.x) - xDst, ySrc + (y - glyph->info.y) - yDst, 0, 0, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); } x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (white) FreePicture(white, 0); if (maskFormat) { x = extents.x1; y = extents.y1; CompositePicture(mask_op, mask_src, mask, mask_dst, xSrc + x - xDst, ySrc + y - yDst, 0, 0, x, y, width, height); FreePicture(mask, 0); FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } } static inline unsigned int uxa_glyph_size_to_count(int size) { size /= GLYPH_MIN_SIZE; return size * size; } static inline unsigned int uxa_glyph_count_to_mask(int count) { return ~(count - 1); } static inline unsigned int uxa_glyph_size_to_mask(int size) { return uxa_glyph_count_to_mask(uxa_glyph_size_to_count(size)); } static PicturePtr uxa_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x, int *out_y) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); PicturePtr glyph_picture = GetGlyphPicture(glyph, screen); uxa_glyph_cache_t *cache = &uxa_screen->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0]; struct uxa_glyph *priv = NULL; int size, mask, pos, s; if (glyph->info.width > GLYPH_MAX_SIZE || glyph->info.height > GLYPH_MAX_SIZE) return NULL; for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) if (glyph->info.width <= size && glyph->info.height <= size) break; s = uxa_glyph_size_to_count(size); mask = uxa_glyph_count_to_mask(s); pos = (cache->count + s - 1) & mask; if (pos < GLYPH_CACHE_SIZE) { cache->count = pos + s; } else { for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) { int i = cache->evict & uxa_glyph_size_to_mask(s); GlyphPtr evicted = cache->glyphs[i]; if (evicted == NULL) continue; priv = uxa_glyph_get_private(evicted); if (priv->size >= s) { cache->glyphs[i] = NULL; uxa_glyph_set_private(evicted, NULL); pos = cache->evict & uxa_glyph_size_to_mask(size); } else priv = NULL; break; } if (priv == NULL) { int count = uxa_glyph_size_to_count(size); mask = uxa_glyph_count_to_mask(count); pos = cache->evict & mask; for (s = 0; s < count; s++) { GlyphPtr evicted = cache->glyphs[pos + s]; if (evicted != NULL) { if (priv != NULL) free(priv); priv = uxa_glyph_get_private(evicted); uxa_glyph_set_private(evicted, NULL); cache->glyphs[pos + s] = NULL; } } } /* And pick a new eviction position */ cache->evict = rand() % GLYPH_CACHE_SIZE; } if (priv == NULL) { priv = malloc(sizeof(struct uxa_glyph)); if (priv == NULL) return NULL; } uxa_glyph_set_private(glyph, priv); cache->glyphs[pos] = glyph; priv->cache = cache; priv->size = size; priv->pos = pos; s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) { if (pos & 1) priv->x += s; if (pos & 2) priv->y += s; pos >>= 2; } uxa_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y); *out_x = priv->x; *out_y = priv->y; return cache->picture; } static void uxa_clear_pixmap(ScreenPtr screen, uxa_screen_t *uxa_screen, PixmapPtr pixmap) { if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(&pixmap->drawable, GXcopy, FB_ALLONES)) goto fallback; if (!uxa_screen->info->prepare_solid(pixmap, GXcopy, FB_ALLONES, 0)) goto fallback; uxa_screen->info->solid(pixmap, 0, 0, pixmap->drawable.width, pixmap->drawable.height); uxa_screen->info->done_solid(pixmap); return; fallback: { GCPtr gc; gc = GetScratchGC(pixmap->drawable.depth, screen); if (gc) { xRectangle rect; ValidateGC(&pixmap->drawable, gc); rect.x = 0; rect.y = 0; rect.width = pixmap->drawable.width; rect.height = pixmap->drawable.height; gc->ops->PolyFillRect(&pixmap->drawable, gc, 1, &rect); FreeScratchGC(gc); } } } static PicturePtr create_white_solid(ScreenPtr screen) { PicturePtr white, ret = NULL; xRenderColor color; int error; color.red = color.green = color.blue = color.alpha = 0xffff; white = CreateSolidPicture(0, &color, &error); if (white) { ret = uxa_acquire_solid(screen, white->pSourcePict); FreePicture(white, 0); } return ret; } static int uxa_glyphs_via_mask(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { ScreenPtr screen = pDst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); CARD32 component_alpha; PixmapPtr pixmap, white_pixmap; PicturePtr glyph_atlas, mask, white; int xDst = list->xOff, yDst = list->yOff; int x, y, width, height; int dst_off_x, dst_off_y; int n, error; BoxRec box; uxa_glyph_extents(nlist, list, glyphs, &box); if (box.x2 <= box.x1 || box.y2 <= box.y1) return 0; dst_off_x = box.x1; dst_off_y = box.y1; width = box.x2 - box.x1; height = box.y2 - box.y1; x = -box.x1; y = -box.y1; if (maskFormat->depth == 1) { PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8); if (!a8Format) return -1; maskFormat = a8Format; } pixmap = screen->CreatePixmap(screen, width, height, maskFormat->depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pixmap) return 1; if (!uxa_pixmap_is_offscreen(pixmap)) { screen->DestroyPixmap(pixmap); return -1; } white_pixmap = NULL; white = create_white_solid(screen); if (white) white_pixmap = uxa_get_drawable_pixmap(white->pDrawable); if (!white_pixmap) { if (white) FreePicture(white, 0); screen->DestroyPixmap(pixmap); return -1; } uxa_clear_pixmap(screen, uxa_screen, pixmap); component_alpha = NeedsComponent(maskFormat->format); mask = CreatePicture(0, &pixmap->drawable, maskFormat, CPComponentAlpha, &component_alpha, serverClient, &error); screen->DestroyPixmap(pixmap); if (!mask) { FreePicture(white, 0); return 1; } ValidatePicture(mask); glyph_atlas = NULL; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { GlyphPtr glyph = *glyphs++; PicturePtr this_atlas; int glyph_x, glyph_y; struct uxa_glyph *priv; if (glyph->info.width == 0 || glyph->info.height == 0) goto next_glyph; priv = uxa_glyph_get_private(glyph); if (priv != NULL) { glyph_x = priv->x; glyph_y = priv->y; this_atlas = priv->cache->picture; } else { if (glyph_atlas) { uxa_screen->info->done_composite(pixmap); glyph_atlas = NULL; } this_atlas = uxa_glyph_cache(screen, glyph, &glyph_x, &glyph_y); if (this_atlas == NULL) { /* no cache for this glyph */ this_atlas = GetGlyphPicture(glyph, screen); glyph_x = glyph_y = 0; } } if (this_atlas != glyph_atlas) { PixmapPtr glyph_pixmap; if (glyph_atlas) uxa_screen->info->done_composite(pixmap); glyph_pixmap = uxa_get_drawable_pixmap(this_atlas->pDrawable); if (!uxa_pixmap_is_offscreen(glyph_pixmap) || !uxa_screen->info->prepare_composite(PictOpAdd, white, this_atlas, mask, white_pixmap, glyph_pixmap, pixmap)) { FreePicture(white, 0); FreePicture(mask, 0); return -1; } glyph_atlas = this_atlas; } uxa_screen->info->composite(pixmap, 0, 0, glyph_x, glyph_y, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); next_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (glyph_atlas) uxa_screen->info->done_composite(pixmap); uxa_composite(op, pSrc, mask, pDst, dst_off_x + xSrc - xDst, dst_off_y + ySrc - yDst, 0, 0, dst_off_x, dst_off_y, width, height); FreePicture(white, 0); FreePicture(mask, 0); return 0; } static int uxa_glyphs_to_dst(CARD8 op, PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { ScreenPtr screen = pDst->pDrawable->pScreen; int x, y, n; xSrc -= list->xOff; ySrc -= list->yOff; x = y = 0; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { GlyphPtr glyph = *glyphs++; PicturePtr glyph_atlas; int glyph_x, glyph_y; struct uxa_glyph *priv; if (glyph->info.width == 0 || glyph->info.height == 0) goto next_glyph; priv = uxa_glyph_get_private(glyph); if (priv != NULL) { glyph_x = priv->x; glyph_y = priv->y; glyph_atlas = priv->cache->picture; } else { glyph_atlas = uxa_glyph_cache(screen, glyph, &glyph_x, &glyph_y); if (glyph_atlas == NULL) { /* no cache for this glyph */ glyph_atlas = GetGlyphPicture(glyph, screen); glyph_x = glyph_y = 0; } } uxa_composite(op, pSrc, glyph_atlas, pDst, xSrc + x - glyph->info.x, ySrc + y - glyph->info.y, glyph_x, glyph_y, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); next_glyph: x += glyph->info.xOff; y += glyph->info.yOff; } list++; } return 0; } static Bool is_solid(PicturePtr picture) { if (picture->pSourcePict) { SourcePict *source = picture->pSourcePict; return source->type == SourcePictTypeSolidFill; } else { return (picture->repeat && picture->pDrawable->width == 1 && picture->pDrawable->height == 1); } } void uxa_glyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { ScreenPtr screen = pDst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (!uxa_screen->info->prepare_composite || uxa_screen->force_fallback || !uxa_drawable_is_offscreen(pDst->pDrawable) || pDst->alphaMap || pSrc->alphaMap || /* XXX we fail to handle (rare) non-solid sources correctly. */ !is_solid(pSrc)) { fallback: uxa_check_glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); return; } /* basic sanity check */ if (uxa_screen->info->check_composite && !uxa_screen->info->check_composite(op, pSrc, NULL, pDst, 0, 0)) { goto fallback; } ValidatePicture(pSrc); ValidatePicture(pDst); if (!maskFormat) { /* If we don't have a mask format but all the glyphs have the same format, * require ComponentAlpha and don't intersect, use the glyph format as mask * format for the full benefits of the glyph cache. */ if (NeedsComponent(list[0].format->format)) { Bool sameFormat = TRUE; int i; maskFormat = list[0].format; for (i = 0; i < nlist; i++) { if (maskFormat->format != list[i].format->format) { sameFormat = FALSE; break; } } if (!sameFormat || uxa_glyphs_intersect(nlist, list, glyphs)) maskFormat = NULL; } } if (!maskFormat) { if (uxa_glyphs_to_dst(op, pSrc, pDst, xSrc, ySrc, nlist, list, glyphs)) goto fallback; } else { if (uxa_glyphs_via_mask(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs)) goto fallback; } } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa-priv.h000066400000000000000000000261711267532330400236120ustar00rootroot00000000000000/* * * Copyright © 2000,2008 Keith Packard * 2005 Zack Rusin, Trolltech * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef UXAPRIV_H #define UXAPRIV_H #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_DIX_CONFIG_H #include #else #include #endif #include "xf86.h" #include "uxa.h" #include #include #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" #include "servermd.h" #include "colormapst.h" #include "gcstruct.h" #include "input.h" #include "mipointer.h" #include "mi.h" #include "dix.h" #include "fb.h" #include "fboverlay.h" #ifdef RENDER #include "fbpict.h" #include "glyphstr.h" #endif #include "damage.h" #include "../src/compat-api.h" /* Provide substitutes for gcc's __FUNCTION__ on other compilers */ #if !defined(__GNUC__) && !defined(__FUNCTION__) # if defined(__STDC__) && (__STDC_VERSION__>=199901L) /* C99 */ # define __FUNCTION__ __func__ # else # define __FUNCTION__ "" # endif #endif /* 1.6 and earlier server compat */ #ifndef miGetCompositeClip #define miCopyRegion fbCopyRegion #define miDoCopy fbDoCopy #endif #define DEBUG_MIGRATE 0 #define DEBUG_PIXMAP 0 #define DEBUG_OFFSCREEN 0 #define DEBUG_GLYPH_CACHE 0 #define UXA_FALLBACK(x) \ if (uxa_get_screen(screen)->fallback_debug) { \ ErrorF("UXA fallback at %s: ", __FUNCTION__); \ ErrorF x; \ } char uxa_drawable_location(DrawablePtr pDrawable); #if DEBUG_PIXMAP #define DBG_PIXMAP(a) ErrorF a #else #define DBG_PIXMAP(a) #endif typedef struct { PicturePtr picture; /* Where the glyphs of the cache are stored */ GlyphPtr *glyphs; uint16_t count; uint16_t evict; } uxa_glyph_cache_t; #define UXA_NUM_GLYPH_CACHE_FORMATS 2 typedef struct { uint32_t color; PicturePtr picture; } uxa_solid_cache_t; #define UXA_NUM_SOLID_CACHE 16 typedef void (*EnableDisableFBAccessProcPtr) (int, Bool); typedef struct { uxa_driver_t *info; CreateGCProcPtr SavedCreateGC; CloseScreenProcPtr SavedCloseScreen; GetImageProcPtr SavedGetImage; GetSpansProcPtr SavedGetSpans; CreatePixmapProcPtr SavedCreatePixmap; DestroyPixmapProcPtr SavedDestroyPixmap; CopyWindowProcPtr SavedCopyWindow; ChangeWindowAttributesProcPtr SavedChangeWindowAttributes; BitmapToRegionProcPtr SavedBitmapToRegion; #ifdef RENDER CompositeProcPtr SavedComposite; TrianglesProcPtr SavedTriangles; GlyphsProcPtr SavedGlyphs; TrapezoidsProcPtr SavedTrapezoids; AddTrapsProcPtr SavedAddTraps; UnrealizeGlyphProcPtr SavedUnrealizeGlyph; #endif Bool force_fallback; Bool fallback_debug; uxa_glyph_cache_t glyphCaches[UXA_NUM_GLYPH_CACHE_FORMATS]; Bool glyph_cache_initialized; PicturePtr solid_clear, solid_black, solid_white; uxa_solid_cache_t solid_cache[UXA_NUM_SOLID_CACHE]; int solid_cache_size; } uxa_screen_t; /* * This is the only completely portable way to * compute this info. */ #ifndef BitsPerPixel #define BitsPerPixel(d) (\ PixmapWidthPaddingInfo[d].notPower2 ? \ (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ (PixmapWidthPaddingInfo[d].padRoundUp+1))) #endif #if HAS_DEVPRIVATEKEYREC extern DevPrivateKeyRec uxa_screen_index; #else extern int uxa_screen_index; #endif static inline uxa_screen_t *uxa_get_screen(ScreenPtr screen) { #if HAS_DEVPRIVATEKEYREC return dixGetPrivate(&screen->devPrivates, &uxa_screen_index); #else return dixLookupPrivate(&screen->devPrivates, &uxa_screen_index); #endif } /** Align an offset to an arbitrary alignment */ #define UXA_ALIGN(offset, align) (((offset) + (align) - 1) - \ (((offset) + (align) - 1) % (align))) /** Align an offset to a power-of-two alignment */ #define UXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) typedef struct { INT16 xSrc; INT16 ySrc; INT16 xDst; INT16 yDst; INT16 width; INT16 height; } uxa_composite_rect_t; /** * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place * to set EXA options or hook in screen functions to handle using EXA as the AA. */ void exaDDXDriverInit(ScreenPtr pScreen); Bool uxa_prepare_access_window(WindowPtr pWin); void uxa_finish_access_window(WindowPtr pWin); /* uxa-unaccel.c */ Bool uxa_prepare_access_gc(GCPtr pGC); void uxa_finish_access_gc(GCPtr pGC); void uxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, DDXPointPtr ppt, int *pwidth, int fSorted); void uxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); void uxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits); RegionPtr uxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty); RegionPtr uxa_check_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane); void uxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit); void uxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt); void uxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment * pSegInit); void uxa_check_poly_arc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs); void uxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle * prect); void uxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase); void uxa_check_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase); void uxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y); void uxa_check_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart); void uxa_check_paint_window(WindowPtr pWin, RegionPtr pRegion, int what); void uxa_check_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps); /* uxa-accel.c */ static _X_INLINE Bool uxa_gc_reads_destination(DrawablePtr pDrawable, unsigned long planemask, unsigned int fillStyle, unsigned char alu) { return ((alu != GXcopy && alu != GXclear && alu != GXset && alu != GXcopyInverted) || fillStyle == FillStippled || !UXA_PM_IS_SOLID(pDrawable, planemask)); } void uxa_copy_window(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); Bool uxa_fill_region_tiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu); void uxa_paint_window(WindowPtr pWin, RegionPtr pRegion, int what); void uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d); void uxa_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart); void uxa_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps); extern const GCOps uxa_ops; #ifdef RENDER void uxa_check_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); #endif /* uxa.c */ Bool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access); void uxa_finish_access(DrawablePtr pDrawable, uxa_access_t access); Bool uxa_picture_prepare_access(PicturePtr picture, int mode); void uxa_picture_finish_access(PicturePtr picture, int mode); void uxa_get_drawable_deltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp); Bool uxa_drawable_is_offscreen(DrawablePtr pDrawable); Bool uxa_pixmap_is_offscreen(PixmapPtr p); PixmapPtr uxa_get_offscreen_pixmap(DrawablePtr pDrawable, int *xp, int *yp); PixmapPtr uxa_get_drawable_pixmap(DrawablePtr pDrawable); RegionPtr uxa_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); void uxa_copy_n_to_n(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure); /* uxa_render.c */ Bool uxa_op_reads_destination(CARD8 op); void uxa_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); void uxa_composite_rects(CARD8 op, PicturePtr pSrc, PicturePtr pDst, int nrect, uxa_composite_rect_t * rects); void uxa_solid_rects (CARD8 op, PicturePtr dst, xRenderColor *color, int num_rects, xRectangle *rects); void uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps); void uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris); PicturePtr uxa_acquire_solid(ScreenPtr screen, SourcePict *source); PicturePtr uxa_acquire_drawable(ScreenPtr pScreen, PicturePtr pSrc, INT16 x, INT16 y, CARD16 width, CARD16 height, INT16 * out_x, INT16 * out_y); PicturePtr uxa_acquire_pattern(ScreenPtr pScreen, PicturePtr pSrc, pixman_format_code_t format, INT16 x, INT16 y, CARD16 width, CARD16 height); Bool uxa_get_rgba_from_pixel(CARD32 pixel, CARD16 * red, CARD16 * green, CARD16 * blue, CARD16 * alpha, CARD32 format); /* uxa_glyph.c */ Bool uxa_glyphs_init(ScreenPtr pScreen); void uxa_glyphs_fini(ScreenPtr pScreen); void uxa_glyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs); void uxa_glyph_unrealize(ScreenPtr pScreen, GlyphPtr pGlyph); #endif /* UXAPRIV_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa-render.c000066400000000000000000001421521267532330400241020ustar00rootroot00000000000000/* * Copyright © 2001 Keith Packard * * Partly based on code that is Copyright © The XFree86 Project Inc. * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "uxa-priv.h" #ifdef RENDER #include "mipict.h" static void uxa_composite_fallback_pict_desc(PicturePtr pict, char *string, int n) { char format[20]; char size[20]; char loc; if (!pict) { snprintf(string, n, "None"); return; } if (pict->pDrawable == NULL) { snprintf(string, n, "source-only"); return; } switch (pict->format) { case PICT_a8r8g8b8: snprintf(format, 20, "ARGB8888"); break; case PICT_x8r8g8b8: snprintf(format, 20, "XRGB8888"); 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; } loc = uxa_drawable_is_offscreen(pict->pDrawable) ? 's' : 'm'; snprintf(size, 20, "%dx%d%s", pict->pDrawable->width, pict->pDrawable->height, pict->repeat ? " R" : ""); snprintf(string, n, "%p:%c fmt %s (%s)%s", pict->pDrawable, loc, format, size, pict->alphaMap ? " with alpha map" :""); } static const char * op_to_string(CARD8 op) { switch (op) { #define C(x) case PictOp##x: return #x C(Clear); C(Src); C(Dst); C(Over); C(OverReverse); C(In); C(InReverse); C(Out); C(OutReverse); C(Atop); C(AtopReverse); C(Xor); C(Add); C(Saturate); /* * Operators only available in version 0.2 */ #if RENDER_MAJOR >= 1 || RENDER_MINOR >= 2 C(DisjointClear); C(DisjointSrc); C(DisjointDst); C(DisjointOver); C(DisjointOverReverse); C(DisjointIn); C(DisjointInReverse); C(DisjointOut); C(DisjointOutReverse); C(DisjointAtop); C(DisjointAtopReverse); C(DisjointXor); C(ConjointClear); C(ConjointSrc); C(ConjointDst); C(ConjointOver); C(ConjointOverReverse); C(ConjointIn); C(ConjointInReverse); C(ConjointOut); C(ConjointOutReverse); C(ConjointAtop); C(ConjointAtopReverse); C(ConjointXor); #endif /* * Operators only available in version 0.11 */ #if RENDER_MAJOR >= 1 || RENDER_MINOR >= 11 C(Multiply); C(Screen); C(Overlay); C(Darken); C(Lighten); C(ColorDodge); C(ColorBurn); C(HardLight); C(SoftLight); C(Difference); C(Exclusion); C(HSLHue); C(HSLSaturation); C(HSLColor); C(HSLLuminosity); #endif default: return "garbage"; #undef C } } static void uxa_print_composite_fallback(const char *func, CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) { uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen); char srcdesc[40], maskdesc[40], dstdesc[40]; if (! uxa_screen->fallback_debug) return; /* Limit the noise if fallbacks are expected. */ if (uxa_screen->force_fallback) return; uxa_composite_fallback_pict_desc(pSrc, srcdesc, 40); uxa_composite_fallback_pict_desc(pMask, maskdesc, 40); uxa_composite_fallback_pict_desc(pDst, dstdesc, 40); ErrorF("Composite fallback at %s:\n" " op %s, \n" " src %s, \n" " mask %s, \n" " dst %s, \n", func, op_to_string (op), srcdesc, maskdesc, dstdesc); } Bool uxa_op_reads_destination(CARD8 op) { /* FALSE (does not read destination) is the list of ops in the protocol * document with "0" in the "Fb" column and no "Ab" in the "Fa" column. * That's just Clear and Src. ReduceCompositeOp() will already have * converted con/disjoint clear/src to Clear or Src. */ switch (op) { case PictOpClear: case PictOpSrc: return FALSE; default: return TRUE; } } static Bool uxa_get_pixel_from_rgba(CARD32 * pixel, CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, CARD32 format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (abits == 0) abits = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { *pixel = alpha >> (16 - abits); return TRUE; } if (!PICT_FORMAT_COLOR(format)) return FALSE; if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { bshift = 0; gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; #if XORG_VERSION_CURRENT >= 10699900 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { ashift = 0; rshift = abits; gshift = rshift + rbits; bshift = gshift + gbits; #endif } else { return FALSE; } *pixel = 0; *pixel |= (blue >> (16 - bbits)) << bshift; *pixel |= (green >> (16 - gbits)) << gshift; *pixel |= (red >> (16 - rbits)) << rshift; *pixel |= (alpha >> (16 - abits)) << ashift; return TRUE; } Bool uxa_get_rgba_from_pixel(CARD32 pixel, CARD16 * red, CARD16 * green, CARD16 * blue, CARD16 * alpha, CARD32 format) { int rbits, bbits, gbits, abits; int rshift, bshift, gshift, ashift; rbits = PICT_FORMAT_R(format); gbits = PICT_FORMAT_G(format); bbits = PICT_FORMAT_B(format); abits = PICT_FORMAT_A(format); if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { rshift = gshift = bshift = ashift = 0; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { bshift = 0; gshift = bbits; rshift = gshift + gbits; ashift = rshift + rbits; } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { rshift = 0; gshift = rbits; bshift = gshift + gbits; ashift = bshift + bbits; #if XORG_VERSION_CURRENT >= 10699900 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { ashift = 0; rshift = abits; if (abits == 0) rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits); gshift = rshift + rbits; bshift = gshift + gbits; #endif } else { return FALSE; } if (rbits) { *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits); while (rbits < 16) { *red |= *red >> rbits; rbits <<= 1; } } else *red = 0; if (gbits) { *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits); while (gbits < 16) { *green |= *green >> gbits; gbits <<= 1; } } else *green = 0; if (bbits) { *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits); while (bbits < 16) { *blue |= *blue >> bbits; bbits <<= 1; } } else *blue = 0; if (abits) { *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits); while (abits < 16) { *alpha |= *alpha >> abits; abits <<= 1; } } else *alpha = 0xffff; return TRUE; } Bool uxa_get_color_for_pixmap (PixmapPtr pixmap, CARD32 src_format, CARD32 dst_format, CARD32 *pixel) { CARD16 red, green, blue, alpha; *pixel = uxa_get_pixmap_first_pixel(pixmap); if (src_format != dst_format) { if (!uxa_get_rgba_from_pixel(*pixel, &red, &green, &blue, &alpha, src_format)) return FALSE; if (!uxa_get_pixel_from_rgba(pixel, red, green, blue, alpha, dst_format)) return FALSE; } return TRUE; } static int uxa_try_driver_solid_fill(PicturePtr pSrc, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen); RegionRec region; BoxPtr pbox; int nbox; int dst_off_x, dst_off_y; PixmapPtr pSrcPix = NULL, pDstPix; CARD32 pixel; if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDst->pDrawable, GXcopy, FB_ALLONES)) return -1; pDstPix = uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y); if (!pDstPix) return -1; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; if (pSrc->pDrawable) { pSrcPix = uxa_get_drawable_pixmap(pSrc->pDrawable); xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; } if (!miComputeCompositeRegion(®ion, pSrc, NULL, pDst, xSrc, ySrc, 0, 0, xDst, yDst, width, height)) return 1; if (pSrcPix) { if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return -1; } } else { SourcePict *source = pSrc->pSourcePict; PictSolidFill *solid = &source->solidFill; if (source == NULL || source->type != SourcePictTypeSolidFill) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return -1; } if (pDst->format == PICT_a8r8g8b8) { pixel = solid->color; } else if (pDst->format == PICT_x8r8g8b8) { pixel = solid->color | 0xff000000; } else { CARD16 red, green, blue, alpha; if (!uxa_get_rgba_from_pixel(solid->color, &red, &green, &blue, &alpha, PICT_a8r8g8b8) || !uxa_get_pixel_from_rgba(&pixel, red, green, blue, alpha, pDst->format)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return -1; } } } if (!(*uxa_screen->info->prepare_solid) (pDstPix, GXcopy, FB_ALLONES, pixel)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return -1; } REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); nbox = REGION_NUM_RECTS(®ion); pbox = REGION_RECTS(®ion); while (nbox--) { (*uxa_screen->info->solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2); pbox++; } (*uxa_screen->info->done_solid) (pDstPix); REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); return 1; } static PicturePtr uxa_picture_for_pixman_format(ScreenPtr screen, pixman_format_code_t format, int width, int height) { PicturePtr picture; PixmapPtr pixmap; int error; if (format == PIXMAN_a1) format = PIXMAN_a8; /* fill alpha if unset */ if (PIXMAN_FORMAT_A(format) == 0) format = PIXMAN_a8r8g8b8; pixmap = screen->CreatePixmap(screen, width, height, PIXMAN_FORMAT_DEPTH(format), UXA_CREATE_PIXMAP_FOR_MAP); if (!pixmap) return 0; if (!uxa_pixmap_is_offscreen(pixmap)) { screen->DestroyPixmap(pixmap); return 0; } picture = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); screen->DestroyPixmap(pixmap); if (!picture) return 0; ValidatePicture(picture); return picture; } static PicturePtr uxa_picture_from_pixman_image(ScreenPtr screen, pixman_image_t * image, pixman_format_code_t format) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); PicturePtr picture; PixmapPtr pixmap; int width, height; width = pixman_image_get_width(image); height = pixman_image_get_height(image); picture = uxa_picture_for_pixman_format(screen, format, width, height); if (!picture) return 0; if (uxa_screen->info->put_image && ((picture->pDrawable->depth << 24) | picture->format) == format && uxa_screen->info->put_image((PixmapPtr)picture->pDrawable, 0, 0, width, height, (char *)pixman_image_get_data(image), pixman_image_get_stride(image))) return picture; pixmap = GetScratchPixmapHeader(screen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!pixmap) { FreePicture(picture, 0); return 0; } if (((picture->pDrawable->depth << 24) | picture->format) == format) { GCPtr gc; gc = GetScratchGC(PIXMAN_FORMAT_DEPTH(format), screen); if (!gc) { FreeScratchPixmapHeader(pixmap); FreePicture(picture, 0); return 0; } ValidateGC(picture->pDrawable, gc); (*gc->ops->CopyArea) (&pixmap->drawable, picture->pDrawable, gc, 0, 0, width, height, 0, 0); FreeScratchGC(gc); } else { PicturePtr src; int error; src = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); if (!src) { FreeScratchPixmapHeader(pixmap); FreePicture(picture, 0); return 0; } ValidatePicture(src); if (uxa_picture_prepare_access(picture, UXA_ACCESS_RW)) { fbComposite(PictOpSrc, src, NULL, picture, 0, 0, 0, 0, 0, 0, width, height); uxa_picture_finish_access(picture, UXA_ACCESS_RW); } FreePicture(src, 0); } FreeScratchPixmapHeader(pixmap); return picture; } static PicturePtr uxa_create_solid(ScreenPtr screen, uint32_t color) { PixmapPtr pixmap; PicturePtr picture; XID repeat = RepeatNormal; int error = 0; pixmap = (*screen->CreatePixmap)(screen, 1, 1, 32, UXA_CREATE_PIXMAP_FOR_MAP); if (!pixmap) return 0; if (!uxa_prepare_access((DrawablePtr)pixmap, UXA_ACCESS_RW)) { (*screen->DestroyPixmap)(pixmap); return 0; } *((uint32_t *)pixmap->devPrivate.ptr) = color; uxa_finish_access((DrawablePtr)pixmap, UXA_ACCESS_RW); picture = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, 32, PICT_a8r8g8b8), CPRepeat, &repeat, serverClient, &error); (*screen->DestroyPixmap)(pixmap); return picture; } static PicturePtr uxa_solid_clear(ScreenPtr screen) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); PicturePtr picture; if (!uxa_screen->solid_clear) { uxa_screen->solid_clear = uxa_create_solid(screen, 0); if (!uxa_screen->solid_clear) return 0; } picture = uxa_screen->solid_clear; return picture; } PicturePtr uxa_acquire_solid(ScreenPtr screen, SourcePict *source) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); PictSolidFill *solid = &source->solidFill; PicturePtr picture; int i; if ((solid->color >> 24) == 0) { picture = uxa_solid_clear(screen); if (!picture) return 0; goto DONE; } else if (solid->color == 0xff000000) { if (!uxa_screen->solid_black) { uxa_screen->solid_black = uxa_create_solid(screen, 0xff000000); if (!uxa_screen->solid_black) return 0; } picture = uxa_screen->solid_black; goto DONE; } else if (solid->color == 0xffffffff) { if (!uxa_screen->solid_white) { uxa_screen->solid_white = uxa_create_solid(screen, 0xffffffff); if (!uxa_screen->solid_white) return 0; } picture = uxa_screen->solid_white; goto DONE; } for (i = 0; i < uxa_screen->solid_cache_size; i++) { if (uxa_screen->solid_cache[i].color == solid->color) { picture = uxa_screen->solid_cache[i].picture; goto DONE; } } picture = uxa_create_solid(screen, solid->color); if (!picture) return 0; if (uxa_screen->solid_cache_size == UXA_NUM_SOLID_CACHE) { i = rand() % UXA_NUM_SOLID_CACHE; FreePicture(uxa_screen->solid_cache[i].picture, 0); } else uxa_screen->solid_cache_size++; uxa_screen->solid_cache[i].picture = picture; uxa_screen->solid_cache[i].color = solid->color; DONE: picture->refcnt++; return picture; } PicturePtr uxa_acquire_pattern(ScreenPtr pScreen, PicturePtr pSrc, pixman_format_code_t format, INT16 x, INT16 y, CARD16 width, CARD16 height) { PicturePtr pDst; if (pSrc->pSourcePict) { SourcePict *source = pSrc->pSourcePict; if (source->type == SourcePictTypeSolidFill) return uxa_acquire_solid (pScreen, source); } pDst = uxa_picture_for_pixman_format(pScreen, format, width, height); if (!pDst) return 0; if (uxa_picture_prepare_access(pDst, UXA_ACCESS_RW)) { fbComposite(PictOpSrc, pSrc, NULL, pDst, x, y, 0, 0, 0, 0, width, height); uxa_picture_finish_access(pDst, UXA_ACCESS_RW); return pDst; } else { FreePicture(pDst, 0); return 0; } } static Bool transform_is_integer_translation(PictTransformPtr t, int *tx, int *ty) { if (t == NULL) { *tx = *ty = 0; return TRUE; } if (t->matrix[0][0] != IntToxFixed(1) || t->matrix[0][1] != 0 || t->matrix[1][0] != 0 || t->matrix[1][1] != IntToxFixed(1) || t->matrix[2][0] != 0 || t->matrix[2][1] != 0 || t->matrix[2][2] != IntToxFixed(1)) return FALSE; if (xFixedFrac(t->matrix[0][2]) != 0 || xFixedFrac(t->matrix[1][2]) != 0) return FALSE; *tx = xFixedToInt(t->matrix[0][2]); *ty = xFixedToInt(t->matrix[1][2]); return TRUE; } static PicturePtr uxa_render_picture(ScreenPtr screen, PicturePtr src, pixman_format_code_t format, INT16 x, INT16 y, CARD16 width, CARD16 height) { PicturePtr picture; int ret = 0; /* XXX we need a mechanism for the card to choose the fallback format */ /* force alpha channel in case source does not entirely cover the extents */ if (PIXMAN_FORMAT_A(format) == 0) format = PIXMAN_a8r8g8b8; /* available on all hardware */ picture = uxa_picture_for_pixman_format(screen, format, width, height); if (!picture) return 0; if (uxa_picture_prepare_access(picture, UXA_ACCESS_RW)) { if (uxa_picture_prepare_access(src, UXA_ACCESS_RO)) { ret = 1; fbComposite(PictOpSrc, src, NULL, picture, x, y, 0, 0, 0, 0, width, height); uxa_picture_finish_access(src, UXA_ACCESS_RO); } uxa_picture_finish_access(picture, UXA_ACCESS_RW); } if (!ret) { FreePicture(picture, 0); return 0; } return picture; } static int drawable_contains (DrawablePtr drawable, int x, int y, int w, int h) { if (x < 0 || y < 0) return FALSE; if (x + w > drawable->width) return FALSE; if (y + h > drawable->height) return FALSE; return TRUE; } PicturePtr uxa_acquire_drawable(ScreenPtr pScreen, PicturePtr pSrc, INT16 x, INT16 y, CARD16 width, CARD16 height, INT16 * out_x, INT16 * out_y) { PixmapPtr pPixmap; PicturePtr pDst; int depth, error; int tx, ty; GCPtr pGC; depth = pSrc->pDrawable->depth; if (!transform_is_integer_translation(pSrc->transform, &tx, &ty) || !drawable_contains(pSrc->pDrawable, x + tx, y + ty, width, height) || depth == 1 || pSrc->filter == PictFilterConvolution) { /* XXX extract the sample extents and do the transformation on the GPU */ pDst = uxa_render_picture(pScreen, pSrc, pSrc->format | (BitsPerPixel(pSrc->pDrawable->depth) << 24), x, y, width, height); if (!pDst) return 0; goto done; } else { if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->height) { *out_x = x + pSrc->pDrawable->x; *out_y = y + pSrc->pDrawable->y; return pSrc; } } pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) return 0; /* Skip the copy if the result remains in memory and not a bo */ if (!uxa_pixmap_is_offscreen(pPixmap)) { pScreen->DestroyPixmap(pPixmap); return 0; } pGC = GetScratchGC(depth, pScreen); if (!pGC) { pScreen->DestroyPixmap(pPixmap); return 0; } ValidateGC(&pPixmap->drawable, pGC); pGC->ops->CopyArea(pSrc->pDrawable, &pPixmap->drawable, pGC, x + tx, y + ty, width, height, 0, 0); FreeScratchGC(pGC); pDst = CreatePicture(0, &pPixmap->drawable, PictureMatchFormat(pScreen, depth, pSrc->format), 0, 0, serverClient, &error); pScreen->DestroyPixmap(pPixmap); if (!pDst) return 0; ValidatePicture(pDst); done: pDst->componentAlpha = pSrc->componentAlpha; *out_x = 0; *out_y = 0; return pDst; } static PicturePtr uxa_acquire_picture(ScreenPtr screen, PicturePtr src, pixman_format_code_t format, INT16 x, INT16 y, CARD16 width, CARD16 height, INT16 * out_x, INT16 * out_y) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); if (uxa_screen->info->check_composite_texture && uxa_screen->info->check_composite_texture(screen, src)) { if (src->pDrawable) { *out_x = x + src->pDrawable->x; *out_y = y + src->pDrawable->y; } else { *out_x = x; *out_y = y; } return src; } if (src->pDrawable) { PicturePtr dst; dst = uxa_acquire_drawable(screen, src, x, y, width, height, out_x, out_y); if (!dst) return 0; if (uxa_screen->info->check_composite_texture && !uxa_screen->info->check_composite_texture(screen, dst)) { if (dst != src) FreePicture(dst, 0); return 0; } return dst; } *out_x = 0; *out_y = 0; return uxa_acquire_pattern(screen, src, format, x, y, width, height); } static PicturePtr uxa_acquire_source(ScreenPtr screen, PicturePtr pict, INT16 x, INT16 y, CARD16 width, CARD16 height, INT16 * out_x, INT16 * out_y) { return uxa_acquire_picture (screen, pict, PIXMAN_a8r8g8b8, x, y, width, height, out_x, out_y); } static PicturePtr uxa_acquire_mask(ScreenPtr screen, PicturePtr pict, INT16 x, INT16 y, INT16 width, INT16 height, INT16 * out_x, INT16 * out_y) { return uxa_acquire_picture (screen, pict, PIXMAN_a8, x, y, width, height, out_x, out_y); } static int uxa_try_driver_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr screen = pDst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); RegionRec region; BoxPtr pbox; int nbox; int xDst_copy = 0, yDst_copy = 0; int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; PicturePtr localSrc, localMask = NULL; PicturePtr localDst = pDst; if (uxa_screen->info->check_composite && !(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst, width, height)) return -1; if (uxa_screen->info->check_composite_target && !uxa_screen->info->check_composite_target(uxa_get_drawable_pixmap(pDst->pDrawable))) { int depth = pDst->pDrawable->depth; PixmapPtr pixmap; int error; GCPtr gc; pixmap = uxa_get_drawable_pixmap(pDst->pDrawable); if (uxa_screen->info->check_copy && !uxa_screen->info->check_copy(pixmap, pixmap, GXcopy, FB_ALLONES)) return -1; pixmap = screen->CreatePixmap(screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pixmap) return 0; gc = GetScratchGC(depth, screen); if (!gc) { screen->DestroyPixmap(pixmap); return 0; } ValidateGC(&pixmap->drawable, gc); gc->ops->CopyArea(pDst->pDrawable, &pixmap->drawable, gc, xDst, yDst, width, height, 0, 0); FreeScratchGC(gc); xDst_copy = xDst; xDst = 0; yDst_copy = yDst; yDst = 0; localDst = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, depth, pDst->format), 0, 0, serverClient, &error); screen->DestroyPixmap(pixmap); if (!localDst) return 0; ValidatePicture(localDst); } pDstPix = uxa_get_offscreen_pixmap(localDst->pDrawable, &dst_off_x, &dst_off_y); if (!pDstPix) { if (localDst != pDst) FreePicture(localDst, 0); return -1; } xDst += localDst->pDrawable->x; yDst += localDst->pDrawable->y; localSrc = uxa_acquire_source(screen, pSrc, xSrc, ySrc, width, height, &xSrc, &ySrc); if (!localSrc) { if (localDst != pDst) FreePicture(localDst, 0); return 0; } if (pMask) { localMask = uxa_acquire_mask(screen, pMask, xMask, yMask, width, height, &xMask, &yMask); if (!localMask) { if (localSrc != pSrc) FreePicture(localSrc, 0); if (localDst != pDst) FreePicture(localDst, 0); return 0; } } if (!miComputeCompositeRegion(®ion, localSrc, localMask, localDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) { if (localSrc != pSrc) FreePicture(localSrc, 0); if (localMask && localMask != pMask) FreePicture(localMask, 0); if (localDst != pDst) FreePicture(localDst, 0); return 1; } pSrcPix = uxa_get_offscreen_pixmap(localSrc->pDrawable, &src_off_x, &src_off_y); if (!pSrcPix) { REGION_UNINIT(screen, ®ion); if (localSrc != pSrc) FreePicture(localSrc, 0); if (localMask && localMask != pMask) FreePicture(localMask, 0); if (localDst != pDst) FreePicture(localDst, 0); return 0; } if (localMask) { pMaskPix = uxa_get_offscreen_pixmap(localMask->pDrawable, &mask_off_x, &mask_off_y); if (!pMaskPix) { REGION_UNINIT(screen, ®ion); if (localSrc != pSrc) FreePicture(localSrc, 0); if (localMask && localMask != pMask) FreePicture(localMask, 0); if (localDst != pDst) FreePicture(localDst, 0); return 0; } } if (!(*uxa_screen->info->prepare_composite) (op, localSrc, localMask, localDst, pSrcPix, pMaskPix, pDstPix)) { REGION_UNINIT(screen, ®ion); if (localSrc != pSrc) FreePicture(localSrc, 0); if (localMask && localMask != pMask) FreePicture(localMask, 0); if (localDst != pDst) FreePicture(localDst, 0); return -1; } if (pMask) { xMask = xMask + mask_off_x - xDst; yMask = yMask + mask_off_y - yDst; } xSrc = xSrc + src_off_x - xDst; ySrc = ySrc + src_off_y - yDst; nbox = REGION_NUM_RECTS(®ion); pbox = REGION_RECTS(®ion); while (nbox--) { (*uxa_screen->info->composite) (pDstPix, pbox->x1 + xSrc, pbox->y1 + ySrc, pbox->x1 + xMask, pbox->y1 + yMask, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } (*uxa_screen->info->done_composite) (pDstPix); REGION_UNINIT(screen, ®ion); if (localSrc != pSrc) FreePicture(localSrc, 0); if (localMask && localMask != pMask) FreePicture(localMask, 0); if (localDst != pDst) { GCPtr gc; gc = GetScratchGC(pDst->pDrawable->depth, screen); if (gc) { ValidateGC(pDst->pDrawable, gc); gc->ops->CopyArea(localDst->pDrawable, pDst->pDrawable, gc, 0, 0, width, height, xDst_copy, yDst_copy); FreeScratchGC(gc); } FreePicture(localDst, 0); } return 1; } /** * uxa_try_magic_two_pass_composite_helper implements PictOpOver using two passes of * simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component * alpha and limited 1-tmu cards. * * From http://anholt.livejournal.com/32058.html: * * The trouble is that component-alpha rendering requires two different sources * for blending: one for the source value to the blender, which is the * per-channel multiplication of source and mask, and one for the source alpha * for multiplying with the destination channels, which is the multiplication * of the source channels by the mask alpha. So the equation for Over is: * * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B * * But we can do some simpler operations, right? How about PictOpOutReverse, * which has a source factor of 0 and dest factor of (1 - source alpha). We * can get the source alpha value (srca.X = src.A * mask.X) out of the texture * blenders pretty easily. So we can do a component-alpha OutReverse, which * gets us: * * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B * * OK. And if an op doesn't use the source alpha value for the destination * factor, then we can do the channel multiplication in the texture blenders * to get the source value, and ignore the source alpha that we wouldn't use. * We've supported this in the Radeon driver for a long time. An example would * be PictOpAdd, which does: * * dst.A = src.A * mask.A + dst.A * dst.R = src.R * mask.R + dst.R * dst.G = src.G * mask.G + dst.G * dst.B = src.B * mask.B + dst.B * * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right * after it, we get: * * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A) * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R) * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G) * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B) */ static int uxa_try_magic_two_pass_composite_helper(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr screen = pDst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); PicturePtr localDst = pDst; int xDst_copy, yDst_copy; assert(op == PictOpOver); if (uxa_screen->info->check_composite && (!(*uxa_screen->info->check_composite) (PictOpOutReverse, pSrc, pMask, pDst, width, height) || !(*uxa_screen->info->check_composite) (PictOpAdd, pSrc, pMask, pDst, width, height))) { return -1; } if (uxa_screen->info->check_composite_target && !uxa_screen->info->check_composite_target(uxa_get_drawable_pixmap(pDst->pDrawable))) { int depth = pDst->pDrawable->depth; PixmapPtr pixmap; int error; GCPtr gc; pixmap = uxa_get_drawable_pixmap(pDst->pDrawable); if (uxa_screen->info->check_copy && !uxa_screen->info->check_copy(pixmap, pixmap, GXcopy, FB_ALLONES)) return -1; pixmap = screen->CreatePixmap(screen, width, height, depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pixmap) return 0; gc = GetScratchGC(depth, screen); if (!gc) { screen->DestroyPixmap(pixmap); return 0; } ValidateGC(&pixmap->drawable, gc); gc->ops->CopyArea(pDst->pDrawable, &pixmap->drawable, gc, xDst, yDst, width, height, 0, 0); FreeScratchGC(gc); xDst_copy = xDst; xDst = 0; yDst_copy = yDst; yDst = 0; localDst = CreatePicture(0, &pixmap->drawable, PictureMatchFormat(screen, depth, pDst->format), 0, 0, serverClient, &error); screen->DestroyPixmap(pixmap); if (!localDst) return 0; ValidatePicture(localDst); } /* Now, we think we should be able to accelerate this operation. First, * composite the destination to be the destination times the source alpha * factors. */ uxa_composite(PictOpOutReverse, pSrc, pMask, localDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); /* Then, add in the source value times the destination alpha factors (1.0). */ uxa_composite(PictOpAdd, pSrc, pMask, localDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (localDst != pDst) { GCPtr gc; gc = GetScratchGC(pDst->pDrawable->depth, screen); if (gc) { ValidateGC(pDst->pDrawable, gc); gc->ops->CopyArea(localDst->pDrawable, pDst->pDrawable, gc, 0, 0, width, height, xDst_copy, yDst_copy); FreeScratchGC(gc); } FreePicture(localDst, 0); } return 1; } static int compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src) { if (op == PictOpSrc) { if (src->format == dst->format) return 1; /* Is the destination an alpha-less version of source? */ if (dst->format == PICT_FORMAT(PICT_FORMAT_BPP(src->format), PICT_FORMAT_TYPE(src->format), 0, PICT_FORMAT_R(src->format), PICT_FORMAT_G(src->format), PICT_FORMAT_B(src->format))) return 1; /* XXX xrgb is promoted to argb during image upload... */ #if 0 if (dst->format == PICT_a8r8g8b8 && src->format == PICT_x8r8g8b8) return 1; #endif } else if (op == PictOpOver) { if (PICT_FORMAT_A(src->format)) return 0; return src->format == dst->format; } return 0; } void uxa_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen); int ret = -1; Bool saveSrcRepeat = pSrc->repeat; Bool saveMaskRepeat = pMask ? pMask->repeat : 0; RegionRec region; int tx, ty; if (uxa_screen->force_fallback) goto fallback; if (!uxa_drawable_is_offscreen(pDst->pDrawable)) goto fallback; if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) goto fallback; /* Remove repeat in source if useless */ if (pSrc->pDrawable && pSrc->repeat && pSrc->filter != PictFilterConvolution && transform_is_integer_translation(pSrc->transform, &tx, &ty) && (pSrc->pDrawable->width > 1 || pSrc->pDrawable->height > 1) && drawable_contains(pSrc->pDrawable, xSrc + tx, ySrc + ty, width, height)) pSrc->repeat = 0; if (!pMask) { if (op == PictOpClear) { PicturePtr clear = uxa_solid_clear(pDst->pDrawable->pScreen); if (clear && uxa_try_driver_solid_fill(clear, pDst, xSrc, ySrc, xDst, yDst, width, height) == 1) goto done; } if (pSrc->pDrawable == NULL) { if (pSrc->pSourcePict) { SourcePict *source = pSrc->pSourcePict; if (source->type == SourcePictTypeSolidFill) { if (op == PictOpSrc || (op == PictOpOver && (source->solidFill.color & 0xff000000) == 0xff000000)) { ret = uxa_try_driver_solid_fill(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height); if (ret == 1) goto done; } } } } else if (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && pSrc->repeat && (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) { ret = uxa_try_driver_solid_fill(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height); if (ret == 1) goto done; } else if (compatible_formats (op, pDst, pSrc) && pSrc->filter != PictFilterConvolution && transform_is_integer_translation(pSrc->transform, &tx, &ty)) { if (!pSrc->repeat && drawable_contains(pSrc->pDrawable, xSrc + tx, ySrc + ty, width, height)) { xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x + tx; ySrc += pSrc->pDrawable->y + ty; if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) goto done; uxa_copy_n_to_n(pSrc->pDrawable, pDst->pDrawable, NULL, REGION_RECTS(®ion), REGION_NUM_RECTS(®ion), xSrc - xDst, ySrc - yDst, FALSE, FALSE, 0, NULL); REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); goto done; } else if (pSrc->repeat && pSrc->repeatType == RepeatNormal && pSrc->pDrawable->type == DRAWABLE_PIXMAP) { DDXPointRec patOrg; /* Let's see if the driver can do the repeat * in one go */ if (uxa_screen->info->prepare_composite) { ret = uxa_try_driver_composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; } /* Now see if we can use * uxa_fill_region_tiled() */ xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x + tx; ySrc += pSrc->pDrawable->y + ty; if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) goto done; /* pattern origin is the point in the * destination drawable * corresponding to (0,0) in the source */ patOrg.x = xDst - xSrc; patOrg.y = yDst - ySrc; ret = uxa_fill_region_tiled(pDst->pDrawable, ®ion, (PixmapPtr) pSrc-> pDrawable, &patOrg, FB_ALLONES, GXcopy); REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); if (ret) goto done; } } } /* Remove repeat in mask if useless */ if (pMask && pMask->pDrawable && pMask->repeat && pMask->filter != PictFilterConvolution && transform_is_integer_translation(pMask->transform, &tx, &ty) && (pMask->pDrawable->width > 1 || pMask->pDrawable->height > 1) && drawable_contains(pMask->pDrawable, xMask + tx, yMask + ty, width, height)) pMask->repeat = 0; if (uxa_screen->info->prepare_composite) { Bool isSrcSolid; ret = uxa_try_driver_composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; /* For generic masks and solid src pictures, mach64 can do * Over in two passes, similar to the component-alpha case. */ isSrcSolid = pSrc->pDrawable ? pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 && pSrc->repeat : pSrc->pSourcePict ? pSrc->pSourcePict->type == SourcePictTypeSolidFill : 0; /* If we couldn't do the Composite in a single pass, and it * was a component-alpha Over, see if we can do it in two * passes with an OutReverse and then an Add. */ if (ret == -1 && op == PictOpOver && pMask && (pMask->componentAlpha || isSrcSolid)) { ret = uxa_try_magic_two_pass_composite_helper(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (ret == 1) goto done; } } fallback: uxa_print_composite_fallback("uxa_composite", op, pSrc, pMask, pDst); uxa_check_composite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); done: pSrc->repeat = saveSrcRepeat; if (pMask) pMask->repeat = saveMaskRepeat; } #endif /** * Same as miCreateAlphaPicture, except it uses uxa_check_poly_fill_rect instead * of PolyFillRect to initialize the pixmap after creating it, to prevent * the pixmap from being migrated. * * See the comments about uxa_trapezoids and uxa_triangles. */ static PicturePtr uxa_create_alpha_picture(ScreenPtr pScreen, PicturePtr pDst, PictFormatPtr pPictFormat, CARD16 width, CARD16 height) { PixmapPtr pPixmap; PicturePtr pPicture; int error; if (width > 32767 || height > 32767) return 0; if (!pPictFormat) { if (pDst->polyEdge == PolyEdgeSharp) pPictFormat = PictureMatchFormat(pScreen, 1, PICT_a1); else pPictFormat = PictureMatchFormat(pScreen, 8, PICT_a8); if (!pPictFormat) return 0; } pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, pPictFormat->depth, UXA_CREATE_PIXMAP_FOR_MAP); if (!pPixmap) return 0; pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, 0, 0, serverClient, &error); (*pScreen->DestroyPixmap) (pPixmap); return pPicture; } static void uxa_check_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) { ScreenPtr screen = dst->pDrawable->pScreen; if (maskFormat) { PixmapPtr scratch = NULL; PicturePtr mask; INT16 xDst, yDst; INT16 xRel, yRel; BoxRec bounds; int width, height; pixman_image_t *image; pixman_format_code_t format; int error; xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; miTrapezoidBounds (ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); scratch = GetScratchPixmapHeader(screen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!scratch) { pixman_image_unref(image); return; } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); if (!mask) { FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; CompositePicture(op, src, mask, dst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } else { if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, 1, traps); } } /** * uxa_trapezoids is essentially a copy of miTrapezoids that uses * uxa_create_alpha_picture instead of miCreateAlphaPicture. * * The problem with miCreateAlphaPicture is that it calls PolyFillRect * to initialize the contents after creating the pixmap, which * causes the pixmap to be moved in for acceleration. The subsequent * call to RasterizeTrapezoid won't be accelerated however, which * forces the pixmap to be moved out again. * * uxa_create_alpha_picture avoids this roundtrip by using * uxa_check_poly_fill_rect to initialize the contents. */ void uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid * traps) { ScreenPtr screen = dst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); BoxRec bounds; Bool direct; if (uxa_screen->force_fallback) { uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps); return; } direct = op == PictOpAdd && miIsSolidAlpha(src); if (maskFormat || direct) { miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; } /* * Check for solid alpha add */ if (direct) { DrawablePtr pDraw = dst->pDrawable; PixmapPtr pixmap = uxa_get_drawable_pixmap(pDraw); int xoff, yoff; uxa_get_drawable_deltas(pDraw, pixmap, &xoff, &yoff); xoff += pDraw->x; yoff += pDraw->y; if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) { PictureScreenPtr ps = GetPictureScreen(screen); for (; ntrap; ntrap--, traps++) (*ps->RasterizeTrapezoid) (dst, traps, 0, 0); uxa_finish_access(pDraw, UXA_ACCESS_RW); } } else if (maskFormat) { PixmapPtr scratch = NULL; PicturePtr mask; INT16 xDst, yDst; INT16 xRel, yRel; int width, height; pixman_image_t *image; pixman_format_code_t format; xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); if (uxa_drawable_is_offscreen(dst->pDrawable)) { mask = uxa_picture_from_pixman_image(screen, image, format); } else { int error; scratch = GetScratchPixmapHeader(screen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); } if (!mask) { if (scratch) FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; CompositePicture(op, src, mask, dst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); if (scratch) FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } else { if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) uxa_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, 1, traps); } } static void uxa_check_triangles(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle *tri) { ScreenPtr screen = dst->pDrawable->pScreen; if (maskFormat) { PixmapPtr scratch = NULL; PicturePtr mask; INT16 xDst, yDst; INT16 xRel, yRel; BoxRec bounds; int width, height; pixman_image_t *image; pixman_format_code_t format; int error; xDst = pixman_fixed_to_int(tri[0].p1.x); yDst = pixman_fixed_to_int(tri[0].p1.y); miTriangleBounds (ntri, tri, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; pixman_add_triangles(image, -bounds.x1, -bounds.y1, ntri, (pixman_triangle_t *)tri); scratch = GetScratchPixmapHeader(screen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!scratch) { pixman_image_unref(image); return; } mask = CreatePicture(0, &scratch->drawable, PictureMatchFormat(screen, PIXMAN_FORMAT_DEPTH(format), format), 0, 0, serverClient, &error); if (!mask) { FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; CompositePicture(op, src, mask, dst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, width, height); FreePicture(mask, 0); FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } else { if (dst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(screen, 1, PICT_a1); else maskFormat = PictureMatchFormat(screen, 8, PICT_a8); for (; ntri; ntri--, tri++) uxa_check_triangles(op, src, dst, maskFormat, xSrc, ySrc, 1, tri); } } /** * uxa_triangles is essentially a copy of miTriangles that uses * uxa_create_alpha_picture instead of miCreateAlphaPicture. * * The problem with miCreateAlphaPicture is that it calls PolyFillRect * to initialize the contents after creating the pixmap, which * causes the pixmap to be moved in for acceleration. The subsequent * call to AddTriangles won't be accelerated however, which forces the pixmap * to be moved out again. * * uxa_create_alpha_picture avoids this roundtrip by using * uxa_check_poly_fill_rect to initialize the contents. */ void uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int ntri, xTriangle * tris) { ScreenPtr pScreen = pDst->pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); PictureScreenPtr ps = GetPictureScreen(pScreen); BoxRec bounds; Bool direct; if (uxa_screen->force_fallback) { uxa_check_triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); return; } direct = op == PictOpAdd && miIsSolidAlpha(pSrc); if (maskFormat || direct) { miTriangleBounds(ntri, tris, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; } /* * Check for solid alpha add */ if (direct) { DrawablePtr pDraw = pDst->pDrawable; if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) { (*ps->AddTriangles) (pDst, 0, 0, ntri, tris); uxa_finish_access(pDraw, UXA_ACCESS_RW); } } else if (maskFormat) { PicturePtr pPicture; INT16 xDst, yDst; INT16 xRel, yRel; int width = bounds.x2 - bounds.x1; int height = bounds.y2 - bounds.y1; GCPtr pGC; xRectangle rect; xDst = tris[0].p1.x >> 16; yDst = tris[0].p1.y >> 16; pPicture = uxa_create_alpha_picture(pScreen, pDst, maskFormat, width, height); if (!pPicture) return; /* Clear the alpha picture to 0. */ pGC = GetScratchGC(pPicture->pDrawable->depth, pScreen); if (!pGC) { FreePicture(pPicture, 0); return; } ValidateGC(pPicture->pDrawable, pGC); rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; uxa_check_poly_fill_rect(pPicture->pDrawable, pGC, 1, &rect); FreeScratchGC(pGC); if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) { (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris); uxa_finish_access(pPicture->pDrawable, UXA_ACCESS_RW); } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; CompositePicture(op, pSrc, pPicture, pDst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); FreePicture(pPicture, 0); } else { if (pDst->polyEdge == PolyEdgeSharp) maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1); else maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8); for (; ntri; ntri--, tris++) uxa_triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } void uxa_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { uxa_check_add_traps(pPicture, x_off, y_off, ntrap, traps); } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa-unaccel.c000066400000000000000000000307411267532330400242350ustar00rootroot00000000000000/* * * Copyright 1999 Keith Packard * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "uxa-priv.h" /* * These functions wrap the low-level fb rendering functions and * synchronize framebuffer/accelerated drawing by stalling until * the accelerator is idle */ /** * Calls uxa_prepare_access with UXA_PREPARE_SRC for the tile, if that is the * current fill style. * * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are * 1bpp and never in fb, so we don't worry about them. * We should worry about them for completeness sake and going forward. */ Bool uxa_prepare_access_gc(GCPtr pGC) { if (pGC->stipple) if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO)) return FALSE; if (pGC->fillStyle == FillTiled) if (!uxa_prepare_access (&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) { if (pGC->stipple) uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); return FALSE; } return TRUE; } /** * Finishes access to the tile in the GC, if used. */ void uxa_finish_access_gc(GCPtr pGC) { if (pGC->fillStyle == FillTiled) uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RO); if (pGC->stipple) uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RO); } Bool uxa_picture_prepare_access(PicturePtr picture, int mode) { if (picture->pDrawable == NULL) return TRUE; if (!uxa_prepare_access(picture->pDrawable, mode)) return FALSE; if (picture->alphaMap && !uxa_prepare_access(picture->alphaMap->pDrawable, mode)) { uxa_finish_access(picture->pDrawable, mode); return FALSE; } return TRUE; } void uxa_picture_finish_access(PicturePtr picture, int mode) { if (picture->pDrawable == NULL) return; uxa_finish_access(picture->pDrawable, mode); if (picture->alphaMap) uxa_finish_access(picture->alphaMap->pDrawable, mode); } char uxa_drawable_location(DrawablePtr pDrawable) { return uxa_drawable_is_offscreen(pDrawable) ? 's' : 'm'; } void uxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans, DDXPointPtr ppt, int *pwidth, int fSorted) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc, DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } RegionPtr uxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { ScreenPtr screen = pSrc->pScreen; RegionPtr ret = NULL; UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, uxa_drawable_location(pSrc), uxa_drawable_location(pDst))); if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) { if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) { ret = fbCopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); uxa_finish_access(pSrc, UXA_ACCESS_RO); } uxa_finish_access(pDst, UXA_ACCESS_RW); } return ret; } RegionPtr uxa_check_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { ScreenPtr screen = pSrc->pScreen; RegionPtr ret = NULL; UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, uxa_drawable_location(pSrc), uxa_drawable_location(pDst))); if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) { if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) { ret = fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); uxa_finish_access(pSrc, UXA_ACCESS_RO); } uxa_finish_access(pDst, UXA_ACCESS_RW); } return ret; } void uxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { fbPolyPoint(pDrawable, pGC, mode, npt, pptInit); uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", pDrawable, uxa_drawable_location(pDrawable), pGC->lineWidth, mode, npt)); if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyLine(pDrawable, pGC, mode, npt, ppt); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } /* fb calls mi functions in the lineWidth != 0 case. */ fbPolyLine(pDrawable, pGC, mode, npt, ppt); } void uxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC, int nsegInit, xSegment * pSegInit) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, uxa_drawable_location(pDrawable), pGC->lineWidth, nsegInit)); if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } /* fb calls mi functions in the lineWidth != 0 case. */ fbPolySegment(pDrawable, pGC, nsegInit, pSegInit); } void uxa_check_poly_arc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); /* Disable this as fbPolyArc can call miZeroPolyArc which in turn * can call accelerated functions, that as yet, haven't been notified * with uxa_finish_access(). */ #if 0 if (pGC->lineWidth == 0) { if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyArc(pDrawable, pGC, narcs, pArcs); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } return; } #endif miPolyArc(pDrawable, pGC, narcs, pArcs); } void uxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle * prect) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyFillRect(pDrawable, pGC, nrect, prect); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, uxa_drawable_location(pDrawable), pGC->fillStyle, pGC->alu)); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access_gc(pGC)) { fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); uxa_finish_access_gc(pGC); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, int w, int h, int x, int y) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, uxa_drawable_location(&pBitmap->drawable), uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) { if (uxa_prepare_access(&pBitmap->drawable, UXA_ACCESS_RO)) { if (uxa_prepare_access_gc(pGC)) { fbPushPixels(pGC, pBitmap, pDrawable, w, h, x, y); uxa_finish_access_gc(pGC); } uxa_finish_access(&pBitmap->drawable, UXA_ACCESS_RO); } uxa_finish_access(pDrawable, UXA_ACCESS_RW); } } void uxa_check_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart) { ScreenPtr screen = pDrawable->pScreen; UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) { fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); uxa_finish_access(pDrawable, UXA_ACCESS_RO); } } void uxa_check_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScreenPtr screen = pDst->pDrawable->pScreen; UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst)); if (uxa_picture_prepare_access(pDst, UXA_ACCESS_RW)) { if (uxa_picture_prepare_access(pSrc, UXA_ACCESS_RO)) { if (!pMask || uxa_picture_prepare_access(pMask, UXA_ACCESS_RO)) { fbComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (pMask) uxa_picture_finish_access(pMask, UXA_ACCESS_RO); } uxa_picture_finish_access(pSrc, UXA_ACCESS_RO); } uxa_picture_finish_access(pDst, UXA_ACCESS_RW); } } void uxa_check_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap * traps) { ScreenPtr screen = pPicture->pDrawable->pScreen; UXA_FALLBACK(("to pict %p (%c)\n", pPicture, uxa_drawable_location(pPicture->pDrawable))); if (uxa_picture_prepare_access(pPicture, UXA_ACCESS_RW)) { fbAddTraps(pPicture, x_off, y_off, ntrap, traps); uxa_picture_finish_access(pPicture, UXA_ACCESS_RW); } } /** * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * that happen to be 1x1. Pixmap must be at least 8bpp. * * XXX This really belongs in fb, so it can be aware of tiling and etc. */ CARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap) { CARD32 pixel; void *fb; if (!uxa_prepare_access(&pPixmap->drawable, UXA_ACCESS_RO)) return 0; fb = pPixmap->devPrivate.ptr; switch (pPixmap->drawable.bitsPerPixel) { case 32: pixel = *(CARD32 *) fb; break; case 16: pixel = *(CARD16 *) fb; break; default: pixel = *(CARD8 *) fb; break; } uxa_finish_access(&pPixmap->drawable, UXA_ACCESS_RO); return pixel; } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa.c000066400000000000000000000401621267532330400226230ustar00rootroot00000000000000/* * Copyright © 2001 Keith Packard * * Partly based on code that is Copyright © The XFree86 Project Inc. * * 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, and that the name of Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /** @file * This file covers the initialization and teardown of UXA, and has various * functions not responsible for performing rendering, pixmap migration, or * memory management. */ #ifdef HAVE_DIX_CONFIG_H #include #endif #include #include "uxa-priv.h" #include #include "dixfontstr.h" #include "uxa.h" #if HAS_DEVPRIVATEKEYREC DevPrivateKeyRec uxa_screen_index; #else int uxa_screen_index; #endif /** * uxa_get_drawable_pixmap() returns a backing pixmap for a given drawable. * * @param pDrawable the drawable being requested. * * This function returns the backing pixmap for a drawable, whether it is a * redirected window, unredirected window, or already a pixmap. Note that * coordinate translation is needed when drawing to the backing pixmap of a * redirected window, and the translation coordinates are provided by calling * uxa_get_drawable_pixmap() on the drawable. */ PixmapPtr uxa_get_drawable_pixmap(DrawablePtr pDrawable) { if (pDrawable->type == DRAWABLE_WINDOW) return pDrawable->pScreen-> GetWindowPixmap((WindowPtr) pDrawable); else return (PixmapPtr) pDrawable; } /** * Sets the offsets to add to coordinates to make them address the same bits in * the backing drawable. These coordinates are nonzero only for redirected * windows. */ void uxa_get_drawable_deltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp) { #ifdef COMPOSITE if (pDrawable->type == DRAWABLE_WINDOW) { *xp = -pPixmap->screen_x; *yp = -pPixmap->screen_y; return; } #endif *xp = 0; *yp = 0; } /** * uxa_pixmap_is_offscreen() is used to determine if a pixmap is in offscreen * memory, meaning that acceleration could probably be done to it, and that it * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it * with the CPU. * * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly * deal with moving pixmaps in and out of system memory), UXA will give drivers * pixmaps as arguments for which uxa_pixmap_is_offscreen() is TRUE. * * @return TRUE if the given drawable is in framebuffer memory. */ Bool uxa_pixmap_is_offscreen(PixmapPtr p) { ScreenPtr pScreen = p->drawable.pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); if (uxa_screen->info->pixmap_is_offscreen) return uxa_screen->info->pixmap_is_offscreen(p); return FALSE; } /** * uxa_drawable_is_offscreen() is a convenience wrapper for * uxa_pixmap_is_offscreen(). */ Bool uxa_drawable_is_offscreen(DrawablePtr pDrawable) { return uxa_pixmap_is_offscreen(uxa_get_drawable_pixmap(pDrawable)); } /** * Returns the pixmap which backs a drawable, and the offsets to add to * coordinates to make them address the same bits in the backing drawable. */ PixmapPtr uxa_get_offscreen_pixmap(DrawablePtr drawable, int *xp, int *yp) { PixmapPtr pixmap = uxa_get_drawable_pixmap(drawable); uxa_get_drawable_deltas(drawable, pixmap, xp, yp); if (uxa_pixmap_is_offscreen(pixmap)) return pixmap; else return NULL; } /** * uxa_prepare_access() is UXA's wrapper for the driver's PrepareAccess() handler. * * It deals with waiting for synchronization with the card, determining if * PrepareAccess() is necessary, and working around PrepareAccess() failure. */ Bool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access) { ScreenPtr pScreen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); PixmapPtr pPixmap = uxa_get_drawable_pixmap(pDrawable); Bool offscreen = uxa_pixmap_is_offscreen(pPixmap); if (!offscreen) return TRUE; if (uxa_screen->info->prepare_access) return (*uxa_screen->info->prepare_access) (pPixmap, access); return TRUE; } /** * uxa_finish_access() is UXA's wrapper for the driver's finish_access() handler. * * It deals with calling the driver's finish_access() only if necessary. */ void uxa_finish_access(DrawablePtr pDrawable, uxa_access_t access) { ScreenPtr pScreen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(pScreen); PixmapPtr pPixmap; if (uxa_screen->info->finish_access == NULL) return; pPixmap = uxa_get_drawable_pixmap(pDrawable); if (!uxa_pixmap_is_offscreen(pPixmap)) return; (*uxa_screen->info->finish_access) (pPixmap, access); } /** * uxa_validate_gc() sets the ops to UXA's implementations, which may be * accelerated or may sync the card and fall back to fb. */ static void uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has * changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/finish_access. */ #ifdef FB_24_32BIT if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); fbGetRotatedPixmap(pGC) = 0; } if (pGC->fillStyle == FillTiled) { PixmapPtr pOldTile, pNewTile; pOldTile = pGC->tile.pixmap; if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { pNewTile = fbGetRotatedPixmap(pGC); if (!pNewTile || pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { if (pNewTile) (*pGC->pScreen-> DestroyPixmap) (pNewTile); /* fb24_32ReformatTile will do direct access * of a newly-allocated pixmap. This isn't a * problem yet, since we don't put pixmaps in * FB until at least one accelerated UXA op. */ if (uxa_prepare_access (&pOldTile->drawable, UXA_ACCESS_RO)) { pNewTile = fb24_32ReformatTile(pOldTile, pDrawable-> bitsPerPixel); uxa_finish_access(&pOldTile->drawable, UXA_ACCESS_RO); } } if (pNewTile) { fbGetRotatedPixmap(pGC) = pOldTile; pGC->tile.pixmap = pNewTile; changes |= GCTile; } } } #endif if (changes & GCTile) { if (!pGC->tileIsPixel && FbEvenTile(pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) { if (uxa_prepare_access (&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) { fbPadPixmap(pGC->tile.pixmap); uxa_finish_access(&pGC->tile.pixmap->drawable, UXA_ACCESS_RW); } } /* Mask out the GCTile change notification, now that we've * done FB's job for it. */ changes &= ~GCTile; } if (changes & GCStipple && pGC->stipple) { /* We can't inline stipple handling like we do for GCTile * because it sets fbgc privates. */ if (uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RW)) { fbValidateGC(pGC, changes, pDrawable); uxa_finish_access(&pGC->stipple->drawable, UXA_ACCESS_RW); } } else { fbValidateGC(pGC, changes, pDrawable); } pGC->ops = (GCOps *) & uxa_ops; } static GCFuncs uxaGCFuncs = { uxa_validate_gc, miChangeGC, miCopyGC, miDestroyGC, miChangeClip, miDestroyClip, miCopyClip }; /** * uxa_create_gc makes a new GC and hooks up its funcs handler, so that * uxa_validate_gc() will get called. */ static int uxa_create_gc(GCPtr pGC) { if (!fbCreateGC(pGC)) return FALSE; pGC->funcs = &uxaGCFuncs; return TRUE; } Bool uxa_prepare_access_window(WindowPtr pWin) { if (pWin->backgroundState == BackgroundPixmap) { if (!uxa_prepare_access (&pWin->background.pixmap->drawable, UXA_ACCESS_RO)) return FALSE; } if (pWin->borderIsPixel == FALSE) { if (!uxa_prepare_access (&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) { if (pWin->backgroundState == BackgroundPixmap) uxa_finish_access(&pWin->background.pixmap-> drawable, UXA_ACCESS_RO); return FALSE; } } return TRUE; } void uxa_finish_access_window(WindowPtr pWin) { if (pWin->backgroundState == BackgroundPixmap) uxa_finish_access(&pWin->background.pixmap->drawable, UXA_ACCESS_RO); if (pWin->borderIsPixel == FALSE) uxa_finish_access(&pWin->border.pixmap->drawable, UXA_ACCESS_RO); } static Bool uxa_change_window_attributes(WindowPtr pWin, unsigned long mask) { Bool ret; if (!uxa_prepare_access_window(pWin)) return FALSE; ret = fbChangeWindowAttributes(pWin, mask); uxa_finish_access_window(pWin); return ret; } static RegionPtr uxa_bitmap_to_region(PixmapPtr pPix) { RegionPtr ret; if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO)) return NULL; ret = fbPixmapToRegion(pPix); uxa_finish_access(&pPix->drawable, UXA_ACCESS_RO); return ret; } void uxa_set_fallback_debug(ScreenPtr screen, Bool enable) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); uxa_screen->fallback_debug = enable; } void uxa_set_force_fallback(ScreenPtr screen, Bool value) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); uxa_screen->force_fallback = value; } /** * uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's * screen private, before calling down to the next CloseSccreen. */ static Bool uxa_close_screen(CLOSE_SCREEN_ARGS_DECL) { uxa_screen_t *uxa_screen = uxa_get_screen(screen); #ifdef RENDER PictureScreenPtr ps = GetPictureScreenIfSet(screen); #endif int n; if (uxa_screen->solid_clear) FreePicture(uxa_screen->solid_clear, 0); if (uxa_screen->solid_black) FreePicture(uxa_screen->solid_black, 0); if (uxa_screen->solid_white) FreePicture(uxa_screen->solid_white, 0); for (n = 0; n < uxa_screen->solid_cache_size; n++) FreePicture(uxa_screen->solid_cache[n].picture, 0); uxa_glyphs_fini(screen); #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,99,903,0) if (screen->devPrivate) { /* Destroy the pixmap created by miScreenInit() *before* * chaining up as we finalize ourselves here and so this * is the last chance we have of releasing our resources * associated with the Pixmap. So do it first. */ (void) (*screen->DestroyPixmap) (screen->devPrivate); screen->devPrivate = NULL; } #endif screen->CreateGC = uxa_screen->SavedCreateGC; screen->CloseScreen = uxa_screen->SavedCloseScreen; screen->GetImage = uxa_screen->SavedGetImage; screen->GetSpans = uxa_screen->SavedGetSpans; screen->CreatePixmap = uxa_screen->SavedCreatePixmap; screen->DestroyPixmap = uxa_screen->SavedDestroyPixmap; screen->CopyWindow = uxa_screen->SavedCopyWindow; screen->ChangeWindowAttributes = uxa_screen->SavedChangeWindowAttributes; screen->BitmapToRegion = uxa_screen->SavedBitmapToRegion; #ifdef RENDER if (ps) { ps->Composite = uxa_screen->SavedComposite; ps->Glyphs = uxa_screen->SavedGlyphs; ps->Trapezoids = uxa_screen->SavedTrapezoids; ps->AddTraps = uxa_screen->SavedAddTraps; ps->Triangles = uxa_screen->SavedTriangles; ps->UnrealizeGlyph = uxa_screen->SavedUnrealizeGlyph; } #endif free(uxa_screen); return (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); } /** * This function allocates a driver structure for UXA drivers to fill in. By * having UXA allocate the structure, the driver structure can be extended * without breaking ABI between UXA and the drivers. The driver's * responsibility is to check beforehand that the UXA module has a matching * major number and sufficient minor. Drivers are responsible for freeing the * driver structure using free(). * * @return a newly allocated, zero-filled driver structure */ uxa_driver_t *uxa_driver_alloc(void) { return calloc(1, sizeof(uxa_driver_t)); } /** * @param screen screen being initialized * @param pScreenInfo UXA driver record * * uxa_driver_init sets up UXA given a driver record filled in by the driver. * pScreenInfo should have been allocated by uxa_driver_alloc(). See the * comments in _UxaDriver for what must be filled in and what is optional. * * @return TRUE if UXA was successfully initialized. */ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver) { uxa_screen_t *uxa_screen; if (!uxa_driver) return FALSE; if (uxa_driver->uxa_major != UXA_VERSION_MAJOR || uxa_driver->uxa_minor > UXA_VERSION_MINOR) { LogMessage(X_ERROR, "UXA(%d): driver's UXA version requirements " "(%d.%d) are incompatible with UXA version (%d.%d)\n", screen->myNum, uxa_driver->uxa_major, uxa_driver->uxa_minor, UXA_VERSION_MAJOR, UXA_VERSION_MINOR); return FALSE; } if (!uxa_driver->prepare_solid) { LogMessage(X_ERROR, "UXA(%d): uxa_driver_t::prepare_solid must be " "non-NULL\n", screen->myNum); return FALSE; } if (!uxa_driver->prepare_copy) { LogMessage(X_ERROR, "UXA(%d): uxa_driver_t::prepare_copy must be " "non-NULL\n", screen->myNum); return FALSE; } #if HAS_DIXREGISTERPRIVATEKEY if (!dixRegisterPrivateKey(&uxa_screen_index, PRIVATE_SCREEN, 0)) return FALSE; #endif uxa_screen = calloc(sizeof(uxa_screen_t), 1); if (!uxa_screen) { LogMessage(X_WARNING, "UXA(%d): Failed to allocate screen private\n", screen->myNum); return FALSE; } uxa_screen->info = uxa_driver; dixSetPrivate(&screen->devPrivates, &uxa_screen_index, uxa_screen); uxa_screen->force_fallback = FALSE; uxa_screen->solid_cache_size = 0; uxa_screen->solid_clear = 0; uxa_screen->solid_black = 0; uxa_screen->solid_white = 0; // exaDDXDriverInit(screen); /* * Replace various fb screen functions */ uxa_screen->SavedCloseScreen = screen->CloseScreen; screen->CloseScreen = uxa_close_screen; uxa_screen->SavedCreateGC = screen->CreateGC; screen->CreateGC = uxa_create_gc; uxa_screen->SavedGetImage = screen->GetImage; screen->GetImage = uxa_get_image; uxa_screen->SavedGetSpans = screen->GetSpans; screen->GetSpans = uxa_get_spans; uxa_screen->SavedCopyWindow = screen->CopyWindow; screen->CopyWindow = uxa_copy_window; uxa_screen->SavedChangeWindowAttributes = screen->ChangeWindowAttributes; screen->ChangeWindowAttributes = uxa_change_window_attributes; uxa_screen->SavedBitmapToRegion = screen->BitmapToRegion; screen->BitmapToRegion = uxa_bitmap_to_region; #ifdef RENDER { PictureScreenPtr ps = GetPictureScreenIfSet(screen); if (ps) { uxa_screen->SavedComposite = ps->Composite; ps->Composite = uxa_composite; uxa_screen->SavedGlyphs = ps->Glyphs; ps->Glyphs = uxa_glyphs; uxa_screen->SavedUnrealizeGlyph = ps->UnrealizeGlyph; ps->UnrealizeGlyph = uxa_glyph_unrealize; uxa_screen->SavedTriangles = ps->Triangles; ps->Triangles = uxa_triangles; uxa_screen->SavedTrapezoids = ps->Trapezoids; ps->Trapezoids = uxa_trapezoids; uxa_screen->SavedAddTraps = ps->AddTraps; ps->AddTraps = uxa_add_traps; } } #endif LogMessage(X_INFO, "UXA(%d): Driver registered support for the following" " operations:\n", screen->myNum); assert(uxa_driver->prepare_solid != NULL); LogMessage(X_INFO, " solid\n"); assert(uxa_driver->prepare_copy != NULL); LogMessage(X_INFO, " copy\n"); if (uxa_driver->prepare_composite != NULL) { LogMessage(X_INFO, " composite (RENDER acceleration)\n"); } if (uxa_driver->put_image != NULL) { LogMessage(X_INFO, " put_image\n"); } if (uxa_driver->get_image != NULL) { LogMessage(X_INFO, " get_image\n"); } return TRUE; } Bool uxa_resources_init(ScreenPtr screen) { if (!uxa_glyphs_init(screen)) return FALSE; return TRUE; } /** * uxa_driver_fini tears down UXA on a given screen. * * @param pScreen screen being torn down. */ void uxa_driver_fini(ScreenPtr pScreen) { /*right now does nothing */ } xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa.h000066400000000000000000000525631267532330400226400ustar00rootroot00000000000000/* * Copyright © 2000, 2008 Keith Packard * 2004 Eric Anholt * 2005 Zack Rusin * * 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, and that the name of copyright holders not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Copyright holders make no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /** @file * UXA - the unified memory acceleration architecture. * * This is the header containing the public API of UXA for uxa drivers. */ #ifndef UXA_H #define UXA_H #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" #include "gcstruct.h" #include "picturestr.h" #include "fb.h" #define UXA_VERSION_MAJOR 1 #define UXA_VERSION_MINOR 0 #define UXA_VERSION_RELEASE 0 typedef enum { UXA_ACCESS_RO, UXA_ACCESS_RW, } uxa_access_t; /** * The UxaDriver structure is allocated through uxa_driver_alloc(), and then * fllled in by drivers. */ typedef struct _UxaDriver { /** * uxa_major and uxa_minor should be set by the driver to the version of * UXA which the driver was compiled for (or configures itself at * runtime to support). This allows UXA to extend the structure for * new features without breaking ABI for drivers compiled against * older versions. */ int uxa_major, uxa_minor; /** * The flags field is bitfield of boolean values controlling UXA's * behavior. * * The flags include UXA_TWO_BITBLT_DIRECTIONS. */ int flags; /** @name solid * @{ */ /** * check_solid() checks whether the driver can do a solid fill to this drawable. * @param pDrawable Destination drawable * @param alu raster operation * @param planemask write mask for the fill * * The check_solid() call is recommended if prepare_solid() is * implemented, but is not required. */ Bool(*check_solid) (DrawablePtr pDrawable, int alu, Pixel planemask); /** * prepare_solid() sets up the driver for doing a solid fill. * @param pPixmap Destination pixmap * @param alu raster operation * @param planemask write mask for the fill * @param fg "foreground" color for the fill * * This call should set up the driver for doing a series of solid fills * through the solid() call. The alu raster op is one of the GX* * graphics functions listed in X.h, and typically maps to a similar * single-byte "ROP" setting in all hardware. The planemask controls * which bits of the destination should be affected, and will only * represent the bits up to the depth of pPixmap. The fg is the pixel * value of the foreground color referred to in ROP descriptions. * * Note that many drivers will need to store some of the data in the * driver private record, for sending to the hardware with each * drawing command. * * The prepare_solid() call is required of all drivers, but it may fail * for any reason. Failure results in a fallback to software rendering. */ Bool(*prepare_solid) (PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); /** * solid() performs a solid fill set up in the last prepare_solid() * call. * * @param pPixmap destination pixmap * @param x1 left coordinate * @param y1 top coordinate * @param x2 right coordinate * @param y2 bottom coordinate * * Performs the fill set up by the last prepare_solid() call, * covering the area from (x1,y1) to (x2,y2) in pPixmap. Note that * the coordinates are in the coordinate space of the destination * pixmap, so the driver will need to set up the hardware's offset * and pitch for the destination coordinates according to the pixmap's * offset and pitch within framebuffer. * * This call is required if prepare_solid() ever succeeds. */ void (*solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2); /** * done_solid() finishes a set of solid fills. * * @param pPixmap destination pixmap. * * The done_solid() call is called at the end of a series of consecutive * solid() calls following a successful prepare_solid(). This allows * drivers to finish up emitting drawing commands that were buffered, or * clean up state from prepare_solid(). * * This call is required if prepare_solid() ever succeeds. */ void (*done_solid) (PixmapPtr pPixmap); /** @} */ /** @name copy * @{ */ /** * check_copy() checks whether the driver can blit between the two Pictures */ Bool(*check_copy) (PixmapPtr pSrc, PixmapPtr pDst, int alu, Pixel planemask); /** * prepare_copy() sets up the driver for doing a copy within video * memory. - * * @param pSrcPixmap source pixmap * @param pDstPixmap destination pixmap * @param dx X copy direction * @param dy Y copy direction * @param alu raster operation * @param planemask write mask for the fill * * This call should set up the driver for doing a series of copies * from the pSrcPixmap to the pDstPixmap. The dx flag will be * positive if the * hardware should do the copy from the left to the right, and dy will * be positive if the copy should be done from the top to the bottom. * This is to deal with self-overlapping copies when * pSrcPixmap == pDstPixmap. * * If your hardware can only support blits that are (left to right, * top to bottom) or (right to left, bottom to top), then you should * set #UXA_TWO_BITBLT_DIRECTIONS, and UXA will break down copy * operations to ones that meet those requirements. The alu raster * op is one of the GX* graphics functions listed in X.h, and * typically maps to a similar single-byte "ROP" setting in all * hardware. The planemask controls which bits of the destination * should be affected, and will only represent the bits up to the * depth of pPixmap. * * Note that many drivers will need to store some of the data in the * driver private record, for sending to the hardware with each * drawing command. * * The prepare_copy() call is required of all drivers, but it may fail * for any reason. Failure results in a fallback to software rendering. */ Bool(*prepare_copy) (PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy, int alu, Pixel planemask); /** * copy() performs a copy set up in the last prepare_copy call. * * @param pDstPixmap destination pixmap * @param srcX source X coordinate * @param srcY source Y coordinate * @param dstX destination X coordinate * @param dstY destination Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied. * * Performs the copy set up by the last prepare_copy() call, copying the * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the * source pixmap to the same-sized rectangle at (dstX, dstY) in the * destination pixmap. Those rectangles may overlap in memory, if * pSrcPixmap == pDstPixmap. Note that this call does not receive the * pSrcPixmap as an argument -- if it's needed in this function, it * should be stored in the driver private during prepare_copy(). As * with solid(), the coordinates are in the coordinate space of each * pixmap, so the driver will need to set up source and destination * pitches and offsets from those pixmaps, probably using * uxaGetPixmapOffset() and uxa_get_pixmap_pitch(). * * This call is required if prepare_copy ever succeeds. */ void (*copy) (PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); /** * done_copy() finishes a set of copies. * * @param pPixmap destination pixmap. * * The done_copy() call is called at the end of a series of consecutive * copy() calls following a successful prepare_copy(). This allows * drivers to finish up emitting drawing commands that were buffered, * or clean up state from prepare_copy(). * * This call is required if prepare_copy() ever succeeds. */ void (*done_copy) (PixmapPtr pDstPixmap); /** @} */ /** @name composite * @{ */ /** * check_composite() checks to see if a composite operation could be * accelerated. * * @param op Render operation * @param pSrcPicture source Picture * @param pMaskPicture mask picture * @param pDstPicture destination Picture * @param width The width of the composite operation * @param height The height of the composite operation * * The check_composite() call checks if the driver could handle * acceleration of op with the given source, mask, and destination * pictures. This allows drivers to check source and destination * formats, supported operations, transformations, and component * alpha state, and send operations it can't support to software * rendering early on. * * See prepare_composite() for more details on likely issues that * drivers will have in accelerating composite operations. * * The check_composite() call is recommended if prepare_composite() is * implemented, but is not required. */ Bool(*check_composite) (int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, int width, int height); /** * check_composite_target() checks to see if the destination of the composite * operation can be used without midification. * * @param pixmap Destination Pixmap * * The check_composite_target() call is recommended if prepare_composite() is * implemented, but is not required. */ Bool(*check_composite_target) (PixmapPtr pixmap); /** * check_composite_texture() checks to see if a source to the composite * operation can be used without midification. * * @param pScreen Screen * @param pPicture Picture * * The check_composite_texture() call is recommended if prepare_composite() is * implemented, but is not required. */ Bool(*check_composite_texture) (ScreenPtr pScreen, PicturePtr pPicture); /** * prepare_composite() sets up the driver for doing a composite * operation described in the Render extension protocol spec. * * @param op Render operation * @param pSrcPicture source Picture * @param pMaskPicture mask picture * @param pDstPicture destination Picture * @param pSrc source pixmap * @param pMask mask pixmap * @param pDst destination pixmap * * This call should set up the driver for doing a series of composite * operations, as described in the Render protocol spec, with the given * pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and * pDst are the pixmaps containing the pixel data, and should be used * for setting the offset and pitch used for the coordinate spaces for * each of the Pictures. * * Notes on interpreting Picture structures: * - The Picture structures will always have a valid pDrawable. * - The Picture structures will never have alphaMap set. * - The mask Picture (and therefore pMask) may be NULL, in which case * the operation is simply src OP dst instead of src IN mask OP dst, * and mask coordinates should be ignored. * - pMarkPicture may have componentAlpha set, which greatly changes * the behavior of the composite operation. componentAlpha has no * effect when set on pSrcPicture or pDstPicture. * - The source and mask Pictures may have a transformation set * (Picture->transform != NULL), which means that the source * coordinates should be transformed by that transformation, * resulting in scaling, rotation, etc. The PictureTransformPoint() * call can transform coordinates for you. Transforms have no * effect on Pictures when used as a destination. * - The source and mask pictures may have a filter set. * PictFilterNearest and PictFilterBilinear are defined in the * Render protocol, but others may be encountered, and must be * handled correctly (usually by prepare_composite failing, and * falling back to software). Filters have * no effect on Pictures when used as a destination. * - The source and mask Pictures may have repeating set, which must be * respected. Many chipsets will be unable to support repeating on * pixmaps that have a width or height that is not a power of two. * * If your hardware can't support source pictures (textures) with * non-power-of-two pitches, you should set #UXA_OFFSCREEN_ALIGN_POT. * * Note that many drivers will need to store some of the data in the * driver private record, for sending to the hardware with each * drawing command. * * The prepare_composite() call is not required. However, it is highly * recommended for performance of antialiased font rendering and * performance of cairo applications. Failure results in a fallback * to software rendering. */ Bool(*prepare_composite) (int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst); /** * composite() performs a composite operation set up in the last * prepare_composite() call. * * @param pDstPixmap destination pixmap * @param srcX source X coordinate * @param srcY source Y coordinate * @param maskX source X coordinate * @param maskY source Y coordinate * @param dstX destination X coordinate * @param dstY destination Y coordinate * @param width destination rectangle width * @param height destination rectangle height * * Performs the composite operation set up by the last * prepare_composite() call, to the rectangle from (dstX, dstY) to * (dstX + width, dstY + height) in the destination Pixmap. Note that * if a transformation was set on the source or mask Pictures, the * source rectangles may not be the same size as the destination * rectangles and filtering. Getting the coordinate transformation * right at the subpixel level can be tricky, and rendercheck * can test this for you. * * This call is required if prepare_composite() ever succeeds. */ void (*composite) (PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height); /** * done_composite() finishes a set of composite operations. * * @param pPixmap destination pixmap. * * The done_composite() call is called at the end of a series of * consecutive composite() calls following a successful * prepare_composite(). This allows drivers to finish up emitting * drawing commands that were buffered, or clean up state from * prepare_composite(). * * This call is required if prepare_composite() ever succeeds. */ void (*done_composite) (PixmapPtr pDst); /** @} */ /** * put_image() loads a rectangle of data from src into pDst. * * @param pDst destination pixmap * @param x destination X coordinate. * @param y destination Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied * @param src pointer to the beginning of the source data * @param src_pitch pitch (in bytes) of the lines of source data. * * put_image() copies data in system memory beginning at src (with * pitch src_pitch) into the destination pixmap from (x, y) to * (x + width, y + height). This is typically done with hostdata * uploads, where the CPU sets up a blit command on the hardware with * instructions that the blit data will be fed through some sort of * aperture on the card. * * put_image() is most important for the performance of uxa_glyphs() * (antialiased font drawing) by allowing pipelining of data uploads, * avoiding a sync of the card after each glyph. * * @return TRUE if the driver successfully uploaded the data. FALSE * indicates that UXA should fall back to doing the upload in software. * * put_image() is not required, but is recommended if composite * acceleration is supported. */ Bool(*put_image) (PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); /** * get_image() loads a rectangle of data from pSrc into dst * * @param pSrc source pixmap * @param x source X coordinate. * @param y source Y coordinate * @param width width of the rectangle to be copied * @param height height of the rectangle to be copied * @param dst pointer to the beginning of the destination data * @param dst_pitch pitch (in bytes) of the lines of destination data. * * get_image() copies data from offscreen memory in pSrc from * (x, y) to (x + width, y + height), to system memory starting at * dst (with pitch dst_pitch). This would usually be done * using scatter-gather DMA, supported by a DRM call, or by blitting * to AGP and then synchronously reading from AGP. * * @return TRUE if the driver successfully downloaded the data. FALSE * indicates that UXA should fall back to doing the download in * software. * * get_image() is not required, but is highly recommended. */ Bool(*get_image) (PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); /** @{ */ /** * prepare_access() is called before CPU access to an offscreen pixmap. * * @param pPix the pixmap being accessed * @param index the index of the pixmap being accessed. * * prepare_access() will be called before CPU access to an offscreen * pixmap. * * This can be used to set up hardware surfaces for byteswapping or * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of * making CPU access use a different aperture. * * The index is one of #UXA_PREPARE_DEST, #UXA_PREPARE_SRC, or * #UXA_PREPARE_MASK, indicating which pixmap is in question. Since * only up to three pixmaps will have prepare_access() called on them * per operation, drivers can have a small, statically-allocated space * to maintain state for prepare_access() and finish_access() in. * Note that the same pixmap may have prepare_access() called on it * more than once, for uxample when doing a copy within the same * pixmap (so it gets prepare_access as * #UXA_PREPARE_DEST and then as #UXA_PREPARE_SRC). * * prepare_access() may fail. An example might be the case of * hardware that can set up 1 or 2 surfaces for CPU access, but not * 3. If prepare_access() * fails, UXA will migrate the pixmap to system memory. * get_image() must be implemented and must not fail if a driver * wishes to fail in prepare_access(). prepare_access() must not * fail when pPix is the visible screen, because the visible screen * can not be migrated. * * @return TRUE if prepare_access() successfully prepared the pixmap * for CPU drawing. * @return FALSE if prepare_access() is unsuccessful and UXA should use * get_image() to migate the pixmap out. */ Bool(*prepare_access) (PixmapPtr pPix, uxa_access_t access); /** * finish_access() is called after CPU access to an offscreen pixmap. * * @param pPix the pixmap being accessed * @param index the index of the pixmap being accessed. * * finish_access() will be called after finishing CPU access of an * offscreen pixmap set up by prepare_access(). Note that the * finish_access() will not be called if prepare_access() failed. */ void (*finish_access) (PixmapPtr pPix, uxa_access_t access); /** * PixmapIsOffscreen() is an optional driver replacement to * uxa_pixmap_is_offscreen(). Set to NULL if you want the standard * behaviour of uxa_pixmap_is_offscreen(). * * @param pPix the pixmap * @return TRUE if the given drawable is in framebuffer memory. * * uxa_pixmap_is_offscreen() is used to determine if a pixmap is in * offscreen memory, meaning that acceleration could probably be done * to it, and that it will need to be wrapped by * prepare_access()/finish_access() when accessing it with the CPU. */ Bool(*pixmap_is_offscreen) (PixmapPtr pPix); /** @} */ } uxa_driver_t; /** @name UXA driver flags * @{ */ /** * UXA_TWO_BITBLT_DIRECTIONS indicates to UXA that the driver can only * support copies that are (left-to-right, top-to-bottom) or * (right-to-left, bottom-to-top). */ #define UXA_TWO_BITBLT_DIRECTIONS (1 << 2) /** @} */ /** @name UXA CreatePixmap hint flags * @{ */ /** * Flag to hint that the first operation on the pixmap will be a * prepare_access. */ #define UXA_CREATE_PIXMAP_FOR_MAP 0x20000000 /** @} */ uxa_driver_t *uxa_driver_alloc(void); Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver); Bool uxa_resources_init(ScreenPtr screen); void uxa_driver_fini(ScreenPtr pScreen); CARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap); Bool uxa_get_color_for_pixmap (PixmapPtr pixmap, CARD32 src_format, CARD32 dst_format, CARD32 *pixel); void uxa_set_fallback_debug(ScreenPtr screen, Bool enable); void uxa_set_force_fallback(ScreenPtr screen, Bool enable); /** * Returns TRUE if the given planemask covers all the significant bits in the * pixel values for pDrawable. */ #define UXA_PM_IS_SOLID(_pDrawable, _pm) \ (((_pm) & FbFullMask((_pDrawable)->depth)) == \ FbFullMask((_pDrawable)->depth)) #endif /* UXA_H */ xserver-xorg-video-intel-2.99.917+git20160325/src/uxa/uxa_module.h000066400000000000000000000001731267532330400241730ustar00rootroot00000000000000#ifndef INTEL_MODULE_H #define INTEL_MODULE_H extern Bool intel_init_scrn(ScrnInfoPtr scrn); #endif /* INTEL_MODULE_H */ xserver-xorg-video-intel-2.99.917+git20160325/test/000077500000000000000000000000001267532330400212525ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/test/.gitignore000066400000000000000000000010321267532330400232360ustar00rootroot00000000000000basic-copyarea basic-copyarea-size basic-copyplane basic-fillrect basic-putimage basic-lines basic-stress basic-stippledrect basic-tiledrect DrawSegments cursor-test render-fill render-trapezoid render-trapezoid-image render-triangle render-fill-copy render-composite-solid render-composite-solid-mask render-copyarea render-copyarea-mask render-copyarea-size render-copy-alphaless render-glyphs mixed-stress lowlevel-blt-bench vsync.avi dri2-race dri2-speed dri2-swap dri2-test dri3-test present-race present-speed present-test shm-test xserver-xorg-video-intel-2.99.917+git20160325/test/DrawSegments.c000066400000000000000000000114651267532330400240300ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const XPoint points[]= { /* top */ { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0}, { 8, 0}, /* right */ { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4}, { 8, 5}, { 8, 6}, { 8, 7}, { 8, 8}, /* bottom */ { 7, 8}, { 6, 8}, { 5, 8}, { 4, 8}, { 3, 8}, { 2, 8}, { 1, 8}, { 0, 8}, /* left */ { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1}, { 0, 0} /* and origin again for luck */ }; #define NUM_POINTS (sizeof(points)/sizeof(points[0])) static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void draw(struct test_display *dpy, struct test_target *tt, int alu, int width, int style, int cap, XSegment *seg, int nseg) { XGCValues val; GC gc; val.function = alu; val.foreground = WhitePixel(dpy->dpy, 0); val.line_width = width; val.line_style = style; val.cap_style = cap; gc = XCreateGC(dpy->dpy, tt->draw, GCForeground | GCFunction | GCLineWidth | GCLineStyle | GCCapStyle, &val); XDrawSegments(dpy->dpy, tt->draw, gc, seg, nseg); XFreeGC(dpy->dpy, gc); } static void hv0(struct test *t, enum target target) { char buf[1024]; struct test_target out, ref; int a, alu, cap; XSegment seg[(NUM_POINTS+1)*8]; int n, x, y, nseg; printf("Testing drawing of zero-width line segments (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); test_target_create_render(&t->ref, target, &ref); y = x = n = 0; for (a = 0; a <= NUM_POINTS; a++) { seg[n].x1 = a + 64; seg[n].y1 = y + 64; seg[n].x2 = NUM_POINTS + 64; seg[n].y2 = y + 64; n++; y++; seg[n].x1 = NUM_POINTS - a + 64; seg[n].y1 = y + 64; seg[n].x2 = 0 + 64; seg[n].y2 = y + 64; n++; y++; seg[n].x2 = a + 64; seg[n].y2 = y + 64; seg[n].x1 = NUM_POINTS + 64; seg[n].y1 = y + 64; n++; y++; seg[n].x2 = NUM_POINTS - a + 64; seg[n].y2 = y + 64; seg[n].x1 = 0 + 64; seg[n].y1 = y + 64; n++; y++; seg[n].y1 = a + 64; seg[n].x1 = x + 64; seg[n].y2 = NUM_POINTS + 64; seg[n].x2 = x + 64; n++; x++; seg[n].y1 = NUM_POINTS - a + 64; seg[n].x1 = x + 64; seg[n].y2 = 0 + 64; seg[n].x2 = x + 64; n++; x++; seg[n].y2 = a + 64; seg[n].x2 = x + 64; seg[n].y1 = NUM_POINTS + 64; seg[n].x1 = x + 64; n++; x++; seg[n].y2 = NUM_POINTS - a + 64; seg[n].x2 = x + 64; seg[n].y1 = 0 + 64; seg[n].x1 = x + 64; n++; x++; } for (alu = 0; alu < 16; alu++) { for (cap = CapNotLast; cap <= CapProjecting; cap++) { for (nseg = 0; nseg < n; nseg++) { sprintf(buf, "cap=%d, alu=%d, nseg=%d", cap, alu, nseg); clear(&t->out, &out); clear(&t->ref, &ref); draw(&t->out, &out, alu, 0, LineSolid, cap, seg, nseg); draw(&t->ref, &ref, alu, 0, LineSolid, cap, seg, nseg); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } } test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); printf("\n"); } static void general(struct test *t, enum target target) { char buf[1024]; struct test_target out, ref; int a, b, alu, lw, style, cap; XSegment seg[NUM_POINTS*NUM_POINTS]; int n = 0; printf("Testing drawing of general line segments (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); test_target_create_render(&t->ref, target, &ref); style = LineSolid; for (a = 0; a < NUM_POINTS; a++) { for (b = 0; b < NUM_POINTS; b++) { seg[n].x1 = points[a].x + 64; seg[n].y1 = points[a].y + 64; seg[n].x2 = points[b].x + 64; seg[n].y2 = points[b].y + 64; n++; } } for (alu = 0; alu < 16; alu++) { for (cap = CapNotLast; cap <= CapProjecting; cap++) { for (lw = 0; lw <= 4; lw++) { sprintf(buf, "width=%d, cap=%d, alu=%d", lw, cap, alu); clear(&t->out, &out); clear(&t->ref, &ref); draw(&t->out, &out, alu, lw, style, cap, seg, n); draw(&t->ref, &ref, alu, lw, style, cap, seg, n); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } } test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); printf("\n"); } int main(int argc, char **argv) { struct test test; enum target t; test_init(&test, argc, argv); for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { hv0(&test, t); general(&test, t); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/Makefile.am000066400000000000000000000026621267532330400233140ustar00rootroot00000000000000stress_TESTS = \ basic-fillrect \ basic-tiledrect \ basic-stippledrect \ basic-rectangle \ basic-string \ basic-copyarea \ basic-copyplane \ basic-copyarea-size \ basic-putimage \ basic-lines \ basic-stress \ DrawSegments \ cursor-test \ render-fill \ render-glyphs \ render-trapezoid \ render-trapezoid-image \ render-triangle \ render-fill-copy \ render-composite-solid \ render-composite-solid-mask \ render-copyarea \ render-copyarea-mask \ render-copyarea-size \ render-copy-alphaless \ mixed-stress \ shm-test \ $(NULL) if DRI2 stress_TESTS += \ dri2-race \ dri2-speed \ dri2-swap \ dri2-test \ $(NULL) endif if X11_DRI3 stress_TESTS += \ dri3-test \ present-race \ present-speed \ present-test \ $(NULL) endif check_PROGRAMS = $(stress_TESTS) noinst_PROGRAMS = lowlevel-blt-bench AM_CFLAGS = @CWARNFLAGS@ $(X11_CFLAGS) $(DRM_CFLAGS) LDADD = libtest.la $(X11_LIBS) $(DRM_LIBS) $(CLOCK_GETTIME_LIBS) noinst_LTLIBRARIES = libtest.la libtest_la_SOURCES = \ test.h \ test_display.c \ test_image.c \ test_log.c \ test_render.c \ $(NULL) if DRI2 libtest_la_SOURCES += \ dri2.c \ dri2.h \ $(NULL) endif if X11_DRI3 libtest_la_SOURCES += \ dri3.c \ dri3.h \ $(NULL) AM_CFLAGS += $(X11_DRI3_CFLAGS) LDADD += $(X11_DRI3_LIBS) endif vsync.avi: mkvsync.sh ./mkvsync.sh $@ clean-vsync-avi: rm -rf vsync.avi .build.tmp EXTRA_DIST = README mkvsync.sh tearing.mp4 virtual.conf clean-local: clean-vsync-avi xserver-xorg-video-intel-2.99.917+git20160325/test/README000066400000000000000000000007441267532330400221370ustar00rootroot00000000000000These are no substitute for xts, rendercheck and cairo-test-suite. They are intended to exercise corner cases in the batch management of long drawing commands and more explicit checking of the acceleration paths. Useful tools: # Packed YUV Xv tester gst-launch-1.0 videotestsrc pattern=snow ! 'video/x-raw,format=UYVY,width=640,height=360' ! xvimagesink # Planar YUV Xv tester gst-launch-1.0 videotestsrc pattern=snow ! 'video/x-raw,format=I420,width=640,height=360' ! xvimagesink xserver-xorg-video-intel-2.99.917+git20160325/test/basic-copyarea-size.c000066400000000000000000000044201267532330400252500ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include "test.h" #define SIZE 20000 struct draw { Pixmap a, b; GC gc; XRenderPictFormat *format; }; static void target_init(struct test_display *t, struct draw *tt, int size) { XGCValues val; tt->a = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), size, size, 32); tt->b = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), size, size, 32); val.graphics_exposures = 0; tt->gc = XCreateGC(t->dpy, tt->a, GCGraphicsExposures, &val); tt->format = XRenderFindStandardFormat(t->dpy, PictStandardARGB32); val.foreground = 0xffff0000; XChangeGC(t->dpy, tt->gc, GCForeground, &val); XFillRectangle(t->dpy, tt->a, tt->gc, 0, 0, size, size); val.foreground = 0xff0000ff; XChangeGC(t->dpy, tt->gc, GCForeground, &val); XFillRectangle(t->dpy, tt->b, tt->gc, 0, 0, size, size); } static void target_fini(struct test_display *t, struct draw *tt) { XFreePixmap(t->dpy, tt->a); XFreePixmap(t->dpy, tt->b); } int main(int argc, char **argv) { struct test test; struct draw out, ref; int size, i; test_init(&test, argc, argv); /* Copy back and forth betwenn two pixmaps, gradually getting larger */ for (size = 1; size <= SIZE; size = (size * 3 + 1) / 2) { target_init(&test.out, &out, size); target_init(&test.ref, &ref, size); printf("size=%d\n", size); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i); do { int sx = rand() % (2*size) - size; int sy = rand() % (2*size) - size; int dx = rand() % (2*size) - size; int dy = rand() % (2*size) - size; int order = rand() & 1; XCopyArea(test.out.dpy, order ? out.a : out.b, (!order) ? out.a : out.b, out.gc, sx, sy, size, size, dx, dy); XCopyArea(test.ref.dpy, order ? ref.a : ref.b, (!order) ? ref.a : ref.b, ref.gc, sx, sy, size, size, dx, dy); } while (--reps); } test_compare(&test, out.a, out.format, ref.a, ref.format, 0, 0, size, size, ""); test_compare(&test, out.b, out.format, ref.b, ref.format, 0, 0, size, size, ""); target_fini(&test.out, &out); target_fini(&test.ref, &ref); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-copyarea.c000066400000000000000000000157641267532330400243150ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *t, Drawable d, XRenderPictFormat *format, int use_window, int tx, int ty, uint8_t alu, int x, int y, int w, int h, uint32_t fg) { XGCValues val; Drawable tmp; GC gc; val.graphics_exposures = 0; val.function = alu; val.foreground = fg; if (use_window) { XSetWindowAttributes attr; attr.override_redirect = 1; tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), tx, ty, w, h, 0, format->depth, InputOutput, DefaultVisual(t->dpy, DefaultScreen(t->dpy)), CWOverrideRedirect, &attr); XMapWindow(t->dpy, tmp); } else tmp = XCreatePixmap(t->dpy, d, w, h, format->depth); gc = XCreateGC(t->dpy, d, GCGraphicsExposures | GCForeground, &val); XFillRectangle(t->dpy, tmp, gc, 0, 0, w, h); XChangeGC(t->dpy, gc, GCFunction, &val); XCopyArea(t->dpy, tmp, d, gc, 0, 0, w, h, x, y); XFreeGC(t->dpy, gc); if (use_window) XDestroyWindow(t->dpy, tmp); else XFreePixmap(t->dpy, tmp); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); uint32_t fg = rand(); fill_rect(&t->out, tt.draw, tt.format, 0, 0, 0, GXcopy, x, y, 1, 1, fg); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = fg; } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; uint32_t result; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = 1 + rand() % (tt.width - 1); int h = 1 + rand() % (tt.height - 1); uint32_t fg = rand(); x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.draw, tt.format, 0, 0, 0, GXcopy, x, y, w, h, fg); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, fg); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *) (image.data + y*image.bytes_per_line + x*image.bits_per_pixel/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target out, ref; int r, s; printf("Testing area fills (%s, using %s source): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (out.width - 1); int y = rand() % (out.height - 1); int w = 1 + rand() % (out.width - x - 1); int h = 1 + rand() % (out.height - y - 1); int tmpx = w == out.width ? 0 : rand() % (out.width - w); int tmpy = h == out.height ? 0 : rand() % (out.height - h); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); fill_rect(&t->out, out.draw, out.format, use_window, tmpx, tmpy, alu, x, y, w, h, fg); fill_rect(&t->ref, ref.draw, ref.format, use_window, tmpx, tmpy, alu, x, y, w, h, fg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t, 0); if (t != PIXMAP) rect_tests(&test, reps, sets, t, 1); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-copyplane.c000066400000000000000000000044731267532330400244770ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static uint8_t clock_bits[] = {0x3C, 0x5E, 0xEF, 0xF7, 0x87, 0xFF, 0x7E, 0x3C}; /* https://bugs.freedesktop.org/show_bug.cgi?id=91499 */ static void draw_clock(struct test_display *t, Drawable d, uint8_t alu, int x, int y, uint32_t fg, uint32_t bg) { Pixmap pixmap; XGCValues val; GC gc; val.graphics_exposures = 0; val.function = alu; val.foreground = fg; val.background = fg; gc = XCreateGC(t->dpy, d, GCGraphicsExposures | GCForeground | GCBackground | GCFunction, &val); pixmap = XCreateBitmapFromData(t->dpy, d, (char *)clock_bits, 8, 8); XCopyPlane(t->dpy, pixmap, d, gc, 0, 0, 8, 8, x, y, 1); XFreePixmap(t->dpy, pixmap); XFreeGC(t->dpy, gc); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void clock_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing clock (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (out.width - 8); int y = rand() % (out.height - 8); uint8_t alu = rand() % (GXset + 1); uint32_t bg = rand(); uint32_t fg = rand(); draw_clock(&t->out, out.draw, alu, x, y, fg, bg); draw_clock(&t->ref, ref.draw, alu, x, y, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { clock_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-fillrect.c000066400000000000000000000136031267532330400243040ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *t, Drawable d, uint8_t alu, int x, int y, int w, int h, uint32_t fg) { XGCValues val; GC gc; val.function = alu; val.foreground = fg; gc = XCreateGC(t->dpy, d, GCForeground | GCFunction, &val); XFillRectangle(t->dpy, d, gc, x, y, w, h); XFreeGC(t->dpy, gc); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); uint32_t fg = rand(); fill_rect(&t->out, tt.draw, GXcopy, x, y, 1, 1, fg); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = fg; } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; uint32_t result; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; uint32_t fg = rand(); x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.draw, GXcopy, x, y, w, h, fg); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, fg); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *) (image.data + y*image.bytes_per_line + x*image.bits_per_pixel/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); fill_rect(&t->out, out.draw, alu, x, y, w, h, fg); fill_rect(&t->ref, ref.draw, alu, x, y, w, h, fg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-lines.c000066400000000000000000000056661267532330400236240ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const XPoint points[]= { /* top */ { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0}, { 8, 0}, /* right */ { 8, 1}, { 8, 2}, { 8, 3}, { 8, 4}, { 8, 5}, { 8, 6}, { 8, 7}, { 8, 8}, /* bottom */ { 7, 8}, { 6, 8}, { 5, 8}, { 4, 8}, { 3, 8}, { 2, 8}, { 1, 8}, { 0, 8}, /* left */ { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1}, { 0, 0} /* and origin again for luck */ }; #define NUM_POINTS (sizeof(points)/sizeof(points[0])) static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void draw_line(struct test_display *dpy, struct test_target *tt, int alu, int width, int style, int cap, const XPoint *p1, const XPoint *p2, int dx, int dy) { XGCValues val; GC gc; val.function = GXcopy; val.foreground = WhitePixel(dpy->dpy, 0); val.line_width = width; val.line_style = style; val.cap_style = cap; gc = XCreateGC(dpy->dpy, tt->draw, GCForeground | GCFunction | GCLineWidth | GCLineStyle | GCCapStyle, &val); XDrawLine(dpy->dpy, tt->draw, gc, p1->x + dx, p1->y + dy, p2->x + dx, p2->y + dy); XFreeGC(dpy->dpy, gc); } static void line_tests(struct test *t, enum target target) { char buf[1024]; struct test_target out, ref; int a, b, alu, lw, style, cap; printf("Testing drawing of single line segments (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); test_target_create_render(&t->ref, target, &ref); style = LineSolid; for (alu = 0; alu < 16; alu++) { for (cap = CapNotLast; cap <= CapProjecting; cap++) { for (lw = 0; lw <= 4; lw++) { for (a = 0; a < NUM_POINTS; a++) { for (b = 0; b < NUM_POINTS; b++) { sprintf(buf, "p1=(%d, %d), p2=(%d, %d), width=%d, cap=%d, alu=%d", points[a].x, points[a].y, points[b].x, points[b].y, lw, cap, alu); clear(&t->out, &out); clear(&t->ref, &ref); draw_line(&t->out, &out, alu, lw, style, cap, &points[a], &points[b], 64, 64); draw_line(&t->ref, &ref, alu, lw, style, cap, &points[a], &points[b], 64, 64); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } } } } test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); printf("\n"); } int main(int argc, char **argv) { struct test test; enum target t; test_init(&test, argc, argv); for (t = TARGET_FIRST; t <= TARGET_LAST; t++) line_tests(&test, t); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-putimage.c000066400000000000000000000153421267532330400243150ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *dpy, Drawable d, XRenderPictFormat *format, int use_shm, uint8_t alu, int x, int y, int w, int h, uint32_t fg) { XImage image; XGCValues val; GC gc; test_init_image(&image, &dpy->shm, format, w, h); pixman_fill((uint32_t*)image.data, image.bytes_per_line/sizeof(uint32_t), image.bits_per_pixel, 0, 0, w, h, fg); val.function = alu; gc = XCreateGC(dpy->dpy, d, GCFunction, &val); if (use_shm) { XShmPutImage(dpy->dpy, d, gc, &image, 0, 0, x, y, w, h, 0); XSync(dpy->dpy, 1); } else { XPutImage(dpy->dpy, d, gc, &image, 0, 0, x, y, w, h); } XFreeGC(dpy->dpy, gc); } static void pixel_tests(struct test *t, int reps, int sets, enum target target, int use_shm) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s %s shm): ", test_target_name(target), use_shm ? "with" : "without" ); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; uint32_t fg = color(red, green, blue, alpha); fill_rect(&t->out, tt.draw, tt.format, use_shm, GXcopy, x, y, 1, 1, fg); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = fg; } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target, int use_shm) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s %s shm): ", test_target_name(target), use_shm ? "with" : "without" ); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; uint32_t fg = color(red, green, blue, alpha); int w, h; x = rand() % tt.width; y = rand() % tt.height; w = rand() % (tt.width - x); h = rand() % (tt.height - y); fill_rect(&t->out, tt.draw, tt.format, use_shm, GXcopy, x, y, w, h, fg); pixman_fill(cells, tt.width, 32, x, y, w, h, fg); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); char buf[600]; show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x[%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_shm) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % out.width; int y = rand() % out.height; int w = rand() % (out.width - x); int h = rand() % (out.height - y); uint8_t alu = rand() % (GXset + 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; uint8_t fg = color(red, green, blue, alpha); fill_rect(&t->out, out.draw, out.format, use_shm, alu, x, y, w, h, fg); fill_rect(&t->ref, ref.draw, ref.format, use_shm, alu, x, y, w, h, fg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t, 0); area_tests(&test, reps, sets, t, 0); rect_tests(&test, reps, sets, t, 0); pixel_tests(&test, reps, sets, t, 1); area_tests(&test, reps, sets, t, 1); rect_tests(&test, reps, sets, t, 1); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-rectangle.c000066400000000000000000000123431267532330400244440ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include "test.h" static void draw_rect(struct test_display *t, Drawable d, uint8_t alu, int x, int y, int w, int h, uint32_t fg, int lw) { XGCValues val; GC gc; val.function = alu; val.foreground = fg; val.line_width = lw; gc = XCreateGC(t->dpy, d, GCForeground | GCFunction | GCLineWidth, &val); XDrawRectangle(t->dpy, d, gc, x, y, w, h); XFreeGC(t->dpy, gc); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void zrect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing empty rects (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t lw = rand() % 4; draw_rect(&t->out, out.draw, alu, x, y, 0, 0, fg, lw); draw_rect(&t->ref, ref.draw, alu, x, y, 0, 0, fg, lw); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void hrect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing horizontal rects (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t lw = rand() % 4; draw_rect(&t->out, out.draw, alu, x, y, w, 0, fg, lw); draw_rect(&t->ref, ref.draw, alu, x, y, w, 0, fg, lw); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void vrect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing vertical rects (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int h = rand() % (2*out.width); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t lw = rand() % 4; draw_rect(&t->out, out.draw, alu, x, y, 0, h, fg, lw); draw_rect(&t->ref, ref.draw, alu, x, y, 0, h, fg, lw); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing general (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t lw = rand() % 4; draw_rect(&t->out, out.draw, alu, x, y, w, h, fg, lw); draw_rect(&t->ref, ref.draw, alu, x, y, w, h, fg, lw); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { zrect_tests(&test, reps, sets, t); hrect_tests(&test, reps, sets, t); vrect_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-stippledrect.c000066400000000000000000000140641267532330400252040ustar00rootroot00000000000000#include #include #include #include "test.h" static unsigned char bitmap4x4[] = { 0x03, 0x06, 0x0c, 0x09 }; static unsigned char bitmap8x8[3][8] = { { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, { 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe }, { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa }, }; static void fill_rect(struct test_target *t, uint8_t alu, XRectangle *clip, int nclip, uint8_t stipple, uint8_t opaque, int tx, int ty, int x, int y, int w, int h, uint32_t fg, uint32_t bg) { Display *dpy = t->dpy->dpy; XGCValues val; GC gc; val.function = alu; val.foreground = fg; val.background = bg; val.fill_style = opaque ? FillOpaqueStippled : FillStippled; val.ts_x_origin = tx; val.ts_y_origin = ty; if (stipple == 0) { val.stipple = XCreateBitmapFromData(dpy, t->draw, (char *)bitmap4x4, 4, 4); } else { char *b = (char *)bitmap8x8[stipple-1]; val.stipple = XCreateBitmapFromData(dpy, t->draw, b, 8, 8); } gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCStipple | GCForeground | GCBackground | GCFunction, &val); if (nclip) XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted); XFillRectangle(dpy, t->draw, gc, x, y, w, h); XFreeGC(dpy, gc); XFreePixmap(dpy, val.stipple); } static void clear(struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(tt->dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void unclipped_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing unclipped stippled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % out.width; int y = rand() % out.height; int w = rand() % (out.width - x); int h = rand() % (out.height - y); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t stipple = rand() % 4; uint8_t opaque = rand() % 1; uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, NULL, 0, stipple, opaque, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, NULL, 0, stipple, opaque, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void simple_clip_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing simple clipped stippled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t stipple = rand() % 4; uint8_t opaque = rand() % 1; uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, NULL, 0, stipple, opaque, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, NULL, 0, stipple, opaque, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void complex_clip_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; XRectangle *clip; int nclip, r, s; printf("Testing complex clipped stippled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { nclip = (rand() % 16) + 2; clip = malloc(sizeof(XRectangle)*nclip); for (r = 0; r < nclip; r++) { clip[r].x = rand() % out.width; clip[r].y = rand() % out.height; clip[r].width = rand() % (out.width - clip[r].x); clip[r].height = rand() % (out.height - clip[r].y); } for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t stipple = rand() % 4; uint8_t opaque = rand() % 1; uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, clip, nclip, stipple, opaque, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, clip, nclip, stipple, opaque, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); free(clip); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { unclipped_tests(&test, reps, sets, t); simple_clip_tests(&test, reps, sets, t); complex_clip_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-stress.c000066400000000000000000000070521267532330400240240ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include #include "test.h" static void fill_rect(struct test_target *tt, int alu, int color, int x, int y, int w, int h) { XGCValues val; val.function = alu; val.foreground = color; XChangeGC(tt->dpy->dpy, tt->gc, GCFunction | GCForeground, &val); XFillRectangle(tt->dpy->dpy, tt->draw, tt->gc, x, y, w, h); } static void clear(struct test_target *tt) { fill_rect(tt, GXcopy, 0, 0, 0, tt->width, tt->height); } static void fill(struct test_target *out, struct test_target *ref) { int x = rand() % (2*out->width) - out->width; int y = rand() % (2*out->height) - out->height; int w = rand() % (2*out->width); int h = rand() % (2*out->height); int color = rand(); int alu = rand() % 16; fill_rect(out, alu, color, x, y, w, h); fill_rect(ref, alu, color, x, y, w, h); } static void copy(struct test_target *out, struct test_target *ref) { int sx = rand() % (2*out->width) - ref->width; int sy = rand() % (2*out->height) - ref->height; int dx = rand() % (2*out->width) - ref->width; int dy = rand() % (2*out->height) - ref->height; int w = rand() % (2*out->width); int h = rand() % (2*out->height); XGCValues val; val.function = rand() % 16; XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val); XCopyArea(out->dpy->dpy, out->draw, out->draw, out->gc, sx, sy, w, h, dx, dy); XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val); XCopyArea(ref->dpy->dpy, ref->draw, ref->draw, ref->gc, sx, sy, w, h, dx, dy); } static void _put(struct test_target *tt, int x, int y, int w,int h, int color, int alu) { XImage image; XGCValues val; val.function = alu; test_init_image(&image, &tt->dpy->shm, tt->format, w, h); pixman_fill((uint32_t*)image.data, image.bytes_per_line/sizeof(uint32_t), image.bits_per_pixel, 0, 0, w, h, color); XChangeGC(tt->dpy->dpy, tt->gc, GCFunction, &val); if (rand() & 1) { XShmPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 0, 0, x, y, w, h, 0); XSync(tt->dpy->dpy, 1); } else { XPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 0, 0, x, y, w, h); } } static void put(struct test_target *out, struct test_target *ref) { int x = rand() % (2*out->width) - out->width; int y = rand() % (2*out->height) - out->height; int w = rand() % out->width; int h = rand() % out->height; int color = rand(); int alu = rand() % 16; _put(out, x, y, w, h, color, alu); _put(ref, x, y, w, h, color, alu); } static void rect_tests(struct test *test, int iterations, enum target target) { struct test_target out, ref; void (* const ops[])(struct test_target *, struct test_target *) = { copy, fill, put, }; int n; printf("Running mixed ops stress against %s: ", test_target_name(target)); fflush(stdout); test_target_create_render(&test->out, target, &out); test_target_create_render(&test->ref, target, &ref); clear(&out); clear(&ref); for (n = 0; n < iterations; n++) ops[rand() % ARRAY_SIZE(ops)](&out, &ref); test_compare(test, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); printf("passed [%d iterations]\n", n); test_target_destroy_render(&test->out, &out); test_target_destroy_render(&test->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int iterations = REPS(i); rect_tests(&test, iterations, 0); rect_tests(&test, iterations, 1); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-string.c000066400000000000000000000043771267532330400240160ustar00rootroot00000000000000#include #include #include #include #include /* for XDestroyImage */ #include "test.h" static void draw_string(struct test_display *t, Drawable d, uint8_t alu, int x, int y, uint32_t fg, uint32_t bg, int s, int fill) { const char *strings[] = { "Hello", "World", "Cairo's twin is Giza", }; XGCValues val; GC gc; val.function = alu; val.foreground = fg; val.background = bg; gc = XCreateGC(t->dpy, d, GCForeground | GCBackground | GCFunction, &val); if (fill) XDrawImageString(t->dpy, d, gc, x, y, strings[s%3], strlen(strings[s%3])); else XDrawString(t->dpy, d, gc, x, y, strings[s%3], strlen(strings[s%3])); XFreeGC(t->dpy, gc); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void string_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing general (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); int str = rand(); int fill = rand() & 1; draw_string(&t->out, out.draw, alu, x, y, fg, bg, str, fill); draw_string(&t->ref, ref.draw, alu, x, y, fg, bg, str, fill); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { string_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/basic-tiledrect.c000066400000000000000000000226721267532330400244650ustar00rootroot00000000000000#include #include #include #include "test.h" static const unsigned char data[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, }; static struct bitmap { int width, height; struct cache { Display *dpy; Pixmap pixmap; } cached[2]; } bitmaps[] = { { 1, 1, }, { 1, 2, }, { 2, 3, }, { 3, 2, }, { 4, 4, }, { 6, 6, }, { 8, 8, }, { 8, 4, }, { 8, 2, }, { 8, 1, }, { 4, 8, }, { 2, 8, }, { 1, 8, }, { 16, 16, }, { 15, 17, }, { 24, 24, }, { 32, 32, }, { 16, 8, }, { 16, 4, }, { 16, 2, }, { 16, 1, }, { 8, 16, }, { 4, 16, }, { 2, 16, }, { 1, 16, }, }; static void reset_cache(void) { int n, m; for (n = 0; n < sizeof(bitmaps)/sizeof(bitmaps[0]); n++) { for (m = 0; m < 2; m++) { if (bitmaps[n].cached[m].dpy) { XFreePixmap(bitmaps[n].cached[m].dpy, bitmaps[n].cached[m].pixmap); bitmaps[n].cached[m].dpy = NULL; } } } } static void fill_rect(struct test_target *t, uint8_t alu, XRectangle *clip, int nclip, uint8_t tile, int tx, int ty, int x, int y, int w, int h, uint32_t fg, uint32_t bg) { Display *dpy = t->dpy->dpy; struct bitmap *b = &bitmaps[(tile >> 1) % (sizeof(bitmaps)/sizeof(bitmaps[0]))]; XGCValues val; GC gc; int n; val.function = alu; val.function = GXcopy; val.fill_style = FillTiled; val.ts_x_origin = tx; val.ts_y_origin = ty; if (tile & 1) { val.tile = 0; for (n = 0; n < 2; n++) { if (b->cached[n].dpy == dpy) { val.tile = b->cached[n].pixmap; break; } } if (val.tile == 0) { val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, (char *)data, b->width, b->height, fg, bg, t->depth); for (n = 0; n < 2; n++) { if (b->cached[n].dpy == NULL) { b->cached[n].dpy = dpy; b->cached[n].pixmap = val.tile; break; } } } } else val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, (char *)data, b->width, b->height, fg, bg, t->depth); gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile | GCFunction, &val); if (nclip) XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted); XFillRectangle(dpy, t->draw, gc, x, y, w, h); XFreeGC(dpy, gc); if ((tile & 1) == 0) XFreePixmap(dpy, val.tile); } static void clear(struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(tt->dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void small_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing small tiled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % out.width; int y = rand() % out.height; int w = rand() % out.width; int h = rand() % 8; int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t tile = rand(); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); fill_rect(&out, alu, NULL, 0, tile, tx, ty, x, y, h, w, fg, bg); fill_rect(&ref, alu, NULL, 0, tile, tx, ty, x, y, h, w, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); if (target == CHILD) { int x = rand() % (t->out.width-out.width); int y = rand() % (t->out.height-out.height); clear(&out); clear(&ref); XMoveWindow(out.dpy->dpy, out.draw, x, y); XMoveWindow(ref.dpy->dpy, ref.draw, x, y); clear(&out); clear(&ref); } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void unclipped_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing unclipped tiled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % out.width; int y = rand() % out.height; int w = rand() % (out.width - x); int h = rand() % (out.height - y); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t tile = rand(); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); if (target == CHILD) { int x = rand() % (t->out.width-out.width); int y = rand() % (t->out.height-out.height); clear(&out); clear(&ref); XMoveWindow(out.dpy->dpy, out.draw, x, y); XMoveWindow(ref.dpy->dpy, ref.draw, x, y); clear(&out); clear(&ref); } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void simple_clip_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing simple clipped tiled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t tile = rand(); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, NULL, 0, tile, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); if (target == CHILD) { int x = rand() % (t->out.width-out.width); int y = rand() % (t->out.height-out.height); clear(&out); clear(&ref); XMoveWindow(out.dpy->dpy, out.draw, x, y); XMoveWindow(ref.dpy->dpy, ref.draw, x, y); clear(&out); clear(&ref); } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void complex_clip_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; XRectangle *clip; int nclip, r, s; printf("Testing complex clipped tiled fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&out); test_target_create_render(&t->ref, target, &ref); clear(&ref); for (s = 0; s < sets; s++) { nclip = (rand() % 16) + 2; clip = malloc(sizeof(XRectangle)*nclip); for (r = 0; r < nclip; r++) { clip[r].x = rand() % out.width; clip[r].y = rand() % out.height; clip[r].width = rand() % (out.width - clip[r].x); clip[r].height = rand() % (out.height - clip[r].y); } for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % (2*out.width); int h = rand() % (2*out.height); int tx = rand() % (2*out.width) - out.width; int ty = rand() % (2*out.height) - out.height; uint8_t tile = rand(); uint8_t alu = rand() % (GXset + 1); uint32_t fg = rand(); uint32_t bg = rand(); fill_rect(&out, alu, clip, nclip, tile, tx, ty, x, y, w, h, fg, bg); fill_rect(&ref, alu, clip, nclip, tile, tx, ty, x, y, w, h, fg, bg); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); free(clip); if (target == CHILD) { int x = rand() % (t->out.width-out.width); int y = rand() % (t->out.height-out.height); clear(&out); clear(&ref); XMoveWindow(out.dpy->dpy, out.draw, x, y); XMoveWindow(ref.dpy->dpy, ref.draw, x, y); clear(&out); clear(&ref); } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { small_tests(&test, reps, sets, t); unclipped_tests(&test, reps, sets, t); simple_clip_tests(&test, reps, sets, t); complex_clip_tests(&test, reps, sets, t); reset_cache(); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/cursor-test.c000066400000000000000000000107341267532330400237150ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include static void core_cursor(Display *dpy, int width, int height) { char text[256]; cairo_surface_t *surface; cairo_text_extents_t extents; cairo_t *cr; Pixmap bitmap; int scr = DefaultScreen(dpy); Window root = RootWindow(dpy, scr); XColor bg, fg; int pitch; char *data; GC gc; sprintf(text, "%dx%d", width, height); pitch = (width + 31) >> 5 << 2; data = calloc(pitch, height); surface = cairo_image_surface_create_for_data((unsigned char *)data, CAIRO_FORMAT_A1, width, height, pitch); cr = cairo_create(surface); cairo_text_extents(cr, text, &extents); cairo_move_to(cr, 0, extents.height); cairo_show_text(cr, text); cairo_destroy(cr); cairo_surface_destroy(surface); bitmap = XCreatePixmap(dpy, root, width, height, 1); gc = XCreateGC(dpy, bitmap, 0, NULL); if (gc != NULL) { XImage ximage = { .height = height, .width = width, .depth = 1, .bits_per_pixel = 1, .xoffset = 0, .format = XYPixmap, .data = data, .byte_order = LSBFirst, .bitmap_unit = 32, .bitmap_bit_order = LSBFirst, .bitmap_pad = 32, .bytes_per_line = pitch, }; XPutImage(dpy, bitmap, gc, &ximage, 0, 0, 0, 0, width, height); XFreeGC(dpy, gc); } free(data); XParseColor(dpy, DefaultColormap(dpy, scr), "green", &fg); XParseColor(dpy, DefaultColormap(dpy, scr), "black", &bg); XDefineCursor(dpy, root, XCreatePixmapCursor(dpy, bitmap, bitmap, &fg, &bg, 0, 0)); XFreePixmap(dpy, bitmap); } static void render_cursor(Display *dpy, int width, int height) { char text[256]; cairo_surface_t *surface; cairo_text_extents_t extents; cairo_t *cr; Pixmap pixmap; Picture picture; sprintf(text, "%dx%d", width, height); pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, 32); surface = cairo_xlib_surface_create_with_xrender_format(dpy, pixmap, DefaultScreenOfDisplay(dpy), XRenderFindStandardFormat(dpy, PictStandardARGB32), width, height); cr = cairo_create(surface); cairo_surface_destroy(surface); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_text_extents(cr, text, &extents); cairo_move_to(cr, 0, extents.height); cairo_set_source_rgb(cr, 1, 0, 1); cairo_show_text(cr, text); cairo_destroy(cr); picture = XRenderCreatePicture(dpy, pixmap, XRenderFindStandardFormat(dpy, PictStandardARGB32), 0, NULL); XFreePixmap(dpy, pixmap); XDefineCursor(dpy, DefaultRootWindow(dpy), XRenderCreateCursor(dpy, picture, 0, 0)); XRenderFreePicture(dpy, picture); } int main(void) { Display *dpy; int sizes[] = { 24, 32, 48, 64, 72, 128, 160, 256 }; int x, y; dpy = XOpenDisplay(NULL); if (dpy == NULL) dpy = XOpenDisplay(":0"); /* lazy */ if (dpy == NULL) return 77; for (x = 0; x < sizeof(sizes)/sizeof(sizes[0]); x++) { for (y = 0; y < sizeof(sizes)/sizeof(sizes[0]); y++) { printf("Testing %dx%d (core)\n", sizes[x], sizes[y]); core_cursor(dpy, sizes[x], sizes[y]); XSync(dpy, True); sleep(2); printf("Testing %dx%d (render)\n", sizes[x], sizes[y]); render_cursor(dpy, sizes[x], sizes[y]); XSync(dpy, True); sleep(2); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri2-race.c000066400000000000000000000547271267532330400232050ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri2.h" #define COUNT 60 #define N_DIVISORS 3 static const int divisors[N_DIVISORS] = { 0, 1, 16 }; static jmp_buf error_handler[4]; static int have_error_handler; #define error_get() \ setjmp(error_handler[have_error_handler++]) #define error_put() \ have_error_handler-- static int (*saved_io_error)(Display *dpy); static int io_error(Display *dpy) { if (have_error_handler) longjmp(error_handler[--have_error_handler], 0); return saved_io_error(dpy); } static int x_error(Display *dpy, XErrorEvent *e) { return Success; } static uint32_t upper_32_bits(uint64_t val) { return val >> 32; } static uint32_t lower_32_bits(uint64_t val) { return val & 0xffffffff; } static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; printf ("Connecting to %s driver on %s\n", driver, device); fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; } static void swap_buffers(Display *dpy, Window win, int divisor, unsigned int *attachments, int nattachments) { xcb_connection_t *c = XGetXCBConnection(dpy); unsigned int seq[2]; seq[0] = xcb_dri2_swap_buffers_unchecked(c, win, 0, 0, 0, divisor, 0, 0).sequence; seq[1] = xcb_dri2_get_buffers_unchecked(c, win, nattachments, nattachments, attachments).sequence; xcb_flush(c); xcb_discard_reply(c, seq[0]); xcb_discard_reply(c, seq[1]); } #define COMPOSITE 1 static int has_composite(Display *dpy) { Display *dummy = NULL; int event, error; int major = -1, minor = -1; if (dpy == NULL) dummy = dpy = XOpenDisplay(NULL); if (XCompositeQueryExtension(dpy, &event, &error)) XCompositeQueryVersion(dpy, &major, &minor); if (dummy) XCloseDisplay(dummy); return major > 0 || minor >= 4; } static void race_window(Display *dpy, int width, int height, unsigned int *attachments, int nattachments, unsigned flags, const char *name) { Window win; XSetWindowAttributes attr; int count, loop, n; DRI2Buffer *buffers; if (flags & COMPOSITE && !has_composite(dpy)) return; printf("%s(%s)\n", __func__, name); /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; for (n = 0; n < N_DIVISORS; n++) { loop = 256 >> ffs(divisors[n]); printf("DRI2SwapBuffers(divisor=%d), loop=%d", divisors[n], loop); do { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1)); XDestroyWindow(dpy, win); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { loop = 256 >> ffs(divisors[n]); printf("xcb_dri2_swap_buffers(divisor=%d), loops=%d", divisors[n], loop); do { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) swap_buffers(dpy, win, divisors[n], attachments, nattachments); XDestroyWindow(dpy, win); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { loop = 256 >> ffs(divisors[n]); printf("DRI2WaitMsc(divisor=%d), loop=%d", divisors[n], loop); do { uint64_t ignore, msc; xcb_connection_t *c = XGetXCBConnection(dpy); win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); DRI2GetMSC(dpy, win, &ignore, &msc, &ignore); msc++; for (count = 0; count < loop; count++) { xcb_discard_reply(c, xcb_dri2_wait_msc(c, win, upper_32_bits(msc), lower_32_bits(msc), 0, 0, 0, 0).sequence); msc += divisors[n]; } XFlush(dpy); XDestroyWindow(dpy, win); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } XSync(dpy, 1); sleep(2); XSync(dpy, 1); } static int rand_size(int max) { return 1 + (rand() % (max - 1)); } static void race_resize(Display *dpy, int width, int height, unsigned int *attachments, int nattachments, unsigned flags, const char *name) { Window win; XSetWindowAttributes attr; int count, loop, n; DRI2Buffer *buffers; if (flags & COMPOSITE && !has_composite(dpy)) return; printf("%s(%s)\n", __func__, name); attr.override_redirect = 1; for (n = 0; n < N_DIVISORS; n++) { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); loop = 256 >> ffs(divisors[n]); printf("DRI2SwapBuffers(divisor=%d), loop=%d", divisors[n], loop); do { int w, h; buffers = DRI2GetBuffers(dpy, win, &w, &h, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1)); XResizeWindow(dpy, win, rand_size(width), rand_size(height)); printf("."); fflush(stdout); } while (--loop); XDestroyWindow(dpy, win); XSync(dpy, True); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); loop = 256 >> ffs(divisors[n]); printf("xcb_dri2_swap_buffers(divisor=%d), loops=%d", divisors[n], loop); do { int w, h; buffers = DRI2GetBuffers(dpy, win, &w, &h, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) swap_buffers(dpy, win, divisors[n], attachments, nattachments); XResizeWindow(dpy, win, rand_size(width), rand_size(height)); printf("."); fflush(stdout); } while (--loop); XDestroyWindow(dpy, win); XSync(dpy, True); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); loop = 256 >> ffs(divisors[n]); printf("DRI2WaitMsc(divisor=%d), loop=%d", divisors[n], loop); do { uint64_t ignore, msc; xcb_connection_t *c = XGetXCBConnection(dpy); DRI2GetMSC(dpy, win, &ignore, &msc, &ignore); msc++; for (count = 0; count < loop; count++) { xcb_discard_reply(c, xcb_dri2_wait_msc(c, win, upper_32_bits(msc), lower_32_bits(msc), 0, 0, 0, 0).sequence); msc += divisors[n]; } XFlush(dpy); XResizeWindow(dpy, win, rand_size(width), rand_size(height)); printf("."); fflush(stdout); } while (--loop); XDestroyWindow(dpy, win); XSync(dpy, True); printf("*\n"); } XSync(dpy, 1); sleep(2); XSync(dpy, 1); } static void race_manager(Display *dpy, int width, int height, unsigned int *attachments, int nattachments, unsigned flags, const char *name) { Display *mgr = XOpenDisplay(NULL); Window win; XSetWindowAttributes attr; int count, loop, n; DRI2Buffer *buffers; if (flags & COMPOSITE && !has_composite(dpy)) return; printf("%s(%s)\n", __func__, name); /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; for (n = 0; n < N_DIVISORS; n++) { printf("DRI2SwapBuffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1)); XFlush(dpy); XDestroyWindow(mgr, win); XFlush(mgr); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; free(buffers); for (count = 0; count < loop; count++) swap_buffers(dpy, win, divisors[n], attachments, nattachments); XFlush(dpy); XDestroyWindow(mgr, win); XFlush(mgr); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("DRI2WaitMsc(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { uint64_t ignore, msc; xcb_connection_t *c = XGetXCBConnection(dpy); win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); DRI2GetMSC(dpy, win, &ignore, &msc, &ignore); msc++; for (count = 0; count < loop; count++) { xcb_discard_reply(c, xcb_dri2_wait_msc(c, win, upper_32_bits(msc), lower_32_bits(msc), 0, 0, 0, 0).sequence); msc += divisors[n]; } XFlush(dpy); XDestroyWindow(mgr, win); XFlush(mgr); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } XSync(dpy, 1); XSync(mgr, 1); sleep(2); XSync(dpy, 1); XSync(mgr, 1); XCloseDisplay(mgr); } static void race_close(int width, int height, unsigned int *attachments, int nattachments, unsigned flags, const char *name) { XSetWindowAttributes attr; int count, loop, n; if (flags & COMPOSITE && !has_composite(NULL)) return; printf("%s(%s)\n", __func__, name); /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; for (n = 0; n < N_DIVISORS; n++) { printf("DRI2SwapBuffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { Display *dpy = XOpenDisplay(NULL); Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); free(DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count)); if (count != nattachments) return; for (count = 0; count < loop; count++) DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1)); XCloseDisplay(dpy); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { Display *dpy = XOpenDisplay(NULL); Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); free(DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count)); if (count != nattachments) return; for (count = 0; count < loop; count++) swap_buffers(dpy, win, divisors[n], attachments, nattachments); XCloseDisplay(dpy); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("DRI2WaitMsc(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { uint64_t ignore, msc; Display *dpy = XOpenDisplay(NULL); xcb_connection_t *c = XGetXCBConnection(dpy); Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); DRI2GetMSC(dpy, win, &ignore, &msc, &ignore); msc++; for (count = 0; count < loop; count++) { xcb_discard_reply(c, xcb_dri2_wait_msc(c, win, upper_32_bits(msc), lower_32_bits(msc), 0, 0, 0, 0).sequence); msc += divisors[n]; } XFlush(dpy); XCloseDisplay(dpy); printf("."); fflush(stdout); } while (--loop); printf("*\n"); } } static void race_client(int width, int height, unsigned int *attachments, int nattachments, unsigned flags, const char *name) { Display *mgr = XOpenDisplay(NULL); XSetWindowAttributes attr; int count, loop, n; if (flags & COMPOSITE && !has_composite(NULL)) return; printf("%s(%s)\n", __func__, name); /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; for (n = 0; n < N_DIVISORS; n++) { printf("DRI2SwapBuffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { Display *dpy; Window win; if (error_get()) { printf("+"); fflush(stdout); continue; } dpy = XOpenDisplay(NULL); win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); free(DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count)); if (count != nattachments) return; for (count = 0; count < loop; count++) DRI2SwapBuffers(dpy, win, 0, divisors[n], count & (divisors[n]-1)); XFlush(dpy); XKillClient(mgr, win); XFlush(mgr); XCloseDisplay(dpy); printf("."); fflush(stdout); error_put(); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("xcb_dri2_swap_buffers(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { Display *dpy; Window win; if (error_get()) { printf("+"); fflush(stdout); continue; } dpy = XOpenDisplay(NULL); win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); free(DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count)); if (count != nattachments) return; for (count = 0; count < loop; count++) swap_buffers(dpy, win, divisors[n], attachments, nattachments); XFlush(dpy); XKillClient(mgr, win); XFlush(mgr); XCloseDisplay(dpy); printf("."); fflush(stdout); error_put(); } while (--loop); printf("*\n"); } for (n = 0; n < N_DIVISORS; n++) { printf("DRI2WaitMsc(divisor=%d)", divisors[n]); loop = 256 >> ffs(divisors[n]); do { uint64_t ignore, msc; Display *dpy; xcb_connection_t *c; Window win; if (error_get()) { printf("+"); fflush(stdout); continue; } dpy = XOpenDisplay(NULL); win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); if (flags & COMPOSITE) XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); DRI2GetMSC(dpy, win, &ignore, &msc, &ignore); c = XGetXCBConnection(dpy); msc++; for (count = 0; count < loop; count++) { xcb_discard_reply(c, xcb_dri2_wait_msc(c, win, upper_32_bits(msc), lower_32_bits(msc), 0, 0, 0, 0).sequence); msc += divisors[n]; } XFlush(dpy); XKillClient(mgr, win); XFlush(mgr); XCloseDisplay(dpy); printf("."); fflush(stdout); error_put(); } while (--loop); printf("*\n"); } XCloseDisplay(mgr); } int main(void) { Display *dpy; int width, height, fd; unsigned int attachments[] = { DRI2BufferBackLeft, DRI2BufferFrontLeft, }; saved_io_error = XSetIOErrorHandler(io_error); XSetErrorHandler(x_error); dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; fd = dri2_open(dpy); if (fd < 0) return 1; width = WidthOfScreen(DefaultScreenOfDisplay(dpy)); height = HeightOfScreen(DefaultScreenOfDisplay(dpy)); race_window(dpy, width, height, attachments, 1, 0, "fullscreen"); race_window(dpy, width, height, attachments, 1, COMPOSITE, "composite fullscreen"); race_window(dpy, width, height, attachments, 2, 0, "fullscreen (with front)"); race_window(dpy, width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)"); race_resize(dpy, width, height, attachments, 1, 0, ""); race_resize(dpy, width, height, attachments, 1, COMPOSITE, "composite"); race_resize(dpy, width, height, attachments, 2, 0, "with front"); race_resize(dpy, width, height, attachments, 2, COMPOSITE, "composite with front"); race_manager(dpy, width, height, attachments, 1, 0, "fullscreen"); race_manager(dpy, width, height, attachments, 1, COMPOSITE, "composite fullscreen"); race_manager(dpy, width, height, attachments, 2, 0, "fullscreen (with front)"); race_manager(dpy, width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)"); race_close(width, height, attachments, 1, 0, "fullscreen"); race_close(width, height, attachments, 1, COMPOSITE, "composite fullscreen"); race_close(width, height, attachments, 2, 0, "fullscreen (with front)"); race_close(width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)"); race_client(width, height, attachments, 1, 0, "fullscreen"); race_client(width, height, attachments, 1, COMPOSITE, "composite fullscreen"); race_client(width, height, attachments, 2, 0, "fullscreen (with front)"); race_client(width, height, attachments, 2, COMPOSITE, "composite fullscreen (with front)"); width /= 2; height /= 2; race_window(dpy, width, height, attachments, 1, 0, "windowed"); race_window(dpy, width, height, attachments, 1, COMPOSITE, "composite windowed"); race_window(dpy, width, height, attachments, 2, 0, "windowed (with front)"); race_window(dpy, width, height, attachments, 2, COMPOSITE, "composite windowed (with front)"); race_manager(dpy, width, height, attachments, 1, 0, "windowed"); race_manager(dpy, width, height, attachments, 1, COMPOSITE, "composite windowed"); race_manager(dpy, width, height, attachments, 2, 0, "windowed (with front)"); race_manager(dpy, width, height, attachments, 2, COMPOSITE, "composite windowed (with front)"); race_close(width, height, attachments, 1, 0, "windowed"); race_close(width, height, attachments, 1, COMPOSITE, "composite windowed"); race_close(width, height, attachments, 2, 0, "windowed (with front)"); race_close(width, height, attachments, 2, COMPOSITE, "composite windowed (with front)"); race_client(width, height, attachments, 1, 0, "windowed"); race_client(width, height, attachments, 1, COMPOSITE, "composite windowed"); race_client(width, height, attachments, 2, 0, "windowed (with front)"); race_client(width, height, attachments, 2, COMPOSITE, "composite windowed (with front)"); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri2-speed.c000066400000000000000000000213431267532330400233570ustar00rootroot00000000000000/* * Copyright (c) 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri2.h" static int _x_error_occurred; static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static double elapsed(const struct timespec *start, const struct timespec *end) { return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000; } static void run(Display *dpy, Window win, const char *name) { xcb_connection_t *c = XGetXCBConnection(dpy); struct timespec start, end; int n, completed = 0; _x_error_occurred = 0; clock_gettime(CLOCK_MONOTONIC, &start); do { for (n = 0; n < 1000; n++) { unsigned int attachments[] = { DRI2BufferBackLeft }; unsigned int seq[2]; seq[0] = xcb_dri2_swap_buffers_unchecked(c, win, 0, 0, 0, 0, 0, 0).sequence; seq[1] = xcb_dri2_get_buffers_unchecked(c, win, 1, 1, attachments).sequence; xcb_flush(c); xcb_discard_reply(c, seq[0]); xcb_discard_reply(c, seq[1]); completed++; } clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec < start.tv_sec + 10); XSync(dpy, True); if (_x_error_occurred) abort(); printf("%s: Completed %d swaps in %.1fs, %.3fus each (%.1f FPS)\n", name, completed, elapsed(&start, &end) / 1000000, elapsed(&start, &end) / completed, completed / (elapsed(&start, &end) / 1000000)); } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; printf ("Connecting to %s driver on %s\n", driver, device); fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; } static void fullscreen(Display *dpy, Window win) { Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&atom, 1); } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XDamageQueryExtension (dpy, &event, &error)) return 0; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } int main(void) { Display *dpy; Window root, win; XRRScreenResources *res; XRRCrtcInfo **original_crtc; XSetWindowAttributes attr; int i, j, fd; attr.override_redirect = 1; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; fd = dri2_open(dpy); if (fd < 0) return 77; if (DPMSQueryExtension(dpy, &i, &i)) DPMSDisable(dpy); root = DefaultRootWindow(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); res = NULL; if (XRRQueryVersion(dpy, &i, &i)) res = _XRRGetScreenResourcesCurrent(dpy, root); if (res == NULL) return 77; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); DRI2CreateDrawable(dpy, root); DRI2SwapInterval(dpy, root, 0); run(dpy, root, "off"); XSync(dpy, True); for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); for (j = 0; mode && j < 2*output->ncrtc; j++) { int c = j; if (c >= output->ncrtc) c = 2*output->ncrtc - j - 1; printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld: %dx%d\n", i, c, (long)res->outputs[i], (long)output->crtcs[c], mode->width, mode->height); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); run(dpy, root, "root"); XSync(dpy, True); win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); fullscreen(dpy, win); XMapWindow(dpy, win); run(dpy, win, "fullscreen"); XDestroyWindow(dpy, win); XSync(dpy, True); win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); XMapWindow(dpy, win); run(dpy, win, "windowed"); XDestroyWindow(dpy, win); XSync(dpy, True); if (has_composite(dpy)) { Damage damage; _x_error_occurred = 0; win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); damage = XDamageCreate(dpy, win, XDamageReportRawRectangles); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); XMapWindow(dpy, win); XSync(dpy, True); if (!_x_error_occurred) run(dpy, win, "composited"); XDamageDestroy(dpy, damage); XDestroyWindow(dpy, win); XSync(dpy, True); } win = XCreateWindow(dpy, root, 0, 0, mode->width/2, mode->height/2, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 0); XMapWindow(dpy, win); run(dpy, win, "half"); XDestroyWindow(dpy, win); XSync(dpy, True); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); } XRRFreeOutputInfo(output); } for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); if (DPMSQueryExtension(dpy, &i, &i)) DPMSEnable(dpy); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri2-swap.c000066400000000000000000000076271267532330400232420ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include "dri2.h" #define COUNT 60 static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; printf ("Connecting to %s driver on %s\n", driver, device); fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; } static void dri2_copy_swap(Display *dpy, Drawable d, int width, int height, int has_front) { XRectangle rect; XserverRegion region; rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; region = XFixesCreateRegion(dpy, &rect, 1); DRI2CopyRegion(dpy, d, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); if (has_front) DRI2CopyRegion(dpy, d, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); XFixesDestroyRegion(dpy, region); } static void xsync(Display *dpy, Window win) { XImage *image; image = XGetImage(dpy, win, 0, 0, 1, 1, ~0, ZPixmap); if (image) XDestroyImage(image); } static double elapsed(const struct timespec *start, const struct timespec *end) { return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec); } static void run(Display *dpy, int width, int height, unsigned int *attachments, int nattachments, const char *name) { Window win; XSetWindowAttributes attr; int count; DRI2Buffer *buffers; struct timespec start, end; /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); xsync(dpy, win); DRI2CreateDrawable(dpy, win); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) DRI2SwapBuffers(dpy, win, 0, 0, 0); xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d %s (%dx%d) swaps in %fs.\n", count, name, width, height, elapsed(&start, &end)); xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) dri2_copy_swap(dpy, win, width, height, nattachments == 2); xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d %s (%dx%d) blits in %fs.\n", count, name, width, height, elapsed(&start, &end)); DRI2SwapInterval(dpy, win, 0); xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) DRI2SwapBuffers(dpy, win, 0, 0, 0); xsync(dpy, win); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d %s (%dx%d) vblank=0 swaps in %fs.\n", count, name, width, height, elapsed(&start, &end)); XDestroyWindow(dpy, win); free(buffers); XSync(dpy, 1); } int main(void) { Display *dpy; int width, height, fd; unsigned int attachments[] = { DRI2BufferBackLeft, DRI2BufferFrontLeft, }; dpy = XOpenDisplay (NULL); if (dpy == NULL) return 77; fd = dri2_open(dpy); if (fd < 0) return 1; width = WidthOfScreen(DefaultScreenOfDisplay(dpy)); height = HeightOfScreen(DefaultScreenOfDisplay(dpy)); run(dpy, width, height, attachments, 1, "fullscreen"); run(dpy, width, height, attachments, 2, "fullscreen (with front)"); width /= 2; height /= 2; run(dpy, width, height, attachments, 1, "windowed"); run(dpy, width, height, attachments, 2, "windowed (with front)"); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri2-test.c000066400000000000000000000221171267532330400232360ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri2.h" #define COUNT 60 static int prime[] = { 0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 27, 29, 31, 37, 41, 43, 47, 51, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131 }; static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static int dri2_open(Display *dpy) { drm_auth_t auth; char *driver, *device; int fd; if (!DRI2Connect(dpy, DefaultRootWindow(dpy), &driver, &device)) return -1; printf ("Connecting to %s driver on %s\n", driver, device); fd = open(device, O_RDWR); if (fd < 0) return -1; if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -1; if (!DRI2Authenticate(dpy, DefaultRootWindow(dpy), auth.magic)) return -1; return fd; } static void dri2_copy_swap(Display *dpy, Drawable d, int width, int height, int has_front) { XRectangle rect; XserverRegion region; rect.x = 0; rect.y = 0; rect.width = width; rect.height = height; region = XFixesCreateRegion(dpy, &rect, 1); DRI2CopyRegion(dpy, d, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); if (has_front) DRI2CopyRegion(dpy, d, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); XFixesDestroyRegion(dpy, region); } static double elapsed(const struct timespec *start, const struct timespec *end) { return (end->tv_sec - start->tv_sec) + 1e-9*(end->tv_nsec - start->tv_nsec); } static uint64_t check_msc(Display *dpy, Window win, uint64_t last_msc) { uint64_t current_msc, current_ust, current_sbc; DRI2GetMSC(dpy, win, ¤t_ust, ¤t_msc, ¤t_sbc); if (current_msc < last_msc) { printf("Invalid MSC: was %llu, now %llu\n", (long long)last_msc, (long long)current_msc); } return current_msc; } static void wait_next_vblank(Display *dpy, Window win) { uint64_t msc, ust, sbc; DRI2WaitMSC(dpy, win, 0, 1, 0, &ust, &msc, &sbc); } static void swap_buffers(xcb_connection_t *c, Window win, unsigned int *attachments, int nattachments) { unsigned int seq[2]; seq[0] = xcb_dri2_swap_buffers_unchecked(c, win, 0, 0, 0, 0, 0, 0).sequence; seq[1] = xcb_dri2_get_buffers_unchecked(c, win, nattachments, nattachments, attachments).sequence; xcb_flush(c); xcb_discard_reply(c, seq[0]); xcb_discard_reply(c, seq[1]); } static void run(Display *dpy, int width, int height, unsigned int *attachments, int nattachments, const char *name) { xcb_connection_t *c = XGetXCBConnection(dpy); Window win; XSetWindowAttributes attr; DRI2Buffer *buffers; struct timespec start, end; uint64_t start_msc, end_msc; int modulus, remainder, count; /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); DRI2CreateDrawable(dpy, win); DRI2SwapInterval(dpy, win, 1); start_msc = check_msc(dpy, win, 0); buffers = DRI2GetBuffers(dpy, win, &width, &height, attachments, nattachments, &count); if (count != nattachments) return; swap_buffers(c, win, attachments, nattachments); start_msc = check_msc(dpy, win, start_msc); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) swap_buffers(c, win, attachments, nattachments); end_msc = check_msc(dpy, win, start_msc); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d [%ld] %s (%dx%d) swaps in %fs.\n", count, (long)(end_msc - start_msc), name, width, height, elapsed(&start, &end)); swap_buffers(c, win, attachments, nattachments); start_msc = check_msc(dpy, win, end_msc); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) dri2_copy_swap(dpy, win, width, height, nattachments == 2); end_msc = check_msc(dpy, win, start_msc); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d [%ld] %s (%dx%d) blits in %fs.\n", count, (long)(end_msc - start_msc), name, width, height, elapsed(&start, &end)); DRI2SwapInterval(dpy, win, 0); wait_next_vblank(dpy, win); swap_buffers(c, win, attachments, nattachments); start_msc = check_msc(dpy, win, end_msc); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) swap_buffers(c, win, attachments, nattachments); end_msc = check_msc(dpy, win, start_msc); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d [%ld] %s (%dx%d) vblank=0 swaps in %fs.\n", count, (long)(end_msc - start_msc), name, width, height, elapsed(&start, &end)); start_msc = check_msc(dpy, win, end_msc); clock_gettime(CLOCK_MONOTONIC, &start); for (count = 0; count < COUNT; count++) wait_next_vblank(dpy, win); end_msc = check_msc(dpy, win, start_msc); clock_gettime(CLOCK_MONOTONIC, &end); printf("%d [%ld] %s waits in %fs.\n", count, (long)(end_msc - start_msc), name, elapsed(&start, &end)); printf("Testing past & future waits\n"); for (modulus = 1; modulus <= 128; modulus <<= 1) { for (count = 0; prime[count] < modulus; count++) { uint64_t msc, ust, sbc; uint64_t target; remainder = prime[count]; DRI2WaitMSC(dpy, win, 0, 1, 0, &ust, &msc, &sbc); target = msc + modulus + 1; target &= -modulus; target += remainder; DRI2WaitMSC(dpy, win, target, modulus, remainder, &ust, &msc, &sbc); if (msc != target) { printf("Missed future MSC (%d, %d): expected=%lld, found=%lld\n", modulus, remainder, (long long)target, (long long)msc); } target = msc; target &= -modulus; target += remainder; if (target <= msc) target += modulus; DRI2WaitMSC(dpy, win, msc, modulus, remainder, &ust, &msc, &sbc); if (msc != target) { printf("Missed past MSC (%d, %d): expected=%lld, found=%lld\n", modulus, remainder, (long long)target, (long long)msc); } } } XDestroyWindow(dpy, win); free(buffers); XSync(dpy, 1); } int main(void) { Display *dpy; int i, j, fd; unsigned int attachments[] = { DRI2BufferBackLeft, DRI2BufferFrontLeft, }; XRRScreenResources *res; XRRCrtcInfo **original_crtc; Window root; uint64_t last_msc; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (!XRRQueryVersion(dpy, &i, &j)) return 77; fd = dri2_open(dpy); if (fd < 0) return 1; root = DefaultRootWindow(dpy); DRI2CreateDrawable(dpy, root); res = _XRRGetScreenResourcesCurrent(dpy, root); if (res == NULL) return 1; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc); last_msc = check_msc(dpy, root, 0); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); last_msc = check_msc(dpy, root, last_msc); for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); for (j = 0; mode && j < 2*output->ncrtc; j++) { int c = j; if (c >= output->ncrtc) c = 2*output->ncrtc - j - 1; printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld\n", i, c, (long)res->outputs[i], (long)output->crtcs[c]); last_msc = check_msc(dpy, root, last_msc); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); last_msc = check_msc(dpy, root, last_msc); run(dpy, mode->width, mode->height, attachments, 1, "fullscreen"); run(dpy, mode->width, mode->height, attachments, 2, "fullscreen (with front)"); run(dpy, mode->width/2, mode->height/2, attachments, 1, "windowed"); run(dpy, mode->width/2, mode->height/2, attachments, 2, "windowed (with front)"); last_msc = check_msc(dpy, root, last_msc); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); last_msc = check_msc(dpy, root, last_msc); } XRRFreeOutputInfo(output); } for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri2.c000066400000000000000000000427101267532330400222620ustar00rootroot00000000000000/* * Copyright © 2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Soft- * ware"), to deal in the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, provided that the above copyright * notice(s) and this permission notice appear in all copies of the Soft- * ware and that both the above copyright notice(s) and this permission * notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- * MANCE OF THIS SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization of * the copyright holder. * * Authors: * Kristian Høgsberg (krh@redhat.com) */ #include #include #include #include #include #include "dri2.h" /* Allow the build to work with an older versions of dri2proto.h and * dri2tokens.h. */ #if DRI2_MINOR < 1 #undef DRI2_MINOR #define DRI2_MINOR 1 #define X_DRI2GetBuffersWithFormat 7 #endif static char dri2ExtensionName[] = DRI2_NAME; static XExtensionInfo *dri2Info; static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); static Status DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); static int DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code); static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_gc */ NULL, /* copy_gc */ NULL, /* flush_gc */ NULL, /* free_gc */ NULL, /* create_font */ NULL, /* free_font */ DRI2CloseDisplay, /* close_display */ DRI2WireToEvent, /* wire_to_event */ DRI2EventToWire, /* event_to_wire */ DRI2Error, /* error */ NULL, /* error_string */ }; static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, 0, NULL) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); XextCheckExtension(dpy, info, dri2ExtensionName, False); switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { #ifdef X_DRI2SwapBuffers case DRI2_BufferSwapComplete: /* Ignore swap events if we're not looking for them */ printf("BufferSwapComplete\n"); return False; #endif #ifdef DRI2_InvalidateBuffers case DRI2_InvalidateBuffers: printf("InvalidateBuffers\n"); return False; #endif default: /* client doesn't support server event */ break; } return False; } /* We don't actually support this. It doesn't make sense for clients to * send each other DRI2 events. */ static Status DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); XextCheckExtension(dpy, info, dri2ExtensionName, False); switch (event->type) { default: /* client doesn't support server event */ break; } return Success; } static int DRI2Error(Display *display, xError *err, XExtCodes *codes, int *ret_code) { if (err->majorCode == codes->major_opcode && err->errorCode == BadDrawable && err->minorCode == X_DRI2CopyRegion) return True; /* If the X drawable was destroyed before the GLX drawable, the * DRI2 drawble will be gone by the time we call * DRI2DestroyDrawable. So just ignore BadDrawable here. */ if (err->majorCode == codes->major_opcode && err->errorCode == BadDrawable && err->minorCode == X_DRI2DestroyDrawable) return True; /* If the server is non-local DRI2Connect will raise BadRequest. * Swallow this so that DRI2Connect can signal this in its return code */ if (err->majorCode == codes->major_opcode && err->minorCode == X_DRI2Connect && err->errorCode == BadRequest) { *ret_code = False; return True; } return False; } Bool DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); if (XextHasExtension(info)) { *eventBase = info->codes->first_event; *errorBase = info->codes->first_error; return True; } return False; } Bool DRI2QueryVersion(Display * dpy, int *major, int *minor) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2QueryVersionReply rep; xDRI2QueryVersionReq *req; int i, nevents; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2QueryVersion, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2QueryVersion; req->majorVersion = DRI2_MAJOR; req->minorVersion = DRI2_MINOR; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *major = rep.majorVersion; *minor = rep.minorVersion; UnlockDisplay(dpy); SyncHandle(); switch (rep.minorVersion) { case 1: nevents = 0; break; case 2: nevents = 1; break; case 3: default: nevents = 2; break; } for (i = 0; i < nevents; i++) { XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); } return True; } Bool DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2ConnectReply rep; xDRI2ConnectReq *req; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2Connect, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2Connect; req->window = window; req->driverType = DRI2DriverDRI; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { UnlockDisplay(dpy); SyncHandle(); return False; } *driverName = Xmalloc(rep.driverNameLength + 1); if (*driverName == NULL) { _XEatData(dpy, ((rep.driverNameLength + 3) & ~3) + ((rep.deviceNameLength + 3) & ~3)); UnlockDisplay(dpy); SyncHandle(); return False; } _XReadPad(dpy, *driverName, rep.driverNameLength); (*driverName)[rep.driverNameLength] = '\0'; *deviceName = Xmalloc(rep.deviceNameLength + 1); if (*deviceName == NULL) { Xfree(*driverName); _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); UnlockDisplay(dpy); SyncHandle(); return False; } _XReadPad(dpy, *deviceName, rep.deviceNameLength); (*deviceName)[rep.deviceNameLength] = '\0'; UnlockDisplay(dpy); SyncHandle(); return True; } Bool DRI2Authenticate(Display * dpy, XID window, unsigned int magic) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2AuthenticateReq *req; xDRI2AuthenticateReply rep; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2Authenticate, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2Authenticate; req->window = window; req->magic = magic; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } UnlockDisplay(dpy); SyncHandle(); return rep.authenticated; } void DRI2CreateDrawable(Display * dpy, XID drawable) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2CreateDrawableReq *req; XextSimpleCheckExtension(dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2CreateDrawable, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2CreateDrawable; req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); } void DRI2DestroyDrawable(Display * dpy, XID drawable) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2DestroyDrawableReq *req; XextSimpleCheckExtension(dpy, info, dri2ExtensionName); XSync(dpy, False); LockDisplay(dpy); GetReq(DRI2DestroyDrawable, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2DestroyDrawable; req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); } DRI2Buffer * DRI2GetBuffers(Display * dpy, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2GetBuffersReply rep; xDRI2GetBuffersReq *req; DRI2Buffer *buffers; xDRI2Buffer repBuffer; uint32_t *p; int i; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReqExtra(DRI2GetBuffers, count * 4, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2GetBuffers; req->drawable = drawable; req->count = count; p = (uint32_t *) & req[1]; for (i = 0; i < count; i++) p[i] = attachments[i]; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return NULL; } *width = rep.width; *height = rep.height; *outCount = rep.count; buffers = Xmalloc(rep.count * sizeof buffers[0]); if (buffers == NULL) { _XEatData(dpy, rep.count * sizeof repBuffer); UnlockDisplay(dpy); SyncHandle(); return NULL; } for (i = 0; i < rep.count; i++) { _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); buffers[i].attachment = repBuffer.attachment; buffers[i].name = repBuffer.name; buffers[i].pitch = repBuffer.pitch; buffers[i].cpp = repBuffer.cpp; buffers[i].flags = repBuffer.flags; } UnlockDisplay(dpy); SyncHandle(); return buffers; } DRI2Buffer * DRI2GetBuffersWithFormat(Display * dpy, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2GetBuffersReply rep; xDRI2GetBuffersReq *req; DRI2Buffer *buffers; xDRI2Buffer repBuffer; uint32_t *p; int i; XextCheckExtension(dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReqExtra(DRI2GetBuffers, count * (4 * 2), req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2GetBuffersWithFormat; req->drawable = drawable; req->count = count; p = (uint32_t *) & req[1]; for (i = 0; i < (count * 2); i++) p[i] = attachments[i]; if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return NULL; } *width = rep.width; *height = rep.height; *outCount = rep.count; buffers = Xmalloc(rep.count * sizeof buffers[0]); if (buffers == NULL) { _XEatData(dpy, rep.count * sizeof repBuffer); UnlockDisplay(dpy); SyncHandle(); return NULL; } for (i = 0; i < rep.count; i++) { _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); buffers[i].attachment = repBuffer.attachment; buffers[i].name = repBuffer.name; buffers[i].pitch = repBuffer.pitch; buffers[i].cpp = repBuffer.cpp; buffers[i].flags = repBuffer.flags; } UnlockDisplay(dpy); SyncHandle(); return buffers; } void DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, uint32_t dest, uint32_t src) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2CopyRegionReq *req; xDRI2CopyRegionReply rep; XextSimpleCheckExtension(dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2CopyRegion, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2CopyRegion; req->drawable = drawable; req->region = region; req->dest = dest; req->src = src; (void) _XReply(dpy, (xReply *) & rep, 0, xFalse); UnlockDisplay(dpy); SyncHandle(); } #ifdef X_DRI2SwapBuffers static void load_swap_req(xDRI2SwapBuffersReq *req, uint64_t target, uint64_t divisor, uint64_t remainder) { req->target_msc_hi = target >> 32; req->target_msc_lo = target & 0xffffffff; req->divisor_hi = divisor >> 32; req->divisor_lo = divisor & 0xffffffff; req->remainder_hi = remainder >> 32; req->remainder_lo = remainder & 0xffffffff; } static uint64_t vals_to_card64(uint32_t lo, uint32_t hi) { return (uint64_t)hi << 32 | lo; } uint64_t DRI2SwapBuffers(Display *dpy, XID drawable, uint64_t target_msc, uint64_t divisor, uint64_t remainder) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2SwapBuffersReq *req; xDRI2SwapBuffersReply rep; uint64_t count; XextCheckExtension (dpy, info, dri2ExtensionName, 0); LockDisplay(dpy); GetReq(DRI2SwapBuffers, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2SwapBuffers; req->drawable = drawable; load_swap_req(req, target_msc, divisor, remainder); (void) _XReply(dpy, (xReply *)&rep, 0, xFalse); count = vals_to_card64(rep.swap_lo, rep.swap_hi); UnlockDisplay(dpy); SyncHandle(); return count; } #endif #ifdef X_DRI2GetMSC Bool DRI2GetMSC(Display *dpy, XID drawable, uint64_t *ust, uint64_t *msc, uint64_t *sbc) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2GetMSCReq *req; xDRI2MSCReply rep; XextCheckExtension (dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2GetMSC, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2GetMSC; req->drawable = drawable; if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *ust = vals_to_card64(rep.ust_lo, rep.ust_hi); *msc = vals_to_card64(rep.msc_lo, rep.msc_hi); *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); UnlockDisplay(dpy); SyncHandle(); return True; } #endif #ifdef X_DRI2WaitMSC static void load_msc_req(xDRI2WaitMSCReq *req, uint64_t target, uint64_t divisor, uint64_t remainder) { req->target_msc_hi = target >> 32; req->target_msc_lo = target & 0xffffffff; req->divisor_hi = divisor >> 32; req->divisor_lo = divisor & 0xffffffff; req->remainder_hi = remainder >> 32; req->remainder_lo = remainder & 0xffffffff; } Bool DRI2WaitMSC(Display *dpy, XID drawable, uint64_t target_msc, uint64_t divisor, uint64_t remainder, uint64_t *ust, uint64_t *msc, uint64_t *sbc) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2WaitMSCReq *req; xDRI2MSCReply rep; XextCheckExtension (dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2WaitMSC, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2WaitMSC; req->drawable = drawable; load_msc_req(req, target_msc, divisor, remainder); if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *ust = ((uint64_t)rep.ust_hi << 32) | (uint64_t)rep.ust_lo; *msc = ((uint64_t)rep.msc_hi << 32) | (uint64_t)rep.msc_lo; *sbc = ((uint64_t)rep.sbc_hi << 32) | (uint64_t)rep.sbc_lo; UnlockDisplay(dpy); SyncHandle(); return True; } #endif #ifdef X_DRI2WaitSBC static void load_sbc_req(xDRI2WaitSBCReq *req, uint64_t target) { req->target_sbc_hi = target >> 32; req->target_sbc_lo = target & 0xffffffff; } Bool DRI2WaitSBC(Display *dpy, XID drawable, uint64_t target_sbc, uint64_t *ust, uint64_t *msc, uint64_t *sbc) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2WaitSBCReq *req; xDRI2MSCReply rep; XextCheckExtension (dpy, info, dri2ExtensionName, False); LockDisplay(dpy); GetReq(DRI2WaitSBC, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2WaitSBC; req->drawable = drawable; load_sbc_req(req, target_sbc); if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } *ust = ((uint64_t)rep.ust_hi << 32) | rep.ust_lo; *msc = ((uint64_t)rep.msc_hi << 32) | rep.msc_lo; *sbc = ((uint64_t)rep.sbc_hi << 32) | rep.sbc_lo; UnlockDisplay(dpy); SyncHandle(); return True; } #endif #ifdef X_DRI2SwapInterval void DRI2SwapInterval(Display *dpy, XID drawable, int interval) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2SwapIntervalReq *req; XextSimpleCheckExtension (dpy, info, dri2ExtensionName); LockDisplay(dpy); GetReq(DRI2SwapInterval, req); req->reqType = info->codes->major_opcode; req->dri2ReqType = X_DRI2SwapInterval; req->drawable = drawable; req->interval = interval; UnlockDisplay(dpy); SyncHandle(); } #endif xserver-xorg-video-intel-2.99.917+git20160325/test/dri2.h000066400000000000000000000070211267532330400222630ustar00rootroot00000000000000/* * Copyright © 2007,2008 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Soft- * ware"), to deal in the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, provided that the above copyright * notice(s) and this permission notice appear in all copies of the Soft- * ware and that both the above copyright notice(s) and this permission * notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- * MANCE OF THIS SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall * not be used in advertising or otherwise to promote the sale, use or * other dealings in this Software without prior written authorization of * the copyright holder. * * Authors: * Kristian Høgsberg (krh@redhat.com) */ #ifndef _DRI2_H_ #define _DRI2_H_ #include #include #include typedef struct { unsigned int attachment; unsigned int name; unsigned int pitch; unsigned int cpp; unsigned int flags; } DRI2Buffer; extern Bool DRI2QueryExtension(Display * display, int *eventBase, int *errorBase); extern Bool DRI2QueryVersion(Display * display, int *major, int *minor); extern Bool DRI2Connect(Display * display, XID window, char **driverName, char **deviceName); extern Bool DRI2Authenticate(Display * display, XID window, unsigned int magic); extern void DRI2CreateDrawable(Display * display, XID drawable); extern void DRI2DestroyDrawable(Display * display, XID handle); extern DRI2Buffer* DRI2GetBuffers(Display * dpy, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount); /** * \note * This function is only supported with DRI2 version 1.1 or later. */ extern DRI2Buffer* DRI2GetBuffersWithFormat(Display * dpy, XID drawable, int *width, int *height, unsigned int *attachments, int count, int *outCount); extern void DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, uint32_t dest, uint32_t src); extern uint64_t DRI2SwapBuffers(Display *dpy, XID drawable, uint64_t target_msc, uint64_t divisor, uint64_t remainder); extern Bool DRI2GetMSC(Display *dpy, XID drawable, uint64_t *ust, uint64_t *msc, uint64_t *sbc); extern Bool DRI2WaitMSC(Display *dpy, XID drawable, uint64_t target_msc, uint64_t divisor, uint64_t remainder, uint64_t *ust, uint64_t *msc, uint64_t *sbc); extern Bool DRI2WaitSBC(Display *dpy, XID drawable, uint64_t target_sbc, uint64_t *ust, uint64_t *msc, uint64_t *sbc); extern void DRI2SwapInterval(Display *dpy, XID drawable, int interval); #endif xserver-xorg-video-intel-2.99.917+git20160325/test/dri3-test.c000066400000000000000000000707611267532330400232470ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "dri3.h" #include "../src/i915_pciids.h" #define ALIGN(x, y) (((x) + (y) - 1) & -(y)) #define PAGE_ALIGN(x) ALIGN(x, 4096) #define GTT I915_GEM_DOMAIN_GTT #define CPU I915_GEM_DOMAIN_CPU static int _x_error_occurred; static const struct pci_id_match ids[] = { INTEL_I830_IDS(020), INTEL_I845G_IDS(021), INTEL_I85X_IDS(022), INTEL_I865G_IDS(023), INTEL_I915G_IDS(030), INTEL_I915GM_IDS(030), INTEL_I945G_IDS(031), INTEL_I945GM_IDS(031), INTEL_G33_IDS(033), INTEL_PINEVIEW_IDS(033), INTEL_I965G_IDS(040), INTEL_I965GM_IDS(040), INTEL_G45_IDS(045), INTEL_GM45_IDS(045), INTEL_IRONLAKE_D_IDS(050), INTEL_IRONLAKE_M_IDS(050), INTEL_SNB_D_IDS(060), INTEL_SNB_M_IDS(060), INTEL_IVB_D_IDS(070), INTEL_IVB_M_IDS(070), INTEL_HSW_D_IDS(075), INTEL_HSW_M_IDS(075), INTEL_VLV_D_IDS(071), INTEL_VLV_M_IDS(071), INTEL_BDW_D_IDS(0100), INTEL_BDW_M_IDS(0100), }; static int i915_gen(int device) { struct drm_i915_getparam gp; int devid = 0; int n; gp.param = I915_PARAM_CHIPSET_ID; gp.value = &devid; if (drmIoctl(device, DRM_IOCTL_I915_GETPARAM, &gp)) return 0; for (n = 0; n < sizeof(ids)/sizeof(ids[0]); n++) { if (devid == ids[n].device_id) return ids[n].match_data; } return 0; } static int is_i915_device(int fd) { drm_version_t version; char name[5] = ""; memset(&version, 0, sizeof(version)); version.name_len = 4; version.name = name; if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) return 0; return strcmp("i915", name) == 0; } static int is_intel(int fd) { struct drm_i915_getparam gp; int ret; /* Confirm that this is a i915.ko device with GEM/KMS enabled */ ret = is_i915_device(fd); if (ret) { gp.param = I915_PARAM_HAS_GEM; gp.value = &ret; if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) ret = 0; } return ret; } static uint32_t gem_create(int fd, int size) { struct drm_i915_gem_create create; create.handle = 0; create.size = size; (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); return create.handle; } struct local_i915_gem_caching { uint32_t handle; uint32_t caching; }; #define LOCAL_I915_GEM_SET_CACHING 0x2f #define LOCAL_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + LOCAL_I915_GEM_SET_CACHING, struct local_i915_gem_caching) static int gem_set_caching(int fd, uint32_t handle, int caching) { struct local_i915_gem_caching arg; arg.handle = handle; arg.caching = caching; return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_SET_CACHING, &arg) == 0; } static int gem_export(int fd, uint32_t handle) { struct drm_prime_handle args; args.handle = handle; args.flags = O_CLOEXEC; if (drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args)) return -1; return args.fd; } static uint32_t gem_import(int fd, int name) { struct drm_prime_handle args; args.fd = name; args.flags = 0; if (drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args)) return 0; return args.handle; } static int gem_write(int fd, uint32_t handle, int offset, void *data, int len) { struct drm_i915_gem_pwrite gem_pwrite; gem_pwrite.handle = handle; gem_pwrite.offset = offset; gem_pwrite.size = len; gem_pwrite.data_ptr = (uintptr_t)data; return drmIoctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &gem_pwrite); } static void *gem_mmap(int fd, uint32_t handle, int size, unsigned prot, int domain) { struct drm_i915_gem_set_domain set_domain; void *ptr; if (domain == CPU) { struct drm_i915_gem_mmap mmap_arg; mmap_arg.handle = handle; mmap_arg.offset = 0; mmap_arg.size = size; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP, &mmap_arg)) return NULL; ptr = (void *)(uintptr_t)mmap_arg.addr_ptr; } else { struct drm_i915_gem_mmap_gtt mmap_arg; mmap_arg.handle = handle; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) return NULL; ptr = mmap(0, size, prot, MAP_SHARED, fd, mmap_arg.offset); if (ptr == MAP_FAILED) return NULL; } set_domain.handle = handle; set_domain.read_domains = domain; set_domain.write_domain = prot & PROT_WRITE ? set_domain.read_domains : 0; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) { munmap(ptr, size); return NULL; } return ptr; } static void gem_sync(int fd, uint32_t handle, int read) { struct drm_i915_gem_set_domain set_domain; set_domain.handle = handle; set_domain.read_domains = read; set_domain.write_domain = 0; drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain); } static int gem_get_tiling(int fd, uint32_t handle) { struct drm_i915_gem_get_tiling tiling; tiling.handle = handle; tiling.tiling_mode = -1; (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, &tiling); return tiling.tiling_mode; } static void gem_close(int fd, uint32_t handle) { struct drm_gem_close close; close.handle = handle; (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close); } static void gem_fill(int fd, uint32_t handle, uint32_t pixel, uint32_t size, int domain) { uint32_t *ptr, s; ptr = gem_mmap(fd, handle, size, PROT_READ | PROT_WRITE, domain); if (ptr == NULL) return; for (s = 0; s < size; s += 4) ptr[s/4] = pixel; munmap(ptr, size); } static int check_pixmap(Display *dpy, Pixmap pix, int x, int y, uint32_t expected, int bpp) { XImage *image; int w = 32 / bpp; image = XGetImage(dpy, pix, x - (x % w), y, w, 1, AllPlanes, ZPixmap); if (image == NULL) return 0; if (*(uint32_t *)image->data != expected) { printf("pixmap[%d, %d]:%d = %08x\n", x, y, bpp, *(uint32_t *)image->data); return 0; } XDestroyImage(image); return 1; } static int check_pixel(int fd, uint32_t handle, uint32_t stride, uint32_t size, int x, int y, uint32_t expected, int bpp, int domain) { uint32_t *ptr; int w = 32 / bpp; assert((stride & 3) == 0); ptr = gem_mmap(fd, handle, size, PROT_READ, domain); if (ptr == NULL) return 0; if (ptr[(y*stride + x - (x % w))/4] != expected) { printf("pixel[%d, %d]:%d = %08x\n", x, y, bpp, ptr[(y * stride + x)/4]); return 0; } munmap(ptr, size); return 1; } static GC get_gc(Display *dpy, Drawable d, int depth) { static GC gc[33]; if (gc[depth] == NULL) { XGCValues gcv; gcv.graphics_exposures = False; gc[depth] = XCreateGC(dpy, d, GCGraphicsExposures, &gcv); } return gc[depth]; } static int can_use_shm(Display *dpy) { int major, minor, has_pixmap; if (!XShmQueryExtension(dpy)) return 0; XShmQueryVersion(dpy, &major, &minor, &has_pixmap); return has_pixmap; } static int gpu_fill(int device, int handle, int width, int height, int pitch, int bpp, int tiling, uint32_t pixel) { struct drm_i915_gem_execbuffer2 execbuf; struct drm_i915_gem_relocation_entry gem_reloc[2]; struct drm_i915_gem_exec_object2 gem_exec[2]; uint32_t batch[10]; int gen = i915_gen(device); int len = 0; int ret; if (gen == 0) return -ENODEV; batch[0] = 2 << 29 | 0x50 << 22; batch[0] |= (gen >= 0100 ? 5 : 4); batch[1] = pitch; if (gen >= 040 && tiling) { batch[0] |= 1 << 11; batch[1] >>= 2; } batch[1] |= 0xf0 << 16; switch (bpp) { default: assert(0); case 32: batch[0] |= 1 << 21 | 1 << 20; batch[1] |= 1 << 25; /* RGB8888 */ case 16: batch[1] |= 1 << 24; /* RGB565 */ case 8: break; } batch[2] = 0; batch[3] = height << 16 | width; batch[4] = 0; len = 5; if (gen >= 0100) batch[len++] = 0; batch[len++] = pixel; batch[len++] = 0xA << 23; if (len & 1) len++; gem_reloc[0].offset = 4 * sizeof(uint32_t); gem_reloc[0].delta = 0; gem_reloc[0].target_handle = handle; gem_reloc[0].read_domains = I915_GEM_DOMAIN_RENDER; gem_reloc[0].write_domain = I915_GEM_DOMAIN_RENDER; gem_reloc[0].presumed_offset = 0; memset(gem_exec, 0, sizeof(gem_exec)); gem_exec[0].handle = handle; gem_exec[1].handle = gem_create(device, 4096); gem_exec[1].relocation_count = 1; gem_exec[1].relocs_ptr = (uintptr_t)gem_reloc; memset(&execbuf, 0, sizeof(execbuf)); execbuf.buffers_ptr = (uintptr_t)gem_exec; execbuf.buffer_count = 2; execbuf.batch_len = len * sizeof(uint32_t); execbuf.flags = gen >= 060 ? I915_EXEC_BLT : 0; ret = gem_write(device, gem_exec[1].handle, 0, batch, execbuf.batch_len); if (ret == 0) ret = drmIoctl(device, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf); if (ret < 0) ret = -errno; gem_close(device, gem_exec[1].handle); return ret; } static int test_shm(Display *dpy, int device, int width, int height) { const int x_loc[] = {0, width/2, width-1}; const int y_loc[] = {0, height/2, height-1}; uint32_t pixel = 0xffff00ff; XShmSegmentInfo shm; Pixmap pixmap; uint32_t handle = 0; uint32_t *ptr; int stride, fd; int x, y; int line; if (!can_use_shm(dpy)) return 0; printf("Creating %dx%d SHM pixmap\n", width, height); _x_error_occurred = 0; shm.shmid = shmget(IPC_PRIVATE, height * 4*width, IPC_CREAT | 0666); if (shm.shmid == -1) return 0; shm.shmaddr = shmat(shm.shmid, 0, 0); if (shm.shmaddr == (char *) -1) { shmctl(shm.shmid, IPC_RMID, NULL); return 0; } shm.readOnly = False; XShmAttach(dpy, &shm); pixmap = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), shm.shmaddr, &shm, width, height, 24); XSync(dpy, False); shmctl(shm.shmid, IPC_RMID, NULL); if (_x_error_occurred) { XShmDetach(dpy, &shm); shmdt(shm.shmaddr); return 0; } printf("Testing write of %dx%d SHM pixmap via DRI3 fd\n", width, height); fd = dri3_create_fd(dpy, pixmap, &stride); if (fd < 0) { line = __LINE__; goto fail; } handle = gem_import(device, fd); close(fd); if (handle == 0) { line = __LINE__; goto fail; } if (gpu_fill(device, handle, width, height, stride, 32, I915_TILING_NONE, pixel)) { line = __LINE__; goto fail; } gem_sync(device, handle, CPU); ptr = (uint32_t *)shm.shmaddr; for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (ptr[y_loc[y]*width + x_loc[x]] != pixel) { printf("pixel[%d, %d]:%d = %08x\n", x, y, 32, ptr[y_loc[y] * width + x_loc[x]]); line = __LINE__; goto fail; } for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, pixmap, x_loc[x], y_loc[y], pixel, 32)) { line = __LINE__; goto fail; } if (_x_error_occurred) { line = __LINE__; goto fail; } out: gem_close(device, handle); XFreePixmap(dpy, pixmap); XShmDetach(dpy, &shm); shmdt(shm.shmaddr); return fd != -1; fail: printf("%s failed at (%dx%d), line %d\n", __func__, width, height, line); fd = -1; goto out; } static int test_read_after_write(Display *dpy, int device, int width, int height, int depth, int domain) { const uint32_t pixel = 0xffff00ff; const int x_loc[] = {0, width/2, width-1}; const int y_loc[] = {0, height/2, height-1}; Window root = RootWindow(dpy, DefaultScreen(dpy)); uint32_t src, dst; int src_fd, dst_fd; int src_stride, src_size; int dst_stride, dst_size; Pixmap src_pix, dst_pix; struct dri3_fence fence; int x, y, bpp; _x_error_occurred = 0; switch (depth) { case 8: bpp = 8; break; case 16: bpp = 16; break; case 24: bpp = 32; break; case 32: bpp = 32; break; default: return 0; } src_stride = width * bpp/8; src_size = PAGE_ALIGN(src_stride * height); printf("Creating %dx%d (source stride=%d, size=%d, domain=%d)\n", width, height, src_stride, src_size, domain); src = gem_create(device, src_size); if (!src) goto fail; if (domain == CPU) gem_set_caching(device, src, 1); gem_fill(device, src, pixel, src_size, domain); src_fd = gem_export(device, src); if (src_fd < 0) goto fail; src_pix = dri3_create_pixmap(dpy, root, width, height, depth, src_fd, bpp, src_stride, src_size); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, src_pix, x_loc[x], y_loc[y], pixel, bpp)) goto fail; close(src_fd); dst_pix = XCreatePixmap(dpy, root, width, height, depth); if (dri3_create_fence(dpy, dst_pix, &fence)) goto fail; dst_fd = dri3_create_fd(dpy, dst_pix, &dst_stride); if (dst_fd < 0) goto fail; dst_size = lseek(dst_fd, 0, SEEK_END); printf("Comparing %dx%d (destination stride=%d, size=%d)\n", width, height, dst_stride, dst_size); dst = gem_import(device, dst_fd); if (dst == 0) goto fail; close(dst_fd); XCopyArea(dpy, src_pix, dst_pix, get_gc(dpy, dst_pix, depth), 0, 0, width, height, 0, 0); dri3_fence_sync(dpy, &fence); dri3_fence_free(dpy, &fence); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixel(device, dst, dst_stride, dst_size, x_loc[x], y_loc[y], pixel, bpp, GTT)) goto fail; XFreePixmap(dpy, dst_pix); XFreePixmap(dpy, src_pix); gem_close(device, src); gem_close(device, dst); if (_x_error_occurred) goto fail; return 0; fail: printf("%s failed at (%dx%d), depth=%d, domain=%d\n", __func__, width, height, depth, domain); return 1; } static XRenderPictFormat *format_for_depth(Display *dpy, int depth) { switch (depth) { case 8: return XRenderFindStandardFormat(dpy, PictStandardA8); case 24: return XRenderFindStandardFormat(dpy, PictStandardRGB24); case 32: return XRenderFindStandardFormat(dpy, PictStandardARGB32); default: assert(0); return NULL; } } static int test_read(Display *dpy, int device, int width, int height, int domain) { const uint32_t pixel = 0xffff00ff; const XRenderColor color = { 0xffff, 0x0000, 0xffff, 0xffff }; const int x_loc[] = {0, width/2, width-1}; const int y_loc[] = {0, height/2, height-1}; Window root = RootWindow(dpy, DefaultScreen(dpy)); uint32_t dst; int dst_stride, dst_size, dst_fd; Pixmap src_pix, dst_pix; Picture src_pic; struct dri3_fence fence; int depth = 32, bpp = 32; int x, y; _x_error_occurred = 0; dst_stride = width * bpp/8; dst_size = PAGE_ALIGN(dst_stride * height); printf("Creating %dx%d (destination stride=%d, size=%d, domain=%d)\n", width, height, dst_stride, dst_size, domain); dst = gem_create(device, dst_size); if (!dst) goto fail; if (domain == CPU) gem_set_caching(device, dst, 1); gem_fill(device, dst, ~pixel, dst_size, domain); dst_fd = gem_export(device, dst); if (dst_fd < 0) goto fail; dst_pix = dri3_create_pixmap(dpy, root, width, height, depth, dst_fd, bpp, dst_stride, dst_size); XSync(dpy, True); if (_x_error_occurred) goto fail; if (dri3_create_fence(dpy, dst_pix, &fence)) goto fail; src_pix = XCreatePixmap(dpy, root, width, height, depth); src_pic = XRenderCreatePicture(dpy, src_pix, format_for_depth(dpy, depth), 0, NULL); XRenderFillRectangle(dpy, PictOpSrc, src_pic, &color, 0, 0, width, height); XCopyArea(dpy, src_pix, dst_pix, get_gc(dpy, dst_pix, depth), 0, 0, width, height, 0, 0); dri3_fence_sync(dpy, &fence); dri3_fence_free(dpy, &fence); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixel(device, dst, dst_stride, dst_size, x_loc[x], y_loc[y], pixel, bpp, domain)) goto fail; XFreePixmap(dpy, dst_pix); XRenderFreePicture(dpy, src_pic); XFreePixmap(dpy, src_pix); gem_close(device, dst); if (_x_error_occurred) goto fail; return 0; fail: printf("%s failed at (%dx%d), depth=%d, domain=%d\n", __func__, width, height, depth, domain); return 1; } static int test_dup_pixmap(Display *dpy, int device) { const uint32_t pixel = 0xffff00ff; const XRenderColor color = { 0xffff, 0x0000, 0xffff, 0xffff }; const XRenderColor inverse = { 0, 0xffff, 0, 0 }; int width = 400, height = 400; const int x_loc[] = {0, width/2, width-1}; const int y_loc[] = {0, height/2, height-1}; Window root = RootWindow(dpy, DefaultScreen(dpy)); uint32_t handle; int stride, size, fd; Pixmap src_pix, dst_pix; Picture src_pic, dst_pic; struct dri3_fence fence; int depth = 32, bpp = 32; int x, y; _x_error_occurred = 0; printf("%s: Creating %dx%d pixmap\n", __func__, width, height); src_pix = XCreatePixmap(dpy, root, width, height, depth); src_pic = XRenderCreatePicture(dpy, src_pix, format_for_depth(dpy, depth), 0, NULL); fd = dri3_create_fd(dpy, src_pix, &stride); if (fd < 0) goto fail; size = lseek(fd, 0, SEEK_END); handle = gem_import(device, fd); printf("%s: Creating duplicate from pixmap exported fd\n", __func__); dst_pix = dri3_create_pixmap(dpy, root, width, height, depth, fd, bpp, stride, size); dst_pic = XRenderCreatePicture(dpy, dst_pix, format_for_depth(dpy, depth), 0, NULL); XSync(dpy, True); if (_x_error_occurred) goto fail; printf("%s: Filling src with %08x, reading dst\n", __func__, pixel); XRenderFillRectangle(dpy, PictOpSrc, src_pic, &color, 0, 0, width, height); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, dst_pix, x_loc[x], y_loc[y], pixel, 32)) goto fail; printf("%s: Filling dst with %08x, reading src\n", __func__, ~pixel); XRenderFillRectangle(dpy, PictOpSrc, dst_pic, &inverse, 0, 0, width, height); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, dst_pix, x_loc[x], y_loc[y], ~pixel, 32)) goto fail; if (dri3_create_fence(dpy, src_pix, &fence)) goto fail; printf("%s: Filling src with %08x, reading fd\n", __func__, pixel); XRenderFillRectangle(dpy, PictOpSrc, src_pic, &color, 0, 0, width, height); dri3_fence_sync(dpy, &fence); dri3_fence_free(dpy, &fence); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixel(device, handle, stride, size, x_loc[x], y_loc[y], pixel, bpp, GTT)) goto fail; printf("%s: Filling fd with %08x, reading src\n", __func__, ~pixel); if (gpu_fill(device, handle, width, height, stride, 32, gem_get_tiling(device, handle), ~pixel)) goto fail; for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, src_pix, x_loc[x], y_loc[y], ~pixel, 32)) goto fail; if (dri3_create_fence(dpy, dst_pix, &fence)) goto fail; printf("%s: Filling dst with %08x, reading fd\n", __func__, pixel); XRenderFillRectangle(dpy, PictOpSrc, dst_pic, &color, 0, 0, width, height); dri3_fence_sync(dpy, &fence); dri3_fence_free(dpy, &fence); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixel(device, handle, stride, size, x_loc[x], y_loc[y], pixel, bpp, GTT)) goto fail; printf("%s: Filling fd with %08x, reading dst\n", __func__, ~pixel); if (gpu_fill(device, handle, width, height, stride, 32, gem_get_tiling(device, handle), ~pixel)) goto fail; for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixmap(dpy, dst_pix, x_loc[x], y_loc[y], ~pixel, 32)) goto fail; XRenderFreePicture(dpy, src_pic); XFreePixmap(dpy, src_pix); if (dri3_create_fence(dpy, dst_pix, &fence)) goto fail; printf("%s: Closed original src, filling dst with %08x, reading fd\n", __func__, pixel); XRenderFillRectangle(dpy, PictOpSrc, dst_pic, &color, 0, 0, width, height); dri3_fence_sync(dpy, &fence); dri3_fence_free(dpy, &fence); for (x = 0; x < sizeof(x_loc)/sizeof(x_loc[0]); x++) for (y = 0; y < sizeof(y_loc)/sizeof(y_loc[0]); y++) if (!check_pixel(device, handle, stride, size, x_loc[x], y_loc[y], pixel, bpp, GTT)) goto fail; XRenderFreePicture(dpy, dst_pic); XFreePixmap(dpy, dst_pix); gem_close(device, handle); if (_x_error_occurred) goto fail; return 0; fail: printf("%s failed at (%dx%d), depth=%d\n", __func__, width, height, depth); return 1; } static int test_bad_size(Display *dpy, int device) { Window root = RootWindow(dpy, DefaultScreen(dpy)); uint32_t src; int src_fd; Pixmap src_pix; int line = -1; _x_error_occurred = 0; src = gem_create(device, 4096); if (!src) goto fail; src_fd = gem_export(device, src); if (src_fd < 0) goto fail; src_pix = dri3_create_pixmap(dpy, root, 16, 16, 32, dup(src_fd), 32, 16*4, 4096); line = __LINE__; XSync(dpy, True); if (_x_error_occurred) goto fail; XFreePixmap(dpy, src_pix); _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 32, 32, 32, dup(src_fd), 32, 32*4, 4096); line = __LINE__; XSync(dpy, True); if (_x_error_occurred) goto fail; XFreePixmap(dpy, src_pix); _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 64, 64, 32, dup(src_fd), 32, 64*4, 4096); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 64, 64, 32, dup(src_fd), 32, 64*4, 64*64*4); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, INT16_MAX, INT16_MAX, 8, dup(src_fd), 8, INT16_MAX, UINT32_MAX); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; close(src_fd); gem_close(device, src); return 0; fail: printf("%s failed at line %d\n", __func__, line); return 1; } static int test_bad_pitch(Display *dpy, int device) { Window root = RootWindow(dpy, DefaultScreen(dpy)); uint32_t src; int src_fd; Pixmap src_pix; int line = -1; _x_error_occurred = 0; src = gem_create(device, 4096); if (!src) goto fail; src_fd = gem_export(device, src); if (src_fd < 0) goto fail; src_pix = dri3_create_pixmap(dpy, root, 16, 16, 32, dup(src_fd), 32, 16*4, 4096); line = __LINE__; XSync(dpy, True); if (_x_error_occurred) goto fail; XFreePixmap(dpy, src_pix); _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 256, 2, 32, dup(src_fd), 32, 256*4, 4096); line = __LINE__; XSync(dpy, True); if (_x_error_occurred) goto fail; XFreePixmap(dpy, src_pix); _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 256, 2, 32, dup(src_fd), 32, 256, 4096); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 256, 2, 32, dup(src_fd), 32, 16384, 4096); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 256, 2, 32, dup(src_fd), 32, 1023, 4096); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; src_pix = dri3_create_pixmap(dpy, root, 256, 2, 32, dup(src_fd), 32, 1025, 4096); line = __LINE__; XSync(dpy, True); if (!_x_error_occurred) goto fail; _x_error_occurred = 0; close(src_fd); gem_close(device, src); return 0; fail: printf("%s failed at line %d\n", __func__, line); return 1; } static int gem_set_tiling(int fd, uint32_t handle, int tiling, int stride) { struct drm_i915_gem_set_tiling set_tiling; set_tiling.handle = handle; set_tiling.tiling_mode = tiling; set_tiling.stride = stride; return drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling) == 0; } static int test_tiling(Display *dpy, int device) { Window root = RootWindow(dpy, DefaultScreen(dpy)); const int tiling[] = { I915_TILING_NONE, I915_TILING_X, I915_TILING_Y }; int line = -1; int t; _x_error_occurred = 0; for (t = 0; t < sizeof(tiling)/sizeof(tiling[0]); t++) { uint32_t src; int src_fd; Pixmap src_pix; src = gem_create(device, 4*4096); if (!src) { line = __LINE__; goto fail; } gem_set_tiling(device, src, tiling[t], 512); src_fd = gem_export(device, src); if (src_fd < 0) { line = __LINE__; goto fail; } src_pix = dri3_create_pixmap(dpy, root, 128, 32, 32, src_fd, 32, 512, 4*4096); XSync(dpy, True); if (_x_error_occurred) { line = __LINE__; goto fail; } XFreePixmap(dpy, src_pix); _x_error_occurred = 0; close(src_fd); gem_close(device, src); } return 0; fail: printf("%s failed with tiling %d, line %d\n", __func__, tiling[t], line); return 1; } static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } int main(void) { Display *dpy; int device; int error = 0; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (DefaultDepth(dpy, DefaultScreen(dpy)) != 24) return 77; XSetErrorHandler(_check_error_handler); device = dri3_open(dpy); if (device < 0) return 127; if (!is_intel(device)) return 77; printf("Opened Intel DRI3 device\n"); error += test_bad_size(dpy, device); error += test_bad_pitch(dpy, device); error += test_tiling(dpy, device); error += test_shm(dpy, device, 400, 300); error += test_shm(dpy, device, 300, 400); error += test_read(dpy, device, 400, 200, GTT); error += test_read(dpy, device, 4000, 20, GTT); error += test_read(dpy, device, 16000, 10, GTT); error += test_read(dpy, device, 30000, 10, GTT); error += test_read(dpy, device, 200, 400, GTT); error += test_read(dpy, device, 20, 4000, GTT); error += test_read(dpy, device, 16, 16000, GTT); error += test_read(dpy, device, 16, 30000, GTT); error += test_read(dpy, device, 400, 200, CPU); error += test_read(dpy, device, 4000, 20, CPU); error += test_read(dpy, device, 16000, 10, CPU); error += test_read(dpy, device, 30000, 10, CPU); error += test_read(dpy, device, 200, 400, CPU); error += test_read(dpy, device, 20, 4000, CPU); error += test_read(dpy, device, 16, 16000, CPU); error += test_read(dpy, device, 16, 30000, CPU); error += test_read_after_write(dpy, device, 400, 200, 24, GTT); error += test_read_after_write(dpy, device, 4000, 20, 24, GTT); error += test_read_after_write(dpy, device, 16000, 10, 24, GTT); error += test_read_after_write(dpy, device, 30000, 10, 24, GTT); error += test_read_after_write(dpy, device, 30000, 10, 8, GTT); error += test_read_after_write(dpy, device, 200, 400, 24, GTT); error += test_read_after_write(dpy, device, 20, 4000, 24, GTT); error += test_read_after_write(dpy, device, 16, 16000, 24, GTT); error += test_read_after_write(dpy, device, 16, 30000, 24, GTT); error += test_read_after_write(dpy, device, 400, 200, 24, CPU); error += test_read_after_write(dpy, device, 4000, 20, 24, CPU); error += test_read_after_write(dpy, device, 16000, 10, 24, CPU); error += test_read_after_write(dpy, device, 30000, 10, 24, CPU); error += test_read_after_write(dpy, device, 30000, 10, 8, CPU); error += test_read_after_write(dpy, device, 200, 400, 24, CPU); error += test_read_after_write(dpy, device, 20, 4000, 24, CPU); error += test_read_after_write(dpy, device, 16, 16000, 24, CPU); error += test_read_after_write(dpy, device, 16, 30000, 24, CPU); error += test_dup_pixmap(dpy, device); return !!error; } xserver-xorg-video-intel-2.99.917+git20160325/test/dri3.c000066400000000000000000000102171267532330400222600ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include #include #include #include #include #include #include #include #include "dri3.h" Pixmap dri3_create_pixmap(Display *dpy, Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size) { xcb_connection_t *c = XGetXCBConnection(dpy); if (fd >= 0) { xcb_pixmap_t pixmap = xcb_generate_id(c); xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); return pixmap; } return 0; } int dri3_create_fd(Display *dpy, Pixmap pixmap, int *stride) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_buffer_from_pixmap_cookie_t cookie; xcb_dri3_buffer_from_pixmap_reply_t *reply; cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; *stride = reply->stride; return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; } int dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); struct dri3_fence f; int fd; fd = xshmfence_alloc_shm(); if (fd < 0) return -1; f.addr = xshmfence_map_shm(fd); if (f.addr == NULL) { close(fd); return -1; } f.xid = xcb_generate_id(c); xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); *fence = f; return 0; } void dri3_fence_sync(Display *dpy, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); xshmfence_reset(fence->addr); xcb_sync_trigger_fence(c, fence->xid); xcb_flush(c); xshmfence_await(fence->addr); } void dri3_fence_free(Display *dpy, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); xshmfence_unmap_shm(fence->addr); xcb_sync_destroy_fence(c, fence->xid); } static void dri3_query_version(xcb_connection_t *c, int *major, int *minor) { xcb_dri3_query_version_reply_t *reply; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), NULL); if (reply != NULL) { *major = reply->major_version; *minor = reply->minor_version; free(reply); } } static int dri3_exists(xcb_connection_t *c) { const xcb_query_extension_reply_t *ext; int major, minor; major = minor = -1; ext = xcb_get_extension_data(c, &xcb_dri3_id); if (ext != NULL && ext->present) dri3_query_version(c, &major, &minor); return major >= 0; } int dri3_open__full(Display *dpy, Window root, unsigned provider) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_open_cookie_t cookie; xcb_dri3_open_reply_t *reply; if (!dri3_exists(c)) return -1; cookie = xcb_dri3_open(c, root, provider); reply = xcb_dri3_open_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; return xcb_dri3_open_reply_fds(c, reply)[0]; } int dri3_open(Display *dpy) { return dri3_open__full(dpy, RootWindow(dpy, DefaultScreen(dpy)), None); } xserver-xorg-video-intel-2.99.917+git20160325/test/dri3.h000066400000000000000000000034021267532330400222630ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifndef DRI3_H #define DRI3_H #include int dri3_open(Display *dpy); int dri3_open__full(Display *dpy, Window root, unsigned provider); Pixmap dri3_create_pixmap(Display *dpy, Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size); int dri3_create_fd(Display *dpy, Pixmap pixmap, int *stride); struct dri3_fence { XID xid; void *addr; }; int dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *out); void dri3_fence_sync(Display *dpy, struct dri3_fence *fence); void dri3_fence_free(Display *dpy, struct dri3_fence *fence); #endif /* DRI3_H */ xserver-xorg-video-intel-2.99.917+git20160325/test/lowlevel-blt-bench.c000066400000000000000000000304431267532330400251070ustar00rootroot00000000000000/* * Copyright © 2009 Nokia Corporation * Copyright © 2010 Movial Creative Technologies Oy * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include /* for XDestroyImage */ #include #include #if HAVE_MIT_SHM #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #include #endif #include /* for pixman blt functions */ #include "test.h" static const struct format { const char *name; pixman_format_code_t pixman_format; } formats[] = { { "a8r8g8b8", PIXMAN_a8r8g8b8 }, { "x8r8g8b8", PIXMAN_x8r8g8b8 }, { "a8", PIXMAN_a8 }, { "a4", PIXMAN_a4 }, { "a1", PIXMAN_a1 }, }; static const struct op { int value; const char *name; } ops[] = { { PictOpClear, "Clear" }, { PictOpSrc, "Src" }, { PictOpDst, "Dst" }, { PictOpOver, "Over" }, { PictOpOverReverse, "OverReverse" }, { PictOpIn, "In" }, { PictOpInReverse, "InReverse" }, { PictOpOut, "Out" }, { PictOpOutReverse, "OutReverse" }, { PictOpAtop, "Atop" }, { PictOpAtopReverse, "AtopReverse" }, { PictOpXor, "Xor" }, { PictOpAdd, "Add" }, { PictOpSaturate, "Saturate" }, { PictOpMultiply, "Multiply" }, { PictOpScreen, "Screen" }, { PictOpOverlay, "Overlay" }, { PictOpDarken, "Darken" }, { PictOpLighten, "Lighten" }, { PictOpColorDodge, "Dodge" }, { PictOpColorBurn, "Burn" }, { PictOpHardLight, "HardLight" }, { PictOpSoftLight, "SoftLight" }, }; static Picture source_pixmap(struct test_display *t, struct test_target *target, int format) { XRenderColor render_color[2] = { { 0x8000, 0x8000, 0x8000, 0x8000 }, { 0xffff, 0xffff, 0xffff, 0xffff }, }; Pixmap pixmap; Picture picture; pixmap = XCreatePixmap(t->dpy, t->root, target->width, target->height, PIXMAN_FORMAT_DEPTH(formats[format].pixman_format)); picture = XRenderCreatePicture(t->dpy, pixmap, XRenderFindStandardFormat(t->dpy, format), 0, NULL); XFreePixmap(t->dpy, pixmap); XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[0], 0, 0, target->width, target->height/2); XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color[1], 0, target->height/2, target->width, target->height/2); return picture; } static Picture source_a8r8g8b8(struct test_display *t, struct test_target *target) { return source_pixmap(t, target, 0); } static Picture source_x8r8g8b8(struct test_display *t, struct test_target *target) { return source_pixmap(t, target, 1); } static Picture source_a8(struct test_display *t, struct test_target *target) { return source_pixmap(t, target, 2); } static Picture source_a4(struct test_display *t, struct test_target *target) { return source_pixmap(t, target, 3); } static Picture source_a1(struct test_display *t, struct test_target *target) { return source_pixmap(t, target, 3); } static Picture source_1x1r(struct test_display *t, struct test_target *target) { XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; XRenderPictureAttributes pa; Pixmap pixmap; Picture picture; pa.repeat = RepeatNormal; pixmap = XCreatePixmap(t->dpy, t->root, 1, 1, 32); picture = XRenderCreatePicture(t->dpy, pixmap, XRenderFindStandardFormat(t->dpy, 0), CPRepeat, &pa); XFreePixmap(t->dpy, pixmap); XRenderFillRectangle(t->dpy, PictOpSrc, picture, &render_color, 0, 0, 1, 1); return picture; } static Picture source_solid(struct test_display *t, struct test_target *target) { XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; return XRenderCreateSolidFill(t->dpy, &render_color); } static Picture source_linear_horizontal(struct test_display *t, struct test_target *target) { XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; XFixed stops[2] = {0, 0xffff}; XLinearGradient gradient = { {0, 0}, {target->width << 16, 0}}; return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); } static Picture source_linear_vertical(struct test_display *t, struct test_target *target) { XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; XFixed stops[2] = {0, 0xffff}; XLinearGradient gradient = { {0, 0}, {0, target->height << 16}}; return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); } static Picture source_linear_diagonal(struct test_display *t, struct test_target *target) { XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; XFixed stops[2] = {0, 0xffff}; XLinearGradient gradient = { {0, 0}, {target->width << 16, target->height << 16}}; return XRenderCreateLinearGradient(t->dpy, &gradient, stops, colors, 2); } static Picture source_radial_concentric(struct test_display *t, struct test_target *target) { XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; XFixed stops[2] = {0, 0xffff}; XRadialGradient gradient = { { ((target->width << 16) + 1) / 2, ((target->height << 16) + 1) / 2, 0, }, { ((target->width << 16) + 1) / 2, ((target->height << 16) + 1) / 2, target->width << 15, } }; return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2); } static Picture source_radial_generic(struct test_display *t, struct test_target *target) { XRenderColor colors[2] = {{0}, {0xffff, 0xffff, 0xffff, 0xffff}}; XFixed stops[2] = {0, 0xffff}; XRadialGradient gradient = { { 0, 0, target->width << 14, }, { target->width << 16, target->height << 16, target->width << 14, } }; return XRenderCreateRadialGradient(t->dpy, &gradient, stops, colors, 2); } #if HAVE_MIT_SHM static XShmSegmentInfo shmref, shmout; static void setup_shm(struct test *t) { XShmSegmentInfo shm; int size; shm.shmid = -1; if (!(t->ref.has_shm_pixmaps && t->out.has_shm_pixmaps)) return; size = t->ref.width * t->ref.height * 4; size = (size + 4095) & -4096; shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0666); if (shm.shmid == -1) return; shm.shmaddr = shmat(shm.shmid, 0, 0); if (shm.shmaddr == (char *) -1) { shmctl(shm.shmid, IPC_RMID, NULL); shm.shmid = -1; return; } shm.readOnly = False; shmref = shm; XShmAttach(t->ref.dpy, &shmref); XSync(t->ref.dpy, True); shmout = shm; XShmAttach(t->out.dpy, &shmout); XSync(t->out.dpy, True); } static Picture source_shm(struct test_display *t, struct test_target *target) { XShmSegmentInfo *shm = t->target == REF ? &shmref : &shmout; Pixmap pixmap; Picture picture; int size; if (shm->shmid == -1) return 0; pixmap = XShmCreatePixmap(t->dpy, t->root, shm->shmaddr, shm, target->width, target->height, 32); picture = XRenderCreatePicture(t->dpy, pixmap, XRenderFindStandardFormat(t->dpy, 0), 0, NULL); XFreePixmap(t->dpy, pixmap); size = target->width * target->height * 4; memset(shm->shmaddr, 0x80, size/2); memset(shm->shmaddr+size/2, 0xff, size/2); return picture; } #else static void setup_shm(struct test *t) { } static Picture source_shm(struct test_display *t, struct test_target *target) { return 0; } #endif static const struct { Picture (*create)(struct test_display *, struct test_target *); const char *name; } source[] = { { source_a8r8g8b8, "a8r8g8b8 pixmap" }, { source_x8r8g8b8, "x8r8g8b8 pixmap" }, { source_a8, "a8 pixmap" }, { source_a4, "a4 pixmap" }, { source_a1, "a1 pixmap" }, { source_1x1r, "a8r8g8b8 1x1R pixmap" }, { source_solid, "solid" }, { source_shm, "a8r8g8b8 shm" }, { source_linear_horizontal, "linear (horizontal gradient)" }, { source_linear_vertical, "linear (vertical gradient)" }, { source_linear_diagonal, "linear (diagonal gradient)" }, { source_radial_concentric, "radial (concentric)" }, { source_radial_generic, "radial (generic)" }, }; static double _bench_source(struct test_display *t, enum target target_type, int op, int src, int loops) { XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; struct test_target target; Picture picture; struct timespec tv; double elapsed; test_target_create_render(t, target_type, &target); XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, 0, 0, target.width, target.height); picture = source[src].create(t, &target); if (picture) { test_timer_start(t, &tv); while (loops--) XRenderComposite(t->dpy, op, picture, 0, target.picture, 0, 0, 0, 0, 0, 0, target.width, target.height); elapsed = test_timer_stop(t, &tv); XRenderFreePicture(t->dpy, picture); } else elapsed = -1; test_target_destroy_render(t, &target); return elapsed; } static void bench_source(struct test *t, enum target target, int op, int src) { double out, ref; fprintf(stdout, "%28s with %s: ", source[src].name, ops[op].name); fflush(stdout); op = ops[op].value; ref = _bench_source(&t->ref, target, op, src, 1000); if (ref < 0) { fprintf(stdout, "SKIP\n"); return; } fprintf(stdout, "ref=%f, ", ref); fflush(stdout); out = _bench_source(&t->out, target, op, src, 1000); if (out < 0) { fprintf(stdout, "SKIP\n"); return; } fprintf(stdout, "out=%f\n", out); } static double _bench_mask(struct test_display *t, enum target target_type, int op, int src, int mask, int loops) { XRenderColor render_color = { 0x8000, 0x8000, 0x8000, 0x8000 }; struct test_target target; Picture ps, pm; struct timespec tv; double elapsed; test_target_create_render(t, target_type, &target); XRenderFillRectangle(t->dpy, PictOpClear, target.picture, &render_color, 0, 0, target.width, target.height); ps = source[src].create(t, &target); pm = source[mask].create(t, &target); if (ps && pm) { test_timer_start(t, &tv); while (loops--) XRenderComposite(t->dpy, op, ps, pm, target.picture, 0, 0, 0, 0, 0, 0, target.width, target.height); elapsed = test_timer_stop(t, &tv); } else elapsed = -1; if (ps) XRenderFreePicture(t->dpy, ps); if (pm) XRenderFreePicture(t->dpy, pm); test_target_destroy_render(t, &target); return elapsed; } static void bench_mask(struct test *t, enum target target, int op, int src, int mask) { double out, ref; fprintf(stdout, "%28s In %28s with %s: ", source[src].name, source[mask].name, ops[op].name); fflush(stdout); op = ops[op].value; ref = _bench_mask(&t->ref, target, op, src, mask, 1000); if (ref < 0) { fprintf(stdout, "SKIP\n"); return; } fprintf(stdout, "ref=%f, ", ref); fflush(stdout); out = _bench_mask(&t->out, target, op, src, mask, 1000); if (out < 0) { fprintf(stdout, "SKIP\n"); return; } fprintf(stdout, "out=%f\n", out); } int main(int argc, char **argv) { struct test test; unsigned op, src, mask; test_init(&test, argc, argv); setup_shm(&test); for (op = 0; op < sizeof(ops)/sizeof(ops[0]); op++) { for (src = 0; src < sizeof(source)/sizeof(source[0]); src++) bench_source(&test, ROOT, op, src); fprintf (stdout, "\n"); for (src = 0; src < sizeof(source)/sizeof(source[0]); src++) for (mask = 0; mask < sizeof(source)/sizeof(source[0]); mask++) bench_mask(&test, ROOT, op, src, mask); fprintf (stdout, "\n"); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/mixed-stress.c000066400000000000000000000117571267532330400240600ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include #include "test.h" static void _render_copy(struct test_target *tt, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor color; Picture src; Pixmap tmp; tmp = XCreatePixmap(tt->dpy->dpy, DefaultRootWindow(tt->dpy->dpy), 10+w, 20+h, tt->format->depth); src = XRenderCreatePicture(tt->dpy->dpy, tmp, tt->format, 0, NULL); /* magenta border */ color.red = 0xffff; color.green = 0; color.blue = 0xffff; color.alpha = 0xffff; XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 0, 0, w+10, h+20); color.red = red * alpha; color.green = green * alpha; color.blue = blue * alpha; color.alpha = alpha << 8 | alpha; XRenderFillRectangle(tt->dpy->dpy, PictOpSrc, src, &color, 5, 10, w, h); XRenderComposite(tt->dpy->dpy, PictOpSrc, src, 0, tt->picture, 5, 10, 0, 0, x, y, w, h); XRenderFreePicture(tt->dpy->dpy, src); XFreePixmap(tt->dpy->dpy, tmp); } static void render_copy(struct test_target *out, struct test_target *ref) { int x = rand() % (2*out->width) - out->width; int y = rand() % (2*out->height) - out->height; int w = rand() % (2*out->width); int h = rand() % (2*out->height); int red = rand() & 0xff; int green = rand() & 0xff; int blue = rand() & 0xff; int alpha = rand() & 0xff; _render_copy(out, x, y, w, h, red, green, blue, alpha); _render_copy(ref, x, y, w, h, red, green, blue, alpha); } static void fill_rect(struct test_target *tt, int alu, int color, int x, int y, int w, int h) { XGCValues val; val.function = alu; val.foreground = color; XChangeGC(tt->dpy->dpy, tt->gc, GCFunction | GCForeground, &val); XFillRectangle(tt->dpy->dpy, tt->draw, tt->gc, x, y, w, h); } static void clear(struct test_target *tt) { fill_rect(tt, GXcopy, 0, 0, 0, tt->width, tt->height); } static void basic_fill(struct test_target *out, struct test_target *ref) { int x = rand() % (2*out->width) - out->width; int y = rand() % (2*out->height) - out->height; int w = rand() % (2*out->width); int h = rand() % (2*out->height); int color = rand(); int alu = rand() % 16; fill_rect(out, alu, color, x, y, w, h); fill_rect(ref, alu, color, x, y, w, h); } static void basic_copy(struct test_target *out, struct test_target *ref) { int sx = rand() % (2*out->width) - ref->width; int sy = rand() % (2*out->height) - ref->height; int dx = rand() % (2*out->width) - ref->width; int dy = rand() % (2*out->height) - ref->height; int w = rand() % (2*out->width); int h = rand() % (2*out->height); XGCValues val; val.function = rand() % 16; XChangeGC(out->dpy->dpy, out->gc, GCFunction, &val); XCopyArea(out->dpy->dpy, out->draw, out->draw, out->gc, sx, sy, w, h, dx, dy); XChangeGC(ref->dpy->dpy, ref->gc, GCFunction, &val); XCopyArea(ref->dpy->dpy, ref->draw, ref->draw, ref->gc, sx, sy, w, h, dx, dy); } static void _put(struct test_target *tt, int x, int y, int w,int h, int color, int alu) { XImage image; XGCValues val; val.function = alu; test_init_image(&image, &tt->dpy->shm, tt->format, w, h); pixman_fill((uint32_t*)image.data, image.bytes_per_line/sizeof(uint32_t), image.bits_per_pixel, 0, 0, w, h, color); XChangeGC(tt->dpy->dpy, tt->gc, GCFunction, &val); if (rand() & 1) { XShmPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 0, 0, x, y, w, h, 0); XSync(tt->dpy->dpy, 1); } else { XPutImage(tt->dpy->dpy, tt->draw, tt->gc, &image, 0, 0, x, y, w, h); } } static void basic_put(struct test_target *out, struct test_target *ref) { int x = rand() % (2*out->width) - out->width; int y = rand() % (2*out->height) - out->height; int w = rand() % out->width; int h = rand() % out->height; int color = rand(); int alu = rand() % 16; _put(out, x, y, w, h, color, alu); _put(ref, x, y, w, h, color, alu); } static void rect_tests(struct test *test, int iterations, enum target target) { struct test_target out, ref; void (* const ops[])(struct test_target *, struct test_target *) = { basic_copy, basic_fill, basic_put, render_copy, }; int n; printf("Running mixed ops stress against %s: ", test_target_name(target)); fflush(stdout); test_target_create_render(&test->out, target, &out); test_target_create_render(&test->ref, target, &ref); clear(&out); clear(&ref); for (n = 0; n < iterations; n++) ops[rand() % ARRAY_SIZE(ops)](&out, &ref); test_compare(test, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); printf("passed [%d iterations]\n", n); test_target_destroy_render(&test->out, &out); test_target_destroy_render(&test->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int iterations = REPS(i); rect_tests(&test, iterations, 0); rect_tests(&test, iterations, 1); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/mkvsync.sh000077500000000000000000000010331267532330400233000ustar00rootroot00000000000000#!/bin/bash OUT="$1" [ -n "$OUT" ] || OUT="vsync.avi" TMP=".build.tmp" rm -rf ${TMP} mkdir ${TMP} convert -size 640x480 -depth 24 canvas:black png24:${TMP}/black.png convert -size 640x480 -depth 24 canvas:white png24:${TMP}/white.png mkdir ${TMP}/anim for ((a=0; $a < 1000; a=$a+2)); do ln -s ../black.png ${TMP}/anim/$a.png done for ((a=1; $a < 1000; a=$a+2)); do ln -s ../white.png ${TMP}/anim/$a.png done mencoder "mf://${TMP}/anim/*.png" -v -vf-clr -mf fps=60 -o "${OUT}" -ovc lavc exitcode=$? rm -rf ${TMP} exit ${exitcode} xserver-xorg-video-intel-2.99.917+git20160325/test/present-race.c000066400000000000000000000257341267532330400240210ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri3.h" static int _x_error_occurred; static uint32_t stamp; static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } static void *setup_msc(Display *dpy, Window win) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_void_cookie_t cookie; uint32_t id = xcb_generate_id(c); xcb_generic_error_t *error; void *q; cookie = xcb_present_select_input_checked(c, id, win, XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY); q = xcb_register_for_special_xge(c, &xcb_present_id, id, &stamp); error = xcb_request_check(c, cookie); assert(error == NULL); return q; } static void teardown_msc(Display *dpy, void *q) { xcb_unregister_for_special_event(XGetXCBConnection(dpy), q); } static uint64_t wait_vblank(Display *dpy, Window win) { xcb_connection_t *c = XGetXCBConnection(dpy); static uint32_t serial = 1; uint64_t msc = 0; int complete = 0; void *q; if (win == 0) win = DefaultRootWindow(dpy); q = setup_msc(dpy, win); xcb_present_notify_msc(c, win, serial ^ 0xdeadbeef, 0, 1, 0); xcb_flush(c); do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC && ce->serial == (serial ^ 0xdeadbeef)) { msc = ce->msc; complete = 1; } free(ev); } while (!complete); if (++serial == 0) serial = 1; teardown_msc(dpy, q); return msc; } static int test_basic(Display *dpy, int dummy) { xcb_connection_t *c = XGetXCBConnection(dpy); XSetWindowAttributes attr; Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy)); Pixmap pixmap; struct dri3_fence fence; Window root, win; unsigned int width, height; unsigned border, depth; int x, y, ret = 1; const char *phase; uint64_t msc; root = DefaultRootWindow(dpy); XGetGeometry(dpy, root, &win, &x, &y, &width, &height, &border, &depth); _x_error_occurred = 0; attr.override_redirect = 1; switch (dummy) { case 0: win = root; phase = "root"; break; case 1: win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "fullscreen"; break; case 2: width /= 2; height /= 2; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "window"; break; case 3: if (!has_composite(dpy)) return 0; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); phase = "composite"; break; default: phase = "broken"; win = root; abort(); break; } XMapWindow(dpy, win); XSync(dpy, True); if (_x_error_occurred) return 1; if (dri3_create_fence(dpy, win, &fence)) return 0; printf("%s: Testing basic flip: %dx%d\n", phase, width, height); fflush(stdout); _x_error_occurred = 0; xshmfence_reset(fence.addr); msc = wait_vblank(dpy, win); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ fence.xid, XCB_PRESENT_OPTION_NONE, (msc + 64) & -64, /* target msc */ 64, /* divisor */ 32, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, /* sync fence */ XCB_PRESENT_OPTION_NONE, (msc + 64) & -64, /* target msc */ 64, /* divisor */ 48, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XDestroyWindow(dpy, win); XFlush(dpy); ret = !!xshmfence_await(fence.addr); dri3_fence_free(dpy, &fence); XSync(dpy, True); ret += !!_x_error_occurred; return ret; } static int test_race(Display *dpy, int dummy) { Display *mgr = XOpenDisplay(NULL); xcb_connection_t *c = XGetXCBConnection(dpy); XSetWindowAttributes attr; Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy)); Pixmap pixmap; struct dri3_fence fence; Window root, win; unsigned int width, height; unsigned border, depth; int x, y, ret = 1; const char *phase; uint64_t msc; root = DefaultRootWindow(dpy); XGetGeometry(dpy, root, &win, &x, &y, &width, &height, &border, &depth); _x_error_occurred = 0; attr.override_redirect = 1; switch (dummy) { case 0: win = root; phase = "root"; break; case 1: win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "fullscreen"; break; case 2: width /= 2; height /= 2; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "window"; break; case 3: if (!has_composite(dpy)) return 0; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); phase = "composite"; break; default: phase = "broken"; win = root; abort(); break; } XMapWindow(dpy, win); XSync(dpy, True); if (_x_error_occurred) return 1; if (dri3_create_fence(dpy, win, &fence)) return 0; printf("%s: Testing race with manager: %dx%d\n", phase, width, height); fflush(stdout); _x_error_occurred = 0; xshmfence_reset(fence.addr); msc = wait_vblank(dpy, win); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ fence.xid, XCB_PRESENT_OPTION_NONE, (msc + 64) & -64, /* target msc */ 64, /* divisor */ 32, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XFlush(dpy); XDestroyWindow(mgr, win); XFlush(mgr); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, /* sync fence */ XCB_PRESENT_OPTION_NONE, (msc + 64) & -64, /* target msc */ 64, /* divisor */ 48, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XFlush(dpy); ret = !!xshmfence_await(fence.addr); dri3_fence_free(dpy, &fence); XSync(dpy, True); ret += !!_x_error_occurred; XCloseDisplay(mgr); return ret; } static int has_present(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_generic_error_t *error = NULL; void *reply; reply = xcb_xfixes_query_version_reply(c, xcb_xfixes_query_version(c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "XFixes not supported on %s\n", DisplayString(dpy)); return 0; } reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "DRI3 not supported on %s\n", DisplayString(dpy)); return 0; } reply = xcb_present_query_version_reply(c, xcb_present_query_version(c, XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "Present not supported on %s\n", DisplayString(dpy)); return 0; } return 1; } int main(void) { Display *dpy; int dummy; int error = 0; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (!has_present(dpy)) return 77; if (DPMSQueryExtension(dpy, &dummy, &dummy)) DPMSDisable(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); for (dummy = 0; dummy <= 3; dummy++) { error += test_basic(dpy, dummy); error += test_race(dpy, dummy); } if (DPMSQueryExtension(dpy, &dummy, &dummy)) DPMSEnable(dpy); return !!error; } xserver-xorg-video-intel-2.99.917+git20160325/test/present-speed.c000066400000000000000000000376111267532330400242040ustar00rootroot00000000000000/* * Copyright (c) 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri3.h" static int _x_error_occurred; static uint32_t stamp; struct list { struct list *next, *prev; }; static void list_init(struct list *list) { list->next = list->prev = list; } static inline void __list_add(struct list *entry, struct list *prev, struct list *next) { next->prev = entry; entry->next = next; entry->prev = prev; prev->next = entry; } static inline void list_add(struct list *entry, struct list *head) { __list_add(entry, head, head->next); } static inline void __list_del(struct list *prev, struct list *next) { next->prev = prev; prev->next = next; } static inline void _list_del(struct list *entry) { __list_del(entry->prev, entry->next); } static inline void list_move(struct list *list, struct list *head) { if (list->prev != head) { _list_del(list); list_add(list, head); } } #define __container_of(ptr, sample, member) \ (void *)((char *)(ptr) - ((char *)&(sample)->member - (char *)(sample))) #define list_for_each_entry(pos, head, member) \ for (pos = __container_of((head)->next, pos, member); \ &pos->member != (head); \ pos = __container_of(pos->member.next, pos, member)) static int _check_error_handler(Display *display, XErrorEvent *event) { if (_x_error_occurred < 0) return True; printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static double elapsed(const struct timespec *start, const struct timespec *end) { return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec)/1000; } struct buffer { struct list link; Pixmap pixmap; struct dri3_fence fence; int fd; int busy; }; #define DRI3 1 #define NOCOPY 2 static void run(Display *dpy, Window win, const char *name, unsigned options) { xcb_connection_t *c = XGetXCBConnection(dpy); struct timespec start, end; #define N_BACK 8 char test_name[128]; struct buffer buffer[N_BACK]; struct list mru; Window root; unsigned int width, height; unsigned border, depth; unsigned present_flags = XCB_PRESENT_OPTION_ASYNC; xcb_xfixes_region_t update = 0; int completed = 0; int queued = 0; uint32_t eid; void *Q; int i, n; list_init(&mru); XGetGeometry(dpy, win, &root, &i, &n, &width, &height, &border, &depth); _x_error_occurred = 0; for (n = 0; n < N_BACK; n++) { buffer[n].pixmap = XCreatePixmap(dpy, win, width, height, depth); buffer[n].fence.xid = 0; buffer[n].fd = -1; if (options & DRI3) { xcb_dri3_buffer_from_pixmap_reply_t *reply; int *fds; if (dri3_create_fence(dpy, win, &buffer[n].fence)) return; reply = xcb_dri3_buffer_from_pixmap_reply (c, xcb_dri3_buffer_from_pixmap(c, buffer[n].pixmap), NULL); if (reply == NULL) return; fds = xcb_dri3_buffer_from_pixmap_reply_fds (c, reply); buffer[n].fd = fds[0]; free(reply); /* start idle */ xshmfence_trigger(buffer[n].fence.addr); } buffer[n].busy = 0; list_add(&buffer[n].link, &mru); } if (options & NOCOPY) { update = xcb_generate_id(c); xcb_xfixes_create_region(c, update, 0, NULL); present_flags |= XCB_PRESENT_OPTION_COPY; } eid = xcb_generate_id(c); xcb_present_select_input(c, eid, win, (options & NOCOPY ? 0 : XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY) | XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY); Q = xcb_register_for_special_xge(c, &xcb_present_id, eid, &stamp); clock_gettime(CLOCK_MONOTONIC, &start); do { for (n = 0; n < 1000; n++) { struct buffer *tmp, *b = NULL; list_for_each_entry(tmp, &mru, link) { if (!tmp->busy) { b = tmp; break; } } while (b == NULL) { xcb_present_generic_event_t *ev; ev = (xcb_present_generic_event_t *) xcb_wait_for_special_event(c, Q); if (ev == NULL) abort(); do { switch (ev->evtype) { case XCB_PRESENT_COMPLETE_NOTIFY: completed++; queued--; break; case XCB_PRESENT_EVENT_IDLE_NOTIFY: { xcb_present_idle_notify_event_t *ie = (xcb_present_idle_notify_event_t *)ev; assert(ie->serial < N_BACK); buffer[ie->serial].busy = 0; if (b == NULL) b = &buffer[ie->serial]; break; } } free(ev); } while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q))); } b->busy = (options & NOCOPY) == 0; if (b->fence.xid) { xshmfence_await(b->fence.addr); xshmfence_reset(b->fence.addr); } xcb_present_pixmap(c, win, b->pixmap, b - buffer, 0, /* valid */ update, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ b->fence.xid, present_flags, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); list_move(&b->link, &mru); queued++; xcb_flush(c); } clock_gettime(CLOCK_MONOTONIC, &end); } while (end.tv_sec < start.tv_sec + 10); while (queued) { xcb_present_generic_event_t *ev; ev = (xcb_present_generic_event_t *) xcb_wait_for_special_event(c, Q); if (ev == NULL) abort(); do { switch (ev->evtype) { case XCB_PRESENT_COMPLETE_NOTIFY: completed++; queued--; break; case XCB_PRESENT_EVENT_IDLE_NOTIFY: break; } free(ev); } while ((ev = (xcb_present_generic_event_t *)xcb_poll_for_special_event(c, Q))); } clock_gettime(CLOCK_MONOTONIC, &end); if (update) xcb_xfixes_destroy_region(c, update); for (n = 0; n < N_BACK; n++) { if (buffer[n].fence.xid) dri3_fence_free(dpy, &buffer[n].fence); if (buffer[n].fd != -1) close(buffer[n].fd); XFreePixmap(dpy, buffer[n].pixmap); } XSync(dpy, True); if (_x_error_occurred) abort(); _x_error_occurred = -1; xcb_present_select_input(c, eid, win, 0); XSync(dpy, True); xcb_unregister_for_special_event(c, Q); test_name[0] = '\0'; if (options) { snprintf(test_name, sizeof(test_name), "(%s%s )", options & NOCOPY ? " no-copy" : "", options & DRI3 ? " dri3" : ""); } printf("%s%s: Completed %d presents in %.1fs, %.3fus each (%.1f FPS)\n", name, test_name, completed, elapsed(&start, &end) / 1000000, elapsed(&start, &end) / completed, completed / (elapsed(&start, &end) / 1000000)); } static int isqrt(int x) { int i; for (i = 2; i*i < x; i++) ; return i; } static void siblings(int max_width, int max_height, int ncpus, unsigned options) { int sq_ncpus = isqrt(ncpus); int width = max_width / sq_ncpus; int height = max_height/ sq_ncpus; int child; if (ncpus <= 1) return; for (child = 0; child < ncpus; child++) { for (; fork() == 0; exit(0)) { int x = (child % sq_ncpus) * width; int y = (child / sq_ncpus) * height; XSetWindowAttributes attr = { .override_redirect = 1 }; Display *dpy = XOpenDisplay(NULL); Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), x, y, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); run(dpy, win, "sibling", options); } } while (child) { int status = -1; pid_t pid = wait(&status); if (pid == -1) continue; child--; } } static int has_present(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_generic_error_t *error = NULL; void *reply; reply = xcb_present_query_version_reply(c, xcb_present_query_version(c, XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "Present not supported on %s\n", DisplayString(dpy)); return 0; } return 1; } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XDamageQueryExtension (dpy, &event, &error)) return 0; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } static int dri3_query_version(Display *dpy, int *major, int *minor) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_query_version_reply_t *reply; xcb_generic_error_t *error; *major = *minor = -1; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(error); if (reply == NULL) return -1; *major = reply->major_version; *minor = reply->minor_version; free(reply); return 0; } static int has_dri3(Display *dpy) { const xcb_query_extension_reply_t *ext; int major, minor; ext = xcb_get_extension_data(XGetXCBConnection(dpy), &xcb_dri3_id); if (ext == NULL || !ext->present) return 0; if (dri3_query_version(dpy, &major, &minor) < 0) return 0; return major >= 0; } static int has_xfixes(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); const xcb_query_extension_reply_t *ext; void *reply; ext = xcb_get_extension_data(c, &xcb_xfixes_id); if (ext == NULL || !ext->present) return 0; reply = xcb_xfixes_query_version_reply(c, xcb_xfixes_query_version(c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION), NULL); free(reply); return reply != NULL; } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static void fullscreen(Display *dpy, Window win) { Atom atom = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&atom, 1); } static void loop(Display *dpy, XRRScreenResources *res, unsigned options) { Window root = DefaultRootWindow(dpy); Window win; XSetWindowAttributes attr; int i, j; attr.override_redirect = 1; run(dpy, root, "off", options); XSync(dpy, True); for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); for (j = 0; mode && j < 2*output->ncrtc; j++) { int c = j; if (c >= output->ncrtc) c = 2*output->ncrtc - j - 1; printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld: %dx%d\n", i, c, (long)res->outputs[i], (long)output->crtcs[c], mode->width, mode->height); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); run(dpy, root, "root", options); XSync(dpy, True); win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); fullscreen(dpy, win); XMapWindow(dpy, win); run(dpy, win, "fullscreen", options); XDestroyWindow(dpy, win); XSync(dpy, True); win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); run(dpy, win, "windowed", options); XDestroyWindow(dpy, win); XSync(dpy, True); if (has_composite(dpy)) { Damage damage; _x_error_occurred = 0; win = XCreateWindow(dpy, root, 0, 0, mode->width, mode->height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); damage = XDamageCreate(dpy, win, XDamageReportRawRectangles); XMapWindow(dpy, win); XSync(dpy, True); if (!_x_error_occurred) run(dpy, win, "composited", options); XDamageDestroy(dpy, damage); XDestroyWindow(dpy, win); XSync(dpy, True); } win = XCreateWindow(dpy, root, 0, 0, mode->width/2, mode->height/2, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); run(dpy, win, "half", options); XDestroyWindow(dpy, win); XSync(dpy, True); siblings(mode->width, mode->height, sysconf(_SC_NPROCESSORS_ONLN), options); XRRSetCrtcConfig(dpy, res, output->crtcs[c], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); } XRRFreeOutputInfo(output); } } int main(void) { Display *dpy; XRRScreenResources *res; XRRCrtcInfo **original_crtc; int i; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (!has_present(dpy)) return 77; if (DPMSQueryExtension(dpy, &i, &i)) DPMSDisable(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); res = NULL; if (XRRQueryVersion(dpy, &i, &i)) res = _XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy)); if (res == NULL) return 77; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); printf("noutput=%d, ncrtc=%d\n", res->noutput, res->ncrtc); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); loop(dpy, res, 0); if (has_xfixes(dpy)) loop(dpy, res, NOCOPY); if (has_dri3(dpy)) loop(dpy, res, DRI3); for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); if (DPMSQueryExtension(dpy, &i, &i)) DPMSEnable(dpy); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/present-test.c000066400000000000000000001466651267532330400240750ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dri3.h" #define ALIGN(x, y) (((x) + (y) - 1) & -(y)) #define PAGE_ALIGN(x) ALIGN(x, 4096) #define GTT I915_GEM_DOMAIN_GTT #define CPU I915_GEM_DOMAIN_CPU static int _x_error_occurred; static uint32_t stamp; static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } static int is_i915_device(int fd) { drm_version_t version; char name[5] = ""; memset(&version, 0, sizeof(version)); version.name_len = 4; version.name = name; if (drmIoctl(fd, DRM_IOCTL_VERSION, &version)) return 0; return strcmp("i915", name) == 0; } static int is_intel(int fd) { struct drm_i915_getparam gp; int ret; /* Confirm that this is a i915.ko device with GEM/KMS enabled */ ret = is_i915_device(fd); if (ret) { gp.param = I915_PARAM_HAS_GEM; gp.value = &ret; if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp)) ret = 0; } return ret; } static void *setup_msc(Display *dpy, Window win) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_void_cookie_t cookie; uint32_t id = xcb_generate_id(c); xcb_generic_error_t *error; void *q; cookie = xcb_present_select_input_checked(c, id, win, XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY); q = xcb_register_for_special_xge(c, &xcb_present_id, id, &stamp); error = xcb_request_check(c, cookie); assert(error == NULL); return q; } static uint64_t check_msc(Display *dpy, Window win, void *q, uint64_t last_msc, uint64_t *ust) { xcb_connection_t *c = XGetXCBConnection(dpy); static uint32_t serial = 1; uint64_t msc = 0; int complete = 0; xcb_present_notify_msc(c, win, serial ^ 0xcc00ffee, 0, 0, 0); xcb_flush(c); do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC && ce->serial == (serial ^ 0xcc00ffee)) { msc = ce->msc; if (ust) *ust = ce->ust; complete = 1; } free(ev); } while (!complete); if ((int64_t)(msc - last_msc) < 0) { printf("Invalid MSC: was %llu, now %llu\n", (long long)last_msc, (long long)msc); } if (++serial == 0) serial = 1; return msc; } static uint64_t wait_vblank(Display *dpy, Window win, void *q) { xcb_connection_t *c = XGetXCBConnection(dpy); static uint32_t serial = 1; uint64_t msc = 0; int complete = 0; xcb_present_notify_msc(c, win, serial ^ 0xdeadbeef, 0, 1, 0); xcb_flush(c); do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC && ce->serial == (serial ^ 0xdeadbeef)) { msc = ce->msc; complete = 1; } free(ev); } while (!complete); if (++serial == 0) serial = 1; return msc; } static uint64_t msc_interval(Display *dpy, Window win, void *q) { xcb_connection_t *c = XGetXCBConnection(dpy); uint64_t msc, ust; int complete = 0; msc = check_msc(dpy, win, q, 0, NULL); xcb_present_notify_msc(c, win, 0xc0ffee00, msc, 0, 0); xcb_present_notify_msc(c, win, 0xc0ffee01, msc + 10, 0, 0); xcb_flush(c); ust = msc = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC && ce->serial == 0xc0ffee00) { msc -= ce->msc; ust -= ce->ust; complete++; } if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC && ce->serial == 0xc0ffee01) { msc += ce->msc; ust += ce->ust; complete++; } free(ev); } while (complete != 2); printf("10 frame interval: msc=%lld, ust=%lld\n", (long long)msc, (long long)ust); XSync(dpy, True); if (msc == 0) return 0; return (ust + msc/2) / msc; } static void teardown_msc(Display *dpy, void *q) { xcb_unregister_for_special_event(XGetXCBConnection(dpy), q); } static int test_whole(Display *dpy, Window win, const char *phase) { xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; struct dri3_fence fence; Window root; unsigned int width, height; unsigned border, depth; int x, y, ret = 1; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); if (dri3_create_fence(dpy, win, &fence)) return 0; printf("%s: Testing simple flip: %dx%d\n", phase, width, height); _x_error_occurred = 0; xshmfence_reset(fence.addr); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ fence.xid, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); pixmap = XCreatePixmap(dpy, win, width, height, depth); xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, /* sync fence */ XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XFlush(dpy); ret = !!xshmfence_await(fence.addr); dri3_fence_free(dpy, &fence); XSync(dpy, True); ret += !!_x_error_occurred; return ret; } static uint64_t flush_flips(Display *dpy, Window win, Pixmap pixmap, void *Q, uint64_t *ust) { xcb_connection_t *c = XGetXCBConnection(dpy); uint64_t msc; int complete; msc = check_msc(dpy, win, Q, 0, NULL); xcb_present_pixmap(c, win, pixmap, 0xdeadbeef, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, msc + 60, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); complete = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; complete = (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP && ce->serial == 0xdeadbeef); free(ev); } while (!complete); XSync(dpy, True); return check_msc(dpy, win, Q, msc, ust); } static int test_double(Display *dpy, Window win, const char *phase, void *Q) { #define COUNT (15*60) xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; Window root; unsigned int width, height; unsigned border, depth; int x, y, n, ret; struct { uint64_t msc, ust; } frame[COUNT+1]; int offset = 0; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); printf("%s: Testing flip double buffering: %dx%d\n", phase, width, height); _x_error_occurred = 0; pixmap = XCreatePixmap(dpy, win, width, height, depth); flush_flips(dpy, win, pixmap, Q, NULL); for (n = 0; n <= COUNT; n++) { int complete; xcb_present_pixmap(c, win, pixmap, n, 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); complete = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP && ce->serial == n) { frame[n].msc = ce->msc; frame[n].ust = ce->ust; complete = 1; } free(ev); } while (!complete); } XFreePixmap(dpy, pixmap); XSync(dpy, True); ret = !!_x_error_occurred; if (frame[COUNT].msc - frame[0].msc != COUNT) { printf("Expected %d frames interval, %d elapsed instead\n", COUNT, (int)(frame[COUNT].msc - frame[0].msc)); for (n = 0; n <= COUNT; n++) { if (frame[n].msc - frame[0].msc != n + offset) { printf("frame[%d]: msc=%03lld, ust=%lld\n", n, (long long)(frame[n].msc - frame[0].msc), (long long)(frame[n].ust - frame[0].ust)); offset = frame[n].msc - frame[0].msc - n; ret++; } } } return ret; } static int test_future(Display *dpy, Window win, const char *phase, void *Q) { xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; struct dri3_fence fence; Window root; unsigned int width, height; unsigned border, depth; int x, y, ret = 0, n; uint64_t msc, ust; int complete, count; int early = 0, late = 0; int earliest = 0, latest = 0; uint64_t interval; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); if (dri3_create_fence(dpy, win, &fence)) return 0; printf("%s: Testing flips into the future: %dx%d\n", phase, width, height); _x_error_occurred = 0; interval = msc_interval(dpy, win, Q); if (interval == 0) { printf("Zero delay between frames\n"); return 1; } pixmap = XCreatePixmap(dpy, win, width, height, depth); msc = flush_flips(dpy, win, pixmap, Q, &ust); for (n = 1; n <= 10; n++) xcb_present_pixmap(c, win, pixmap, n, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, msc + 60 + n*15*60, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_present_pixmap(c, win, pixmap, 0xdeadbeef, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, msc + 60 + n*15*60, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); complete = 0; count = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP); if (ce->serial == 0xdeadbeef) { int64_t time; time = ce->ust - (ust + (60 + 15*60*n) * interval); if (time < -(int64_t)interval) { fprintf(stderr, "\tflips completed too early by %lldms\n", (long long)(-time / 1000)); } else if (time > (int64_t)interval) { fprintf(stderr, "\tflips completed too late by %lldms\n", (long long)(time / 1000)); } complete = 1; } else { int diff = (int64_t)(ce->msc - (15*60*ce->serial + msc + 60)); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tframe %d displayed early by %d frames\n", ce->serial, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tframe %d displayed late by %d frames\n", ce->serial, diff); latest = diff; } late++; ret++; } count++; } free(ev); } while (!complete); if (early) printf("\t%d frames shown too early (worst %d)!\n", early, earliest); if (late) printf("\t%d frames shown too late (worst %d)!\n", late, latest); if (count != 10) { fprintf(stderr, "Sentinel frame received too early! %d frames outstanding\n", 10 - count); ret++; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP); free(ev); } while (++count != 10); } ret += !!_x_error_occurred; return ret; } static int test_exhaustion(Display *dpy, Window win, const char *phase, void *Q) { #define N_VBLANKS 256 /* kernel event queue length: 128 vblanks */ xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; struct dri3_fence fence[2]; Window root; xcb_xfixes_region_t region; unsigned int width, height; unsigned border, depth; int x, y, ret = 0, n; uint64_t target, final; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); if (dri3_create_fence(dpy, win, &fence[0]) || dri3_create_fence(dpy, win, &fence[1])) return 0; printf("%s: Testing flips with long vblank queues: %dx%d\n", phase, width, height); _x_error_occurred = 0; region = xcb_generate_id(c); xcb_xfixes_create_region(c, region, 0, NULL); pixmap = XCreatePixmap(dpy, win, width, height, depth); xshmfence_reset(fence[0].addr); xshmfence_reset(fence[1].addr); target = check_msc(dpy, win, Q, 0, NULL); for (n = N_VBLANKS; n--; ) xcb_present_pixmap(c, win, pixmap, 0, 0, /* valid */ region, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, target + N_VBLANKS, /* target msc */ 1, /* divisor */ 0, /* remainder */ 0, NULL); xcb_present_pixmap(c, win, pixmap, 0, region, /* valid */ region, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ fence[0].xid, XCB_PRESENT_OPTION_NONE, target, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); for (n = 1; n < N_VBLANKS; n++) xcb_present_pixmap(c, win, pixmap, 0, region, /* valid */ region, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, target + n, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_present_pixmap(c, win, pixmap, 0, region, /* valid */ region, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ fence[1].xid, XCB_PRESENT_OPTION_NONE, target + N_VBLANKS, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); ret += !!xshmfence_await(fence[0].addr); final = check_msc(dpy, win, Q, 0, NULL); if (final < target) { printf("\tFirst flip too early, MSC was %llu, expected %llu\n", (long long)final, (long long)target); ret++; } else if (final > target + 1) { printf("\tFirst flip too late, MSC was %llu, expected %llu\n", (long long)final, (long long)target); ret++; } ret += !!xshmfence_await(fence[1].addr); final = check_msc(dpy, win, Q, 0, NULL); if (final < target + N_VBLANKS) { printf("\tLast flip too early, MSC was %llu, expected %llu\n", (long long)final, (long long)(target + N_VBLANKS)); ret++; } else if (final > target + N_VBLANKS + 1) { printf("\tLast flip too late, MSC was %llu, expected %llu\n", (long long)final, (long long)(target + N_VBLANKS)); ret++; } flush_flips(dpy, win, pixmap, Q, NULL); XFreePixmap(dpy, pixmap); xcb_xfixes_destroy_region(c, region); dri3_fence_free(dpy, &fence[1]); dri3_fence_free(dpy, &fence[0]); XSync(dpy, True); ret += !!_x_error_occurred; return ret; #undef N_VBLANKS } static int test_accuracy(Display *dpy, Window win, const char *phase, void *Q) { #define N_VBLANKS (60 * 120) /* ~2 minutes */ xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; Window root; unsigned int width, height; unsigned border, depth; int x, y, ret = 0, n; uint64_t target; int early = 0, late = 0; int earliest = 0, latest = 0; int complete, count; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); printf("%s: Testing flip accuracy: %dx%d\n", phase, width, height); _x_error_occurred = 0; pixmap = XCreatePixmap(dpy, win, width, height, depth); target = flush_flips(dpy, win, pixmap, Q, NULL); for (n = 0; n <= N_VBLANKS; n++) xcb_present_pixmap(c, win, pixmap, n, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, target + 60 + n, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_present_pixmap(c, win, pixmap, 0xdeadbeef, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, target + 60 + n, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); complete = 0; count = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP); if (ce->serial != 0xdeadbeef) { int diff = (int64_t)(ce->msc - (target + ce->serial + 60)); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tframe %d displayed early by %d frames\n", ce->serial, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tframe %d displayed late by %d frames\n", ce->serial, diff); latest = diff; } late++; ret++; } count++; } else complete = 1; free(ev); } while (!complete); if (early) printf("\t%d frames shown too early (worst %d)!\n", early, earliest); if (late) printf("\t%d frames shown too late (worst %d)!\n", late, latest); if (count != N_VBLANKS+1) { fprintf(stderr, "Sentinel frame received too early! %d frames outstanding\n", N_VBLANKS+1 - count); ret++; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP); free(ev); } while (++count != N_VBLANKS+1); } XFreePixmap(dpy, pixmap); XSync(dpy, True); ret += !!_x_error_occurred; return ret; #undef N_VBLANKS } static int test_modulus(Display *dpy, Window win, const char *phase, void *Q) { xcb_connection_t *c = XGetXCBConnection(dpy); Pixmap pixmap; Window root; unsigned int width, height; unsigned border, depth; xcb_xfixes_region_t region; int x, y, ret = 0; uint64_t target; int early = 0, late = 0; int earliest = 0, latest = 0; int complete, expect, count; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); printf("%s: Testing flip modulus: %dx%d\n", phase, width, height); _x_error_occurred = 0; region = xcb_generate_id(c); xcb_xfixes_create_region(c, region, 0, NULL); pixmap = XCreatePixmap(dpy, win, width, height, depth); target = flush_flips(dpy, win, pixmap, Q, NULL); expect = 0; for (x = 1; x <= 7; x++) { for (y = 0; y < x; y++) { xcb_present_pixmap(c, win, pixmap, y << 16 | x, /* serial */ region, /* valid */ region, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ x, /* divisor */ y, /* remainder */ 0, NULL); expect++; } } xcb_present_pixmap(c, win, pixmap, 0xdeadbeef, /* serial */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, target + 2*x, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); xcb_flush(c); complete = 0; count = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; if (ce->kind != XCB_PRESENT_COMPLETE_KIND_PIXMAP) break; assert(ce->serial); if (ce->serial != 0xdeadbeef) { uint64_t msc; int diff; x = ce->serial & 0xffff; y = ce->serial >> 16; msc = target; msc -= target % x; msc += y; if (msc <= target) msc += x; diff = (int64_t)(ce->msc - msc); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tframe (%d, %d) displayed early by %d frames\n", y, x, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tframe (%d, %d) displayed late by %d frames\n", y, x, diff); latest = diff; } late++; ret++; } count++; } else complete = 1; free(ev); } while (!complete); if (early) printf("\t%d frames shown too early (worst %d)!\n", early, earliest); if (late) printf("\t%d frames shown too late (worst %d)!\n", late, latest); if (count != expect) { fprintf(stderr, "Sentinel frame received too early! %d frames outstanding\n", expect - count); ret++; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); free(ev); } while (++count != expect); } XFreePixmap(dpy, pixmap); xcb_xfixes_destroy_region(c, region); XSync(dpy, True); ret += !!_x_error_occurred; return ret; } static int test_future_msc(Display *dpy, void *Q) { xcb_connection_t *c = XGetXCBConnection(dpy); Window root = DefaultRootWindow(dpy); int ret = 0, n; uint64_t msc, ust; int complete, count; int early = 0, late = 0; int earliest = 0, latest = 0; uint64_t interval; printf("Testing notifies into the future\n"); _x_error_occurred = 0; interval = msc_interval(dpy, root, Q); if (interval == 0) { printf("Zero delay between frames\n"); return 1; } msc = check_msc(dpy, root, Q, 0, &ust); printf("Initial msc=%llx, interval between frames %lldus\n", (long long)msc, (long long)interval); for (n = 1; n <= 10; n++) xcb_present_notify_msc(c, root, n, msc + 60 + n*15*60, 0, 0); xcb_present_notify_msc(c, root, 0xdeadbeef, msc + 60 + n*15*60, 0, 0); xcb_flush(c); complete = 0; count = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); if (ce->serial == 0xdeadbeef) { int64_t time, tolerance; tolerance = 60 + 15*60*n/10; if (tolerance < interval) tolerance = interval; time = ce->ust - (ust + (60 + 15*60*n) * interval); if (time < -(int64_t)tolerance) { fprintf(stderr, "\tnotifies completed too early by %lldms, tolerance %lldus\n", (long long)(-time / 1000), (long long)tolerance); } else if (time > (int64_t)tolerance) { fprintf(stderr, "\tnotifies completed too late by %lldms, tolerance %lldus\n", (long long)(time / 1000), (long long)tolerance); } complete = 1; } else { int diff = (int64_t)(ce->msc - (15*60*ce->serial + msc + 60)); if (ce->serial != count + 1) { fprintf(stderr, "vblank received out of order! expected %d, received %d\n", count + 1, (int)ce->serial); ret++; } count++; if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tnotify %d early by %d msc\n", ce->serial, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tnotify %d late by %d msc\n", ce->serial, diff); latest = diff; } late++; ret++; } } free(ev); } while (!complete); if (early) printf("\t%d notifies too early (worst %d)!\n", early, earliest); if (late) printf("\t%d notifies too late (worst %d)!\n", late, latest); if (count != 10) { fprintf(stderr, "Sentinel vblank received too early! %d waits outstanding\n", 10 - count); ret++; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); free(ev); } while (++count != 10); } XSync(dpy, True); ret += !!_x_error_occurred; return ret; } static int test_wrap_msc(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); Window root, win; int x, y; unsigned int width, height; unsigned border, depth; XSetWindowAttributes attr; int ret = 0, n; uint64_t msc, ust; int complete; uint64_t interval; void *Q; XGetGeometry(dpy, DefaultRootWindow(dpy), &root, &x, &y, &width, &height, &border, &depth); attr.override_redirect = 1; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy, win); XSync(dpy, True); if (_x_error_occurred) return 1; printf("Testing wraparound notifies\n"); _x_error_occurred = 0; Q = setup_msc(dpy, win); interval = msc_interval(dpy, win, Q); if (interval == 0) { printf("Zero delay between frames\n"); return 1; } msc = check_msc(dpy, win, Q, 0, &ust); printf("Initial msc=%llx, interval between frames %lldus\n", (long long)msc, (long long)interval); for (n = 1; n <= 10; n++) xcb_present_notify_msc(c, win, n, msc + ((long long)n<<32) + n, 0, 0); for (n = 1; n <= 10; n++) xcb_present_notify_msc(c, win, -n, 0, (long long)n << 32, 0); xcb_present_notify_msc(c, win, 0xdeadbeef, msc + 60*10, 0, 0); xcb_flush(c); complete = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); if (ce->serial == 0xdeadbeef) { complete = 1; } else { fprintf(stderr, "\tnotify %d recieved at +%llu\n", ce->serial, ce->msc - msc); ret++; } free(ev); } while (!complete); teardown_msc(dpy, Q); XDestroyWindow(dpy, win); XSync(dpy, True); return ret; } static int test_exhaustion_msc(Display *dpy, void *Q) { #define N_VBLANKS 256 /* kernel event queue length: 128 vblanks */ xcb_connection_t *c = XGetXCBConnection(dpy); Window root = DefaultRootWindow(dpy); int ret = 0, n, complete; int earliest = 0, early = 0; int latest = 0, late = 0; uint64_t msc; printf("Testing notifies with long queues\n"); _x_error_occurred = 0; msc = check_msc(dpy, root, Q, 0, NULL); for (n = N_VBLANKS; n--; ) xcb_present_notify_msc(c, root, N_VBLANKS, msc + N_VBLANKS, 0, 0); for (n = 1; n <= N_VBLANKS ; n++) xcb_present_notify_msc(c, root, n, msc + n, 0, 0); xcb_flush(c); complete = 2*N_VBLANKS; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; int diff; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); diff = (int64_t)(ce->msc - msc - ce->serial); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tnotify %d early by %d msc\n",(int)ce->serial, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tnotify %d late by %d msc\n", (int)ce->serial, diff); latest = diff; } late++; ret++; } free(ev); } while (--complete); if (early) printf("\t%d notifies too early (worst %d)!\n", early, earliest); if (late) printf("\t%d notifies too late (worst %d)!\n", late, latest); XSync(dpy, True); ret += !!_x_error_occurred; return ret; #undef N_VBLANKS } static int test_accuracy_msc(Display *dpy, void *Q) { #define N_VBLANKS (60 * 120) /* ~2 minutes */ xcb_connection_t *c = XGetXCBConnection(dpy); Window root = DefaultRootWindow(dpy); int ret = 0, n; uint64_t msc; int early = 0, late = 0; int earliest = 0, latest = 0; int complete, count; printf("Testing notify accuracy\n"); _x_error_occurred = 0; msc = check_msc(dpy, root, Q, 0, NULL); for (n = 0; n <= N_VBLANKS; n++) xcb_present_notify_msc(c, root, n, msc + 60 + n, 0, 0); xcb_present_notify_msc(c, root, 0xdeadbeef, msc + 60 + n, 0, 0); xcb_flush(c); complete = 0; count = 0; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); if (ce->serial != 0xdeadbeef) { int diff = (int64_t)(ce->msc - (msc + ce->serial + 60)); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tnotify %d early by %d msc\n", ce->serial, -diff); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tnotify %d late by %d msc\n", ce->serial, diff); latest = diff; } late++; ret++; } count++; } else complete = 1; free(ev); } while (!complete); if (early) printf("\t%d notifies too early (worst %d)!\n", early, earliest); if (late) printf("\t%d notifies too late (worst %d)!\n", late, latest); if (count != N_VBLANKS+1) { fprintf(stderr, "Sentinel vblank received too early! %d waits outstanding\n", N_VBLANKS+1 - count); ret++; do { xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); free(ev); } while (++count != N_VBLANKS+1); } XSync(dpy, True); ret += !!_x_error_occurred; return ret; #undef N_VBLANKS } static int test_modulus_msc(Display *dpy, void *Q) { xcb_connection_t *c = XGetXCBConnection(dpy); Window root = DefaultRootWindow(dpy); xcb_present_complete_notify_event_t *ce; xcb_generic_event_t *ev; int x, y, ret = 0; uint64_t target; int early = 0, late = 0; int earliest = 0, latest = 0; int complete, count, expect; printf("Testing notify modulus\n"); _x_error_occurred = 0; target = wait_vblank(dpy, root, Q); expect = 0; xcb_present_notify_msc(c, root, 0, 0, 0, 0); for (x = 1; x <= 19; x++) { for (y = 0; y < x; y++) { xcb_present_notify_msc(c, root, y << 16 | x, 0, x, y); expect++; } } xcb_present_notify_msc(c, root, 0xdeadbeef, target + 2*x, 0, 0); xcb_flush(c); ev = xcb_wait_for_special_event(c, Q); if (ev) { ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); assert(ce->serial == 0); assert(target == ce->msc); target = ce->msc; } complete = 0; count = 0; do { ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); assert(ce->serial); if (ce->serial != 0xdeadbeef) { uint64_t msc; int diff; x = ce->serial & 0xffff; y = ce->serial >> 16; msc = target; msc -= target % x; msc += y; if (msc <= target) msc += x; diff = (int64_t)(ce->msc - msc); if (diff < 0) { if (-diff > earliest) { fprintf(stderr, "\tnotify (%d, %d) early by %d msc (target %lld, reported %lld)\n", y, x, -diff, (long long)msc, (long long)ce->msc); earliest = -diff; } early++; ret++; } else if (diff > 0) { if (diff > latest) { fprintf(stderr, "\tnotify (%d, %d) late by %d msc (target %lld, reported %lld)\n", y, x, diff, (long long)msc, (long long)ce->msc); latest = diff; } late++; ret++; } count++; } else complete = 1; free(ev); } while (!complete); if (early) printf("\t%d notifies too early (worst %d)!\n", early, earliest); if (late) printf("\t%d notifies too late (worst %d)!\n", late, latest); if (count != expect) { fprintf(stderr, "Sentinel vblank received too early! %d waits outstanding\n", expect - count); ret++; do { ev = xcb_wait_for_special_event(c, Q); if (ev == NULL) break; ce = (xcb_present_complete_notify_event_t *)ev; assert(ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC); free(ev); } while (++count != expect); } XSync(dpy, True); ret += !!_x_error_occurred; return ret; } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static int for_each_crtc(Display *dpy, int (*func)(Display *dpy, RRCrtc crtc, int width, int height, void *closure), void *closure) { XRRScreenResources *res; XRRCrtcInfo **original_crtc; int i, j, err = 0; if (!XRRQueryVersion(dpy, &i, &j)) return -1; res = _XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy)); if (res == NULL) return -1; original_crtc = malloc(sizeof(XRRCrtcInfo *)*res->ncrtc); for (i = 0; i < res->ncrtc; i++) original_crtc[i] = XRRGetCrtcInfo(dpy, res, res->crtcs[i]); for (i = 0; i < res->noutput; i++) { XRROutputInfo *output; XRRModeInfo *mode; output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; mode = NULL; if (res->nmode) mode = lookup_mode(res, output->modes[0]); for (j = 0; mode && j < output->ncrtc; j++) { printf("[%d, %d] -- OUTPUT:%ld, CRTC:%ld\n", i, j, (long)res->outputs[i], (long)output->crtcs[j]); XRRSetCrtcConfig(dpy, res, output->crtcs[j], CurrentTime, 0, 0, output->modes[0], RR_Rotate_0, &res->outputs[i], 1); XSync(dpy, True); err += func(dpy, output->crtcs[j], mode->width, mode->height, closure); XRRSetCrtcConfig(dpy, res, output->crtcs[j], CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0); XSync(dpy, True); } XRRFreeOutputInfo(output); } for (i = 0; i < res->ncrtc; i++) XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime, original_crtc[i]->x, original_crtc[i]->y, original_crtc[i]->mode, original_crtc[i]->rotation, original_crtc[i]->outputs, original_crtc[i]->noutput); free(original_crtc); XRRFreeScreenResources(res); return err; } struct test_crtc { Window win; int depth; unsigned flags; struct dri3_fence fence; void *queue; uint64_t msc; }; #define SYNC 0x1 #define FUTURE 0x2 static int __test_crtc(Display *dpy, RRCrtc crtc, int width, int height, void *closure) { struct test_crtc *test = closure; Pixmap pixmap; int err = 0; test->msc = check_msc(dpy, test->win, test->queue, test->msc, NULL); if (test->flags & SYNC) xshmfence_reset(test->fence.addr); pixmap = XCreatePixmap(dpy, test->win, width, height, test->depth); xcb_present_pixmap(XGetXCBConnection(dpy), test->win, pixmap, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ crtc, None, /* wait fence */ test->flags & SYNC ? test->fence.xid : None, XCB_PRESENT_OPTION_NONE, test->msc, /* target msc */ 1, /* divisor */ 0, /* remainder */ 0, NULL); if (test->flags & SYNC) { Pixmap tmp = XCreatePixmap(dpy, test->win, width, height, test->depth); xcb_present_pixmap(XGetXCBConnection(dpy), test->win, tmp, 1, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ crtc, None, /* wait fence */ None, /* sync fence */ XCB_PRESENT_OPTION_NONE, test->msc + (test->flags & FUTURE ? 5 * 16 : 1), /* target msc */ 1, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, tmp); XFlush(dpy); err += !!xshmfence_await(test->fence.addr); } XFreePixmap(dpy, pixmap); test->msc = check_msc(dpy, test->win, test->queue, test->msc, NULL); return err; } static int test_crtc(Display *dpy, void *queue, uint64_t last_msc) { struct test_crtc test; int err = 0; XSync(dpy, True); _x_error_occurred = 0; test.win = DefaultRootWindow(dpy); test.depth = DefaultDepth(dpy, DefaultScreen(dpy)); if (dri3_create_fence(dpy, test.win, &test.fence)) return -1; test.queue = queue; test.msc = last_msc; printf("Testing each crtc, without waiting for each flip\n"); test.flags = 0; test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); err += for_each_crtc(dpy, __test_crtc, &test); test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); printf("Testing each crtc, waiting for flips to complete\n"); test.flags = SYNC; test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); err += for_each_crtc(dpy, __test_crtc, &test); test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); printf("Testing each crtc, with future flips\n"); test.flags = FUTURE | SYNC; test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); err += for_each_crtc(dpy, __test_crtc, &test); test.msc = check_msc(dpy, test.win, test.queue, test.msc, NULL); dri3_fence_free(dpy, &test.fence); XSync(dpy, True); err += !!_x_error_occurred; if (err) printf("%s: failures=%d\n", __func__, err); return err; } static int can_use_shm(Display *dpy) { int major, minor, has_pixmap; if (!XShmQueryExtension(dpy)) return 0; XShmQueryVersion(dpy, &major, &minor, &has_pixmap); return has_pixmap; } static int test_shm(Display *dpy) { Window win = DefaultRootWindow(dpy); XShmSegmentInfo shm; Pixmap pixmap; Window root; unsigned int width, height; unsigned border, depth; int x, y, ret = 1; if (!can_use_shm(dpy)) return 0; _x_error_occurred = 0; XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); printf("Using %dx%d SHM\n", width, height); shm.shmid = shmget(IPC_PRIVATE, height * 4*width, IPC_CREAT | 0666); if (shm.shmid == -1) return 0; shm.shmaddr = shmat(shm.shmid, 0, 0); if (shm.shmaddr == (char *) -1) goto rmid; shm.readOnly = False; XShmAttach(dpy, &shm); pixmap = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), shm.shmaddr, &shm, width, height, 24); if (_x_error_occurred) goto detach; xcb_present_pixmap(XGetXCBConnection(dpy), win, pixmap, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XSync(dpy, True); if (_x_error_occurred) goto detach; ret = 0; detach: XShmDetach(dpy, &shm); shmdt(shm.shmaddr); XSync(dpy, False); rmid: shmctl(shm.shmid, IPC_RMID, NULL); return ret; } static uint32_t gem_create(int fd, int size) { struct drm_i915_gem_create create; create.handle = 0; create.size = size; (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); return create.handle; } struct local_i915_gem_caching { uint32_t handle; uint32_t caching; }; #define LOCAL_I915_GEM_SET_CACHING 0x2f #define LOCAL_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + LOCAL_I915_GEM_SET_CACHING, struct local_i915_gem_caching) static int gem_set_caching(int fd, uint32_t handle, int caching) { struct local_i915_gem_caching arg; arg.handle = handle; arg.caching = caching; return drmIoctl(fd, LOCAL_IOCTL_I915_GEM_SET_CACHING, &arg) == 0; } static int gem_set_tiling(int fd, uint32_t handle, int tiling, int stride) { struct drm_i915_gem_set_tiling set_tiling; int err; restart: set_tiling.handle = handle; set_tiling.tiling_mode = tiling; set_tiling.stride = stride; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling) == 0) return 1; err = errno; if (err == EINTR) goto restart; if (err == EAGAIN) { sched_yield(); goto restart; } return 0; } static int gem_export(int fd, uint32_t handle) { struct drm_prime_handle args; args.handle = handle; args.flags = O_CLOEXEC; if (drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args)) return -1; return args.fd; } static void gem_close(int fd, uint32_t handle) { struct drm_gem_close close; close.handle = handle; (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close); } static int test_dri3_tiling(Display *dpy) { Window win = DefaultRootWindow(dpy); const int tiling[] = { I915_TILING_NONE, I915_TILING_X, I915_TILING_Y }; Window root; unsigned int width, height; unsigned border, depth, bpp; unsigned stride, size; void *Q; int x, y; int device; int line = -1; int t; device = dri3_open(dpy); if (device < 0) return 0; if (!is_intel(device)) return 0; printf("Opened Intel DRI3 device\n"); XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); switch (depth) { case 8: bpp = 8; break; case 15: case 16: bpp = 16; break; case 24: case 32: bpp = 32; break; default: return 0; } stride = ALIGN(width * bpp/8, 512); size = PAGE_ALIGN(stride * ALIGN(height, 32)); printf("Creating DRI3 %dx%d (source stride=%d, size=%d) for GTT\n", width, height, stride, size); _x_error_occurred = 0; Q = setup_msc(dpy, root); for (t = 0; t < sizeof(tiling)/sizeof(tiling[0]); t++) { uint64_t msc; uint32_t src; int src_fd; Pixmap src_pix; src = gem_create(device, size); if (!src) { line = __LINE__; goto fail; } gem_set_tiling(device, src, tiling[t], stride); src_fd = gem_export(device, src); if (src_fd < 0) { line = __LINE__; goto fail; } src_pix = dri3_create_pixmap(dpy, root, width, height, depth, src_fd, bpp, stride, size); msc = wait_vblank(dpy, root, Q); xcb_present_pixmap(XGetXCBConnection(dpy), win, src_pix, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, msc + 2, /* target msc */ 1, /* divisor */ 0, /* remainder */ 0, NULL); xcb_present_pixmap(XGetXCBConnection(dpy), win, src_pix, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, msc + 3, /* target msc */ 1, /* divisor */ 0, /* remainder */ 0, NULL); XSync(dpy, True); if (_x_error_occurred) { line = __LINE__; goto fail; } XFreePixmap(dpy, src_pix); _x_error_occurred = 0; close(src_fd); gem_close(device, src); } teardown_msc(dpy, Q); return 0; fail: printf("%s failed with tiling %d, line %d\n", __func__, tiling[t], line); teardown_msc(dpy, Q); return 1; } static int test_dri3(Display *dpy) { Window win = DefaultRootWindow(dpy); Pixmap pixmap; Window root; unsigned int width, height; unsigned border, depth; unsigned stride, size; int x, y, ret = 1; int device, handle; int bpp; device = dri3_open(dpy); if (device < 0) return 0; if (!is_intel(device)) return 0; printf("Opened Intel DRI3 device\n"); XGetGeometry(dpy, win, &root, &x, &y, &width, &height, &border, &depth); switch (depth) { case 8: bpp = 8; break; case 15: case 16: bpp = 16; break; case 24: case 32: bpp = 32; break; default: return 0; } stride = width * bpp/8; size = PAGE_ALIGN(stride * height); printf("Creating DRI3 %dx%d (source stride=%d, size=%d) for GTT\n", width, height, stride, size); pixmap = 0; handle = gem_create(device, size); if (handle) { pixmap = dri3_create_pixmap(dpy, root, width, height, depth, gem_export(device, handle), bpp, stride, size); gem_close(device, handle); } if (pixmap == 0) goto fail; xcb_present_pixmap(XGetXCBConnection(dpy), win, pixmap, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XSync(dpy, True); if (_x_error_occurred) goto fail; printf("Creating DRI3 %dx%d (source stride=%d, size=%d) for CPU\n", width, height, stride, size); pixmap = 0; handle = gem_create(device, size); if (handle) { gem_set_caching(device, handle, CPU); handle = dri3_create_pixmap(dpy, root, width, height, depth, gem_export(device, handle), bpp, stride, size); gem_close(device, handle); } if (pixmap == 0) goto fail; xcb_present_pixmap(XGetXCBConnection(dpy), win, pixmap, 0, /* sbc */ 0, /* valid */ 0, /* update */ 0, /* x_off */ 0, /* y_off */ None, None, /* wait fence */ None, XCB_PRESENT_OPTION_NONE, 0, /* target msc */ 0, /* divisor */ 0, /* remainder */ 0, NULL); XFreePixmap(dpy, pixmap); XSync(dpy, True); if (_x_error_occurred) goto fail; ret = 0; fail: close(device); return ret; } static int has_present(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_generic_error_t *error = NULL; void *reply; reply = xcb_xfixes_query_version_reply(c, xcb_xfixes_query_version(c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "XFixes not supported on %s\n", DisplayString(dpy)); return 0; } reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "DRI3 not supported on %s\n", DisplayString(dpy)); return 0; } reply = xcb_present_query_version_reply(c, xcb_present_query_version(c, XCB_PRESENT_MAJOR_VERSION, XCB_PRESENT_MINOR_VERSION), &error); free(reply); free(error); if (reply == NULL) { fprintf(stderr, "Present not supported on %s\n", DisplayString(dpy)); return 0; } return 1; } static int has_composite(Display *dpy) { int event, error; int major, minor; if (!XCompositeQueryExtension(dpy, &event, &error)) return 0; XCompositeQueryVersion(dpy, &major, &minor); return major > 0 || minor >= 4; } int main(void) { Display *dpy; Window root; int dummy; int error = 0; uint64_t last_msc; void *queue; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (!has_present(dpy)) return 77; if (DPMSQueryExtension(dpy, &dummy, &dummy)) DPMSDisable(dpy); root = DefaultRootWindow(dpy); signal(SIGALRM, SIG_IGN); XSetErrorHandler(_check_error_handler); queue = setup_msc(dpy, root); last_msc = check_msc(dpy, root, queue, 0, NULL); error += test_future_msc(dpy, queue); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_wrap_msc(dpy); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_accuracy_msc(dpy, queue); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_modulus_msc(dpy, queue); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_exhaustion_msc(dpy, queue); last_msc = check_msc(dpy, root, queue, last_msc, NULL); for (dummy = 0; dummy <= 3; dummy++) { Window win; uint64_t msc = 0; XSetWindowAttributes attr; Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy)); unsigned int width, height; unsigned border, depth; const char *phase; int x, y; void *Q; attr.override_redirect = 1; XGetGeometry(dpy, root, &win, &x, &y, &width, &height, &border, &depth); _x_error_occurred = 0; switch (dummy) { case 0: win = root; phase = "root"; break; case 1: win = XCreateWindow(dpy, root, 0, 0, width, height, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "fullscreen"; break; case 2: win = XCreateWindow(dpy, root, 0, 0, width/2, height/2, 0, depth, InputOutput, visual, CWOverrideRedirect, &attr); phase = "window"; break; case 3: if (!has_composite(dpy)) continue; win = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)), CWOverrideRedirect, &attr); XCompositeRedirectWindow(dpy, win, CompositeRedirectManual); phase = "composite"; break; default: phase = "broken"; win = root; abort(); break; } XMapWindow(dpy, win); XSync(dpy, True); if (_x_error_occurred) continue; Q = setup_msc(dpy, win); msc = check_msc(dpy, win, Q, msc, NULL); error += test_whole(dpy, win, phase); msc = check_msc(dpy, win, Q, msc, NULL); error += test_double(dpy, win, phase, Q); msc = check_msc(dpy, win, Q, msc, NULL); error += test_future(dpy, win, phase, Q); msc = check_msc(dpy, win, Q, msc, NULL); error += test_accuracy(dpy, win, phase, Q); msc = check_msc(dpy, win, Q, msc, NULL); error += test_modulus(dpy, win, phase, Q); msc = check_msc(dpy, win, Q, msc, NULL); error += test_exhaustion(dpy, win, phase, Q); msc = check_msc(dpy, win, Q, msc, NULL); teardown_msc(dpy, Q); if (win != root) XDestroyWindow(dpy, win); } error += test_crtc(dpy, queue, last_msc); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_shm(dpy); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_dri3(dpy); last_msc = check_msc(dpy, root, queue, last_msc, NULL); error += test_dri3_tiling(dpy); last_msc = check_msc(dpy, root, queue, last_msc, NULL); teardown_msc(dpy, queue); if (DPMSQueryExtension(dpy, &dummy, &dummy)) DPMSEnable(dpy); return !!error; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-composite-solid-mask.c000066400000000000000000000060261267532330400267420ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static void fill_rect(struct test_display *dpy, Picture p, uint8_t op, int x, int y, int w, int h, uint8_t s_red, uint8_t s_green, uint8_t s_blue, uint8_t s_alpha, uint8_t m_red, uint8_t m_green, uint8_t m_blue, uint8_t m_alpha) { XRenderColor render_color; Picture source, mask; render_color.red = s_red * s_alpha; render_color.green = s_green * s_alpha; render_color.blue = s_blue * s_alpha; render_color.alpha = s_alpha << 8 | s_alpha; source = XRenderCreateSolidFill(dpy->dpy, &render_color); render_color.red = m_red * m_alpha; render_color.green = m_green * m_alpha; render_color.blue = m_blue * m_alpha; render_color.alpha = m_alpha << 8 | m_alpha; mask = XRenderCreateSolidFill(dpy->dpy, &render_color); XRenderComposite(dpy->dpy, op, source, mask, p, 0, 0, 0, 0, x, y, w,h); XRenderFreePicture(dpy->dpy, mask); XRenderFreePicture(dpy->dpy, source); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void ref_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % out.width; int h = rand() % out.height; int op = ops[rand() % sizeof(ops)]; int s_red = rand() % 0xff; int s_green = rand() % 0xff; int s_blue = rand() % 0xff; int s_alpha = rand() % 0xff; int m_red = rand() % 0xff; int m_green = rand() % 0xff; int m_blue = rand() % 0xff; int m_alpha = rand() % 0xff; fill_rect(&t->out, out.picture, op, x, y, w, h, s_red, s_green, s_blue, s_alpha, m_red, m_green, m_blue, m_alpha); fill_rect(&t->ref, ref.picture, op, x, y, w, h, s_red, s_green, s_blue, s_alpha, m_red, m_green, m_blue, m_alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) ref_tests(&test, reps, sets, t); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-composite-solid.c000066400000000000000000000140671267532330400260150ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static void fill_rect(struct test_display *dpy, Picture p, uint8_t op, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor render_color; Picture solid; render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8 | alpha; solid = XRenderCreateSolidFill(dpy->dpy, &render_color); XRenderComposite(dpy->dpy, op, solid, 0, p, 0, 0, 0, 0, x, y, w,h); XRenderFreePicture(dpy->dpy, solid); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, 1, 1, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, w, h, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % out.width; int h = rand() % out.height; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, out.picture, op, x, y, w, h, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, op, x, y, w, h, red, green, blue, alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-copy-alphaless.c000066400000000000000000000151541267532330400256250ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *t, Picture p, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue) { Drawable tmp; XRenderColor c; Picture src; XRenderPictFormat *format; format = XRenderFindStandardFormat(t->dpy, PictStandardRGB24); tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, format->depth); src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); c.red = (int)red << 8 | red; c.green = (int)green << 8 | green; c.blue = (int)blue << 8 | blue; c.alpha = 0xffff; XRenderFillRectangle(t->dpy, PictOpSrc, src, &c, 0, 0, w, h); XRenderComposite(t->dpy, PictOpOver, src, 0, p, 0, 0, 0, 0, x, y, w, h); XRenderFreePicture(t->dpy, src); XFreePixmap(t->dpy, tmp); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); fill_rect(&t->out, tt.picture, x, y, 1, 1, red, green, blue); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, 0xff); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; uint32_t result; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = 1 + rand() % (tt.width - 1); int h = 1 + rand() % (tt.height - 1); uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, x, y, w, h, red, green, blue); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, 0xff)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *) (image.data + y*image.bytes_per_line + x*image.bits_per_pixel/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead (set %d, reps %d)\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, s, reps, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target out, ref; int r, s; printf("Testing area fills (%s, using %s source): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x, y, w, h; uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); x = rand() % (out.width - 1); y = rand() % (out.height - 1); w = 1 + rand() % (out.width - x - 1); h = 1 + rand() % (out.height - y - 1); fill_rect(&t->out, out.picture, x, y, w, h, red, green, blue); fill_rect(&t->ref, ref.picture, x, y, w, h, red, green, blue); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); pixel_tests(&test, reps, sets, PIXMAP); area_tests(&test, reps, sets, PIXMAP); rect_tests(&test, reps, sets, PIXMAP, 0); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-copyarea-mask.c000066400000000000000000000103161267532330400254300ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include "test.h" static void fill_rect(struct test_display *t, Picture p, XRenderPictFormat *format, int use_window, int tx, int ty, uint8_t op, int x, int y, int w, int h, int mask_x, int mask_y, int mask_w, int mask_h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { Drawable tmp; Pixmap pixmask; XRenderColor c; Picture src, mask; if (use_window) { XSetWindowAttributes attr; attr.override_redirect = 1; tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), tx, ty, w, h, 0, format->depth, InputOutput, DefaultVisual(t->dpy, DefaultScreen(t->dpy)), CWOverrideRedirect, &attr); XMapWindow(t->dpy, tmp); } else tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, format->depth); pixmask = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, 8); mask = XRenderCreatePicture(t->dpy, pixmask, XRenderFindStandardFormat(t->dpy, PictStandardA8), 0, NULL); c.red = c.green = c.blue = c.alpha = 0; XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c, 0, 0, w, h); c.red = c.green = c.blue = c.alpha = 0xffff; XRenderFillRectangle(t->dpy, PictOpSrc, mask, &c, mask_x, mask_y, mask_w, mask_h); src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); c.red = red * alpha; c.green = green * alpha; c.blue = blue * alpha; c.alpha = alpha << 8 | alpha; XRenderFillRectangle(t->dpy, PictOpSrc, src, &c, 0, 0, w, h); XRenderComposite(t->dpy, op, src, mask, p, 0, 0, 0, 0, x, y, w, h); XRenderFreePicture(t->dpy, src); if (use_window) XDestroyWindow(t->dpy, tmp); else XFreePixmap(t->dpy, tmp); XRenderFreePicture(t->dpy, mask); XFreePixmap(t->dpy, pixmask); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target out, ref; int r, s; printf("Testing area fills (%s, using %s source): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x, y, w, h; int mask_x, mask_y, mask_w, mask_h; int tmpx, tmpy; uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); uint8_t alpha = rand(); int try = 50; do { x = rand() % (out.width - 1); y = rand() % (out.height - 1); w = 1 + rand() % (out.width - x - 1); h = 1 + rand() % (out.height - y - 1); tmpx = w == out.width ? 0 : rand() % (out.width - w); tmpy = h == out.height ? 0 : rand() % (out.height - h); } while (((tmpx+w > x && tmpx < x+w) || (tmpy+h > y && tmpy < y+h)) && --try); mask_x = (rand() % (2*w)) - w; mask_y = (rand() % (2*h)) - h; mask_w = rand() % w; mask_h = rand() % h; if (try) { fill_rect(&t->out, out.picture, out.format, use_window, tmpx, tmpy, PictOpSrc, x, y, w, h, mask_x, mask_y, mask_w, mask_h, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, ref.format, use_window, tmpx, tmpy, PictOpSrc, x, y, w, h, mask_x, mask_y, mask_w, mask_h, red, green, blue, alpha); } } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { rect_tests(&test, reps, sets, t, 0); if (t != PIXMAP) rect_tests(&test, reps, sets, t, 1); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-copyarea-size.c000066400000000000000000000051101267532330400254430ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include "test.h" #define SIZE 20000 struct draw { Pixmap a, b; Picture pa, pb; GC gc; XRenderPictFormat *format; }; static void target_init(struct test_display *t, struct draw *tt, int size) { XRenderColor color; tt->format = XRenderFindStandardFormat(t->dpy, PictStandardARGB32); tt->a = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), size, size, tt->format->depth); tt->pa = XRenderCreatePicture(t->dpy, tt->a, tt->format, 0, NULL); color.alpha = 0xffff; color.red = 0xffff; color.green = 0; color.blue = 0; XRenderFillRectangle(t->dpy, PictOpSrc, tt->pa, &color, 0, 0, size, size); tt->b = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), size, size, tt->format->depth); tt->pb = XRenderCreatePicture(t->dpy, tt->b, tt->format, 0, NULL); color.alpha = 0xffff; color.red = 0; color.green = 0; color.blue = 0xffff; XRenderFillRectangle(t->dpy, PictOpSrc, tt->pb, &color, 0, 0, size, size); } static void target_fini(struct test_display *t, struct draw *tt) { XRenderFreePicture(t->dpy, tt->pa); XFreePixmap(t->dpy, tt->a); XRenderFreePicture(t->dpy, tt->pb); XFreePixmap(t->dpy, tt->b); } int main(int argc, char **argv) { struct test test; struct draw out, ref; int size, i; test_init(&test, argc, argv); /* Copy back and forth betwenn two pixmaps, gradually getting larger */ for (size = 1; size <= SIZE; size = (size * 3 + 1) / 2) { target_init(&test.out, &out, size); target_init(&test.ref, &ref, size); printf("size=%d\n", size); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i); do { int sx = rand() % (2*size) - size; int sy = rand() % (2*size) - size; int dx = rand() % (2*size) - size; int dy = rand() % (2*size) - size; int w = rand() % size; int h = rand() % size; int order = rand() & 1; XRenderComposite(test.out.dpy, PictOpSrc, order ? out.pa : out.pb, 0, (!order) ? out.pa : out.pb, sx, sy, 0, 0, dx, dy, w, h); XRenderComposite(test.ref.dpy, PictOpSrc, order ? ref.pa : ref.pb, 0, (!order) ? ref.pa : ref.pb, sx, sy, 0, 0, dx, dy, w, h); } while (--reps); } test_compare(&test, out.a, out.format, ref.a, ref.format, 0, 0, size, size, ""); test_compare(&test, out.b, out.format, ref.b, ref.format, 0, 0, size, size, ""); target_fini(&test.out, &out); target_fini(&test.ref, &ref); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-copyarea.c000066400000000000000000000172631267532330400245070ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *t, Picture p, XRenderPictFormat *format, int use_window, int tx, int ty, uint8_t op, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { Drawable tmp; XRenderColor color; Picture src; if (use_window) { XSetWindowAttributes attr; attr.override_redirect = 1; tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), tx, ty, w, h, 0, format->depth, InputOutput, DefaultVisual(t->dpy, DefaultScreen(t->dpy)), CWOverrideRedirect, &attr); XMapWindow(t->dpy, tmp); } else tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w, h, format->depth); src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); color.red = red * alpha; color.green = green * alpha; color.blue = blue * alpha; color.alpha = alpha << 8 | alpha; XRenderFillRectangle(t->dpy, PictOpSrc, src, &color, 0, 0, w, h); XRenderComposite(t->dpy, op, src, 0, p, 0, 0, 0, 0, x, y, w, h); XRenderFreePicture(t->dpy, src); if (use_window) XDestroyWindow(t->dpy, tmp); else XFreePixmap(t->dpy, tmp); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); uint8_t alpha = rand(); fill_rect(&t->out, tt.picture, tt.format, 0, 0, 0, PictOpSrc, x, y, 1, 1, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; uint32_t result; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = 1 + rand() % (tt.width - 1); int h = 1 + rand() % (tt.height - 1); uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); uint8_t alpha = rand(); x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, tt.format, 0, 0, 0, PictOpSrc, x, y, w, h, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *) (image.data + y*image.bytes_per_line + x*image.bits_per_pixel/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target out, ref; int r, s; printf("Testing area fills (%s, using %s source): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x, y, w, h; int tmpx, tmpy; uint8_t red = rand(); uint8_t green = rand(); uint8_t blue = rand(); uint8_t alpha = rand(); int try = 50; do { x = rand() % (out.width - 1); y = rand() % (out.height - 1); w = 1 + rand() % (out.width - x - 1); h = 1 + rand() % (out.height - y - 1); tmpx = w == out.width ? 0 : rand() % (out.width - w); tmpy = h == out.height ? 0 : rand() % (out.height - h); } while (((tmpx+w > x && tmpx < x+w) || (tmpy+h > y && tmpy < y+h)) && --try); if (try) { fill_rect(&t->out, out.picture, out.format, use_window, tmpx, tmpy, PictOpSrc, x, y, w, h, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, ref.format, use_window, tmpx, tmpy, PictOpSrc, x, y, w, h, red, green, blue, alpha); } } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t, 0); if (t != PIXMAP) rect_tests(&test, reps, sets, t, 1); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-fill-copy.c000066400000000000000000000151721267532330400245770ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static void fill_rect(struct test_display *dpy, Picture p, XRenderPictFormat *format, uint8_t op, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { Display *d = dpy->dpy; XRenderColor render_color; Pixmap pixmap1, pixmap2; Picture tmp1, tmp2; XRenderPictureAttributes pa; GC gc; render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8; pixmap1 = XCreatePixmap(d, dpy->root, 1, 1, format->depth); tmp1 = XRenderCreatePicture(d, pixmap1, format, 0, NULL); pixmap2 = XCreatePixmap(d, dpy->root, 1, 1, format->depth); pa.repeat = 1; tmp2 = XRenderCreatePicture(d, pixmap2, format, CPRepeat, &pa); gc = XCreateGC(d, pixmap1, 0, NULL); XRenderFillRectangle(d, PictOpSrc, tmp1, &render_color, 0, 0, 1,1); XCopyArea(d, pixmap1, pixmap2, gc, 0, 0, 1, 1, 0, 0); XRenderComposite(d, PictOpSrc, tmp2, 0, p, 0, 0, 0, 0, x, y, w,h); XFreeGC(d, gc); XRenderFreePicture(d, tmp2); XFreePixmap(d, pixmap2); XRenderFreePicture(d, tmp1); XFreePixmap(d, pixmap1); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, tt.picture, tt.format, PictOpSrc, x, y, 1, 1, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x, found %08x instead\n", x, y, cells[y*tt.width+x] & mask, result & mask); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, tt.format, PictOpSrc, x, y, w, h, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x, found %08x instead\n", x, y, cells[y*tt.width+x] & mask, result & mask); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % out.width; int h = rand() % out.height; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, out.picture, out.format, op, x, y, w, h, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, ref.format, op, x, y, w, h, red, green, blue, alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-fill.c000066400000000000000000000135751267532330400236340ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static void fill_rect(struct test_display *dpy, Picture p, uint8_t op, int x, int y, int w, int h, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor render_color; render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8; XRenderFillRectangle(dpy->dpy, op, p, &render_color, x, y, w,h); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; test_target_create_render(&t->out, target, &tt); printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, 1, 1, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*tt.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, w, h, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask; if (image.depth == 32) mask = 0xffffffff; else mask = (1 << image.depth) - 1; die("failed to set pixel (%d,%d) to %08x[%08x], found %08x instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % out.width; int h = rand() % out.height; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, out.picture, op, x, y, w, h, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, op, x, y, w, h, red, green, blue, alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } int main(int argc, char **argv) { struct test test; int i; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); enum target t; for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { pixel_tests(&test, reps, sets, t); area_tests(&test, reps, sets, t); rect_tests(&test, reps, sets, t); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-glyphs.c000066400000000000000000000223141267532330400242030ustar00rootroot00000000000000#include #include #include #include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" static const XRenderColor colors[] = { /* red, green, blue, alpha */ { 0 }, { 0, 0, 0, 0xffff }, { 0xffff, 0, 0, 0xffff }, { 0, 0xffff, 0, 0xffff }, { 0, 0, 0xffff, 0xffff }, { 0xffff, 0xffff, 0xffff, 0xffff }, }; static struct clip { void *func; } clips[] = { { NULL }, }; static int _x_error_occurred; static int _check_error_handler(Display *display, XErrorEvent *event) { _x_error_occurred = 1; return False; /* ignored */ } static void clear(struct test_display *dpy, struct test_target *tt, const XRenderColor *c) { XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, c, 0, 0, tt->width, tt->height); } static bool check_op(struct test_display *dpy, int op, struct test_target *tt) { XRenderColor render_color = {0}; XSync(dpy->dpy, True); _x_error_occurred = 0; XRenderFillRectangle(dpy->dpy, op, tt->picture, &render_color, 0, 0, 0, 0); XSync(dpy->dpy, True); return _x_error_occurred == 0; } struct glyph_iter { enum { GLYPHS, OP, DST, SRC, MASK, CLIP, } stage; int glyph_format; int op; int dst_color; int src_color; int mask_format; int clip; struct { struct test_display *dpy; struct test_target tt; GlyphSet glyphset; Picture src; XRenderPictFormat *mask_format; } ref, out; }; static void glyph_iter_init(struct glyph_iter *gi, struct test *t, enum target target) { memset(gi, 0, sizeof(*gi)); gi->out.dpy = &t->out; test_target_create_render(&t->out, target, &gi->out.tt); gi->ref.dpy = &t->ref; test_target_create_render(&t->ref, target, &gi->ref.tt); gi->stage = GLYPHS; gi->glyph_format = -1; gi->op = -1; gi->dst_color = -1; gi->src_color = -1; gi->mask_format = -1; gi->clip = -1; } static void render_clear(char *image, int image_size, int bpp) { memset(image, 0, image_size); } static void render_black(char *image, int image_size, int bpp) { if (bpp == 4) { uint32_t *p = (uint32_t *)image; image_size /= 4; while (image_size--) *p++ = 0x000000ff; } else memset(image, 0x55, image_size); } static void render_green(char *image, int image_size, int bpp) { if (bpp == 4) { uint32_t *p = (uint32_t *)image; image_size /= 4; while (image_size--) *p++ = 0xffff0000; } else memset(image, 0xaa, image_size); } static void render_white(char *image, int image_size, int bpp) { memset(image, 0xff, image_size); } static GlyphSet create_glyphs(Display *dpy, int format_id) { #define N_GLYPHS 4 XRenderPictFormat *format; XGlyphInfo glyph = { 8, 8, 0, 0, 8, 0 }; char image[4*8*8]; GlyphSet glyphset; Glyph gid; int image_size; int bpp; int n; format = XRenderFindStandardFormat(dpy, format_id); if (format == NULL) return 0; switch (format_id) { case PictStandardARGB32: case PictStandardRGB24: image_size = 4 * 8 * 8; bpp = 4; break; case PictStandardA8: case PictStandardA4: image_size = 8 * 8; bpp = 1; break; case PictStandardA1: image_size = 8; bpp = 0; break; default: return 0; } glyphset = XRenderCreateGlyphSet(dpy, format); for (n = 0; n < N_GLYPHS; n++) { gid = n; switch (n) { case 0: render_clear(image, image_size, bpp); break; case 1: render_black(image, image_size, bpp); break; case 2: render_green(image, image_size, bpp); break; case 3: render_white(image, image_size, bpp); break; } XRenderAddGlyphs(dpy, glyphset, &gid, &glyph, 1, image, image_size); } return glyphset; } static const char *glyph_name(int n) { switch (n) { case 0: return "clear"; case 1: return "black"; case 2: return "green"; case 3: return "white"; default: return "unknown"; } } static bool glyph_iter_next(struct glyph_iter *gi) { restart: if (gi->stage == GLYPHS) { if (++gi->glyph_format == PictStandardNUM) return false; if (gi->out.glyphset) XRenderFreeGlyphSet(gi->out.dpy->dpy, gi->out.glyphset); gi->out.glyphset = create_glyphs(gi->out.dpy->dpy, gi->glyph_format); if (gi->ref.glyphset) XRenderFreeGlyphSet(gi->ref.dpy->dpy, gi->ref.glyphset); gi->ref.glyphset = create_glyphs(gi->ref.dpy->dpy, gi->glyph_format); gi->stage++; } if (gi->stage == OP) { do { if (++gi->op == 255) goto reset_op; } while (!check_op(gi->out.dpy, gi->op, &gi->out.tt) || !check_op(gi->ref.dpy, gi->op, &gi->ref.tt)); gi->stage++; } if (gi->stage == DST) { if (++gi->dst_color == ARRAY_SIZE(colors)) goto reset_dst; gi->stage++; } if (gi->stage == SRC) { if (++gi->src_color == ARRAY_SIZE(colors)) goto reset_src; if (gi->ref.src) XRenderFreePicture(gi->ref.dpy->dpy, gi->ref.src); gi->ref.src = XRenderCreateSolidFill(gi->ref.dpy->dpy, &colors[gi->src_color]); if (gi->out.src) XRenderFreePicture(gi->out.dpy->dpy, gi->out.src); gi->out.src = XRenderCreateSolidFill(gi->out.dpy->dpy, &colors[gi->src_color]); gi->stage++; } if (gi->stage == MASK) { if (++gi->mask_format > PictStandardNUM) goto reset_mask; if (gi->mask_format == PictStandardRGB24) gi->mask_format++; if (gi->mask_format < PictStandardNUM) { gi->out.mask_format = XRenderFindStandardFormat(gi->out.dpy->dpy, gi->mask_format); gi->ref.mask_format = XRenderFindStandardFormat(gi->ref.dpy->dpy, gi->mask_format); } else { gi->out.mask_format = NULL; gi->ref.mask_format = NULL; } gi->stage++; } if (gi->stage == CLIP) { if (++gi->clip == ARRAY_SIZE(clips)) goto reset_clip; gi->stage++; } gi->stage--; return true; reset_op: gi->op = -1; reset_dst: gi->dst_color = -1; reset_src: gi->src_color = -1; reset_mask: gi->mask_format = -1; reset_clip: gi->clip = -1; gi->stage--; goto restart; } static void glyph_iter_fini(struct glyph_iter *gi) { if (gi->out.glyphset) XRenderFreeGlyphSet (gi->out.dpy->dpy, gi->out.glyphset); if (gi->ref.glyphset) XRenderFreeGlyphSet (gi->ref.dpy->dpy, gi->ref.glyphset); test_target_destroy_render(gi->out.dpy, &gi->out.tt); test_target_destroy_render(gi->ref.dpy, &gi->ref.tt); } static const char *stdformat_to_str(int id) { switch (id) { case PictStandardARGB32: return "ARGB32"; case PictStandardRGB24: return "RGB24"; case PictStandardA8: return "A8"; case PictStandardA4: return "A4"; case PictStandardA1: return "A1"; default: return "none"; } } static char *glyph_iter_to_string(struct glyph_iter *gi, const char *format, ...) { static char buf[100]; va_list ap; int len; len = sprintf(buf, "glyphs=%s, op=%d, dst=%08x, src=%08x, mask=%s", stdformat_to_str(gi->glyph_format), gi->op, xrender_color(&colors[gi->dst_color]), xrender_color(&colors[gi->src_color]), stdformat_to_str(gi->mask_format)); if (format) { buf[len++] = ' '; va_start(ap, format); vsprintf(buf+len, format, ap); va_end(ap); } return buf; } static void single(struct test *t, enum target target) { struct glyph_iter gi; int n; printf("Testing single glyph (%s): ", test_target_name(target)); fflush(stdout); glyph_iter_init(&gi, t, target); while (glyph_iter_next(&gi)) { XGlyphElt8 elt; char id[N_GLYPHS]; for (n = 0; n < N_GLYPHS; n++) { id[n] = n; elt.chars = &id[n]; elt.nchars = 1; elt.xOff = 0; elt.yOff = 0; clear(gi.out.dpy, &gi.out.tt, &colors[gi.dst_color]); elt.glyphset = gi.out.glyphset; XRenderCompositeText8 (gi.out.dpy->dpy, gi.op, gi.out.src, gi.out.tt.picture, gi.out.mask_format, 0, 0, 0, 8, &elt, 1); clear(gi.ref.dpy, &gi.ref.tt, &colors[gi.dst_color]); elt.glyphset = gi.ref.glyphset; XRenderCompositeText8 (gi.ref.dpy->dpy, gi.op, gi.ref.src, gi.ref.tt.picture, gi.ref.mask_format, 0, 0, 0, 8, &elt, 1); test_compare(t, gi.out.tt.draw, gi.out.tt.format, gi.ref.tt.draw, gi.ref.tt.format, 0, 0, gi.out.tt.width, gi.out.tt.height, glyph_iter_to_string(&gi, "glyph=%s", glyph_name(n))); } elt.chars = &id[0]; elt.nchars = n; clear(gi.out.dpy, &gi.out.tt, &colors[gi.dst_color]); elt.glyphset = gi.out.glyphset; XRenderCompositeText8 (gi.out.dpy->dpy, gi.op, gi.out.src, gi.out.tt.picture, gi.out.mask_format, 0, 0, 0, 8, &elt, 1); clear(gi.ref.dpy, &gi.ref.tt, &colors[gi.dst_color]); elt.glyphset = gi.ref.glyphset; XRenderCompositeText8 (gi.ref.dpy->dpy, gi.op, gi.ref.src, gi.ref.tt.picture, gi.ref.mask_format, 0, 0, 0, 8, &elt, 1); test_compare(t, gi.out.tt.draw, gi.out.tt.format, gi.ref.tt.draw, gi.ref.tt.format, 0, 0, gi.out.tt.width, gi.out.tt.height, glyph_iter_to_string(&gi, "all")); } glyph_iter_fini(&gi); } int main(int argc, char **argv) { struct test test; int t; test_init(&test, argc, argv); XSetErrorHandler(_check_error_handler); for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { single(&test, t); //overlapping(&test, t); //gap(&test, t); //mixed(&test, t); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-trapezoid-image.c000066400000000000000000000362541267532330400257660ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" enum trapezoid { RECT_ALIGN, RECT_UNALIGN, GENERAL }; static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static XRenderPictFormat *mask_format(Display *dpy, enum mask mask) { switch (mask) { default: case MASK_NONE: case MASK_NONE_AA: return NULL; case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1); case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8); } } static const char *mask_name(enum mask mask) { switch (mask) { default: case MASK_NONE: return "none"; case MASK_NONE_AA: return "none/aa"; case MASK_A1: return "a1"; case MASK_A8: return "a8"; } } static const char *trapezoid_name(enum trapezoid trapezoid) { switch (trapezoid) { default: case RECT_ALIGN: return "pixel-aligned"; case RECT_UNALIGN: return "rectilinear"; case GENERAL: return "general"; } } static void show_cells(char *buf, const uint32_t *out, const uint32_t *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", out[j*w+i]); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", ref[j*w+i]); } len += sprintf(buf+len, "\n"); } } static void fill_rect(struct test_display *t, Picture p, XRenderPictFormat *format, uint8_t op, int x, int y, int w, int h, int dx, int dy, enum mask mask, int use_window, int tx, int ty, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor color; XTrapezoid trap; Drawable tmp; Picture src; int w1 = w + (dx!=0); int h1 = h + (dy!=0); if (use_window) { XSetWindowAttributes attr; attr.override_redirect = 1; tmp = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), tx, ty, w1, h1, 0, format->depth, InputOutput, DefaultVisual(t->dpy, DefaultScreen(t->dpy)), CWOverrideRedirect, &attr); XMapWindow(t->dpy, tmp); } else tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), w1, h1, format->depth); src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); color.red = red * alpha; color.green = green * alpha; color.blue = blue * alpha; color.alpha = alpha << 8 | alpha; XRenderFillRectangle(t->dpy, PictOpSrc, src, &color, 0, 0, w1, h1); trap.left.p1.x = trap.left.p2.x = (x << 16) + dx; trap.top = trap.left.p1.y = trap.right.p1.y = (y << 16) + dy; trap.right.p1.x = trap.right.p2.x = ((x + w) << 16) + dx; trap.bottom = trap.left.p2.y = trap.right.p2.y = ((y + h) << 16) + dy; XRenderCompositeTrapezoids(t->dpy, op, src, p, mask_format(t->dpy, mask), 0, 0, &trap, 1); XRenderFreePicture(t->dpy, src); if (use_window) XDestroyWindow(t->dpy, tmp); else XFreePixmap(t->dpy, tmp); } static void pixel_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; printf("Testing setting of single pixels (%s using %s): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &tt); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int tx, ty; do { tx = rand() % (tt.width - 1); ty = rand() % (tt.height - 1); } while (tx == x && ty == y); fill_rect(&t->out, tt.picture, use_window ? t->out.format : tt.format, PictOpSrc, x, y, 1, 1, 0, 0, MASK_NONE, use_window, tx, ty, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*t->out.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void set_mask(struct test_display *t, struct test_target *tt, enum mask mask) { XRenderPictureAttributes pa; switch (mask) { case MASK_NONE: pa.poly_edge = PolyEdgeSharp; break; default: pa.poly_edge = PolyEdgeSmooth; break; } XRenderChangePicture(t->dpy, tt->picture, CPPolyEdge, &pa); } static void fill(uint32_t *cells, int x, int y, int w, int h, int max_width, int max_height, uint32_t pixel) { if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= max_width || y >= max_height) return; if (x + w > max_width) w = max_width - x; if (y + h > max_height) h = max_height - y; if (w <= 0 || h <= 0) return; pixman_fill(cells, max_width, 32, x, y, w, h, pixel); } static void area_tests(struct test *t, int reps, int sets, enum target target, int use_window) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s using %s source): ", test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int tx, ty, try = 50; int w, h; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; if (use_window) { do { w = 1 + rand() % (tt.width - 1); h = 1 + rand() % (tt.height - 1); tx = w == tt.width ? 0 : rand() % (tt.width - w); ty = h == tt.height ? 0 : rand() % (tt.height - h); } while (((tx+w > x && tx < x+w) && (ty+h > y && ty < y+h)) && --try); if (!try) continue; } else { w = 1 + rand() % (2*tt.width); h = 1 + rand() % (2*tt.height); tx = ty = 0; } fill_rect(&t->out, tt.picture, use_window ? t->out.format : tt.format, PictOpSrc, x, y, w, h, 0, 0, MASK_NONE, use_window, tx, ty, red, green, blue, alpha); if (use_window) fill(cells, tx, ty, w, h, tt.width, tt.height, color(red, green, blue, alpha)); fill(cells, x, y, w, h, tt.width, tt.height, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { char buf[600]; uint32_t mask = depth_mask(image.depth); show_cells(buf, (uint32_t*)image.data, cells, x, y, tt.width, tt.height); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n%s", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result, buf); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int dx, int dy, enum mask mask, int reps, int sets, enum target target, int use_window) { struct test_target out, ref; int r, s; printf("Testing area fills (offset %dx%d, mask %s) (%s using %s source): ", dx, dy, mask_name(mask), test_target_name(target), use_window ? "window" : "pixmap"); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); set_mask(&t->out, &out, mask); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); set_mask(&t->ref, &ref, mask); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x, y, w, h; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int tx, ty, try = 50; do { x = rand() % (out.width - 1); y = rand() % (out.height - 1); w = 1 + rand() % (out.width - x - 1); h = 1 + rand() % (out.height - y - 1); tx = w == out.width ? 0 : rand() % (out.width - w); ty = h == out.height ? 0 : rand() % (out.height - h); } while (((tx+w > x && tx < x+w) && (ty+h > y && ty < y+h)) && --try); if (try) { fill_rect(&t->out, out.picture, use_window ? t->out.format : out.format, op, x, y, w, h, dx, dy, mask, use_window, tx, ty, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, use_window ? t->ref.format : ref.format, op, x, y, w, h, dx, dy, mask, use_window, tx, ty, red, green, blue, alpha); } } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void random_trapezoid(XTrapezoid *trap, enum trapezoid trapezoid, int x1, int y1, int x2, int y2) { switch (trapezoid) { case RECT_ALIGN: x1 = x1 + rand() % (x2 - x1); x2 = x1 + rand() % (x2 - x1); y1 = y1 + rand() % (y2 - y1); y2 = y1 + rand() % (y2 - y1); trap->left.p1.x = trap->left.p2.x = x1 << 16; trap->top = trap->left.p1.y = trap->right.p1.y = y1 << 16; trap->right.p1.x = trap->right.p2.x = x2 << 16; trap->bottom = trap->left.p2.y = trap->right.p2.y = y2 << 16; break; case RECT_UNALIGN: x1 <<= 16; x2 <<= 16; y1 <<= 16; y2 <<= 16; x1 = x1 + rand() % (x2 - x1); x2 = x1 + rand() % (x2 - x1); y1 = y1 + rand() % (y2 - y1); y2 = y1 + rand() % (y2 - y1); trap->left.p1.x = trap->left.p2.x = x1; trap->top = trap->left.p1.y = trap->right.p1.y = y1; trap->right.p1.x = trap->right.p2.x = x2; trap->bottom = trap->left.p2.y = trap->right.p2.y = y2; break; case GENERAL: x1 <<= 16; x2 <<= 16; y1 <<= 16; y2 <<= 16; trap->top = y1 + rand() % (y2 - y1); trap->bottom = y1 + rand() % (y2 - y1); trap->left.p1.x = x1 + rand() % (x2 - x1); trap->left.p2.x = x1 + rand() % (x2 - x1); trap->right.p1.x = x1 + rand() % (x2 - x1); trap->right.p2.x = x1 + rand() % (x2 - x1); break; } } static void fill_traps(struct test_display *t, Picture p, XRenderPictFormat *format, uint8_t op, XTrapezoid *traps, int ntraps, enum mask mask, int srcx, int srcy, int srcw, int srch, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor color; Drawable tmp; Picture src; tmp = XCreatePixmap(t->dpy, DefaultRootWindow(t->dpy), srcw, srch, format->depth); src = XRenderCreatePicture(t->dpy, tmp, format, 0, NULL); color.red = red * alpha; color.green = green * alpha; color.blue = blue * alpha; color.alpha = alpha << 8 | alpha; XRenderFillRectangle(t->dpy, PictOpSrc, src, &color, 0, 0, srcw, srch); XRenderCompositeTrapezoids(t->dpy, op, src, p, mask_format(t->dpy, mask), srcx, srcy, traps, ntraps); XRenderFreePicture(t->dpy, src); XFreePixmap(t->dpy, tmp); } static void trap_tests(struct test *t, enum mask mask, enum trapezoid trapezoid, int reps, int sets, enum target target) { struct test_target out, ref; XTrapezoid *traps; int max_traps = 65536; int r, s, n; traps = malloc(sizeof(*traps) * max_traps); if (traps == NULL) return; printf("Testing trapezoids (%s with mask %s) (%s): ", trapezoid_name(trapezoid), mask_name(mask), test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); set_mask(&t->out, &out, mask); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); set_mask(&t->ref, &ref, mask); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int num_traps = rand() % max_traps; int srcx = rand() % 2*out.width - out.width; int srcy = rand() % 2*out.height - out.height; int srcw = rand() % out.width; int srch = rand() % out.height; for (n = 0; n < num_traps; n++) random_trapezoid(&traps[n], 0, 0, 0, out.width, out.height); fill_traps(&t->out, out.picture, out.format, op, traps, num_traps, mask, srcx, srcy, srcw, srch, red, green, blue, alpha); fill_traps(&t->ref, ref.picture, ref.format, op, traps, num_traps, mask, srcx, srcy, srcw, srch, red, green, blue, alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); free(traps); } int main(int argc, char **argv) { struct test test; int i, dx, dy; enum target target; enum mask mask; enum trapezoid trapezoid; test_init(&test, argc, argv); for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { pixel_tests(&test, reps, sets, target, 0); area_tests(&test, reps, sets, target, 0); for (dy = 0; dy < 1 << 16; dy += 1 << 14) for (dx = 0; dx < 1 << 16; dx += 1 << 14) for (mask = MASK_NONE; mask <= MASK_A8; mask++) rect_tests(&test, dx, dy, mask, reps, sets, target, 0); if (target != CHILD) { pixel_tests(&test, reps, sets, target, 1); area_tests(&test, reps, sets, target, 1); for (dy = 0; dy < 1 << 16; dy += 1 << 14) for (dx = 0; dx < 1 << 16; dx += 1 << 14) for (mask = MASK_NONE; mask <= MASK_A8; mask++) rect_tests(&test, dx, dy, mask, reps, sets, target, 1); } } for (target = TARGET_FIRST; target <= TARGET_LAST; target++) for (trapezoid = RECT_ALIGN; trapezoid <= GENERAL; trapezoid++) trap_tests(&test, mask, trapezoid, reps, sets, target); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-trapezoid.c000066400000000000000000000334251267532330400247030ustar00rootroot00000000000000#include #include #include #include /* for XDestroyImage */ #include /* for pixman blt functions */ #include "test.h" enum trapezoid { RECT_ALIGN, RECT_UNALIGN, GENERAL }; static const uint8_t ops[] = { PictOpClear, PictOpSrc, PictOpDst, }; static XRenderPictFormat *mask_format(Display *dpy, enum mask mask) { switch (mask) { default: case MASK_NONE: return NULL; case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1); case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8); } } static const char *mask_name(enum mask mask) { switch (mask) { default: case MASK_NONE: return "none"; case MASK_A1: return "a1"; case MASK_A8: return "a8"; } } static const char *trapezoid_name(enum trapezoid trapezoid) { switch (trapezoid) { default: case RECT_ALIGN: return "pixel-aligned"; case RECT_UNALIGN: return "rectilinear"; case GENERAL: return "general"; } } static void fill_rect(struct test_display *dpy, Picture p, uint8_t op, int x, int y, int w, int h, int dx, int dy, enum mask mask, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { XRenderColor render_color; XTrapezoid trap; Picture src; render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8; trap.left.p1.x = trap.left.p2.x = (x << 16) + dx; trap.top = trap.left.p1.y = trap.right.p1.y = (y << 16) + dy; trap.right.p1.x = trap.right.p2.x = ((x + w) << 16) + dx; trap.bottom = trap.left.p2.y = trap.right.p2.y = ((y + h) << 16) + dy; src = XRenderCreateSolidFill(dpy->dpy, &render_color); XRenderCompositeTrapezoids(dpy->dpy, op, src, p, mask_format(dpy->dpy, mask), 0, 0, &trap, 1); XRenderFreePicture(dpy->dpy, src); } static void pixel_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = malloc(t->out.width*t->out.height*4); struct { uint16_t x, y; } *pixels = malloc(reps*sizeof(*pixels)); int r, s; printf("Testing setting of single pixels (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (tt.width - 1); int y = rand() % (tt.height - 1); int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, 1, 1, 0, 0, MASK_NONE, red, green, blue, alpha); pixels[r].x = x; pixels[r].y = y; cells[y*t->out.width+x] = color(red, green, blue, alpha); } test_init_image(&image, &t->out.shm, tt.format, 1, 1); for (r = 0; r < reps; r++) { uint32_t result; uint32_t x = pixels[r].x; uint32_t y = pixels[r].y; XShmGetImage(t->out.dpy, tt.draw, &image, x, y, AllPlanes); result = *(uint32_t *)image.data; if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(pixels); free(cells); } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void area_tests(struct test *t, int reps, int sets, enum target target) { struct test_target tt; XImage image; uint32_t *cells = calloc(sizeof(uint32_t), t->out.width*t->out.height); int r, s, x, y; printf("Testing area sets (%s): ", test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &tt); clear(&t->out, &tt); test_init_image(&image, &t->out.shm, tt.format, tt.width, tt.height); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int w = rand() % tt.width; int h = rand() % tt.height; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; x = rand() % (2*tt.width) - tt.width; y = rand() % (2*tt.height) - tt.height; fill_rect(&t->out, tt.picture, PictOpSrc, x, y, w, h, 0, 0, MASK_NONE, red, green, blue, alpha); if (x < 0) w += x, x = 0; if (y < 0) h += y, y = 0; if (x >= tt.width || y >= tt.height) continue; if (x + w > tt.width) w = tt.width - x; if (y + h > tt.height) h = tt.height - y; if (w <= 0 || h <= 0) continue; pixman_fill(cells, tt.width, 32, x, y, w, h, color(red, green, blue, alpha)); } XShmGetImage(t->out.dpy, tt.draw, &image, 0, 0, AllPlanes); for (y = 0; y < tt.height; y++) { for (x = 0; x < tt.width; x++) { uint32_t result = *(uint32_t *)(image.data + y*image.bytes_per_line + image.bits_per_pixel*x/8); if (!pixel_equal(image.depth, result, cells[y*tt.width+x])) { uint32_t mask = depth_mask(image.depth); die("failed to set pixel (%d,%d) to %08x [%08x], found %08x [%08x] instead\n", x, y, cells[y*tt.width+x] & mask, cells[y*tt.width+x], result & mask, result); } } } } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &tt); free(cells); } static void rect_tests(struct test *t, int dx, int dy, enum mask mask, int reps, int sets, enum target target) { struct test_target out, ref; int r, s; printf("Testing area fills (offset %dx%d, mask %s) (%s): ", dx, dy, mask_name(mask), test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { int x = rand() % (2*out.width) - out.width; int y = rand() % (2*out.height) - out.height; int w = rand() % out.width; int h = rand() % out.height; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; fill_rect(&t->out, out.picture, op, x, y, w, h, dx, dy, mask, red, green, blue, alpha); fill_rect(&t->ref, ref.picture, op, x, y, w, h, dx, dy, mask, red, green, blue, alpha); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); } static void random_trapezoid(XTrapezoid *trap, enum trapezoid trapezoid, int x1, int y1, int x2, int y2) { switch (trapezoid) { case RECT_ALIGN: x1 = x1 + rand() % (x2 - x1); x2 = x1 + rand() % (x2 - x1); y1 = y1 + rand() % (y2 - y1); y2 = y1 + rand() % (y2 - y1); trap->left.p1.x = trap->left.p2.x = x1 << 16; trap->top = trap->left.p1.y = trap->right.p1.y = y1 << 16; trap->right.p1.x = trap->right.p2.x = x2 << 16; trap->bottom = trap->left.p2.y = trap->right.p2.y = y2 << 16; break; case RECT_UNALIGN: x1 <<= 16; x2 <<= 16; y1 <<= 16; y2 <<= 16; x1 = x1 + rand() % (x2 - x1); x2 = x1 + rand() % (x2 - x1); y1 = y1 + rand() % (y2 - y1); y2 = y1 + rand() % (y2 - y1); trap->left.p1.x = trap->left.p2.x = x1; trap->top = trap->left.p1.y = trap->right.p1.y = y1; trap->right.p1.x = trap->right.p2.x = x2; trap->bottom = trap->left.p2.y = trap->right.p2.y = y2; break; case GENERAL: x1 <<= 16; x2 <<= 16; y1 <<= 16; y2 <<= 16; trap->top = y1 + rand() % (y2 - y1); trap->bottom = y1 + rand() % (y2 - y1); trap->left.p1.x = x1 + rand() % (x2 - x1); trap->left.p2.x = x1 + rand() % (x2 - x1); trap->right.p1.x = x1 + rand() % (x2 - x1); trap->right.p2.x = x1 + rand() % (x2 - x1); break; } } static void trap_tests(struct test *t, enum mask mask, enum trapezoid trapezoid, int reps, int sets, enum target target) { struct test_target out, ref; XTrapezoid *traps; int max_traps = 65536; int r, s, n; traps = malloc(sizeof(*traps) * max_traps); if (traps == NULL) return; printf("Testing trapezoids (%s with mask %s) (%s): ", trapezoid_name(trapezoid), mask_name(mask), test_target_name(target)); fflush(stdout); test_target_create_render(&t->out, target, &out); clear(&t->out, &out); test_target_create_render(&t->ref, target, &ref); clear(&t->ref, &ref); for (s = 0; s < sets; s++) { for (r = 0; r < reps; r++) { XRenderColor render_color; int op = ops[rand() % sizeof(ops)]; int red = rand() % 0xff; int green = rand() % 0xff; int blue = rand() % 0xff; int alpha = rand() % 0xff; int num_traps = rand() % max_traps; Picture src; for (n = 0; n < num_traps; n++) random_trapezoid(&traps[n], 0, 0, 0, out.width, out.height); render_color.red = red * alpha; render_color.green = green * alpha; render_color.blue = blue * alpha; render_color.alpha = alpha << 8; src = XRenderCreateSolidFill(t->out.dpy, &render_color); XRenderCompositeTrapezoids(t->out.dpy, op, src, out.picture, mask_format(t->out.dpy, mask), 0, 0, traps, num_traps); XRenderFreePicture(t->out.dpy, src); src = XRenderCreateSolidFill(t->ref.dpy, &render_color); XRenderCompositeTrapezoids(t->ref.dpy, op, src, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, traps, num_traps); XRenderFreePicture(t->ref.dpy, src); } test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, ""); } printf("passed [%d iterations x %d]\n", reps, sets); test_target_destroy_render(&t->out, &out); test_target_destroy_render(&t->ref, &ref); free(traps); } enum edge { EDGE_SHARP = PolyEdgeSharp, EDGE_SMOOTH, }; static const char *edge_name(enum edge edge) { switch (edge) { default: case EDGE_SHARP: return "sharp"; case EDGE_SMOOTH: return "smooth"; } } static void set_edge(Display *dpy, Picture p, enum edge edge) { XRenderPictureAttributes a; a.poly_edge = edge; XRenderChangePicture(dpy, p, CPPolyEdge, &a); } static void edge_test(struct test *t, enum mask mask, enum edge edge, enum target target) { struct test_target out, ref; XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; Picture src_ref, src_out; XTrapezoid trap; int left_or_right, p; test_target_create_render(&t->out, target, &out); set_edge(t->out.dpy, out.picture, edge); src_out = XRenderCreateSolidFill(t->out.dpy, &white); test_target_create_render(&t->ref, target, &ref); set_edge(t->ref.dpy, ref.picture, edge); src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); printf("Testing edges (with mask %s and %s edges) (%s): ", mask_name(mask), edge_name(edge), test_target_name(target)); fflush(stdout); for (left_or_right = 0; left_or_right <= 1; left_or_right++) { for (p = -64; p <= out.width + 64; p++) { char buf[80]; if (left_or_right) { trap.left.p1.x = 0; trap.left.p1.y = 0; trap.left.p2.x = 0; trap.left.p2.y = out.height << 16; trap.right.p1.x = p << 16; trap.right.p1.y = 0; trap.right.p2.x = out.width << 16; trap.right.p2.y = out.height << 16; } else { trap.right.p1.x = out.width << 16; trap.right.p1.y = 0; trap.right.p2.x = out.width << 16; trap.right.p2.y = out.height << 16; trap.left.p1.x = 0; trap.left.p1.y = 0; trap.left.p2.x = p << 16; trap.left.p2.y = out.height << 16; } trap.top = 0; trap.bottom = out.height << 16; sprintf(buf, "trap=((%d, %d), (%d, %d)), ((%d, %d), (%d, %d))\n", trap.left.p1.x >> 16, trap.left.p1.y >> 16, trap.left.p2.x >> 16, trap.left.p2.y >> 16, trap.right.p1.x >> 16, trap.right.p1.y >> 16, trap.right.p2.x >> 16, trap.right.p2.y >> 16); clear(&t->out, &out); XRenderCompositeTrapezoids(t->out.dpy, PictOpSrc, src_out, out.picture, mask_format(t->out.dpy, mask), 0, 0, &trap, 1); clear(&t->ref, &ref); XRenderCompositeTrapezoids(t->ref.dpy, PictOpSrc, src_ref, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, &trap, 1); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } } XRenderFreePicture(t->out.dpy, src_out); test_target_destroy_render(&t->out, &out); XRenderFreePicture(t->ref.dpy, src_ref); test_target_destroy_render(&t->ref, &ref); printf("pass\n"); } int main(int argc, char **argv) { struct test test; int i, dx, dy; enum target target; enum mask mask; enum edge edge; enum trapezoid trapezoid; test_init(&test, argc, argv); for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { for (mask = MASK_NONE; mask <= MASK_A8; mask++) for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++) edge_test(&test, mask, edge, target); } for (i = 0; i <= DEFAULT_ITERATIONS; i++) { int reps = REPS(i), sets = SETS(i); for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { pixel_tests(&test, reps, sets, target); area_tests(&test, reps, sets, target); for (dy = 0; dy < 1 << 16; dy += 1 << 14) for (dx = 0; dx < 1 << 16; dx += 1 << 14) for (mask = MASK_NONE; mask <= MASK_A8; mask++) rect_tests(&test, dx, dy, mask, reps, sets, target); for (trapezoid = RECT_ALIGN; trapezoid <= GENERAL; trapezoid++) trap_tests(&test, mask, trapezoid, reps, sets, target); } } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/render-triangle.c000066400000000000000000000076041267532330400245070ustar00rootroot00000000000000#include #include #include #include "test.h" enum edge { EDGE_SHARP = PolyEdgeSharp, EDGE_SMOOTH, }; static void set_edge(Display *dpy, Picture p, enum edge edge) { XRenderPictureAttributes a; a.poly_edge = edge; XRenderChangePicture(dpy, p, CPPolyEdge, &a); } static XRenderPictFormat *mask_format(Display *dpy, enum mask mask) { switch (mask) { default: case MASK_NONE: return NULL; case MASK_A1: return XRenderFindStandardFormat(dpy, PictStandardA1); case MASK_A8: return XRenderFindStandardFormat(dpy, PictStandardA8); } } static const char *mask_name(enum mask mask) { switch (mask) { default: case MASK_NONE: return "none"; case MASK_A1: return "a1"; case MASK_A8: return "a8"; } } static const char *edge_name(enum edge edge) { switch (edge) { default: case EDGE_SHARP: return "sharp"; case EDGE_SMOOTH: return "smooth"; } } static void clear(struct test_display *dpy, struct test_target *tt) { XRenderColor render_color = {0}; XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 0, 0, tt->width, tt->height); } static void step_to_point(int step, int width, int height, XPointFixed *p) { do { p->x = (step - 64) << 16; p->y = -64 << 16; step -= width - 128; if (step <= 0) return; p->x = (width + 64) << 16; p->y = (step - 64) << 16; step -= height - 128; if (step <= 0) return; p->x = (width + 64 - step) << 16; p->y = (height + 64) << 16; step -= width - 128; if (step <= 0) return; p->x = -64 << 16; p->y = (height + 64 - step) << 16; step -= height - 128; } while (step > 0); } static void edge_test(struct test *t, enum mask mask, enum edge edge, enum target target) { struct test_target out, ref; XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; Picture src_ref, src_out; XTriangle tri; unsigned step, max; test_target_create_render(&t->out, target, &out); set_edge(t->out.dpy, out.picture, edge); src_out = XRenderCreateSolidFill(t->out.dpy, &white); test_target_create_render(&t->ref, target, &ref); set_edge(t->ref.dpy, ref.picture, edge); src_ref = XRenderCreateSolidFill(t->ref.dpy, &white); printf("Testing edges (with mask %s and %s edges) (%s): ", mask_name(mask), edge_name(edge), test_target_name(target)); fflush(stdout); max = 2*(out.width + 128 + out.height+128); step = 0; for (step = 0; step <= max; step++) { char buf[80]; step_to_point(step, out.width, out.height, &tri.p1); step_to_point(step + out.width + 128, out.width, out.height, &tri.p2); step_to_point(step + out.height + 128 + 2*(out.width + 128), out.width, out.height, &tri.p3); sprintf(buf, "tri=((%d, %d), (%d, %d), (%d, %d))\n", tri.p1.x >> 16, tri.p1.y >> 16, tri.p2.x >> 16, tri.p2.y >> 16, tri.p3.x >> 16, tri.p3.y >> 16); clear(&t->out, &out); XRenderCompositeTriangles(t->out.dpy, PictOpSrc, src_out, out.picture, mask_format(t->out.dpy, mask), 0, 0, &tri, 1); clear(&t->ref, &ref); XRenderCompositeTriangles(t->ref.dpy, PictOpSrc, src_ref, ref.picture, mask_format(t->ref.dpy, mask), 0, 0, &tri, 1); test_compare(t, out.draw, out.format, ref.draw, ref.format, 0, 0, out.width, out.height, buf); } XRenderFreePicture(t->out.dpy, src_out); test_target_destroy_render(&t->out, &out); XRenderFreePicture(t->ref.dpy, src_ref); test_target_destroy_render(&t->ref, &ref); printf("pass\n"); } int main(int argc, char **argv) { struct test test; enum target target; enum mask mask; enum edge edge; test_init(&test, argc, argv); for (target = TARGET_FIRST; target <= TARGET_LAST; target++) { for (mask = MASK_NONE; mask <= MASK_A8; mask++) for (edge = EDGE_SHARP; edge <= EDGE_SMOOTH; edge++) edge_test(&test, mask, edge, target); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/test/shm-test.c000066400000000000000000000104251267532330400231640ustar00rootroot00000000000000/* * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #include #include #include #include #include #include #include #include #include static int _x_error_occurred; static int can_use_shm(Display *dpy) { int major, minor, has_pixmap; if (!XShmQueryExtension(dpy)) return 0; XShmQueryVersion(dpy, &major, &minor, &has_pixmap); return has_pixmap; } static int test_subpage(Display *dpy) { const int width = 10; const int height = 10; uint32_t pixel = 0xffffffff; char *expected; XShmSegmentInfo shm; Pixmap pixmap, source; XGCValues gcv; GC gc; printf("Creating %dx%d SHM pixmap\n", width, height); _x_error_occurred = 0; expected = malloc(4096); if (expected == NULL) return 0; shm.shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); if (shm.shmid == -1) return 0; shm.shmaddr = shmat(shm.shmid, 0, 0); if (shm.shmaddr == (char *) -1) { shmctl(shm.shmid, IPC_RMID, NULL); return 0; } shm.readOnly = False; XShmAttach(dpy, &shm); memset(shm.shmaddr, 0xcc, 4096); memset(expected, 0xcc, 4096); memset(expected + 64, 0xff, 4*width * height); pixmap = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), shm.shmaddr + 64, &shm, width, height, 24); XSync(dpy, False); shmctl(shm.shmid, IPC_RMID, NULL); source = XCreatePixmap(dpy, DefaultRootWindow(dpy), width, height, 24); gcv.graphics_exposures = False; gcv.subwindow_mode = IncludeInferiors; gcv.foreground = pixel; gcv.function = GXcopy; gcv.fill_style = FillSolid; gc = XCreateGC(dpy, pixmap, GCGraphicsExposures | GCSubwindowMode | GCFillStyle | GCForeground | GCFunction, &gcv); XCopyArea(dpy, pixmap, source, gc, 0, 0, width, height, 0, 0); XFillRectangle(dpy, source, gc, 0, 0, width, height); XCopyArea(dpy, source, pixmap, gc, 0, 0, width, height, 0, 0); XSync(dpy, True); if (_x_error_occurred == 0) _x_error_occurred = memcmp(shm.shmaddr, expected, 4096); printf("%s: %s\n", __func__, _x_error_occurred ? "failed" : "passed"); XShmDetach(dpy, &shm); shmdt(shm.shmaddr); free(expected); return !_x_error_occurred;; } static int _check_error_handler(Display *display, XErrorEvent *event) { printf("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code); _x_error_occurred++; return False; /* ignored */ } int main(void) { Display *dpy; int error = 0; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 77; if (DefaultDepth(dpy, DefaultScreen(dpy)) != 24) return 77; if (!can_use_shm(dpy)) return 0; XSetErrorHandler(_check_error_handler); error += test_subpage(dpy); return !!error; } xserver-xorg-video-intel-2.99.917+git20160325/test/tearing.mp4000066400000000000000000005326361267532330400233440ustar00rootroot00000000000000ftypmp42isommp42moovlmvhdֵ4ֵ4XFP@iodsO)wtrak\tkhd|%ֵ4FP@mdia mdhd|%ֵ4<U-hdlrvideVideoHandlerminfvmhd$dinfdref url ~stblstsdavc1HH0avcCdgd$[<2h<btrt sttsPstss=y-i;w+g8stsc.     "#%&'(*+-./0235678:;=>$stszn`\X]~zC}  uaVvk{}n_t&>xuhbvtvrs}walV]d{z16}6[o/3bk#S}n[M^uY|amdV\jwlvvbZPahzpcID@LSympog4uyd\SYDx2ud_pj\]o|(1Bm!?2+]gbY(ttx%zzg_Od]yv| f||s Z]xDdki]; Qtwh"gD=uruBkuz}JogxwqzYa]{Di&&V  nXT]aw(xzuzajdcub:vl^C6q(.leTV^W)dSTew}(|qmstco>#_/-:tDNW`Jjt ||ȮڇLt&0:|OZ"d>n0|:ۏn ?"u-5AfQZ2dmxN:trak\tkhdֵ4ֵ4FP@{mdia mdhdֵ4ֵ4D0ULhdlrsounIsoMedia File Produced by Google, 5-11-2011minfsmhd$dinfdref url stbl[stsdKmp4aD'esds@ stts 4stsc> stsz  stco>".p9CWN8V_j(sN{ *-J&/X9NYecms| `=Y})( !,T5@QYud lGwY} Dudtameta!hdlrmdirapplilstgsstdata0gstddata300918gssd0dataB4A7DA341MH1369585716144924gspudatagspmdatagshhdatar4---sn-5go7ln7s.c.youtube.commdatex7sp'Sg1{ =o6+9bl_Q?Av zvCW(x` V &`{4`XAA Otaj*`N%0# ;{9cg eOV01*Ѕyli*@#a!bUb=xҲ&{ 82,ʹnj B^W%X@ɉ#pNAAAa%~3Q7 y8^Nd"\֤H?ˠcZ l#!ס1<8x_9|E/Q+ty(*B,lÌGN Hq@A6|&](!G8vҌ\ xA A⠰Β+-``H\/b*0#v. F\bBDrTgrk)Z2'NqCj w Ia8'ⰜVqXN+ a8'ⰜVqXN+ a8֠A&APXgI@|*ÂbMBcg !rNT8yUI#0&0-G^5FyDlǔFyDlǔFyDlǔFyDlǔFyDlǔFyDyA.A,3,cÄSex1g`͸m>._ޜ:Ket_csYUp ʒ{7 dIoR|ʌ`1)cXo)N!gsycpDAr Pڂxw0Q <)yMO:Mϭ X=̕EA6ARh,Jzl8#3Y| 59]}z~!A'~K'dO]#}T.Q4aåK,:XtaåK,:]%jA>A%\ѕ$94^Άؗ d;%XqK]M,&o&Ezx7c*:ˋ 0'EmO>d|\A FA \cL(?_GEƅ<{ `\b-R1h&ÜI,&NI׸1r-Zȴ#XA$NAټ0w uq@v+YFRm E A:0TA(VAItCe!ԁy?Js ]h" 7GtP#!YA,^A뎃j,qL֖*XF35}8".kJ*snH`G X/P;2!ޝ9A0fA8IC{?xk`+FCKPeG$䛂AteL,"(u60{x4Xf{MA4nA-ICDxig^6z2_a§`=#Z<A3Vs|@GA8vARٰX k1p1H~l ?n=Uk;Wc <NB/4P,"?.{NVPL'ڍ>t77./ :b."dQxm{/BDT| D%KV}tB@UzA<~Ap?;=v6,J}=$dnNX]۽L(Zt&23ʉ O}O`i"ӤEHN"-:DZti"c!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A@A fȏir-71rSq$nǘ#<]ޑuCW}|.{~f$Ν54\*g5^ –=,oO)f"$Z~}Eok jX&B.y3D(ADA% zEF95CbK*&f?Cd*\#m:um0(R ?'g4tЎdg&{nF=*=Q.^.ը@Tjs*wBe ,z?R'VNVh a TWY`AHAÄAG }"@~J?{˲7 :atQ{q9ڲ̋5&ӠM;<ٻ8ffbwb)Uah+V.L ƾ~Y ݊6) h/٣dL%VE+;]Nmi[fO7z.+lՃL~ #;X^HJ0bN"MvbI5smvہ7 jC&'SoM!{IMAALA q- ًCRbQⳏ_&j~lWDtQxD 9H˟}.T-( ɞ+-BF^ #14;f9}Xu\T[=gGXdvixgC g@>ׂ7AB8vXѕnHTm'3w;gp 3w;gp kATA@%"`RqғK撢x=DZ#FГeL(C}F#)8# yL)-M: \#HG|?]a8'ⰜVqXN+ a8'ⰜVqXN0 AXAk>,n GOSF ?@DEB&kAsiسe o.N PЖR&$6m7B3w;gp 3w;h A\AO:KG0 Žc*'#HՖ%/f6zD5nh.=.,(Leg!-d\f,ؾb{P$|?3Պת|/7P@[l5#qFtU3s%1{\Sgu"ePt3هC=t3هC=t3هC=u]A`ANAcpJ+lQ*-u7MDߙm 7Mfs2\8LՓG)MўExg5ģ*Cп+(N@;:˜@aT~D1*]d2OFu B]` 40Tbe 9V?;\;bb3xLT,Qj< 2h^ډ WHaAdAՂX/Hk#!VBRn:{fw'xOէ@zpIoxw=t8xزΡ\f VX)P<,Quf%K :H6pPƽw,}.^[I .4KlRkNxI6N6VD3GΌ>dO@S$Q\4[v<aYaAhAǃ{"/&.CTT #f>3 r<  L]M384ъ_r` R|/vcV}qbq8@g׹DV 4b %bXɌqc+uy6tM_A<<T.^Fb9vAlAf횤:ˇp !]u* 7N)Qm#lc 9fCf>qsa(<T㬲_8Ww]mAxA_o /`;] HOf?Ub!^Gm t 8oVL.&ĭl^mS,1T=-/Omh1B rT鯾O+Aj>]x=G*8I"lmzUA{ql#qv6ޅ vm0!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A|Aǂ)&G~Ugs"3fm7{ϲ&7eF}J{H UEs)z_ݶPse_DSGiO/^zXM}Iq~^Vo}3R4p_bP=:% F6cת,W{L`9s#8:ORRAANl Pf ̼q\MfE*1JJ>v3Rd]DT<.2PK^TXohO}>O}>O}>O?AA ( ? Q:ҡcx6'k߈f`nMwzi}CifZDv1Fvx:FpUKfjcƛ0$V+R  eG}Tkyò1A"Q ګr{ u^ZfC^\U}` f g h5n>37t9D%'2Nag \4"4hh* ZhB5O\485%+ߑ i\Co =pҹ8*Jz|o b6HڵqAAx,3kbE,ajtJsA+eo\Ɵ#.IKt */ik;'1K;maM'#1PllY4,ilg\ cռrxv0A6A ( ?邫EG0'Sˎ%+b~S\*߶\H-PuKV#jp^Xc-ï@ ZQG ~:&WB` /P'1 n0&9HG`nTMUkaȣ1f ?o[?. hVt8u9A>Ak:J+`G'\ <.MPe3;krHu/mfqEXYـy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy`AFAͷEg=T66m2aCZtF@* U,JN ]%9̵6`pCrr[g= ]GJjcVsxAtix<]VzG߆䪾rbCQ NPANAۂ+-`gñ"h)w0ZjHNE)跁mt6#'Qt]z+(0T{%J8'ⰜVqXN+ a8'ⰜVqXN68AVAmz@|*pp'*z1e^d"\֤J,KXyyA%`\ rBjaoJqF]-MR%-9#<Jk G"\؇IG(}}im}.|AnA\&q|i-T|X#&":Mo YE5aRX (X L?Փap L5-2Ik<ˁ!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#~AvA\yN1!"h8g~ ?Ond_8* dFŪ%!prM8=Yx 5u Lp|UyA~AkZa"#@S('u X_qg>rd2^Ei<=I!,G'^M'n0+0}@g8BV7XM86AA3,DSdX$-HC0( U5hwӫC? ;yFwTwt͟C`!A8lVq&)LlStMX‡uelQAŎAICDYD]7""?0U<˪ fO~D$z{Q<Mq_cX¨!NTdJI ~oq/Q޷u:\V50 E@AɖAICVL.e`5yF@je-BD)E3ȵU5wOLt'XCIoA͞A5YBpTXQMĢdk^A$:/5 9/ϟyˤRx .0.~;VIDFj;+r] GŸWj=Z* X "(Aͺ(;AѦAhuG-|rd#~8(1>RUBMGj/^RɽO;7,ѡd~akp`iWۣH"V=_4?HOOW5Z(AծAa?!eKU-$0sng`#6jC?T4O[BvJ>cN}v U .; ꨪ@D Y sh NDTnN )2Ie@[,o<=sAٶAip"иl*Pr@z~enQ"o0I&]y*. ӃB-]ӝ4U9tym`uH-Q/{hkfY`]gJFs2-(]夂6#KpOCم':S,wu-{.2-T }X/v{_COAc7?7?1lJBcmtnf{9w1 &Y|AݾA68}#j̧gt CNlg {W]4sIRLa` Y"QǖV˿ɑwgiIdI'#J2Fv 6XDZ a  C[]:$Z' @wP;Pti:z% AAu 86cfӡ~ H=+yy @% ɒIEحKLlNjK22" MehroEy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^X2AA#r@4K?QѼWKv.COt,Qo0)];:d/P)NJYfN%+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҶAAK?ޒ3:;^;|ux.Bj!TYG3>Y 'iîbhfmfi%OͶiX&pBM-ppA8AsM(<(Kh ;Kl (Z;QD*B17,7opqdP=AA $,l0(sptd )\×g B^P:d4,e\G0Ea!?Ly. pDȇ{qAAM*9Z y^?DX0| r#$2k(2(hx}!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#e@Cx7sp'Sg1{ ̌\kZMybl4Mic1ɷ XlJvK90Qj{m  v` p@5zp6w `l@s jP|>! d2/w`P=`1*$ `-AA}(hs.`-{w@81e f^alI\V,k150Np"M5l{e ^M54':6;TLh?z^\҆?s 3Z?Qb@g(w;v۷nݻv۷nݻv۷nݻwC@A&Aǃ{"/6 >++| J>_YYq=Md&$@JTbɈ@pԣ͈R P@!Bn1y eOMt1s%.-FԝA.Aǂ)&G>Ubj@W7/ly8+쐦bS;!ҴeTTC2vKf0~9ӈp6|6bl핽m-uDpB={ *dl@TG`A6AqD诚s0ƺcPl7 ^1mS,!5*̣ \}f} Hq+bFxgmrun䞖/B -N22' 52j{6tDoA>Az{n-glw*=9k#l7qܝkR!bt yYP7^.HLd'/(wmT֚:SZ_\qp8,Q'dU[Q϶KllE~yߪ?yiI}<λ[NfH[[ȥI"Z|ne{6 r@6"tBo /A FA6͜&K9R7#eF ,/1OUWJ1-d[ڦXcm""J_K[` =(6A4vo.8;J`Xz?VS:S |qA$NAǃ{ӷ5'TjKiH霥25غ)FsiG;noEtsT8\ӆ+j` ш^ך}(XVपܑTY`c*w>Bv{kĕA(VAۂ[IpQYX;PZ֜Z{[P/W30elzGcw^IԪXK(v}:US`C>^ԓR>= ,΀g}DAuqy{}wA,^AQΒ׼d%S9$c~ E8 -UK ez>QێڦX*dk@b.[[EZVUjZVUjZVUjZVUj=A0fA!k:J9킫ԐK. wԕdQou"-q(i08U)1 Bo a-ox!\^бg4_a&JRgS,f?-t\X@`PHA4nA|p^Pvn*DQ PWDGhϠ:ySRt~ͺ.mTƯ*c$s ugJ ?g-RGc,BN˳KD 9!Qle1Ԅg&<:C.>4oA8vA,ͷEg?Gj~sI\} fg|'Q[6k_/in,faqIz=b_1/b_1/Ea!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A<~AP:'b T9)tIMm'2l?J\A@Am/Z( ?2:&#nZv׻IL=" rKW)IمlD [fWmPg- +pFuX2!"tY&Jւ1 w!C{@OdwADAWn ֊D?G%guߐ$+/x=qѕ6e1[y+ڐ@]"++++++++,AAHA_Β'-_/%`RN&\DxP`VǨav {Ѐ ׼nvp63M)x2J`*8H>_λ&~ -~+CALA)pXgI@|8(lgM}82V(Ls.Yg0<q`>YRkZ (MC}aS)e2LS)e2LS)e2LS)e2LS)APAx,3>zB^(? "Pr1No m @T/NK9drT$1@aV-OPD2d5fߟV< Tͺ[zo`P)x%yEj՚2 ATA]h8^ʫV 䘷fU.O,W%m+uĸ0M LD|O:u.酿x yna CQBO k,:XtaåK,:Xtaå@AXA5\Ph)Q)łӇtVugf*ҐnY&EQN-e ݔ9~BVcB2&xL! QwRK=$c<)W)}hj*+qA\A\ѠMP@h$lW-sɴQ񝉲5eDw]A`A4 %)6j]{! if)r<umj$0-RAdAUR8 fY:?ϤrdnLy9حBnZNCArAhAqa krM0/ ]v:,8u'szo>g.pݡls?l&x?DxfFn&"UK[%dgAlA ICI ;"$YэiV6(qVK:ᎀApA%ICDQvQp_gu՘.&c]@(araN7cɺ{AAtAG׷ICD[o]v'_=D/HWz;d  "d)j-7C:>8AZ52! %VmƵR2kɵڽ_!q-chu.ɾc.kA0D!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#wAxA/ޒ3Y"nN6z Xa 6r^Kl=%D8 :DZti"ӤEHN"-:DZtAA|A۫`[Lpp'G3&Cw@BtXVz@n)j)d\M!+(S;DFyDlǔFyDlǔFyDlǔFyDlǔFyDlǔFyDlAA<% q$A"7Ҡp(_xG?6x7 ?2QDQИs]bD@{O>EZSOdl[A:FT7b07Ӗ9Ab] B҉XDWe5|AAJgR. PM g!E7殻պ2 Z ]ÜE+ Ԑ|J@ P/>; d1Eɨ]5U BC EZK(bHB@%`AA6 1%@[t!f=tb(Ҁoe$P$ⴳ^@oi\];f*虝.~rT|/z4694_%fV!o73='}O:wDqAA,Xs?7zyGr`|w@[FK*lU_ m'j *Nδ#Zdc.kC*_LRI§=*R_*p?@VqXN+ a8'ⰜVqXN+ a8'ⰜVA&A~Acp cԟF.B9#~u‡5hU_|eX!y2DWDAOICŤak`lG9g2D-ܶ@L3O3sX9r 8>>t,62L%8uң'Gcޭn:P}3`sxvL?mC B<*جu;yAFAuPgΚ":/~|u Hd/ Օ/* x ?Y`T@5l][q$O1:XtaåK,:XtaåK)qANAW,"RA]&A?۶Er\gt➪ f9KL|ͶI=wU{ 'Xas_k'gxX UH}& 0o[~!ZYc-R٥d~բplI!Ĵ[ `A[t_-V9n0Zum+jAVA zD#rҴ]m?G=Qi(qӣyERQp,}kxhih)ˌ^ge4 @sr~Q[A^Au cOc2gT:fI9V34g* j5&!XQِ .D AvAU4!gpSK fuw~W-mS,9 "JKhBS(SppSm9d՘T/W&svTk8;0Vm/2$O=S+iA~Aǃ{=0(2{b՝ Hv͡aq&^MEANO}*|R0{|9NLTH,Ax!] i 'YمC~U =N ̕tмE0AA~m/Z(ɪ?f'Ot^()?kP`r`H3eyL /s>]nM+"fzU_B*sV4^:3Ql漶9ŝk=>nݚE>AŎAj<P}EG&Apb[Qr CF9!EZ 7$ /@b&z* ŏƏX(`J J1 @ A &X6Kt #79+\T_Gf)jEaAɖA⠰Βp;`gN [/#/nn74 dµ9u< ?Kr<o@F30PT=2IȦbʀuiڣm귫^ aPrc  PC\اfsB tMLY؟A͞Atz@#F(.lt R9Gi![|Q̗>^l<}@qYb_1/b_1/bAѦAbΒ۸+Ux)/K?XE7\3 AVoD76:x@X.lIY z z[9DT2T?~Dnv8} K7z&C aA?y5AծA\P~;Ws?_4r(E5FP'WaF ϫŠZ ~G)sdZ`: ?};4[J.Sb@2V,9;9D wmp,B<L 3Ur\,?Ű㎯c?PI~wQdR!qd)xP!ÿka"{KuBtkL.f<-Bل.k5εܛpG٘D];4Ū\6h'-"Fh*9cf90k㞃p9Kk)V:9}tAA,3,yfZ?#`Pe݋:j0S; eo`|i:~F $C"3~EHN"-:DZti"ӤEHN!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AAGh7+UxP[Q߾g)uңU;Xda0@9ꄜbJLfKaY.1i\@`9VBAMО mmrDӃK,:XtaåK,:Xtue`Cx7sp'Sg1{ Q;Qx+}.1< 4 D<sl  qAA \י`byN"JۆQtieRj PM{0 B?>-T =w~QpiLiۛFW܋p+8wXח61c ȀdAA8ޑ& bE ]yP],>)j)&:4A A!c2Ӷ\bةU䊬M6BG0j<|DU}YDg:#Ǩ[X1VV;2s+TB0*mǔ h^A&A뎃i̦#-q`s/̽8ƦĕVU׉IV(*\p*&@Pe5; -@IrA.AICUy>  ȼ?# ' {rr\nᯨKἲpA6A-XGA d39vtwqifVسxP7Npc{A>ARٰX(82{X^%X_WLm`E!_B}ai5\ Fs9g3s9g3s9g3s9g3}A FAq%hJLK leL XWءU[@MiA(PX&C=t3هC=t3هC=t3هC=t3هC=t3هC=t3<A$NA)_ȏFp'B3ڋjN&S#HPv#`tIE957@}M!(; u2l%F2W_!RH \D>sMf5 OYB$(" \E㍍܍AbxAz"sO!K'ҽ A4nA0WICV'B1X48EWzprr[8Tw{M<7v= efG i=<8 C@ky^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy`!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A8vA#IkXq#qCU-Rl؝`(/RL'F@Y1>K~r g.lRhpiLDl1%9p%f@?b_1/b_1/hA<~Ak$#+]bXԖ #2X1D%H+yZu ,ԨGl 0`{2-f'|`1s%sc Vx Nޅzq5t'.N#lvDADŽ'S:!OtB(?Q ~8qGD)⎈S:!OtB(?Q{rA@AO:KGa|1X-u9{c1Io1fM/ S~]8*\&eQFnVM&Q}ViB̠pY= pܪhK G蚌&4JBAoZb9YD*DJnAHAuG2AR<lu!VBR-ߎ^aN~5]zf( ؐq3O2åK,:XtaåK,:XtALAǃ{"/= DxYlr<  L]8[Sh9v/]0vSQ]*хug*6, *uy7 ͭ oAPAff _=P)%.RmqrR܁;8` !B=km'iSThŮkDSpt8Z%e:̪EZ aGkATA̱|ts&I)cW|MkLu1_v2e 6=B5%HޣrA2D ^4]X隧@^/ duyAXAY & w^O2rz,uxJ_=MڦXCGte 6vlBùHNjZu<۽g*?g *&L ;A\ArSɂT~s-bJ`e[8e1DI$ܯRm`!ߗp#yC092Ƴj6sCȒ5LW.j,{Sƭ- bkល&A`Aǂ)&G}bC[x:h[!ۘgIJPy>7NLD}$-B<%<q9_k zg 0ЉdAdA6ώMg73m+1ëG[!Toc 1xopw\TU1G:O #%g!ͣL/%oƊ\s콧N+.X_ /.o|fAhAEk:J!UXl;f@ >CgJh8䫦}7@F:2+;)=9 e2*O}>O}>O}>O}>eQAlA ( ?! Qqq$YńVNQW9>[AMGg@ kQI\}uܐ$hQ"$~( m;^ErԷ-f߱3 3`t0CN_QTwV3AxAbqPXgI@Y ;TIq dIҪ3]&OP9 ̗t;@AABG%ZViZViZViZViZViZViZViZViZVkA|A ( ? Qgxlo#*ؓЂwn-#hFu3"־АR@"ǢLLG ] j_*XNƇQ?mFO.Ј h Tϴ9AAk:J+`G P xߔ{;2H/+#|P"@h((BqJҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴAAAͷEg>VO39v f.b)m괝귁ms>9DXb5J*Հ/rs/IڈQ4D~{b_tR:F 4UJ_sL4 L:=l0<2n+d?8IvAAiXgI@|,+UxPsOPk# -@34W[2nq;pɞQ~ W\bS=;Hw'"; z-6Y wc)v*Հ 8p2_kvֿVb\̩PKaAAmz@Y\J+Ŏ\Pd)c73˯>m;m/­& xV < W"ӤEHN"-:DZti"ӤEM sA&At,3,c r# d__~PW2'7R}mh#!QIA9j ȵ}~i"ӤEHN"-:DZti"ӦA.A=\P(y1dp` Ŏx6,-Z0&,k?oIĠ;M2>LֻՖla0"Vb!S(nFL94@V|}Z%IyF,C6)4i]A6A\&ÂX?2\A\|soA8t~~yN!깲ӫ'(]'춵_~Xp P$(-tK#p?h6\Q 3S`RAFAk$(??JSڋ(!,_T{4ZgYANAd1da 樀P BjF_6b A@`AVAICDDt^dlRN%Cy Lo u. 82F*YHݮGJjdLM 3!H!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#wA^A8ICIL.;;B%;=D&7@Vi]p(\M:L6 AfA5Y2#1."\@,a/h'GPtNXH 3q>L8sJ~ql8Ҵ/_Vȋ wH*YVZƪ.Nbd# %a@9SFѲHa$XS vAnAhuG&y\GZo˴akbя֎א/&r2j>Q|P f)xeK,:XtaåK,:XtaAvAƯxp3 uC 5$8O{+~F?@QnUheFh:HSOaրJ yϨwe;jBO-5&P 万=SyYym fߏ3ݚh;mWXX\A~Aip% 'a3YpkZ,#ݶT?,?$.7wlY WKh0$,Ug3!S82L;LP Q&Q9{Gz*^Ljj=O|;?ktaRd>TD!-AA68t)|\C ':OKa(h.X~yB;~dY9W@A\ < EAU,Q^i5gtp/텓'_ o s5nکۑQ_4b-QˮC4TD'&Ʊ"8 b9YL#D>T+:},v"6)΁g`(ٍ 2l浰AŎAu 8'SݮCљ S~]z?\IPvkg\2l?`bi&v7 D0YOs+ne+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҶ_AɖA#,nX? Xyx\AtIQ<F[VCSy7w a}uu/ cwj\}PƆ mS<7zLYH⍢Z1,<pgpH:R> ,WKM sK+]}A͞AK?ޒ3#ڿv7y:=D9e3EJ\QY`XPk֦˪iC ٠ i|,Mzi{ӆa"P"++++++++AѦARn\,D[7t+83PzW+ %eWRG]L}(`^HÄ1@ezJYgw6/Y;gp 3w;gp 3w|AծA{j(9bX Y})xL D, < Y{TJ=cvwE$\⋳v 4`\cY:g *2ɤeNfb%P)8x@\bȡ2Ԍ% %-0h(] 1gܖa8'ⰜVqXN+ a8'ⰜVAAٶA}(hs?5Ԁ'_qj E=qEf(j/PC@l%{JPd hz*8H06ZZnǰg9IԹGOʬc/gΙ]݅Dq @AA4 g[iyi/ɺTwAKC׀ 9yd1 K{LΖ"Bɾ \A!NKV`A %6 c9Dę̍i>ʑ<n`AyAAW,"RA4, 4ͳ`O_*%~7o]Ei|}ԪSI9Ȋ6CpɌwldxm@OVp@h f|F0C#'wZ=LFY:.H#ERv09Mb') OjLB44. i5k&ylA Aۂ=!G GX̲Z_)BJ s^O2{)p4܌"n2z_W(e-1t#/JXTP$OѐhFȩiJ7fٓ7IRo q*[ۙ^kqdBIcbJn@h)(c5!Le-&Ѵ{fݷnA&AQΒ "LB׀G^b}Gb˻ޫ݃i"ZP@ܳ}1}T&њ:*ܴ5V;SaS8x5Q1ɖZXLo ar-~ ILmV`"=5.RVH+Wl[-eِ]!B't&)2A.A!k:J9킵WiD?;BuT瀒kG<:@pǔWA)AzqfCũ  mT XSЂ2D[n2 tΌmR@1d™ܛ.ydgH>V`!F`?A,ͷEg,;`S";(_e|;mf8+VbcѶ-_\ϮtH26 a\ȯ++++++++A(VAWn ֊D?HDs2U:S/l{<:UFkxddKQ|EBsDw2]jH R3qiDoשyl~eE|,cq-ajWfs3ugֆ'OZii#Qq=S!? }V~{y=@A,^A_Β's?u<,篽p޼`lQ(Kmq(h 巀{,3 }mPha;vzB^(?[ W/_?)xPgh1ffYD/٬ۨ,-wU:}lؼwZ/Sg_m8җ?*e,U{o@0lsZuHA8vA]h8^7DXl͜ VeGMn~|!-iNN?;x:p(]XPଵhc/7DZ/puc{x3jVU0:YwSN!, 9U ܾ;nkYizJy4Hs&^JUIYgpT UcauS;8p 4Ab pj7C80CHp ц% #ؘ)A<~A5\PՃCeog/@Zw<'ڿfz^׆SNnH&Coُe>AA9U4j.֖b',:!ġBOjPU6\_E#v/qr|{A@A\%YV(LʹlY涾kExB%L"hפ`R._̴0- WADAټ+HBTqs_ FIs+TouHFN AHAc2VA;x| #oj-{nSEfw"VfJg#}GVFMޙJ": n[ܷě?>*j Că-x>m%y/^˲4|:>. H~閽MMdw JJ<@ҍw)ydS7nS֊ Cs .SAPA 8H ç-E1`L:[#l?nM#{7Zaɸ 끌Oo "NbC*rKOl0ɓ :/Xya3 o+nώ2 ATA%ICD {gHPvk&Q! :.7xKT[CB YRN6B0K=!0^^,8|[f~J!h7@`}`Ijz@#}W<03-vN!eDbf$#Sa>̹ p? V~AXAG׷ICDF6߂l!iJĨ,&aS#)C`Ñ XVsx\_/ aåK,:XtaåK,=A\A/ޒ3ީHI1~E̗Xw>sb} Klp6-VlvUX _0/6TA0TA9r*$2.v p&*~%DP3 5CnX`,DiaHTPkA`Avиlά $-13~4?46z$Sxض۠aatQ.DYXitǶHٵڂ\d_v'voZdeg`ӸP? .?&h?s[9~; @AIQ,!fJ60b,xd/y:3h5+L̼6ȍW[O7Kk/[9^m ;g ?`X*T¹l~2!:ˮxV3p?7s>(ኔ)IoE*:c6VAJ"*g.x1A|x5  {zbW Ea73Q6#hS[ RC]wLw@>`H07fO0TtY֓yZD-qwLc)ĩ[MsH)}4=9nm9vSiPT0 N\nW}ZDa+q"@RPAgo8<1'o\72_W(v+AdA<"#˾ {_|cnN1 -Z c^G(y\T(Œ;A <6/t4Jz$h>{ćwkoj],0E,^@F6gI޶W b'пvtww~a֞@Bw Tűי\dj3WVDv#RE*s S#CV*ΒgFgATSіwyvyVܚK\Cc-AhAyJ3;k97b ΠQ[/H&HS6F3$)l( *6Lk`US7 v\^~&"0Qd6a+q"()g~lEntb࠰?? !I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AlA6  Vz,[QX[R'E ]T>!O*2 ,$נQ15ߐ uP=E0:li`)닒@g4 `gSA_"85 ?<"LQh"!$d j]h)( ➀e<9ApA*ਪ1Bkd..Bn,jы'M ]I(:R׹de ATOFL%pw{EnXZoyͫzuqV *P;0c`!7 HqӯṡFv>#^4!69TjF:b%h@QRBO@&?,旤&795rFBׂrm<3Xآ2Ȯ\ًYT`@ZyLy"K9X4&j0C Ij# v& F$A|A횪dGʝt5YQCol@oMIꆮGd]`^bo:.Y.pZȤY(\UuwΦȯ&WOB0oSNZ8[@ޙE882J DJ 48^g#ܽHjY(O$X&;HSKYAAW.5a=HʄHGcv06b(Ȋ;Oj'g;,^R< {Q zt9ELtڹtNٖCI"o꨹A@/-: ۤ<vT;uʷe2MLq_p0]L{SoW PGgA.Aރ؉)@Qsgj /T$1uY ȗph@}2`sFzD k?@Z['ӖA6ANSE"Få睹-0+G3'[oe%;j@ϝAИhX&83v޻V_|Bózɋ+.YOF4cj͋L:iPA>Aۂ !*h8F$`IYkƽp&Ao±kR9tV=,Z[n=nC>9\h!nL [5k}{e_ԩ\1Rx@AFAǃ{= ^  =`%Ofb"̲B`+mc *8}q!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#ANA~m/Z(ɪ膌& ə$zJZtfY??[R;/6)b>`L!fOD 2i|wmS,HҜ}<͜Zm]'(yY@r[K2o3 mFޣJV 6$t>XUݨQʆ_'eIW̪:8Wc k.<|W}*/Hl/Ȫ\c.yOyAVAj<P{ZWc2"7M ID YRM&=EVk8rNۭ^*-7@K.ڦX&SѸ]ہS 'T}=.0 vaazDB&~g0зʳ<&,3%zUJs:jl}JQ{aZ-:2Q}-kK֠:r 6ˁ1DMjs`ET8Q8߹tSrסAnAbΒ۸*DQk $ fb~S\LbZNw%0&DPP.7?!'"Ѕ"++++++++AvA\P~;ju ĶQVu(P+HpihQ1־АR@"0pw@Gx Cc 続 ~-!2O%ʆ]̚C/ǚWS|:REC)A~A Ot$Zƒ ` ;n:ĞDX"3Hw|i:@LVE7ȷnϼe#?fSNa5Ŏi&[p*S )YPsM+h#$x{YKܻ؎NS!(6PIM;>@AAAa%g; 4< x$PM9M]tp- =Zǥ RVvR6qn /@%dG%QD?j8P fł%i 6Nr"|^upcOc\1 \t(%Zۡ4R8E3@/HULb7;kwU d㥪+A6u cM^\W#ZpVPOc#vswLU)\!&)p7 [8zL[O\6yAז܍+/YHfP9i`8uqAɖAPXgI@Y= ^Vz,ۣ=~JY8U kDJpd&u sjz|^1([@8vͽ8J:GF_GA.CwYc^ݜYO, a 1#. kpL?-Y6OaAѦAGh&9@~(-A69ps6S~$%H# O[Jș޾`ЊՍLǔ[9-gqg|yϟ۫A7fn@yAծA%\ѹC5K8'!r@t^Нt:zVI' jQXZ&x6" ▩2DM{F`2>djAٶA \cL(??TE' y/7+bAn 8M 6FɊǼg |"i1NVMQe[ BWAݾA4jG;A~Xb)#4Har[!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#IAAya4V'YحBnZNC@ZAA뎃j,q?CJS,f8c:Q7SAh/*祍On((@@LK`z': ,gtfQqAA8ICHa)?Em"M~!F!{o@''cԟʂskLk1J˚!1́AA-X̩uC g7t CLs*Tn;i1@C _,o=T4DI fl0".y =@Ax1 #@6GwRuPuB :H*@wHBJ@̨PE+Ue(x7sp'Sg1{ Zqm.Ho?wԨ:v.3A= & (=NQS-uC@ӕkm:JŸ ooN2^„`̃ e<  4]ݨ jTdT8zJ; b$YJYh> g@6 eM4$PxAAp88_e,]A]qzcJ7{| Q,I8jW  k4i"ӤEHN"-:DZti$EAA)p% 'a3ЋuP-ܮ$_?UfM/Ɣ70D`YcV'q {;kk;u*y)OZ[>$SR7m _1/b_1/b_`A&A~4@9`. Ab*Ii'15R+P);7eu2Eʛ.\ٮn4K }ϝv{S]%) v;UF]@WnsǪ7qo|Vx=/86P_5?A.A qP̡>,/5N6z X?ʍCI*R߭I$ˢFchRd0dΉ@,Vb9:!V.10Tk5G#`& ]kx͸^(Fz.:`qcE o~KiA6A0WICHE7Ne+Y G9T/nr߼߉$4*( x l˷tȯ+++++++++A>Aͅ~XHS3 cX5h=3eiWWEGhH >;gp 3w;gp 3w A FAk$& $:įt}+2<3=kmeGV8})g:\!G][s~9BPdΘl:'I14|1phZf3Ƹ)M "(bJb[<'j#pIt]RL}:V71A$NAO+F9Hn߳%-0S1 hP>ӷRNF@4"vCX WK{GfA+rk}U`%@|$bgg"/ʼy#pEHN"-:DZtis@A(VANAcpmZo˴)aMv+)m k8:N3̄ءHN"-:DZzp1=)/MVb]ML/j6D8!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A,^AٰXc0g=nNV!>Ts ;2b/Jp%FBGm, Z13K,:XtaåT z%K,:XteA0fAǃ{"/=ֈ1jBW٭x@ mjlύ}ch9AG>&AKp*(0h=EH@BL::A{'KGXj2a]A4nAff8 GT .N2N65{q /J p,*a 3bB Z~̯{hG"ЎEB9!Y|A8vA_5Ono?N3c@ PҀh\v)kR!M5*3k1јܵxFP=Bz(j'V 1Ń㪡YVA<~Au߃D垚6ݟ|?jZ~LKo(SI[v*fU 6!o-ե]_G0kDg Ǫ I_OFc*F`A@Aᦜ=0AI`P{j呔?<#(UMkYϮm,h K E[`fmsdEp/FYoDk0[#|+wm0+QQ' ߹4ADAǃ )U/Dֲ]$&-(MHKPKh}oc78ظSrOT<_~JԪNS.y%e#9j-V/ucWiX'r}݄ "ra Gl6e_Hfƀ㥤%XW#>P ODAHA/kC>8Q4"4%i/AW?.@,d1W15z3n Aǣê st/L0ǏB샵~tV1j~*r;GڦXj-)^ul QN^ٚv]kv]kv]kv]kAPAtOmIc``#c.g `9 XP'sgX $,[H3 ` IBEKQ8`V X+`V X+`V X+`V X+d=ATAx,3,^( R%YoM.z~S\Aec'u(d-""Ƶyǹg1/b_1/b_3AXAO:J߽ QTB7p8noX*[c[@9g>Of=I@yc < :>A{+F'ҁXR6. iaVO0h̊txQҵD[(苵_-xC(C]G*XՕhA\AbqPXgI@Y ~nQp> ,\37)\!ow؍qyYN&D vךJ.߃Cd׋;ҝK݄u|hih~kG~~ .A`A ( ? Qg^jpA ^-~H>#aph7)VĖ {\ˀ@θQ  +S  h]_ۣ{qu7 z.߈WUz RC\R 'xQ ǿ/#ƣ񘓼߮'vpP>[w^'ⰜVqXN+ a8'ⰜVqXN+ a8'{AlAiXgI@|,*DQ!ehKk ͼ(3Ͷ.ؒE fxV}W\Y4T?g/ĹJTg-1Gw#,LNZ$ W!Z%Kln  &B2E.}4ǤqApAmz@Y%]y,ФDP`X'B-rSXUOZo*lU$%i*h_MtǽTs*- 3;+ڲd ӐLhY{)AtAt,3,c~DG9|##@_Mazڋ_Pj5r8idRPNK~{1=pt`&_•,3QTX.B{D: ύG3]FH W#)lB1^p 3oUAxA=\PDaÜf~>> Q أ.+Sp}2WN)pBF)aŋ_'tjۧAqIu?\s.iA|A\&qD} ]^=pT&'npٹG 0r#&VE  L?AlAf'r{8M`AA\ UHH^(`M%NoIಂ EC0p/bׇkp'o7GRAAk(??XX2'.iXAAj\JRl 1(^qQ|ki Ÿ]fAAICD2-\T>Aж Yn\mGGt4ft/| d"cAYݏ~ 2~͵@}A&A8ICIL]'rܕńU/%gl',F9 Ja~8[/E[*G1[r0A.A=I6VJyjzA b?pGe] LS0X>MN@]b= @( AP5\\*L IuFQljɥ+?trH.OQ2ț`sUUn"^.A6AhuGin"n7?gt!e}C6s2S W1RjYi`]Yj(YDW ČJ@ZrL-^◆XtaåK,:XtaåKA>AƯxpJ:vÉ$0D|]֪&֏|x0(݇ޟ 󮲡jJ'Fg6tB# fFC Jyy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy`VAfAK?ޒ3 W)E .Bk#o_shٵɧA93.ZpX(N(7p$>Yi'NRzbGw<90G]\KcXk_oX0~-3xY`^!]Y.Bw Os*N=j|ԐnB9YAnAL1NT,F 7˾DCԨGl#50bS-(dev faЋ7hw7"P`!jQ% ~gc:CC _,F, Mнg1W<AvA߸ph\6\8&$R#G ]uع ٬4Ji>w{D 9Hҋ}|[vi{C5DAAF^ U15fK벖DXZ1|Nm7t+mx 0, :RFùFt<7|Sq !=^~=/Mt߸{]؇[;~!gCQ:x"-臃A~A}L7,q~>ZْLUJ%*%B fD Q0Na a=/vp~]` 4Jk̜)뙺:sj2#}YteZI#h Yg AAB (D$˅1EN.cc?@G ^d`ݏה!Ys x:V,-&0`ʼDӐ{0g{0g{0g{0g{0g{0hgAŎAff j.z.BƗnB>BG'5- lȜoOAcz \cx_/CJJa02W#)*X:?d?Cªf"jEz;'}A͞AC:CKH.k SM%bF4s~{ݵLnr(AQi7!(cp%!jJ LS#k r^ ,>DhhAѦAW+I4Dtb Ss D"LG)>Ly`y} In<&!8"犊Lq/%Ph- `-IvRwAծA wt++- op_q`~_Xkx7qZ@ u$E< h!tʲv-$&/ BImV7zFj8ؔK{4hMqtm|!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AٶAͻO1HxA^ cjHVe?ӪvSv .fQ]ڦXcoN"hIZY u*Qh*2n۸G%pjj_t$i/Zm276-xCbw*'5UwAݾAǃ{ӷ?5'}f"r:g)|h /\@?L~cz(@DޑnRC2ΐDŽ]Q|Թ$~'kDD7_ԊE!vwz^=F#8'xDZ-<|7!,u+_fi¸0faAAۂ=!\ FeXq\Hc|Oi aAG@ũ$eX؍>2Ltg%֭ 1e1}Ԫ^cKŴoI)nAc"?["$Nj4PZbkqNGҮ0#=Nj~T<׸o"AAQΒ0q"ݡ%U1(7.% 'Kt R@n9!kc0iQ\P *'yYv*k&\!k C"X4qrv[߬z^aG'1-3WࡻJY.|PH%NnᵃK` EPr6DX(^Fa"PjǯeLgEѹ8GAA|p^P~Ns? l$Q] {o;ܓNp1Uف^?3)63';r}X{v)H ͘B0'Ux)bّC WH~V*Y(DH-6HĢA7R1_^R+fJO-e0x7sp'Sg1{ $fPE) X]Rd%w};TM= !>7t@2p<|0ozd>p] $,MF+9Xm 7 Ev8ђ v#;X\+ 7|g yB>Sq`HH^·|fg豑v"@5ßn,/ %|q4}0JPMr衠$Q3!3ip焦 =m6S] `ِO k3>S\y0р=q0`5Kn/4B#py  I8DԤn AA0yh,u ^OÂbú]ne$e:g/_ 2@!&;Tg0 ףj1L;:¯[ݵm^y'˄iB:z(*B+, aAA vt~駑nFIM\ pg |M^ۘLO[g|Qs(8m=@ BXGݕA*p 3w;gp 3w;GA AWn ֊D?HI7vˀnV CB Y`CbA%911'm"\7]b0>(S3S=4EqNv. qZEk)|~2@#&]dJ ¬`~ #aA&A_Β'^(?-T|WQSx(:dJ W09)V `x *)4PyCp I̝=$iO-[vr˕E{IÝ-q$•iZViZViZViZViZViZViZVi[cA.A)pXgI@Y< ^(cCJS.zaeߠhJiN*|%t/p!.G%0JrHQb1/b_1/b_1rA6Ax,3,c~DG9."[ojשfc^ȡYgDJ UWL@EgVN"-:DZti"ӤEHN51rA>A]h,Jzl9pp'RŶfPGHj}'ai+wPpL7%N,:XtaåK,:Xtaå@A FA-\ѹ>3,H|㙨dMdwԀA^\TOcN ݗFvVA$sE, Zۙ$ Elplzh9Eg"YȬVr+9 !I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#^A$NA\%YV(d3A?/Q^34<-VA(VAټ)O&MeܗqM:#H'@LA,^A׸¿eTIaj8;r֞"p??L]A0fA\}-qW#> gzqF9'\H zkїY+fvRwb̶<{ƨdA4nA ICDy;bvEPh_1BpםO,iͳlEQ (d,QWzcbhG"ЎEB9p@vA8vA%ICD71pb:NX{7Ðvc .e*k-nYu|A<~AGٰXƟa`N$- Nc߂l5hIs==[#)OZ|g-$\PC$(2PУ}9;S"o{ƣퟞ_!|HU2Z M7EN }|A@A/ޒ3԰'եE}ΤDou^6zsĄL֢`폨Xdp@D qר)*!(i"ӤEHN"-:DZti"ӤH~ADAv" 'a3ݢ h_'gsv,}$W}qF[T.Q=a? 7P$0Lb_1/b_1/3AHA<Cш3 ܵq_!!b6T5iM%ͷNnwau`#`*l%KWb_1/b_1/ALAyJ>o _}#G9{HvoDtQC_~/^d>[2+++++++++$APA Inb ՁCŴɄ?B}+2ўY"z$ˢ OUOv T|eۺdWy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^W倬AXA~ fَ:Zr@U}O[hs'Дڄ0?$t,fSP4ˀS Ӡ6D6 *#i}'A󇋸yyKalqzUScb_1/b_10AdAOICG{T_'gss3)#{hEZ| ^PCXp*Sj&|4N֎7}zr` }^OG7M& hG;H:e? =9IqBlxNS.14TGi{AhAuADQ,Ǹ?.Bx;2&^@y6P{~w, >* ;K.ŒK,:XtaåK,:Xta]AlAW,%%#JoHrQ?t $xj:/|q)z(Ʈ2YiɃ|@Bidu @a/l ta`Ӓ: z_3t:@׫AlApA zD#oBX G?l< x:TlhQؤu,pCyxæ 0tkO~e4 @sr~Q_AtAtz[hXOO(On*?"ٮCMcg[o $ʌt~gkPT7$~HDԐYBL*@AxA0O;+?Hqxi nkR!du6Ze"euS#.Qß_}j8f.GGh$BIid/>dKG7ʼnPUT2{餹w IK) ((?+9ahO*#jX';g=Q,Z- PL.2ovZW=:JTb ?-6˱)ˮ{35k3 &s~˞@߻s|@ ^q"vAAǃ{=]XOslXjb%1n6#2iيXn2RI*/:&aڦXxNQx TSU#xDC@IW۠* NL]XQ%1t\&`r^K#U(xQa絨Rdˈ#@h *iQ۷3kSHwqS8ƹ^A)qOc) (9D(TGc#U`DJA}7Φ/Y/7 Q8jQQki\7 SI0<ƕ]:,}i,yТʁg&QU!Sjw6Bl";C \H -oַ;lmPg5@AA~m/Z(ɪP%T0P@ZVo$%ś8QRGѸScMO%Ս *0%1j` 8"Ir\8L;9I=?P&@!H^ւWCYӳ[kB9 *١:T<#0EѲ`9\UU#_y4`Bzg V`Bp@=F楸`n"FT\V)%LǫtdF"YlYؼKw*1A#Fg=K֠ɑ bQF20E P(O}T8x-'6@_D~+2?} bg[14 &Wwt`cjpLt:hqjd<6#"m1hJ"Q`?-ţgq5O(1e@ "D) [u\'rONaya13W[T afg,`:>c$k' (X~@/eHA&A⠰Β±#CohV5 }BLooMb4,5?ީzKH+tm~kz/TԔq&n}'B8 r$Ap2+2WDC;86j;D$8_5:GIRk64uv#orY9YwYAe Y[N zW750u__eX_.̓>7rrGl'1INxYxS-Df';7>e=v3|A.Atz@!b{#ݦڎ.$gw2`&9`)_1/b_1/b_P!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A6AbΒ۸*DQ}4έ \rڱK9Zp8se^H$NPMV{(/(Yp|F>@[<1[v?o}y..eSZ'A>A\P~;W8[<\[LP;O:KV̈́JQ8S^C̓-n.Z#v P.@6 _|'Oa"j5>7d; %f4{*+[XX]Ssu/\|GP3mmЛm~qɀAFA Ot'U"O`R%YrS^<(^a:rRwbY;AܒǧDY+l-tT+s:]!~ZҸmEQ=91Аbg|ztpd;qⓞ!lANAAa%g6Uz-Z1[Sr]>mV{8]?eAl3\0HS\wnSR"Ix}l6S!YZ}[*ڶ+AVA⠰ΒGpUzeT>> cL6%:G PQ99X@(OL\\CG,ױǕF[IqɄ!ef)׵{p=y VyG!.5s>?@5`A^APXgI@Y= ^QX?2`SHXX_LߙSwSՆޗl قa߅ŒJܪ3R Lf/Ml@2Gc; vsMfI)g铪¿NELHٯvWk"+)7l<6mD{Ct6DV<Hƴާ ,,IoJ/LQyG~GϟT}OAfA,3>z|BfT{ŴɅ[ΗA}A"돏Vh1gtBי*0Ԧ@.=V<Fc`O:w@ dE-@fڟO /5΢E u ra\?c{T[`1,YԉДŏh; 1HWęfqfkV7hwlГ[#"VXa'AnAGh&%_P20_3-UK _哋;Ę%ŘDLP9r7EVZ5w *kP\+ypFrH5.pp\D5⡿ oC~*PߊT7⡿uAvA%\'7HTƒ9l">\V ^b2ηhG|2Jb9OH^|M(τiz+%-vs5]׋R%0YJiAAڹ`Z':u=4`w:g7WфHg +3ɵH| |XB@3*wo۞ꡤ\3_+f G+}lAŎANC*@J8v,,^?iIAZGZ6ly鰓zbīTQ`}AɖA,n1-k~&a p.IF D{(\B&7 Ck3*2% PmCy~7n9asj,ʫ (# `ugj- Ԏ~7uHx訠O&}h {)(F/#WK(M)jAѦA-YqC@z; Fu +x`_,kB5f c"җ'|Vifq w#qWm{,&DW! cN݅neG D=h&0V!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AծA]׼8ICVJ,J,XK_}px詯H.VWИԒ1ao17KNUL6\{|P_ٰFC=t3هC=t3هC=t3هC=t3هC=t3هC=XAٶAޒ3ԁ ' \Y 4Lq, tMolx}@ g_֣J̭-H >?'ɵЈ( F߈ᠳ- DEg= ռxS9_BwȻF^~]^WNzGzd܍CN"-:DZti"ӤHkAݾA)_"#zie'x#!˟>"xz7wlRC`)*gŝ@=׮ndH:ۑ v`<9i=1X8qQ/'_ޤ7WL+Z{mE2;lha-q9hE-: |O}2^}`(Wڕ> =3DxoIrt]Ax}5h83qdibn;MQ3 Ɋ;l 0+ w%nKӣ|1ݱQ Y¤.Rk^1_HAA%@%#3Z[XH`ng83f8u٬SG7ʀuica6M80L៣K4Gonwdʍ6oma4N":VHCK$6 %uB/b_1/AA~4@9(XO Cm{$6C,O9O(״پ :=),ȻcZl`d!zΛIgYaor7ʼܓW0nxK5-e LZƊkt?7t2Mz .#sfxZ"ͮe"xaP:TۏeWqAA qP. ۡb*FXic׫)GE]vk(U{cjl gZ.)`@1΃W g > (p]u\b8'> QhRZ{{Qp52iZViZViZViZViZVšcAA0WICDXtE16%5N6z X?Я@\QBZC^j}>R[x*n_aYE\cQO[;Iҭz/T`֔E' TDDT7r+Me?tͱi!$mgڔ4<}4HRy*oc#rNMluEzXOpڞF٠w獥Eɷ6GU =[fM@ ˚UWfa(9G&u fNx`!fHf2oq۪kle 0e8x7sp'Sg1{ dN\Mǝ-(]V-nfވww'4@P/z f^=없vdl*P*RP0pO #i p ;]|);3XG WxD4[h | p`!2`[ EP9Ύp`쮥 SMʀ0-@M@AAkQPс@)&,]ȼ׍>txeG/)4Dz_Lf=!P}HlPUr7v'ݬhI}FWm-O]Q)^\O6GLu ܸGJPSh s$УIkC@"y-Y2̗}ζyXf֢S;e ϧ.J&QտE}J=ff͂$M(A.Aǃ{"/ pQԩ#~<|Uåc'9US6iq<5!Ԍ@/g`i )ɘB Q02 UMD[A=by=n!Zez.4K&/TL&04L0Mf1TM1Nf2TՁA6AffȏD(<\[u3 \uԪ9o|J&-I=6vGwr!Ԙ=@dDSpUT)\KEfFNP$5*AUmd 8qA>A0 DPHD+' _kR!I?jc>!Ƌ, 2/u7_-C(yOl8Q}rD? G"xؐ@Xq40X"4G#Xmikwm[j` s< gI@rR$u8iޑMCb4[w.}z e% xA0fAEk:Jϴ',"DT!M̛M$I+tL%'v]R֋83 !qT 9}ԪVM ERsBRx݈b1F#b1F#b1F#b1F#0A4nAtgC߀|̲ ; n~K} 22J@` %[BN}?#iA[: XhkOݵLP؋5`G@j*H2(^|?(3???? A8vAx,3,^(?30 #JHU:ySAn5hՃ]GȱF.`@X-:ޙz|ڦXj^&) jD^Us"c FI0Fk Am@_Q 0v0 rA9 rA9 rA9 rA94A@AbqPXgI@Y9%p˄O9;QCJ_UoHO5b S5k``_Ș5W[{ha~3-2odhs@e|[W CBKիOJKCoԀG!eI6p6H<"RdB`A5:¿lͥ8ADA ( =1%mEϨ"wЎ !{}"$&ĩd@L ".KVFJmT֎jrI'?ҍ {.eCG#p8G#p8G#p8G#p8[pAHAk:Jä7:]lvSէ"AH58! obN'{kn'T7 GoOOsXO6ڦXDlV%Лl$P;$]p8G#p8G#p8G#p8G#ALAͷEgh{3,p4;@?Ju'^GH{ʐZFТ@af[yPC,ݹŞJs۰`A`A\&qQocbP`..,XAdA\ HH/ $ v_-RŽ8xU OAhAk$(?̩+Tv?G|0d2fMIUAlAY(t\jNc2ջ%ߞf bV4Gp(|ApAICDXg=2 \ĨUd?~5ބ kC[!2˯[gU^`eVhw$*UrebC _ĤAtA8ICDIdسnhw;/g7\=x~r҂L+nib\bxq_=2AxA=8ICl ` % l2t'2}VI +ɫ s(a!@Ӝ|!p@GX$y/nNe>]zGiQTIvPjņC]}?A<;|>[i"551A|AhٰXc}ӷX%B`ˋjp򥽫iL?gc?."goL`XjUvJ[o\ܮ3c~)Nǜoe)urRw`b1Ʊ59mqfxW İү9BsLh Ō9-vIB aL^Y1Pl'JƊ:^UoZ)4'#_8Qq覑5gA:jRwbgjQ̐AAƯoޒ*a`! BY}-}tfM3sNK,ư,P~MҔ.@7iiM-OL .BЩԬ^HY=^GAN|mVromZG|$-5>x Q|XS!XпcpAAi_% g@+dd U3W/Nvkq2k.O"GxA VvT[50P eB,h %j.n`eʔkթ3i*%}`P1,E%xAA͂D!eKrW(c~(i"km7M փW}?{a ^BlduA#Ā;gp 3w;gp 3w;hAAW -`%`N"FȬ(`}/yBd Ih8!ё@@=c4 u)ӽIfO f0 -(mO:'ⰜVqXN+ a8'ⰜVqXN+ a8'AA&A#>,n1"S /̲ Pq!$x>q WX˰Ϧ.93%"ivKlқ|:|mv+++++++++!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A.AK> cv-80-u9.$|W|/bt5|5}}>Aw+U2j, , , , , , , , , —A6AL1i; IJ}7=D[52.2w{덑b GP@6Av2]dRʓi$ĥiZViZViZViZViZViZViZViZViZVA>A߸pnb±gt CvF;I2\1ݧ5hF@7v-tDPnBDSIΎ 0n5K/ܯJh|=^ز;¬X34AyGVoW-vW{WAFA}Ll,EG:\d-u3PUX9]Ox>%SůӲ,s֡Xe_Y)ԘyFL0p'@Of뛃 g0+]lh(2_RG3c*uANAB (h8V`h_1~?A~X~'Iw s,:=šsՠjR罌W^o {UmJ ŏV.dسvYçڈ4}|g>u1jr$-AVAffȏ2{W!b(I?M;eJ^RI- oCDD6OAIwLaysnݻv۷nݻv۷nݻv۷nݻA^AtA9Sg /&1P1]vt_WiۂX{+qqx ez{JԢ)03}030 +BE!Pft5¤B/F蒭O -\M{ !@ͭk^gG _G3AfAh8|nc6S}ԪJ|R8V< 'Jl_qk$'\Or>}Um4⩭g#}; Otv[k)J#(uaZmE纼{)u[`V9m=Pjv -c}AEn؛~ۆbǸ5ޥAXRKh/ sοG҈+0{VD\.6/a68HH{<`:#LAnAW,"RA+Z)8ޟP»)u@so]Uy׭=.µ7yc;ef\[\"FV prBHV 2GhE%V>R~q<٭NAvA z7Au+G1ɶDo5v#GSlM@4کgݵL@7 -h@J/ ѫٰ_P㎮Tv21[m0 Y|7-d2QF"aP| GK@A~A݌O6sfd :@dp=y4:["SiNrd=kR1OONfU!dk\B-s#CAM5>y/$oj')'/)I AAǃ{ӷ߮DA T)8&0\M㋀¾{[%IN%g/<#xa\`;wL1~X2l3! Px >ez\E jU)E7/YF:tف((@w^CUE _m՜gv`t_ |aDhG ttw2LGQtt7 `AŎAۂv?H*(ѻ2 X@͸7]h8:0T p֌fֺ\/im@Ѝ.@ 4qZ{10G5ZyڦX֫cB@&f0\ĭ@񤁫gxI-wֆ]k~,Ꟈs9\F]kIO(k@AɖAQΒ"p&SėW^s /ޭ;. ;\O{m$T+J[o^f3oj`3Y$1`a-5x}W#ﺸ}0Guq>\`A!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A͞A!k:Jž%M 1h3~48 \[}MfF]t# 7@(r $H=“1ZVMg ;2ط!D X 2VMxHEqe8 ݘX:hania\n6rh^U;ޡALΦ|AѦA|p^P~Ns?:rMOp'B4G`,ֱb(2@IKBqcUv2x:uDǀfq9Mi_y;FS/ B_A/.S`CݸP;08E;&hAծA,ͷEgX%M9V /|翏s.Lf&N~TRABlK`o,YX|fbś7o,,YX|fbś7o,,YAAٶA0yh,u RB2-)D6B>Q)t\ZaWtNq8_ lqۿ}a8'ⰜVqXN+ a8'ⰜVqXN+ a8.AݾA vtj(uhIƏn1X"qv0R?FLB|vN&a/Hwݩ{EN/s`9pP8oI8Hebm;06 gNB끌Dz֖F|Ѱ&=WKrS_yAei>a (\qʺ3 iV`@!CmB`cD7k춬>Io9!K2qGOy~: tG#l@1(߂Ec c5kZ!@AA_Β'^ԠG4\ R!ߢG(3҅hDT9 !vn* S,AL>E_NuvՕhXk`R01]!`M}2v]c9 TS CQ$͵MƁ7JnTjՑɓ4+ė Rt>aB7ʐoX)em)ICyv΍' (0/UܿnXr.ce-ilqeяbKMjqwYߟQ !mpshWETF F6 ~-V|;㦾"cXK]<|!eq127=aF-DÀ9U #;KFmL6;Ƙ-|V%&e1+| |!sa+}/[ulDkkPx7rzb%yG9zw/tzЛJ+~'UF?}ð Wf*W,{Y<>.sZFK>Y.'AA)pXgI@Y<&#P&̣31sKu߹%J-6Nhj/*+K޵96d+{/\u4tyT+T$݉iG)!b>oip _Xb7*к/J3ѣ!H_ Ch%ٿg|}}V_@ƇsA4c>JDb+@W4a_XLEyLRK˜@<͌Y86ϬoQ, xM7_S7e/ td* bjCk+>CwR%{騊NGqwPb /W^~#îe ,>EHyCD`)>j&xv!m;#T:TQEBcJ'TSRAAx,3,c~rQ{yžH45k: ق/Ԭq잒kȤhj},y ֮Dcϣ,]8N[KAީn0 حrN^:)lbҨ@lXnīuA+aBUp\c,oAZ _yS߰:=YSC5bf H@z\@LwE 1 xiEp$!qifJ:RGMK^^~a,Nnq\a݁먏RuzLkJf_> -N.K{0,"!Hb!V'DhU6apu/]_dmI:z1ا wC?wil2ft؏@Bљ^x nO@\W1e?x7sp'Sg1{ 2lw xkr0#3mlPWD%iZ2|n cu6ħəijh"]/?lLsTToV>vw qeE̜>hWv]Bƭ֢ |-84.(Bz7bv^"2 N`y{虆Hz*0ԘImT?ԱOwv~჈ AN^b&"}ƬHH L:޲5rP7G{iqpQ13(p5 (o!4d@pL_f-Z8]_S"&`POwjҶ=i54Ѣ50 ˕ú=fA!@tof59P'%VHL$&[VQkU=xn|fe٫u#a~TD!bQ_wO*@: Pfz=eᇖ'QFl%)d*zɍT2{!$v'Eǩ(^ 1tAA\%YV k\-9KXMj )LJ0 QB(0GY0 A w zF+F߶.Q6qJ*,Wt+^ڂA>9r}V>uCȆ[w~j aw͡'yfPw$n8AM4)Om.8V[*iKXc/Ѡdv" m`` AD|W-75X >*8[G1@{I,H^WAzpoH }E t0Ց~ɀV?v݀vxA&Ao)Z6hV"cV]Zcg6i>ΖM8>]`olOA i+D`W  e 7!铟|+[Hwե,CMhX"?4Rܱ, hycn6~'ʚwuC$coHmH`D.A.AZcӈ 8Z"*qOe_Ӊ;i `kۂ"P{@ʸRĒ|\nw΃n`+f죠SID^/;r"T*rPv(Å5AjC2Rsluբz IZ{NF|xz-fpx^Mbd+S I߉Z܉XE9 &!ZpCҙ(пs9]C4_~^!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A6A ICD*8X*#nYQ[hTkTy@9apA%bq5[(/PL?lHRC+2nj>юr KJb ,@2)+Mc(blC <Ӛ#~ !d3bJlL#4&VB4GS+esqU C M<=kmT-"طγ[}>c(V9! LQ*ց/+A FAGuGqb {"3J݁Zs`>]#?cK%j1x1sOB̘ \=y[މA-`SVə!ZeS_ݛys4N V?53g#yP(pz +-lɌ}Eң*!jR)X &Aqh`ɘ"#CT'[j{2:AJG&lc_'Ub,N51VPqA$NAP c99FiC07t CNlC.8!& f_H7X^)~F?CN"-:DZti"ӤEHN"E|A(VAl~, iB3+w@;r#zZpXU&;`HRb#@~1/b_1/b_1A,^A9%#jҠKc6 h{.0"6oîbE]WT&F00p,ˑ_q(AWߠp{Dɹ8M=s%H/rbϾVZ]bgCmA0fAyJ F[0p25N6zA]Y^<&IEt?s Q!N+V+~_gYEXq-90@~Z2"K6DT;(3 O &f07U'רA4nA InaQvݢ11t1W#/2-:$m\Qsą4 _ք@ɍa q&n+]J,^ %~C2 $E|]ACW,MhΌ\'g ќA8vAICVX1pxgt CG80Յ *~ųo3HRM53*p.`INQZp?ViZViZViZViZViZViZViZViZViZA<~A~ cp% "'+| )~7[SEsЎi5=0J_Nހ`٤3zRuFU sC{St}!o+໥]m?0&,2SI8oA@AL7'%L' dg+9mS>w~'[_yfИAt*T5>rub^B!4c@]֔I(bW_eVZ3^nN);'uADA<% ?yGu<.YP GzA 6O*ofnF[įp."Uib_1/b_1/g=AHAOICD}/8|ߧY輝׍Az d WV-@EĕZ&\‚EY:jB 9"k$%thAOR$M@Yp2$fRvj䰰 g`ALAuADQ " Qrd%)݄GNx}@<l*OԮmd;FcL e2)xeK,:XtaåK,:XtaׅAPAW.5bͱ)pk<|Z]GlK1E3u/Db ٮQ.UT'evlI`#fGm$ں(`AD: Zpypt@)A!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#`ATA,Hs?iP!^S~=@\mֆf9tE 'sYc獣"V4[c0#[AXAu %%F,./ݣ,qݣK[K|H@a>b)r-№x"U$A\A'14 ~'4bYڤ󱽠]NԂ|KmS,!P`U1[;d[ *mETI V1؁JPKtĮi|uO= }A`A1O%=asZ$_p_AŇ<;3'"kR)>d qpkrG$M2VBijOb/?^ë\cCn%OtAjQ4 A| BP1 C7ApAj<P}z9(s?7^ේP71S*bYJd£ْ#2@wytܢOEu_Nq cbUvS^" S Pɘ_i.k\<`DT@ aa =`PL 0o@qAAbΒ "9y.ht=4!̎d#z2A%9ؒp. wp"꼯+++++++++AA\P~;~DG9 *Z,5zgxZ.Bj(D)VĚV-yŞAK !DWy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^W倭lA A Ot'U"#XJY͉/=s)EhI[Jgf:H/" 3-~>ˈ6 T;,|k#vxqhM+W rǎgbl&>7f:8 A&AAa%g6V Un;|#swKA~%L>dj.H f:hBC 2Oyw'Ǵ%ZBI0{b:ɥ.B@(ic91|o!vҒ P߇"#˚O߼Ŋ ӥ!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A.A⠰ΒGpUzF(j$ \J=|\n7B&0CҏA,3,Jzl~l~{D< g4_ Kτk鹿!`! 6r$q6`Wޗ9x :DZti"ӤEHN"-:DZtAA FAGh&Cxl,U@si.Йp加B-elQbx*q(0FH47>\%zaPXwxLP/?5S٬Q:8J꟢_\1@i\O6x#zohŜ V DfA$NA%\'7HT|`R/qB{ƶqp&M*iw3c2-P`;" LJ lٳf͛6lٳf͛6lٳf͛6lyXA(VA \cL(?a^Pч$Ls"ܬ3mu @F@r YסxA4nA,Xs?Kn(zu%L{m't1.@Ur=3PaF '@ p9A/ \A8vAICD&dzMw=D'pA[[0~MkpYzNB^L4XgO2̍ܺUQA][JTfv#pBZ(nGC BVLh~H*^00jo&.wd}.6X ,CHE&THNUgezes, #}A<~A-X w1,ag7t CNn?e_[ =sġm#}A@A]׼8ICIL-qߴk\\Ybܬƫ}=x}@ 34J$ǩV@6l ă #HVncy8"-:DZti"ӤEHN"-:DZtADAޒ2.Om~^vz20=@:3`؅K\-y˷%5qpAmvR[A:l;W%k a%F˜9N"-:DZti"ӤEHN50AHA)_% g'hݮCr77t C&ſ`Ti+L-8u٬SI1}b\rB̷)HAb_1/b_1/$ALA%eU=L}%QÞضGgtLe7?;$WNvIo56P'?γ &9&)4< .:Ļsnk8#BmOJu TOXW*Hc`LEckH.J.1d֘i֣ٿXah}YДǍ#6NV)&AdAO+*Q<,jE É`%~HyjꆮG=ʓ_=iBq; : YD(X>dAV{J+-qާ6"b'{}ɠӍ!DIԣζ~=q+BDq KVF3ܷy㐅,?іS(~AhAJcp%ok w&DqrV4HN{@J{0\@U V$kQ:6(o ܦZTc_2!G=S_BōK]K|dc.H+CpN. zHEFn=Y)Im~ŇDޛXX!,=HxÎKIDG({)@9?@LZ_0i'깋X44 >BY Gưzg)L7y@Rc-8 =)AW MqD~ӎ! 4o6yÍYW_fFLlb[Scq4Xs>AlAٰY-`A,[t ovJ;8J#9$ʒJcC)y47HM3}G=?3ObA`y}OzgmAȯЈl<zL.aMم1 X_v+j3o-T|eZ9<y[fD_]nQf9h, {x=]>]g,aR_.mVMBpܼ1FǑQ_0"}BrR<7Qdr0xd4Rp(pܜiApAǃ{"/&"8`ذ(ĶJ 5UVі*'P!\)a 4Q`ma5 -p /,+-s%Z vځgށt`798n-W~VER#!Q`;=Ȟzb{kWD= BӮYJ3(=)&9VXLUT/'FԮ/g|DP$TBr TF ܵ#`:󉈛T0zyR-hE= qb~\Y|?H7QnvVac553֬i ~AtAffc&@rZ0bo|<íh̕N%'o>7BT_EXi`rd)YIs͓o Md hI ySxYtxZ0üpO`DOltgҠ5L &N?Jr235;:lZ8"!]*fqIP g>ͬQRء 꾼A|Ao+aPCeQ?O[/5< ̷F-{ݵL2$:2 !PK؛azuǗn -el (rӟi/5GjQPT]Pt)pO2 >n™DgFJ8 aI,\RvۀAA킜z+R> ۍ)| :U! idA)I3*19~AMh J\~Nl :,:V1WTvk#:i;AAǃ )b&AbKoiO)*w50&ԝ Wqաw뭀 g' (}ԪPt!s_ؖ ZSRu[X?7nhc]2WK|尛׬D3o,YmB 8b^dSn8TQ!5KddxiY, ͔ƺC$->eC@F%0d{naJ'|9pųQ5AA6|pc`|c'!p )gIQ0qvI\CKA&=߼S/ڠbJuwSj` cpK-rx@8ёQ9aYVpXv?a_4tHd 3irBfODr`)ݥ1bsΨIJa+D"R*:3%SzECP+Cű|N61!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#.AAEk:JϴCm2a\VB3֜e!ۑ}F(}[?#P!ٜ!`P?*E0Z?r,;f!ݵLd9 Q@p%\:dq< "U[`u-u;ܺlTeEω.A&AtUQ Ē٩p-Nf0d ^$M' vAeYN|51QO*  K, M@ ^gbO}B)ȕR~]_& Y\s|>4]#R>5.B7Nɿi̶lL)/ 2̷&epf͐)| =A.Ax,3, $)Ȏs?04|P{'p(}fY?gr/oj(4" :p:/m&4cZMYA>AKtx,3=$*c3i Pd.e0bbpm,E)ry=MJ\g))p{ؑh"wR_j`lƔ ; 6Xd MJP@QȽv}(1Յ* r1ʦ(&<զlŭ"Cca0EmAX!JȩMIq.P D]h(YT]lKnЀjvȫpq  E蔀wM︂zK3\ :qmc-!VJۃ~[mv5AYY%3kAFA ( =1oޏ*Q%QRN1 ^Q K#!PVۅ9Roz@&[iiPڕ@NA? I<&ǽ n⧬URgN)9^ x/^ x/^ x/TANAk:Jä4f^/o% wwP|޾҃꫍WJoE8kp5^B vQh @r\QGQ\-vNҢ,DRVw1܋AE"zU Β5AYr^^ r<.) 233P鶠44$BdZN/ؤ'vz, K+)J Ve}qA^AiXgI@Y3!:Tpzlh.U dd@.WaO0NXS:|6mh31.\0bi5֚ZkMi5֚ZkMi5֚ZkMi5֚ZkgPAfAmz@Y4 }4_ <[̐;.=?cUuIA!H<ԾO3?42XўaMYN6fLə3&d̙2fLə3&d̙2fLə3&d̙2fLə3&d̙2l|AnAhh8]QcoHmiF׻2R( ڴ0lrO{g@sPt׎4K,:XtaåK,:XtaåK]AvA=\PDaO#ܚv Џ@{ dO6V 5ekzI< 1^#y8 (-e@B^vF^mE~rra"/YW!-B kSkbXўm`4*wYIAZIFmh D*!Fr$^sD%ithE/_m>-=:).pLocA~A\&qk~^-qGwxǤCŠFHs^;!D$L:zW!N#6ĸ) hsaFgz(;= U'K`c4q;UtaåK,:XtaåAݾAhٰYB]'P$ s#21AeO ۬XFHrbU7o ZR^la4fvrgg%*?.P/]O0uΡ@G>oO\PXuZU.w 1Yxˎxꀨ;AAƯoޑhg'[p3Y?Q!Ś8oWS2}atQt(Leg4@ O K> p̫]SBiS"k%BJ grZ`8 Ze}F af af af af'AAi_% g'+cp6߂l.f'2i.FNXT.Mynl(XĄT{H/b_1/b_1/AAEp?XD0[XHU Y+>Dśޕn_REB_={w{._  T|eۺdWy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^WAAW _IJ拣e`np㬥PkA9,q6!vEƤo`k"i:0f,vy ) gALEtҷ*`1<,)F y>dVIdRefW`e@Cx7sp'Sg1{  _&ŷYJ[dB%ekz2 zh+vP X#w G| D AAK> cB5@)+8`nr6Mm*o'IfmΞq>xf 0՗g|VqXN+ a8'ⰜVqXN+ a8'ⰜV/AALc@r[L@_+b"t??zAjplmz.2w{J|( 5Qnʓ.y^Wy^Wy^Wy^Wy^Wy^Wy^Wy^W@A A߯ޒ3}֦gtEEu G:>@OF{L(~1 Ha|,Hy3JwyZjdR\A.`݆)A|=' P$UF޽6)BPMKMݽ]*4t!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A&A}Ll,EG'sEK;ZtBi]f= Q0Tن̷A.: 6'|K ioҢ=[OLktЙ t[lI]X+@EӜKKd W=Ël'3ul,N24gO n?xPu镺ZhcㆺkA.AB(hs?%G &<7t Cjݬ*"R[cN !_YR5dXc`  Y t0^ ` ui 1B"v2 M"N^dlA>AA8C.!] C>߻w(L++b1-)S[Z@  ?F2]΅t8˯RGi3G_ P(f&d=ZNVְ~f(R|pA FAJ3,hL=0$i'P'o:@}VTJv4,`E?d-tE_hr@ЋF#VNR%^]XbíGJL0}ÐtA$NAW+I 䞂3ߵUG.P vUjpKMfD8 HWl1EW..Ġ8IPLػD3Bs@KR/%ۯq0roc 3~=A(VAbdATr!Xh Oг/MB[6?S>ņ QXŰdps}v2Oß/JWj'#c( !'fՓ.hg0/^16 A2p[U-h%")8Pkء0g5$RءfFA,^AI9~]dM-JhbHM| ̢ݵLdޝ< DВ>όMY: (,*'bu8_ФԴSZe}JawxA0fAǃ{y9*TFP/ KUu i-c'^Dw<g7ǬyS)ΥOA6Bȑ"3x\SlN|b(^ ZPFI:7LSȂu^.߯&wNCMcl8XI?F[gF^R.@ S!u`}xy)t|:kuBͼ 㐺i뀂A4nAhBRhKx/ ƦKŅَ5;Z7W1ڏ**ǐ%6C@?#~ azU߅Տ1:])x ]uIeY13O аI7aLwܡ1@bڶku4] Bʊ(!jIkB(A+-2n3]yٛ"ؙlwg`A8vApXgI@pV'bdx⃨NaL:kEe1JD EYhFBLГ$j4$ 2FBLГ$j4$ 2FBLГ$j4$ 2FBTA<~A!k:JB Qg,jܭwޙjj\9%5Rc(@JsxKDp5zBY" e$zb_1/b_1/fA@A|p^P~Ns71qKN:G D)@`JsxZ>AAЇBtb_1/b_1/gADA,ͷEg-`Gni$w9E/Βe-@QDhdYk'H m_3@xLrߙ4dYg/@OMA(C7brQAm=K H^Wj>~ȿ37 .jb^^Dya[ip&nFF[AXA)pXgI@Y< Qq394fWz~STiNP#nfSDw2M&_EHHvGXpQ"\S%"i(8s D23LVtաܺr)D@[AlA40'|ֻjGS> Zf?Tntj 2i6q\ɒs̅AKApA2]j0}!/!.j8;r֞"p??L`AtAޏ14!/)AVM4o$4'heܮ2$C7 ϫ\!ʇwp׈aYAxA ICD-L/Vnc.dW -N(VNT;EB9r-uA|A%ICDʒe^-o-wqSryDRc .ezwL 40AAGuG \6KAh4)v}@99P/B;9*`RjC1C@)! IND>f (́nxP:.Ɂ객=A!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#rAAOy 1%#ޣ*HRt h R/FeDo;Sq5| Qrwi4i"ӤEHN"-:DZti$YAAl~ RypIgsDq^x_oaPDKDC 53Cb_1/b_1/cAA9%#dy(.B9"[;SPîbSTL5fvX]~s (`t1/b_1/b_10?A&AyEF9=?x@J[7ω$z rбa2UIEt?M!0I f#帶dWy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^WIA.A I(hs?oӟIguR(idy4 ۠FE،=X?U+ͅ%QyPewbܻA#IJlgۣF-wXӔE6S߁a).UmsrmE(T:Sc+=#Аdcʤ^vA6A8ICDQKx-fWB'_,w >qYtCP5@.7wHhT.Q=W? 5Qn5 SYc4 ?Ud("+fXfm^Wy^Wy^Wy^Wy^Wy^WA>A~ cp`.)o"H$Ew@BOJ>#* K?tH"A_f ?ȑ40Y֌bIt S^nԖPP3w8?뮾, N(k`綛%-ae|(hj,9xt fu~mb 吝QߩwרBppFc6 eAFA(hs9$ rWs5N$7{ PiU_(G] 6,zwIa8'ⰜVqXN+ a8'ⰜVqXN+ a8q|ANA-|+Lg؜|G:5r^ xL/?87# t{R.6Hʱ1Ԋߐ]zWY& $84jv8$ Wƽ6d$kmŤ4Ԕ{Ȅ`:.(}8VWj }j[\bAnA,Hs?a +4xJ?O:0BZ#)^P; ds[('mMP{ܥ_`qxAvAu cOJjfgT:&bØ v0i! [yݑݫ,!R}H'&Yu.3E߸eù4WT [>9A~AM؇сofyc>;]x@7໋`򣺗7zSК򣏭4j4RGi ¨@3$@@3( ̔U224Gf-}wZ&Mv FG'H"C46ٞMZ'@!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AARD"2U ]8ќ@AkN2#NQ"V0-R5ڦXSݼi6ԪBa9^4CKL\.?S/Y̗EoAc%\f⭤gI׊EB)o~@3cAŎA;,'8vpx(*8LO4aDk]p,Z]@cC ԯAծA⠰Βrv?HDsdH/u'_ޙj6JqK1wWx-p~@?}Fq$}|bMQ .:ˬSt5]0bhRtW^nˮAٶAt@!3p'hzQͧ}j58ʐYytINcgsZk  $1Kw'%sEq/Ttf9YoM>wF+߰5gT}nJ*&(h+454AݾAbΒ "9Ct?s(si)3;.Аx 7S*3w05Z+V_ұ5߽mw*2/fV~^AA\P~;~DG9|&6¿GӥTf9ݻc4N(d: f:8N1cK+/y^Wy^Wy^Wy^Wy^Wy^Wy^X AA Ot)l~(35[(o_uHxXwIPVo _1p.čW:FĿnh5݁]iG]1I+w6SէCel`&uQg{9xjH05KfB[&'~@Kr:!x/dWy^Wy^Wy^Wy^X%AAAa%g6V0.Ddtx}63, s'j:gT5,D5a$$k^ ŵ^e4i_. ECjEi~&nXzadeJ-dxO쪒Yfn^Кn>vAA⠰Βz -ÄTnV׻L@5& 'Q[ح>T_%9P[D>\!(mGmmv !*YwS[Gϙ?>(mt! tz 6?I:/e`Cx7sp'Sg1{  S&@q0u5c%㜒dZ'@g9x`_ 9@ Cf PAAP+ xAA,3,[wW9?Qrj)a _:rc/QE>JDhEʞWUY;N"-:DZti"ӤEHN"E!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AAGhHs<8DhBYVLA9"+`rFr~T46 ú*ܷR4nqqLs;uٮ3_Qߊ٫K"S!^6٘GƵ^mBHa:cBr$"H$"HkoA A%\ѹ>:$3,Uh,L@K=%F[(,r`x›ig%yIKַmA {>d|#GA&A \cL(?(QRePs\/`|8(OEC'h'i[o{2d:"ICѰR{ ˷?YDgS`h==Գa )͜"- 1A.A4b`O|@A*NT憼 1ԱwABBv뢀 L dSn(o(҅:m9b~L5R4gISs/TW#ؚ8 O!([.Bn$5SC8b.jvY!@MQܟ ZJ9ҙkE% & +&|B&Y&SFjF{GA<~A p7,qo_.)z>;Zo˵!}2W PfMVU1~eީ56\r4'R2NN77N@)TA_!mY2$S쇐m='4&>[oڟWAyjkqry8FS1j)@=CA@A0WuGqFWl)ex'4~ؑ$jvbO3Jőy=m}atQ?5SpFWVo1 !zR#璆[g|I=,!&D+Ys YSE, ޳J>9>jn#o$J+hzw]F-_ 0eB/_t~h)sH)y!!HGՙjç17ItYEk,UUNp!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#VADA+JNd Hv˖@! B'K&8u٬S@PF+zS>T$oh!x|"}AskK&ߦa>\O (l8 ew"<%3fʃ%cF]ء++2ƚkjQ[]w4`6 9'`Sh"{OsZqXpSO/ӟALA(C}v,D 6jf)bD-1&ov١:L($t5gxs!~jf !aZ;xC$95+4C!x{Sпu~aiTcB55Cq0~%3i|h@f$\ XŖQuߢ[q\U.z)a\!U[ ;%ϓ5Ö6果.C!nv$C\J\])l-dDN ,;#uWuu.&cLfWv^Yims@IUnPVzP1KĖ׷P s,V1i.:1s_+ﴤ4϶&CgIxb .k]:b?*6 Q5Gfw)(APAJcp%&^*|QaˋVȤ +&'Qڋ(&b-ӨrpwkKFpjX ާ7/nCH&62C^_]aaLTw4Ufn{IUI&D@ )燔Eۣ.8I<^ޘƛwJ乃,sDo49M\39qiZXATAٰY-`k; E ls`J4?\$ڣ ёH`x@ ] 9^^y[ʠ3Z^{v,Q-Zgi߬DA~P<A`A۱|th@Qwz`1:W|Mk^þjU$9Z'97,i++@O$ء\H.9onzf`O柹P!]טy{<}Ddj:%Bf9Zg`NDOE֣Fv:ي0"#Wc7u$&rpAdAt/L7ic?oE?OҺ8RE5YmjɑFJfAP2A;l4iZl G։@&[4 r="sYknVyػ?iΚȷA$ޏ6[5 -Bvp ő9QYtAhAhluBoY!`Iz\P#}aϽR<#NU#7c ]S3'D#J%$T{Syp6iAlAǃ{x&eM+mc`R0)~ qKF1X$TAϥX=8ڒ01:x\ )ڛϝrU|nY ;y%FL<#h-wGҝݫ&TY7ޟy;!f<N|WN^wLlApAۂb_GM1 SA/=]H&?kP< в%r 0#W`$g^^5ݨ3mS,X=h @mP0w[,A7&,K2̵-˒/K0L 1LS2L'xAtAEk:JϵpVG[BCL`ifY?+ tw E:ڸ _*њ+k mjRN qJGg q| E2$Dz+xAH?b%C/dЗN i(Cb i"$ L[AxAtloސ(37D[(xrhRC0l;c[~eI@4Jk T9' Y D0Y#>Eq^cT""-:DZti"ӤEHN"-:DfA|Ax,3, B|Yq߀O3GӥTfQ%@ B$^#Ƴ%͋ k^7sjBL VBV15VX 9MK{\?> &RNyVUXSox f8l' *I!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AAO:J vV0+e 9rIO'$lTt^vSIr\[,Z}Hl`%+|ROag?o%)U"XH}KZE0n1bFMmB s:c3¼++++++++!AAKtx,3,pT,ng?xH\*, ^dy3gidk+?/cZ#{( Fc}g BV~pY#:ag -DC9i@pZ ءvrj&Rf,VjvUݭ:QXN+ a9 |s VpBqXN+ a8' AA.* (p `V&Ψ7 omTOQ5"0hᰊ=:?TǵL4yB(湀5Kfbޭ0ަV\^{1pW3oQ\:+s试k0<T9E~ ep5 E ņk.IV@S?)x/Ȧ"h^ )1AAk:J,s01\{ 1u>r*하 fF,Y1Z]%9ؒp. zӫgaz"++lF+++򼱴)ND@gDIePA&AͷEg>0Uz?FxYq`6$`;TLxn*d: f9*Ҵ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+JҴ+ja@A.AiXgI@Y=b@90 W-P9&[GЈ O=K4$m>:|xX؊_\#kUh!@%P ew!3Rf&IE&ƚPUF9+O'C`AhӅ7ߪ߬!dۺ1r, 0}b'z;Pоjlh6EtLjMLz+Q)G&dw!}% e8|h'rPBC$]q't8֝y|FC_Pky]A6Amz@Y= -`*(9q:vU%Ս}L" mt6N  ,2QX1;TmT:pYjW8cC#3u:á:á:áќA>Ahh8^➲>QԸGdT%:+C4zz;}Ii@4 <<ƪ aæ7nha7+UqPaåK,:XtAFA=\P4S&!*6_BfU_V@Y:|9$>=#M ^? 㺉܀JLj4u9OnҐѽݙ?x-'6̭.D4nƿv|yўP0bb˷s|_|``ANA\&qE[Kҡ6;,Í=agAVA\|noD;;Z.[ZοK8 buMN˧k3=0s1LT/Du^6T(MeA^Ak$(?̧TvrR~cB~ag&`@F% D%>2)UY$Ji`\AfAi 3,% 0YeYm46 ;XZ{0tn OvѰeewa@Y^uIB|V$8D!YAnAX$ªt10b%[_{@::01!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AvAH2$!ӵցyl Ҍ`C)>THtV:Ѧ7nmiqMK+h#@Jy{ pE)C?f s !'#*leM0 H̶ ߄n>`p>6~! @%(t@WA~A=8ICILq8[د}K?6z@p"whz|(ߒ'1Rjry,<8 !PK*mC x,:Xu6d" K,:Xta!AAhٰX(dIp谬ma;n7f/$zC2=Rۄ{VoosL0iKmFzj?*  s߭XUtivx3kܕqS{{júAň =5iQP"1idǟȈfY}%){V}ε_U_A?}-ze/Fk!T{,փAŎAƯoޒ3p(2}EdI5N6z2_)s`0ly&]y-] :"/gpd#O;^wL(N|vJ5Gn`ʁ1.UO@zZ|h@oB2=;Rڑ+ nqgA~{<j3\QAɖAi}AcpJO ` l!S~]m155'H'Ӈ]4Rωi@Ԡ( Hb_1/b_1/pY7A͞AzE}f0VDK&H܏Q1yl?8ԢF߹@.7w,>:6G:'y@o6L DTu$ UCKfg#ű[b( (4UDfgYj䙘!#1hFp›Q4-a<[nR[ڒ2;d5û'ygdz8MtYH7UIS9GчqeϕJR4YblX7 G%KLV+dYc?&y RqZ54AѦA샇 (8N}őE, S!M4TH `ZjXIEؗd/P7gMjL&,t+ l4G >nhRp['Ft(JrLu>J>It*lG%1nf9nwUkkZE:]*h!rTdISN#%MnRJ6iI*mb2Te$SyUYAծA#>,ldmbE{w@BaՑ]}{mu$"apJTAZB{oQ5}pm mv|ëAAAAAAAAAAAAAAAٶAK<౸3E!o..BƓE3. xd4Tf]x aia?`{-) 4 Pv< U$xB׿X³U= 7ã[+ ϶U·u԰97w1ۮ|'~H./AݾALc4@9r-026/Hn Һ,_& rO((2y$!:8.eeZXZŚ1t$fuR(P(3NAkngAā7O U@UTлk%L2zAA߯ޑhg1/>c~ؑ$\qwIkyS,Sf$tQbW @qTD*1/b_1/b_3AA}ll,@91Tu> o`w4@;e_mT $a vdنn[o2LAFF~S4DFTL)Ϋ<# *vvGɡwJ}#Z;i{6}Gg> ^5<%=H74U7ǟ_`ox MAAtSAh/-OP1%~g6%7^%N`D?Sc,x$7D5mb;@| $`w zVߨb8BHznw;GV; d̬ =5$-BƭGz g.-ۗ) &oi2,V:-% ъLb]!)sp-?& ^b^]Elvt1[v"dW26q~cз?2;H%|s_5bD̚pt[&Dz1 㬲8e x7 ow+'?uwN~f]rdXl%ѼM'=p@`jbV|(3XEH  d$vx-0R0g@x+@g&PCɀK?`!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#pAAǂ)&G>Ub dKw@U:Tadtu*AN&F_1{)k0+|Xt`aA9mEAssAAZc1NJd]4v* V6ZQ&PAs Q X:c!SVA A HO 7Fǫt~{@|!7p'fa~:kxDULSmS,)hj*ze>Z񸷉"uԡ_EȁnW{tQR\UׂxA&Av6uBЂD_ir=C8dp\ᕷr=Y9VbHdf 'Mh ?AAl,ˎҪ*ժ%A.Aǃ{d@f[4b_ z3-0urAE=($,"IA9ClZ;@@|7-4 cVUpJ n=껌bچIt!) A6AhHfd>d#krQur#j nc,|ݶ{Ϟ;ݶPLwhm HD^im[O$O7e7yGyGyGyGyUaA>ApXgI@p7bRf%L1,20ڸA _p$"@G! 7@9jbٍ-٨Jpjy@/S9\D~mS,%*F7PKvmX1-&Ҹe+kv]kv]kv]kA FA!k:JB Qg| NE($.a!b42I9R`x/Jt3۵LYbXT@ߢHLo&#ZoJ(G «2p̡*(G «2p̡*(G «2p֑A$NA|p^P~N,'1K5'LOL} ͘,{/nEݑp@S2('{}( 'gvڕ@<"UJ1 6E2gl^ҁ~=gtLݤ=c ,y/Ka5&Yj&jUvLk/WO 0jP(4EV|~{R0|;<(V0QͶwmei H߾@OGΝ!S1j#@K^^bgvoay4FeHrlqSc\;X$r#I,YV4ڌ ^tKhqZ&̥Iz %#2I#YU/,|wECsq##HI8 e]a"V Uf"5׻Iz,Jy-T0rp 7@A8vA%Β07HUDɸK}/WB%C,ً gWeZ/tO+.(ȃ PC)IwP;hjHߗ XBy/A_T/V*5 =[MQ Բ5٢s1p*.10MŊN Vγ k*Uxo"5D*RzaQV,mj1yH,ʎaԋbޑ5=<0Gc4z,HA<~A)pXgI@Y=s?̡,rbenV׻LAIp,j۠=6FJNH<1u<ӓfmWa$U|=\#wgB'EpeOoTmrqF1w1/o&7ŕZ5ޗī@,81}1 lhG)ЌFdOٔNymB.j}әR^lP{uMWѸA`dAN(I,Ob]YHH!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A@Ax,3,cÄDLG '`E|ޅ""s lN[SXUOZo*guZR(!V3KK~- vHG?4v a4*=W7l8Dqc~$BLAld=="@P ^ `$vWLE+K*ϏirPgz[71v z8VEOSEHOa"mfGtٚ<̧k!Y*Ŭ4 v%'dNpR?<'@sixR,v1thDž_AHA-\ѕ&41d<T#4(T"@4~W]{]]B?Tn1>qI`N֡['\ M FS5_>hYїVAڭ ~Qz>Ӓ(eN/5ܬ5< b[\?S+ H6{s|;a0` )^Ҡ.v)ALA\%YV k&eD[58W4җ|(Y~ vUSEGZMڡheRk*k@dr%SF퓤͹c`0AcAPA4v0Ȍn*|>!J37y{w,mgxdNxj?U $ATAEoN ;Xb躻D5M̞F,"|5s 'G}& o@ʷ '$`%`|=lW#ƣ롇 XEŷ<AXAZc {'fKz#%k(U&uI{F890}v06Xy-_$BA>AKA\_<}A܊`zEDXR{-/2C)uS] 1Qb扌TJR!Ay}rH_G+C~2UB۾~X^E<.wyk|ݎ"VAdAGuG2+-W8a`nG-uG"^sƬ'͈by`I/%N,]zy.:WK@+xR3K8 AhAP c%`N$G3ڠ}a @$ (VVV~%jR5@PQz(\+PrL0Vg馷#Y!Itr:t.!~l.lJT >qvMhtz<|`q .AlAl~3 _<6߂l.d;%Xm`o6?P# 췰\z %"@n3WP-|DT UHcmjkeO/b_1 S&9Hbs Aܽ11ǍoO2)`p[E;GzAjHKyM ApA3#Tx|?`n h%^ d<Eղ%xcATy~'C F?pd4yuSIۇ<N-dcC)ꕔ9"N{ZB%zFsfŬo_TmsZb(G (fAQo͐efc_%1х&y m~'ќ%p"׫ʼf"\;ƖsԭU=n(fmGz!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AxA I(hs?!?ξו!?,@R\S5hC7 '\*ؑA$Q.(YfN=kYq $u*@]z0'lQ0'uHƬ|,.9a2qfq'_փ 4,go^Fc%c2jufz>%S v"(|.a1PcLy'A|AICD {gHPvk&Q! gv~&]n`YIDm@דM20  A ja.Gk]J,^ %~C2 $E|]ACW,MhΌ\'g z9AA% ŝECb-_A~[, 1 sIE?k$'kR?yq*+-љ.w&N fUHW{p4HtS`.حM8J]g>@W つ>u3*lΧǒI!=sCC[|3R{on뺊U12勤e8yā N$q }É (H`tD:T&8jČ$t#o!<}I4IFxAA̪KpMZu7t CHs)g٠lZ?uiîbS@'#]^v8P& 1|k@˿)b_1/b_1/@AA<% g?`ST!cB'_ <hv2w{܇F5tc_Q~~o1/b_1/b_3AAOH3p$|b'Wҁͷ5?/FϦ_JsdC򈢎H FmrEv31P >հ=fO/?7VVO7'AnSܫ 6p*NŞPGbTN}A&AuAZ^o7x"8 h{dڂHI󛂳"<@"uO6 VI  L/ aåK,:XtaåK,:A.AWGGGS^])puG"c7IYUtJHJ"3; ruow3AW o##oٍx~`[ufd\f0C= hy E"=46f¯XJ!9+CqAFA,SP1g11F袟],W J{MJh1Lwb/\W{@M`AVAW.;6?-Mg6gsu~*j@DpwOC\R|VA%ڏ&ߐh%TJUaf}zorZ {!) ă>ԫS_v(m @[i8qWpQ;)S`jS*U\~^5:@d]ZK%rۀLNMSk@$8Uӛf0말av?":p 1 y|V6H0ig߶zEA^Aǃ{ފMDHT1/@XXtxdCX(b+w+1M7) 2j,+ˉ^t'•@ 7 &K'A!2iXN\mKM0~i-zweUW1x׫d[UtV2 1s=fSɦp]Ua&mz{sGɏ~}2b96sT_ TovAfA~m/Z( v? fY?4?O){ pv:}B]Rl7֥PXFCws}71@7R׌aQ*M=]<י0:;63!N8Q&`/%6%M,>u&BAu7NY@dH4mNA!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AnAj<P}@T0)$w.ZpF+Wb,+4_04;0ciD}dh]W&!q3zjv*5EYM;aAR%l\6>EcX>EcX>EcYAvA⠰Βrv?HDs`NTJ7 erK_LJqo,L,]S S@EOl*%ʄO!<Cy!<Cy!<Cy!<Cy!]A~At킫LO%S*8ppoW$[:Aomq갇fx(B+;7tVqXN+ a8'ⰜVqXN+ a8'ⰜVAA~mpXgI@z<8HUILCHspwWB$2tK=@Oa2_$;m}A&nhsmy2ՂR͚t3oZ^-up(¸+T_n,AŎA\P~;~D9;W6M9+k} KQRϥϲ~rK1[kZBC' Ki\8Ey^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^X AɖA Ot)l~(3N}Ź憼} `.X@⽜˨ѹ)VĖ w\ˀJPռ\RA{7S9)$*Si9fjCD_ɂeۦj.kau>8; Gg˙A͞AAa%g60UzB{tGdLIrc!ZPKCS4蓩j< 2Nܳ XiDHukcb_1/b_1/oAծAPXgI@Y=! Q)EH( )w׎4{pJ(xE葦.]32. 4z6OM!gׁb_1/b_1/n|AٶA,3,[wKGLrŌcV].0>.` E)tt::C 9[?U"ӤEHN"-:DZti"ӤEMAݾAGh&FU}ɠP P4_mr=WOb$i&r-ZȴdvAAڹ$D? fZ~8";Xg!4 |)'GdR^ Fѷ_<La;C2A@!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#yAAf8|̲;0&BVd뚁d1 @f)ز+>+&;2T>Zż|FEX m@0Cle(x7sp'Sg1{ FO66h&jJ&6@[lPn.UVsP@[Z 'q8z @n@YpZ\Pess@o$"8GAAH30'}B#}CQ.Bj Sחaխ)d cZPh0O3DABݹqA?*nM7lGq`ZI&Aj>C{I L5ՅڀAA-X kID; wB8 I821^\ߔ? ֶtp{mjm;ajs̀kM ! %_DGA A]׷ICD Q,OHzMw;=Dǐ1= 3R[?XG/9"/o q,YA<JUܺ;f3) 0m;[D{у1be>Bӿ #}!"΂-+ A&A c ŲoЯdΡQ<YF%>'0 c\+l}Eě#r* mfAIQ?CN"-:DZti"ӤEHN"DPA.A)F"`?hQPΆ7t CiI`0"/z(pXwXK,oGt'$b8R=t 14g#d9ϽM ߍJAnWuzBZFA6A_ zHv~w%X'8?׉RđnawɆL<>mqhʶgaST6gA0yFU(^9WbY/v)ӬWP 6\w"|Ek^ֆzQB#.ݗ4bHuڣ|κunE#@ˑvB0E:?ce7bHez!}F-㏾d QTmsQ|W둲JG };Kȫ[M ؀M ؁{NA>A3԰&"?/,' +t)b4b)ͫ='~AT{1obuVBzY_ 9<pd9LO=}H@[WXZ hiXA(VA+zJ ͑?|S%Mu C]4ĢFV퍪 t,$ru^W@?~i@(ڃ;W5xlBTX}ƫS4@]E>c:m{6B<4++xW8K/A,^AkhT1_ 6?.7x0  '0^$dQu8BV]g%Ecϼ4 v'^$ߏ- =8ĥs}llzA :&=1anV| !I#u~o PUrCR=Ҏ W@!asLLp*#K= -lM+/.M#^h2QH :Yϟhҷ2٨"+KJY~ FB1lWmղ^Y3*~}rM6A6`0Z+Big+ asX^ÞMSA4nAJfy[( QMĤu>}c˜,LhEl=?}gwjs ؙFѐ'4ŗnAYrA$!<⋸Ҳ`\Aݚ0Du,m4D(R oSʜ4-"4˸ .3WL}[}к!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A8vAٰU-TȏQIo=?E W4 sknJdKp@a$%\~Sb  xƴ{hv8@x^FĵD-"2n40a*B͸PwSZW,ޅC)|9V`MAADAK`FY?|N s%B1!02<[ MUԟv2 72;s]NhЫ>^C(BFGlEGX~\FO8wwcAHA*߾~#ALŖSriK^ke:yeDj+ >T y `y)5aa:SށtALAOz+Rr ܷlO1ъя5KU!\"4r^mW? T݆Ks+KCoFhVR-.IĘAPAǃ{x')XNA)hs N-=>]B.RTuI.FFa1ցbd%{ĠŒmS,Bc0 ?Jץ Й^ڐo1C_ZjxoŰPPI_ LdN|莄rI{}r!&cn)fV d1x+0.( ks=ğV%EF۶sL"G\ / +|*02%@Uw4>po b=EUI9H؀|&c3 Lf>1𙏄|&c4;AXAEk:J0%P1S4 ߊË@¬5(5h|"p zyUYaOӸTRSSi<] )M".lQZ*)X *l{7x7x7x7x7xA\AtloގJ 'e7]-dz26?dl!($s<"ܳ}1}T :$\ }??1a\`}W#ﺸ}0Guq>IA`Ax,3, 0qRX I;Ok8٣Qd"g,`0O-#V^qnY F9i@PeSt&@&cXkݛrA9 rA9 rA9 rA9 AdAO:Je>['.6}=D aa=>%AgZ6T<̓m,3_iaGlM}L(c,2dOy%"nF=JauZQ[LyEObthYnP1^+)Xxh5[AhAKtx,3,aOx8X(TIH(Ђ[exAVf(C{t#(VZECL[SY Hux:2TʙS*eL2TʙS*eL2TʙS*eL2TʙS*eLAlA.* (KC RB%G=S\(C%omn I;bvh5zu3Ew+ FӾ{I+!A;7 [D\2࡝|Ӝ& 4W@.HTŮ2Sp5S ߍ\ApAk:J޲zBwv,щ|˾w\{B'mF7fp_\K\/=56(`^"%`a$+_w3w;gp 3w;gp !I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AtAͷEg?; "92+-WI7[> CɃ`Ģvu]%9'}-Ǔn F@ڂe솹{tb$+kpT;y5[kU~?{fn%(A&\\Jq<[1NvB3QBxDmAxAiXgI@Y=s?y&-q!Irzgt6-\gpi|.@㏯>fɼC 뾱;3MSnEw|$F3#|Lɗ =|A|Amz@Y= -`881mlZ#yw\kpfG&n谌OL:x@A$cܨ$ I.YGk]3* P4F"DLJO1/b_1/b_99sAAhh8]U` @dHwJ! $ wX}AJ=,,,?|ϟ>|ϟ>|4AvAA\ is?l {O`I$B#ԕ-Z+57KeEn1jD lI@^@P` @ u`6&(:0|!YgZBҀUA&Aw|2n[ATBɋxƟb5C\PM3~lD]A.A ADVs@r[Xkql1e9UƄ͊mΧUR`DYA6AX!9 k 4=wqWGR;wA>AICDw'C Udmvz gZ2n" #Yw@ aAFA=ICD}ӷX/242/'_gi:bdp6hF/fF6v-z P<+Oj i4.W%e0(6p`b8 q40qY~P;Q8[P^[t Adj1"W叫ideaZ"mrqr1htBR+66n6p<AnA샇 (i; Tͽy,t_v$XHVoy<DtQm ɶo~CZ&50*ě΅K̮/G?wGe(Ax0`ȃ8Iu\E6i:1pPXxџЃF@AvA$Vy J!xA[+zd JVS҇1lm$ ~\ ɧ"Ps~)8f@y"\R.#|xAALc4@93Z[hm{$6AciHvfC\Qu.~Ǭ[>fwlygk|y i\tV`Sz'jT#;cc.AwFӟ&y&Vȵ2O+.GIz{m əAŎA߯!xihR՛~܏Q"A">5~'n`Y |__ŵ-lC-+6Pucaw7ObYL3JŜpX2Tt!E]ZΞᥧ>Ac 6ͰcnWs|F_~>FQp;$gs|as>'b_1/b_10AɖA}lKRB)y;o)P6Zxz̻QBLR6,S%KD(,\c}@|&&t`/Fp!B'ؔ7{P^׎o+ UhyDlǔFyDlǔFyDlǔFyDlǔFyDlǔFaA͞AB(hs?`N$J)uH"?rw8AZ|`PXj0"&FRI@Ub3)<,ީTwQ[jpr] B)v@L_-]|g",ծ39xObˏK{k[JVJPiAݾAZ*bA&{?4>'}ԪH{x@q %6Fݲ:74[f휓AASk/E=F&l7Sa)qC^ZZZ6'50#jU&/m7EFX޽iش'ME/ya…! T LkIf-H*i<ТK-4zAtT%Ȕw[&wʰaJ[ޡI!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#eAAǃ{dtR?5] h gQʮܯia?`0Yame; ݶBL:Q kWiuˌiKmS,VfYmٸYx@t̏ V LfywWcܩ}13׼X(A٫cX5qJ_`[ 4k^6J\=#@6qTlZ($M98A e/} 9aUq/֬XeY ֪^5*.n'gQ᱙O{G \tr?PAAh&h% ?u?OD!440 Z!ӱ[Z<!Zϳ\*]Yh$ݵL,\M9YP{3 1ϙє#2õO[^7[Ν 18bj +y';|X}HT5sԣ9Y9g.WqWu/!^_0: ""+ 綎=ܜvUriL8}9;!ׄNF؊ i`%/P{g1bs \d}Uv}>(Mw8I)}Vu*m"j!m5{JR6/jJP"e0x7sp'Sg1~C-nrΑAFcŞ۷$v9iN0Qg#3@0=Lb* &e$iF0/f7tIN F4ﲀ*~Pq5P)&CyWg.L5AAPa%~T@9~k֭AM*v)eC"^%7?KeD8`**? mkJRʎU\G &J (ha^*78 ޯe#*ܨyA~΍L[kzl}|Eȥ:AAA|p^P~N c0'b%QqMh"gs(B$p:;l83>n]%9KYɬԥ0 Rz{VmיD{%#0 MVB=jQkR+J3M+и<-|QD@?9y)#x~1<"@LaWgzm1s"}wH!➄ofya`@lj_8K \'o$0e- xKc۶W~f:+lA.A vt A@p< `YFlCIIӔ]#HqH c;%N>q ]h4pFxۉ{@cP7 - Ftfs-/HVRGDŽbwzznl0덱NC8ōAvD02Ǜ3;2S%uf/M^Ou>L}̀ rEVkqS=DΓylbAރA6Aa%g*Uz3h^q~ũMOOQރ2_c &pRxz?<deo(Ny^L~Scӱn h1`A^ @(Dg޺ 46lh Y X08Q׎, Y@[n+fAxZ}7Nvgc $(/,T}~ bM\KqA?誩%Fbp#^e!}<S=<7´wV'bodLp[ 'Tyذ%Lpv6K–> ,W(kHYBo5 F |BP5إ  UH?wTC` o/ypi6z3 12q`k'wh~q ף'VᎲ~y YC]K+n7Px`ބ@%mo>Y,EbjA]A>A%Βz ^ീyaBCPA ԓߨgȸ҉kvsf !kӍLb34ژ4 mۚ{q% 6oe%T1eJx-xfpo^7Ю0nUY4ᡡg?f@)礜!3T/Na"?R>&Kt0R+=6\L+b`A FA)pXgI@Y=s>\ R$+ܭw{}xLտI.&]S3IzrEb_1/}vZtVE;yˢk#EĽCfȦ'wv[ΗpFTd/إ ϗ@A$NAx,3,c"?^{W5`袚ݜ(WR\?`][p2\-:寰۠V6ld)jA0fA\%YVc`KWn#b{kEw>s֢KŌt!`R$0 BA< `T =#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#TA4nA4w0Y^i}~v]j("[Z .@7 xPA8vAA1d"l\^\äUf FkO|x8 YA<~Aqb{4, )_<=}*y #؜0pW(]A@A ICD B.Enc'T[Wp`Y(A'GowlZȴ#hG"Ў\ADA%X-w%;NQ#VT߰D =pKJ+. %(/Wjl5诲uѱWʬ?d,:^#пI . F)miVRk$DRWv)1AHAGٰYc#7>.B~09c2>$^D(ZҡS^7UU~51sp@< A(ݠz9Ps3R(/ypH!v$Ir$A@>*V Wpz7(W8؀ALA{%`K Lbgw@Bt\N&T_!ZvO- $3Jj&,6H YAk05[ɋ*ϜwAS[ aLqpMw޺A1%]ayNՔd]602s߶m݂"++++++++,A`AICDI(^6z zqoT&%ywF 0<䦐c9%3j/D/;I=Y9{!͔(}JhooR wJ[ՈZ !I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AlA<% gs!.΀5輝׍C8s7/jhyv.7w26pfTk ^+^=$z:Yٶtޥk{0- fh1sYnෳFifcJ.PssApAOICDВ4h{y_tZ-]ھhe _P FvGIFf Δ>hn'EHN"-:DZti"ӤEHNV$AtAuvl7o;*`|1>\\cѶ$ ]3,%FFR?<;#eP"o}-<[ Uf}H !/0K0q"2nQ /Z|V$]qXqdVMXhR-wi`Bã){>![# ~\$ BK"{dŁEn ytZbHƦ^7gXb0 QΜEB 0>a5>7tAxAW,wL=iԛPRZQ%7o@"Un5|C JI@5RH-%Ӈ^sKvA|A @EG>d)YRG.V'Za)g=iG.O>yV;ƁN N'e_+`rLtIqM9a;t@d"X>KyvIzE@~AAnL1oߪ9Ss67Y%O;;jUZ@ Nꢭ< 3T#,x`veI [$WQ::PҜ^q|`kqAAoN~ p:XK;Tv7_K{{[$vu4@2HFwlh8= z:Eɓ'nO `dqAA 92rxM> *dK'6HMީb/vݵL׃FռwNUCVWK*ϺFxDCu d@|c\~mX snN_f/FfAAW.5bͱKI2 8KUʌ?07ŪO9+1\zjW&';֥P0R!vݸU,#Mo :P4A}!j,ڕdڝĘpsFpѷWIA&A!SjQВ> fFRJ3j(U{ _Ik(d7`M^uNe*5IH +hJ3)1LZ͞k܎[5sjڦX&$q;WTp$P}`L Y#Y*9򧌠y8~ґR?JGH)#~ґR?zAA>A⠰Βr{sCX(Y_$upׁ A 0*aI>2w'nQT[1ͫ 7.c`\ȯv4 «2p̡*(G «2p̡*(G «2p̡D`AFAtX`KQ4_ ]8 <_aY/mUp )x`YYvsfe&H_?6E@ْ۰ͩWj`"n[Aw7Xus}Ϲ>s}Ϲ>s}Ϲ>s}Ϲ>ANA~mpXgI@z7GMl0(so9~)CJP6ƂB\cchWax@ 9p@#W&[Ԫ7spRT B,S3o9n6ͼ3o9n6ͼ3o9n6w!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AVA\P~;ÄD-.f'\ǹDTq@52RQ{忤j ׻j`<-qNsYӛD3@P_kW*iZKIi-%ZKIi-%ZKIi-%ZKIi-%hA^A OtJ9M0gΠ>cEla)6TFɬo(Ў<G^`4}j`,5na˦ܴ!/#p8G#p8G#p8G#p8G AfAAa%g8BUCG.Ne,r=>ͽF| @G|Z֣"hi< 6S,qkpU+.B)=ݿrfQ8G#p8G#p8G#p8G#pAnA⠰Βz * -),0ԮLxqsڦv)[m+#'$Hk !ȭ5[oq 9v^0;]DAQF+n[:g.AvAPXgI@Y6A8t)c1uZ@'}%>2W̲nH@?NDAfH*9f/7sF&6ؗ#@t`|0E<L]&ٰߠSVhd[?jG?f 8/]AɖA \cuZqp'rzsĆg_YpmAH"؈Sa\:'*Yȴ#hG"ЎE fA͞A4aX0wk_c w]9had!/XY}Y穋ǸQ^۫Yu?.4 aA``AѦA,O }yy?a/Qk^qBI*1_AծA,Y!`tM>V W)^AS>הʤX>"u4Cr`,{hSKXMY{AٶAICD0F"6}89kbD/ D!SD\=yI;Ic8 JKΗI&¡}AݾA-YB̸dSAD{SANLiJ,txلS|I(O"%S#)B肅 D.(]P tAB肅!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AA]׷ICD1/~ Hl9P3E)V&'.^9L#OkVm"8O"bGxC-#xĦ8(> LKg`ki u[MqAA cLF[إ`ncm|= Q~Q#[v`_xT\]9x :DZti"ӤEHN"-:DZtA~AA)Af8X> hz9)-u9^*t9Ÿފ:)5z|HJ@n@=b_1/b_1/AAA_ zJNg担ĉbHdQ#_ &]nd1솼A_yeW0-73| nyv.{Dcխ1me8x7sp'Sg1{ 22l<\Hưq`*r2>(UvS^`p]V6+A8޺ G :: 48>tn0 X ` @ PP%@D}0 (P6@N HWXAA p|l,L DLǰ7t +.eJlZ ]-5łu <}qcR5nzXг'e%8\6Ӳ=o3I}ZATId=y螘NCʪ[t:AA0WՂX?^,(w@[FL@+$_0;٠N`+HP@?@ޣi$u-@HKrUya:&%%u<{R1fma8'ⰜVqXN+ a8'ⰜVqXN+ A A+zEF9*fDL =DT`GjtT[ D2|\Q˝D=X.-BjnYS'],D2cɤ˛%ΜB`DΩ;fS,idD~t5=^e] ;/҇(S^b'wIw]BcĥrKb~?U.A&AkiBˁA `nz/ھ wT?pXgd?V -r߳ T, q4\"7B|eW#@2T4`m{ɒʵu~)?he,yA.A(h Xp1HfhwKq/5)!u٬UB$ů8Su;`HRb#@~1/b_1/b_1o^A6A~zJZ?"FX ZZ>)vw[pB7Lc1y.V\@xo9a%soTEϑtIK=|RLW蛽~-^=q=|kh7~9qЃ=}̼;VXWMYpvx '_ÓU 1 DU\OTmwW٣龜f ϥa@Snk!& éP2?]y^W&W'o?ڀ=Ԣ:TB |\GoR3';n}mn ;# af a6A>A߽$#_o>ؖse6v:sLr[V^OdoOSYޢ*}J*CDɉDԈ<mBrr5@x^3Y`HKge\8%FڊҔxc4 <:aBƱE>۸N—Fjpfc! ](-@׬//Ϥk ItP3d_nx3oYMV@L>#a|a?B|R \m2HCܼH(!\4ߛS}7c`ڐZrA FAǃ{"/8 RŨTOh·d6*ho)efR^EӼ+o&4ظTugf0׻|c"d*8ELhA$NAǃ )Sb&>ۖx1YeLniާGU[,ڶ Q$Y fԚ~AtMw3~@A(VAGD>JMv q^ =b(ex/'}Ԫ< \Q"*U 2Cst%^7p+7B$[Iɗ& WfZ"!‘n"!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#ZA,^AdbK$ ]x@vϻEJ`@VNV2Oh.8PZMj9.tA0fAᅲfbJ/9hVXɹy3i0UW8]t}Ԫpiml8bxit\%K$pj)Rǜ RFL$7+-80ْ@mD>^:x)jVLj v PZ[ܲݪwgx 4uA4 rlgz̖Hnsvw e\ih|Q#BʠнVږMPXst8>1Gsk$0^H'۵tA<~AEk:Jcs 3,HAQs?|][0R^m@ [Q JRgp 7cݷܴY\w:xFFD'ML0Wk|pThy5x `-H\O4VYYEm8H2x(=fτm 9ˤ:)A@Atlxp(0w."\+"=v B^o+#$@Jk o&J _ n`1?iM#?Weh тEnW"*)>)~ %醽9 WÒLJ }/zY ٍu'JE_DŽ!7֬FmXUvW+۪fq5?%7 );PK 'vk)`WΚ>ZAHAO:J+tU"#ӡk^C63\r_O.W䙏'I=Gs%0u/0/KψdPRfq Jrj|P+++++++܁?ALAKtx,3,pv ^(cdlh?ߍ?j.̲N$^ʴ9do&+`1-G>gS[\PnFɲI qFF ~:UiZW!ḍ6en}Zk 39>9|%@^vuxG1(I;HS}7C}*Cl8=Bw41 ͉DދsMY/XNAV]ĥɮ~yhH;_^X3&ҵ2APA.* ( ?)킵W71L}Vܝ &7aObNӫ"( CRH۳4T݀8.W,z}hF=:/a474υR 7Q;}:#uo*$P@еFTO(>%1z'D\OAݪ/x;5^i fVCg$L^H(gѴZTbPհ\:ɰI*ԛvS&߶o13CYdTj|{jǞ!ATAk:JB{`dGp(.4bd##!p$״S^U\LZS=b_6Q1] V6 'n@<{E$ RI4KRط'ⰜVePw/yDۼ+PϺ2\J/`jUB25j6,g˺"PI3?EIݕOE_ Y <k]mAXAͷE0oސ3TpPk1GfhvSrx=^Q&w](jmfDnDL6;!Rd"KS.0=q~ 9V5q#%ސ+825aaN*<=xvmKsn4%1k]*e7y?$8D@2R{YyTB/Pv {\-k2m5`s_ҷA4f =UHe 2*6d]OXhl `]ziw睁-<{{TŠ6[ɛbCc$ݺ)IRb+ HTo{Ds9=J5){(M~[ԔYwBAY ^làg !&>a̓>C"eAޟِͅ'bGԁ oV"_c=3/iLxR@A4r7#O mr*͂"V* #BU9vkapp?D=[ ߶9}뾎R1Dgx hԧv@ Z,8Z('BctSzf.zu? 5ïzH@t=J?H+HmK|@/ն H9:i8`O0Yv-!*AdAhh8]5T,Nގ|K_DM99dWM΂w0J")qޡ^~70'tCy8kq]ݲ3}aX^VĎU<=*Muͣ}ա8;Lu0 5 9Fܗ̆t^v+Թ^3;ƦHII #SCYt>5 GHH>2h b_R=B%Z*IVzC1/~t Xo֦h+LB7l AAƮ: "#%:P-=Zont8hȁ}@ 3-᮫ӿtAD> = 2 i >]#_2 m rP'h)0 ǞTuuS ,NT>BmXTy;x.y F؟~aeotHHNj~X).(kh+xXãqp"j+fGdT+NSDQkV2eƒDlq!)þ`u2^Nz 9]wVz2N IAMq2~xA6A(hs?4 K_Q|iVdh_gsF)MATcBC7w-POY=Ԣ@/UΞ ּ+++++++++A>A$(?`P?`w@;rp*:UMNvkt*uvI⟌(LARwzcù!yDzFY4Z:o3Ll;nߧԆhKҀQJ* em- oGZL/dCxB!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#AFAbvBfOG_ڣ7`JBÙPrhTMr(YCRMJӟRп4 %12y^Wy^Wy^Wy^Wy^Wy^Wy^Wy^Wy^WPANAL 8 )+(V,jHNx h{\P+? #vUfMeH"kNcJ00M%Fvb_1ΔnUBLx%D+]D?%Ou<@[3%# 8+g=xZ䓯/!6HD?7 N}O/xhz3Q~9kdipAVA cTp(iB7t CNc3HVڼ҇5hq !ORvs7%>$-*Pu3% ~A^A}ll-L}.'&E$}&F1v]PhD?山l!Z7ԂW`?);ůrFyDlǔFyEVE^DDlUJIQ1Zɓt3 *>|v%U.3H] jRhAfAB(hs?41sUDA`>[Y@>x?蟂!|I t.m&J9:q.H렂~#ڃ)@5T־D,:Xt9"Xe'bM5?%Ud~AsՋ@EăS AnAǃ )U/E;71pؓ@Y G 5B!x7KJtA`K* d`k 6[ flt>_규fDLCS4i Ejd,y^HKOaafC⳶d|I8#4 ,MAAr]lTY|Mk໋ىzme%^Jɀsm(Ҳ7m#ݿ9"}nB$ydH0_drq=Q\+@oH5/I- AŎA1$^SA$JKw$-:T/E28s/QļtwݵL,PnuSHՓJc'h,A8a D1Hy^ ΕHN^cf@4(Ua'ًX-0D.WknPjn&$2G4JRum sM/7L(JV(X}n<6M,? #eRAɖA~ycCY׋V.FeP;O2``u34ebl,+C8URF=H'-fj` )}8tR@p$@ZG V*;P8_:Xr'%jjrh('[M|e?Op~!Z-')L8^(׭qFh5@Q#M3A͞Aǃ{d@E՗W hlוFDq_BAWUh0>DLPxc5'Ŝ֥P!RgcfU)< WJ fE렸:<wm],)Q~/Q3yXI,fi٠mMȭ"J-pzP.ștM0b[g4޳TyMpx<8<tjAٶAPa%~Tk|.)F v'\#+HOCq_aAS]H i B^7@\;*#yQkxR@wVB#dl6F#dl6F#dl6F#dl6F!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I# AݾA|p^P~!;Nfd`Nx 35lN-Zl4}Y v< ;0HpUg?jI"A= =7wkAp S @B] <S57 !U^-F\`a&$ V5Ȋ.%f{в2. naM~]%5n#i ^NUWMOhw&x0ɘ +W!u:auOB]%>H/A A]h,?᰾JRl(.1:MEu?qXidmJ*"4F{z.VK;c - xs&FA¸-[od?#zJYBdi)U6r5k[5{_W bX-dY6UeٖmgY7A&A-\'<8HTLq:Jϊl2lu?0GjSa*x*#\,a-N⥒6rXCsߢ2>]`A.A\%YVclcg]="Ac2M4t^aQDy*Eܵ<aA FA Q<Ċ <&=*=GI%,5i2K[nx%`sA$NA ICD51Ig6o}I++̑oڷZ1$$P+}  2eA^( }!Ohøk1}La3c\$!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A(VA%X])Igt CNl8wX@2?K\hp K;F]B7o0$"!#{T05*_po򨅊&GJa&P nA,^AGٰX kvM3[QXxh77O~ YߊUV./Ai۬`X.%4A<~As GnJ⧢-u7Q|Uջ?"7aKYd_I9ijCiVLe&Fǯ;g שAʒĖ&³:5u2 ^66 }WA5HGPtŁ {GPN^7$A@A IL7,qK6Ō`n|wuԸ?B*XnnU1~e~6\I]nݝ,Ӑӓp#쩓'p]?h /F~䝹7098R% ]0ozʡ xXTjV@(6Xbmiл.)'A kmq9Ci;,یcLayGJ%{eX`.R^ K )gbeADAX'$.Eg:1rd%)jtsYH,xPfM5=L~dM`e^ct{^KcnXL{ }` Luqpuq@ 9p"Do >P>]J^!^Wy^WMY^Wy`+AHA"#wýo h8ȡSzW(pXOPM[¶p&`/@8=`i01 (o ĊI?4.n_P** - ;S,b.V~33g 迫j$/i]+\JJYt!/\2+5s $7vi t0)'dZ=iZ߀~ALAL7,q ξѫ_3?r)Ӈ]4ORωi@Ԡ( Hb_1/b_1/hAPA<"#3ZZTzKCN #HG@Iȥ&]n`eJ|0"(Vz|!3_i%e'b_M cecb_1/b_ATAOh,q(ֽFly !3*BN*©KDIc Yx-y>?W9ZKd܀* 5@NEiJ47Y"ӤEHN"-:DZti"ӤEIxAXAuvl7Z P:5#wC@F |iwWWc˞e-RYpr&i◆XtaåK,:XtaåKxAA\AW,wL=iԛPRZF݌ˎX-I j< "Wݨ`;Md}V S׹j"_ I^`ĕ_}Cʆ' Dt-ܓ [ƍ.lU*[`!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#!I#A`A @EGT 4h&lA_wU ^£-g'Vfn"`"< nf/MΏcY73 "Hp!ϡUC12]0$i0 A`)_-+"LwT@j-czؼƈ6d"BπYNjBApAW.5a=H"A1^`n wj@쪁?rDBϷݵL2:< 5_ƑSW֒}+ZcVEF3+Z(| "mR[ FlbY{ktc8bk߰|AtA!SݏV&޲y g&L$ƟlA* hBV{`b #include #include #include #include #define DEFAULT_ITERATIONS 20 enum target { ROOT, CHILD, PIXMAP, }; #define TARGET_FIRST ROOT #define TARGET_LAST PIXMAP enum mask { MASK_NONE, MASK_NONE_AA, MASK_A1, MASK_A8, }; struct test { struct test_display { Display *dpy; Window root; XShmSegmentInfo shm; int max_shm_size; int has_shm_pixmaps; int width, height, depth; XRenderPictFormat *format; enum { REF, OUT } target; } out, ref; }; void die(const char *fmt, ...); #define die_unless(expr) do{ if (!(expr)) die("verification failed: %s\n", #expr); } while(0) void test_init(struct test *test, int argc, char **argv); void test_compare(struct test *out, Drawable out_draw, XRenderPictFormat *out_format, Drawable ref_draw, XRenderPictFormat *ref_format, int x, int y, int w, int h, const char *info); #define MAX_DELTA 3 int pixel_difference(uint32_t a, uint32_t b); static inline int pixel_equal(int depth, uint32_t a, uint32_t b) { if (depth != 32) { uint32_t mask = (1 << depth) - 1; a &= mask; b &= mask; } if (a == b) return 1; return pixel_difference(a, b) < MAX_DELTA; } void test_init_image(XImage *ximage, XShmSegmentInfo *shm, XRenderPictFormat *format, int width, int height); const char *test_target_name(enum target target); struct test_target { struct test_display *dpy; Drawable draw; GC gc; XRenderPictFormat *format; Picture picture; int width, height, depth; enum target target; }; void test_target_create_render(struct test_display *dpy, enum target target, struct test_target *tt); void test_target_destroy_render(struct test_display *dpy, struct test_target *tt); static inline uint32_t depth_mask(int depth) { if (depth == 32) return 0xffffffff; else return (1 << depth) - 1; } static inline uint32_t color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { uint16_t ra = red * alpha; uint16_t ga = green * alpha; uint16_t ba = blue * alpha; return alpha << 24 | ra >> 8 << 16 | ga >> 8 << 8 | ba >> 8; } static inline uint32_t xrender_color(const XRenderColor *c) { uint32_t ra = c->red * c->alpha; uint32_t ga = c->green * c->alpha; uint32_t ba = c->blue * c->alpha; return c->alpha >> 8 << 24 | ra >> 24 << 16 | ga >> 24 << 8 | ba >> 24; } void test_timer_start(struct test_display *t, struct timespec *tv); double test_timer_stop(struct test_display *t, struct timespec *tv); #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) #endif #define SETS(I) ((I) >= 12 ? 1 : 1 << (12 - (I))) #define REPS(I) (1 << (I)) #endif xserver-xorg-video-intel-2.99.917+git20160325/test/test_display.c000066400000000000000000000074111267532330400241250ustar00rootroot00000000000000#include #include #include #include #include #include #include "test.h" static Window get_root(struct test_display *t) { XSetWindowAttributes attr; Window w; /* Be nasty and install a fullscreen window on top so that we * can guarantee we do not get clipped by children. */ attr.override_redirect = 1; w = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy), 0, 0, t->width, t->height, 0, DefaultDepth(t->dpy, DefaultScreen(t->dpy)), InputOutput, DefaultVisual(t->dpy, DefaultScreen(t->dpy)), CWOverrideRedirect, &attr); XMapWindow(t->dpy, w); return w; } static Display *out_display(int argc, char **argv) { Display *dpy; const char *name = NULL; int i; for (i = 0; i < argc; i++) { if (strncmp(argv[i], "-d", 2) == 0) { if (argv[i][2] == '\0') { if (i+1 < argc) { name = argv[i+1]; i++; } } else name = argv[i] + 2; } } if (name == NULL) name = getenv("DISPLAY"); if (name == NULL) name = ":0"; /* useful default */ dpy = XOpenDisplay(name); if (dpy == NULL) die("unable to open out display %s\n", name); printf("Opened connection to %s for testing.\n", name); return dpy; } static Display *ref_display(int width, int height, int depth) { Display *dpy; char buf[160]; const char *name; int try; name = getenv("REF_DISPLAY"); if (name) { dpy = XOpenDisplay(name); if (dpy == NULL) die("unable to open reference display %s\n", name); printf("Opened connection to %s for reference.\n", name); return dpy; } snprintf(buf, sizeof(buf), "Xvfb -ac -terminate -screen 0 %dx%dx%d :99 >/dev/null 2>&1 &", width, height, depth); if (system(buf)) die("unable to spawn '%s' for reference display\n", buf); try = 0; while (try++ < 1000) { dpy = XOpenDisplay(":99"); if (dpy) break; usleep(1000); } if (dpy == NULL) die("unable to open reference display\n"); return dpy; } static void shm_setup(struct test_display *d) { int major, minor; int size; XShmQueryVersion(d->dpy, &major, &minor, &d->has_shm_pixmaps); if (major == 0 && minor == 0) die("XSHM not supported\n"); size = d->width * d->height * 4; d->max_shm_size = size; d->shm.shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600); if (d->shm.shmid == -1) die("failed to allocated %d bytes for a shm segment\n", size); d->shm.shmaddr = shmat(d->shm.shmid, NULL, 0); d->shm.readOnly = 0; XShmAttach(d->dpy, &d->shm); XSync(d->dpy, 1); } static void default_setup(struct test_display *dpy) { dpy->width = WidthOfScreen(DefaultScreenOfDisplay(dpy->dpy)); dpy->height = HeightOfScreen(DefaultScreenOfDisplay(dpy->dpy)); dpy->format = XRenderFindVisualFormat(dpy->dpy, DefaultVisual(dpy->dpy, DefaultScreen(dpy->dpy))); dpy->depth = DefaultDepth(dpy->dpy, DefaultScreen(dpy->dpy)); } static void test_get_displays(int argc, char **argv, struct test_display *out, struct test_display *ref) { out->dpy = out_display(argc, argv); default_setup(out); shm_setup(out); out->root = get_root(out); out->target = OUT; ref->dpy = ref_display(out->width, out->height, out->depth); default_setup(ref); shm_setup(ref); ref->root = get_root(ref); ref->target = REF; } void test_init(struct test *test, int argc, char **argv) { memset(test, 0, sizeof(*test)); test_get_displays(argc, argv, &test->out, &test->ref); } void test_timer_start(struct test_display *t, struct timespec *tv) { clock_gettime(CLOCK_MONOTONIC, tv); } double test_timer_stop(struct test_display *t, struct timespec *tv) { XImage *image; struct timespec now; image = XGetImage(t->dpy, t->root, 0, 0, 1, 1, AllPlanes, ZPixmap); clock_gettime(CLOCK_MONOTONIC, &now); XDestroyImage(image); return (now.tv_sec - tv->tv_sec) + 1e-9*(now.tv_nsec - tv->tv_nsec); } xserver-xorg-video-intel-2.99.917+git20160325/test/test_image.c000066400000000000000000000151331267532330400235420ustar00rootroot00000000000000#include #include #include #include #include "test.h" #define MAX_DELTA 3 int pixel_difference(uint32_t a, uint32_t b) { int max = 0; int i; for (i = 0; i < 32; i += 8) { uint8_t ac = (a >> i) & 0xff; uint8_t bc = (b >> i) & 0xff; int d; if (ac > bc) d = ac - bc; else d = bc - ac; if (d > max) max = d; } return max; } static void show_pixels(char *buf, const XImage *out, const XImage *ref, int x, int y, int w, int h) { int i, j, len = 0; for (j = y - 2; j <= y + 2; j++) { if (j < 0 || j >= h) continue; for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", *(uint32_t*)(out->data + j*out->bytes_per_line + i*out->bits_per_pixel/8)); } len += sprintf(buf+len, "\t"); for (i = x - 2; i <= x + 2; i++) { if (i < 0 || i >= w) continue; len += sprintf(buf+len, "%08x ", *(uint32_t*)(ref->data + j*out->bytes_per_line + i*out->bits_per_pixel/8)); } len += sprintf(buf+len, "\n"); } } static void test_compare_fallback(struct test *t, Drawable out_draw, XRenderPictFormat *out_format, Drawable ref_draw, XRenderPictFormat *ref_format, int x, int y, int w, int h) { XImage *out_image, *ref_image; char *out, *ref; char buf[600]; uint32_t mask; int i, j; die_unless(out_format->depth == ref_format->depth); out_image = XGetImage(t->out.dpy, out_draw, x, y, w, h, AllPlanes, ZPixmap); out = out_image->data; ref_image = XGetImage(t->ref.dpy, ref_draw, x, y, w, h, AllPlanes, ZPixmap); ref = ref_image->data; mask = depth_mask(out_image->depth); /* Start with an exact comparison. However, one quicky desires * a fuzzy comparator to hide hardware inaccuracies... */ for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { uint32_t a = ((uint32_t *)out)[i] & mask; uint32_t b = ((uint32_t *)ref)[i] & mask; if (a != b && pixel_difference(a, b) > MAX_DELTA) { show_pixels(buf, out_image, ref_image, i, j, w, h); die("discrepancy found at (%d+%d, %d+%d): found %08x, expected %08x (delta: %d)\n%s", x,i, y,j, a, b, pixel_difference(a, b), buf); } } out += out_image->bytes_per_line; ref += ref_image->bytes_per_line; } XDestroyImage(out_image); XDestroyImage(ref_image); } static void unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data) { unsigned int i; for (i = 0; i < row_info->rowbytes; i += 4) { uint8_t *b = &data[i]; uint32_t pixel; uint8_t alpha; memcpy (&pixel, b, sizeof (uint32_t)); alpha = (pixel & 0xff000000) >> 24; if (alpha == 0) { b[0] = (pixel & 0xff0000) >> 16; b[1] = (pixel & 0x00ff00) >> 8; b[2] = (pixel & 0x0000ff) >> 0; b[3] = 0xff; } else { b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; b[3] = alpha; } } } static void save_image(XImage *image, const char *filename) { FILE *file; png_struct *png = NULL; png_info *info = NULL; png_byte **rows = NULL; int i; file = fopen(filename, "w"); if (file == NULL) return; png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png == NULL) goto out; info = png_create_info_struct(png); if (info == NULL) goto out; rows = png_malloc(png, sizeof(png_byte *) * image->height); if (rows == NULL) goto out; for (i = 0; i < image->height; i++) rows[i] = (png_byte *)(image->data + image->bytes_per_line * i); if (setjmp(png_jmpbuf(png))) goto out; png_set_IHDR(png, info, image->width, image->height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_init_io(png, file); png_write_info(png, info); png_set_write_user_transform_fn(png, unpremultiply_data); png_write_image(png, rows); png_write_end(png, info); out: if (rows) png_free(png, rows); png_destroy_write_struct(&png, &info); fclose(file); } void test_compare(struct test *t, Drawable out_draw, XRenderPictFormat *out_format, Drawable ref_draw, XRenderPictFormat *ref_format, int x, int y, int w, int h, const char *info) { XImage out_image, ref_image; uint32_t *out, *ref; char buf[600]; uint32_t mask; int i, j; if (w * h * 4 > t->out.max_shm_size) return test_compare_fallback(t, out_draw, out_format, ref_draw, ref_format, x, y, w, h); test_init_image(&out_image, &t->out.shm, out_format, w, h); test_init_image(&ref_image, &t->ref.shm, ref_format, w, h); die_unless(out_image.depth == ref_image.depth); die_unless(out_image.bits_per_pixel == ref_image.bits_per_pixel); die_unless(out_image.bits_per_pixel == 32); XShmGetImage(t->out.dpy, out_draw, &out_image, x, y, AllPlanes); out = (uint32_t *)out_image.data; XShmGetImage(t->ref.dpy, ref_draw, &ref_image, x, y, AllPlanes); ref = (uint32_t *)ref_image.data; /* Start with an exact comparison. However, one quicky desires * a fuzzy comparator to hide hardware inaccuracies... */ mask = depth_mask(out_image.depth); for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { uint32_t a = out[i] & mask; uint32_t b = ref[i] & mask; if (a != b && pixel_difference(a, b) > MAX_DELTA) { show_pixels(buf, &out_image, &ref_image, i, j, w, h); save_image(&out_image, "out.png"); save_image(&ref_image, "ref.png"); die("discrepancy found at (%d+%d, %d+%d): found %08x, expected %08x (delta: %d)\n%s%s\n", x,i, y,j, a, b, pixel_difference(a, b), buf, info); } } out = (uint32_t *)((char *)out + out_image.bytes_per_line); ref = (uint32_t *)((char *)ref + ref_image.bytes_per_line); } } static int _native_byte_order_lsb(void) { int x = 1; return *((char *) &x) == 1; } void test_init_image(XImage *ximage, XShmSegmentInfo *shm, XRenderPictFormat *format, int width, int height) { int native_byte_order = _native_byte_order_lsb() ? LSBFirst : MSBFirst; ximage->width = width; ximage->height = height; ximage->format = ZPixmap; ximage->data = shm->shmaddr; ximage->obdata = (void *)shm; ximage->byte_order = native_byte_order; ximage->bitmap_unit = 32; ximage->bitmap_bit_order = native_byte_order; ximage->bitmap_pad = 32; ximage->depth = format->depth; ximage->bytes_per_line = 4*width; ximage->bits_per_pixel = 32; ximage->red_mask = 0xff << 16; ximage->green_mask = 0xff << 8; ximage->blue_mask = 0xff << 0; ximage->xoffset = 0; XInitImage(ximage); } xserver-xorg-video-intel-2.99.917+git20160325/test/test_log.c000066400000000000000000000003111267532330400232310ustar00rootroot00000000000000#include #include #include #include "test.h" void die(const char *fmt, ...) { va_list va; va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); exit(1); } xserver-xorg-video-intel-2.99.917+git20160325/test/test_render.c000066400000000000000000000055271267532330400237450ustar00rootroot00000000000000#include #include #include #include #include #include #include "test.h" const char *test_target_name(enum target target) { switch (target) { default: case ROOT: return "root"; case CHILD: return "child"; case PIXMAP: return "pixmap"; } } void test_target_create_render(struct test_display *dpy, enum target target, struct test_target *tt) { XSetWindowAttributes attr; XGCValues gcv; tt->dpy = dpy; tt->target = target; tt->draw = dpy->root; tt->format = dpy->format; tt->width = dpy->width; tt->height = dpy->height; tt->depth = dpy->depth; switch (target) { case ROOT: break; case CHILD: attr.override_redirect = 1; tt->width /= 4; tt->height /= 4; tt->draw = XCreateWindow(dpy->dpy, tt->draw, dpy->width/2, dpy->height/2, tt->width, tt->height, 0, tt->format->depth, InputOutput, DefaultVisual(dpy->dpy, DefaultScreen(dpy->dpy)), CWOverrideRedirect, &attr); XMapWindow(dpy->dpy, tt->draw); break; case PIXMAP: tt->format = XRenderFindStandardFormat(dpy->dpy, PictStandardARGB32); tt->draw = XCreatePixmap(dpy->dpy, tt->draw, dpy->width, dpy->height, tt->format->depth); tt->depth = 32; break; } tt->picture = XRenderCreatePicture(dpy->dpy, tt->draw, tt->format, 0, NULL); gcv.graphics_exposures = 0; tt->gc = XCreateGC(dpy->dpy, tt->draw, GCGraphicsExposures, &gcv); } void test_target_destroy_render(struct test_display *dpy, struct test_target *tt) { XRenderFreePicture(dpy->dpy, tt->picture); switch (tt->target) { case ROOT: break; case CHILD: XDestroyWindow(dpy->dpy, tt->draw); break; case PIXMAP: XFreePixmap(dpy->dpy, tt->draw); break; } } #if 0 static int random_bool(void) { return rand() > RAND_MAX/2; } static Picture create_alpha_map(void) { return 0; } static Pixmap create_clip_mask(void) { return 0; } unsigned int test_render_randomize_picture_attributes(XRenderPictureAttributes *pa) { unsigned int flags = 0; memset(pa, 0, sizeof(*pa)); if (random_bool()) { pa->repeat = repeat_modes[rand() % ARRAY_SIZE(repeat_modes)]; flags |= CPRepeat; } if (random_bool()) { pa->alpha_map = create_alpha_map(); pa->alpha_x_origin = rand() % 1024; pa->alpha_y_origin = rand() % 1024; flags |= CPAlphaMap; } if (random_bool()) { pa->clip_mask = create_clip_mask(); pa->clip_x_orgin = rand() % 1024; pa->clip_y_orgin = rand() % 1024; flags |= CPClipMask; } if (random_bool()) { pa->subwindow_mode = random_bool(); flags |= CPSubwindowMode; } if (random_bool()) { pa->poly_edge = random_bool(); flags |= CPPolyEdge; } if (random_bool()) { pa->poly_mode = random_bool(); flags |= CPPolyMode; } if (random_bool()) { pa->component_alpha = random_bool(); flags |= CPComponentAlpha; } return flags; } #endif xserver-xorg-video-intel-2.99.917+git20160325/test/virtual.conf000066400000000000000000000011161267532330400236060ustar00rootroot00000000000000Section "Device" Identifier "Device0" Driver "intel" Option "ZaphodHeads" "LVDS1" Option "VirtualHeads" "1" BusID "PCI:0:2:0" Screen 0 EndSection Section "Device" Identifier "Device1" Driver "intel" Option "ZaphodHeads" "HDMI1" BusID "PCI:0:2:0" Screen 1 EndSection Section "Screen" Identifier "Screen0" Device "Device0" EndSection Section "Screen" Identifier "Screen1" Device "Device1" EndSection Section "ServerFlags" Option "AutoAddGPU" "False" EndSection Section "ServerLayout" Identifier "ServerLayout0" Screen 0 "Screen0" 0 0 Screen 1 "Screen1" 0 0 EndSection xserver-xorg-video-intel-2.99.917+git20160325/tools/000077500000000000000000000000001267532330400214335ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/tools/.gitignore000066400000000000000000000001661267532330400234260ustar00rootroot00000000000000cursor dri3info intel-virtual-output org.x.xf86-video-intel.backlight-helper.policy xf86-video-intel-backlight-helper xserver-xorg-video-intel-2.99.917+git20160325/tools/Makefile.am000066400000000000000000000051521267532330400234720ustar00rootroot00000000000000# 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. AM_CFLAGS = \ @CWARNFLAGS@ \ @NOWARNFLAGS@ \ $(NULL) drivermandir = $(DRIVER_MAN_DIR) policydir = $(datarootdir)/polkit-1/actions bin_PROGRAMS = noinst_PROGRAMS = libexec_PROGRAMS = if BUILD_TOOLS bin_PROGRAMS += intel-virtual-output driverman_DATA = intel-virtual-output.$(DRIVER_MAN_SUFFIX) endif if BUILD_TOOL_CURSOR noinst_PROGRAMS += cursor cursor_CFLAGS = $(TOOL_CURSOR_CFLAGS) cursor_LDADD = $(TOOL_CURSOR_LIBS) endif if X11_DRI3 noinst_PROGRAMS += dri3info dri3info_SOURCES = dri3info.c dri3info_CFLAGS = $(X11_DRI3_CFLAGS) $(DRI_CFLAGS) dri3info_LDADD = $(X11_DRI3_LIBS) $(DRI_LIBS) endif if BUILD_BACKLIGHT_HELPER libexec_PROGRAMS += xf86-video-intel-backlight-helper nodist_policy_DATA = org.x.xf86-video-intel.backlight-helper.policy backlight_helper = $(libexecdir)/xf86-video-intel-backlight-helper install-exec-hook: -chown root $(DESTDIR)$(backlight_helper) && chmod u+s $(DESTDIR)$(backlight_helper) endif intel_virtual_output_CFLAGS = \ @CWARNFLAGS@ \ $(IVO_CFLAGS) \ @NOWARNFLAGS@ \ $(NULL) intel_virtual_output_SOURCES = \ virtual.c \ $(NULL) intel_virtual_output_LDADD = \ $(IVO_LIBS) \ $(NULL) xf86_video_intel_backlight_helper_SOURCES = \ backlight_helper.c \ $(NULL) EXTRA_DIST = intel-virtual-output.man org.x.xf86-video-intel.backlight-helper.policy.in CLEANFILES = $(driverman_DATA) $(nodist_policy_DATA) # String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man .man.$(DRIVER_MAN_SUFFIX): $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ xserver-xorg-video-intel-2.99.917+git20160325/tools/backlight_helper.c000066400000000000000000000024561267532330400250750ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #if MAJOR_IN_MKDEV #include #elif MAJOR_IN_SYSMACROS #include #endif #define DBG 0 #if defined(__GNUC__) && (__GNUC__ > 3) __attribute__((format(printf, 1, 2), noreturn)) #endif static void die(const char *format, ...) { if (DBG) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); } exit(1); } int main(int argc, char *argv[]) { struct stat st; char buf[1024]; int len, fd; if (argc != 2) die("Usage: xf86-video-intel-backlight-helper \n"); if (strchr(argv[1], '/') != NULL) die("Invalid interface '%s': contains '/'\n", argv[1]); if (snprintf(buf, sizeof(buf), "/sys/class/backlight/%s/brightness", argv[1]) >= sizeof(buf)) die("Invalid interface '%s': name too long\n", argv[1]); fd = open(buf, O_RDWR); if (fd < 0 || fstat(fd, &st) || major(st.st_dev)) die("Invalid interface '%s': unknown backlight file\n", argv[1]); while (fgets(buf, sizeof(buf), stdin)) { len = strlen(buf); if (write(fd, buf, len) != len) die("Failed to update backlight interface '%s': errno=%d\n", argv[1], errno); } return 0; } xserver-xorg-video-intel-2.99.917+git20160325/tools/cursor.c000066400000000000000000000062631267532330400231230ustar00rootroot00000000000000/* * Copyright © 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include int main(int argc, char **argv) { Display *dpy; XFixesCursorImage *cur; unsigned long *src; /* XXX deep sigh */ unsigned x, y; png_struct *png; png_info *info; png_byte **rows; FILE *file; dpy = XOpenDisplay(NULL); if (dpy == NULL) return 1; if (!XFixesQueryExtension(dpy, (int *)&x, (int *)&y)) return 1; cur = XFixesGetCursorImage(dpy); if (cur == NULL) return 1; printf("Cursor on display '%s': %dx%d, (hotspot %dx%d)\n", DisplayString(dpy), cur->width, cur->height, cur->xhot, cur->yhot); if (1) { int x, y; src = cur->pixels; for (y = 0; y < cur->height; y++) { for (x = 0; x < cur->width; x++) { if (x == cur->xhot && y == cur->yhot) printf("+"); else printf("%c", *src ? *src >> 24 >= 127 ? 'x' : '.' : ' '); src++; } printf("\n"); } } file = fopen("cursor.png", "wb"); if (file == NULL) return 2; png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info = png_create_info_struct(png); png_init_io(png, file); png_set_IHDR(png, info, cur->width, cur->height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png, info); src = cur->pixels; rows = malloc(cur->height*sizeof(png_byte*)); if (rows == NULL) return 3; for (y = 0; y < cur->height; y++) { rows[y] = malloc(cur->width * 4); for (x = 0; x < cur->width; x++) { uint32_t p = *src++; uint8_t r = p >> 0; uint8_t g = p >> 8; uint8_t b = p >> 16; uint8_t a = p >> 24; if (a > 0x00 && a < 0xff) { r = (r * 0xff + a /2) / a; g = (g * 0xff + a /2) / a; b = (b * 0xff + a /2) / a; } rows[y][4*x + 0] = b; rows[y][4*x + 1] = g; rows[y][4*x + 2] = r; rows[y][4*x + 3] = a; } } png_write_image(png, rows); png_write_end(png, NULL); fclose(file); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/tools/dri3info.c000066400000000000000000000172051267532330400233210ustar00rootroot00000000000000/* * Copyright (c) 2015 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * To compile standalone: gcc -o dri3info dri3info.c `pkg-config --cflags --libs xcb-dri3 x11-xcb xrandr xxf86vm libdrm` */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int dri3_query_version(Display *dpy, int *major, int *minor) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_query_version_reply_t *reply; xcb_generic_error_t *error; *major = *minor = -1; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(error); if (reply == NULL) return -1; *major = reply->major_version; *minor = reply->minor_version; free(reply); return 0; } static int dri3_exists(Display *dpy) { const xcb_query_extension_reply_t *ext; int major, minor; ext = xcb_get_extension_data(XGetXCBConnection(dpy), &xcb_dri3_id); if (ext == NULL || !ext->present) return 0; if (dri3_query_version(dpy, &major, &minor) < 0) return 0; return major >= 0; } static int dri3_open(Display *dpy) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_open_cookie_t cookie; xcb_dri3_open_reply_t *reply; if (!dri3_exists(dpy)) return -1; cookie = xcb_dri3_open(c, RootWindow(dpy, DefaultScreen(dpy)), None); reply = xcb_dri3_open_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; return xcb_dri3_open_reply_fds(c, reply)[0]; } static void get_device_path(int fd, char *buf, int len) { struct stat remote, local; int i; if (fstat(fd, &remote)) goto out; for (i = 0; i < 16; i++) { snprintf(buf, len, "/dev/dri/card%d", i); if (stat(buf, &local)) continue; if (local.st_mode == remote.st_mode && local.st_rdev == remote.st_rdev) return; snprintf(buf, len, "/dev/dri/renderD%d", i + 128); if (stat(buf, &local)) continue; if (local.st_mode == remote.st_mode && local.st_rdev == remote.st_rdev) return; } out: strncpy(buf, "unknown path", len); } static void get_driver_name(int fd, char *name, int len) { drm_version_t version; memset(name, 0, len); memset(&version, 0, sizeof(version)); version.name_len = len; version.name = name; (void)drmIoctl(fd, DRM_IOCTL_VERSION, &version); } static int compute_refresh_rate_from_mode(long n, long d, unsigned flags, int32_t *numerator, int32_t *denominator) { int i; /* The mode flags are only defined privately to the Xserver (in xf86str.h) * but they at least bit compatible between VidMode, RandR and DRM. */ # define V_INTERLACE 0x010 # define V_DBLSCAN 0x020 if (flags & V_INTERLACE) n *= 2; else if (flags & V_DBLSCAN) d *= 2; /* The OML_sync_control spec requires that if the refresh rate is a * whole number, that the returned numerator be equal to the refresh * rate and the denominator be 1. */ if (n % d == 0) { n /= d; d = 1; } else { static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 }; /* This is a poor man's way to reduce a fraction. It's far from * perfect, but it will work well enough for this situation. */ for (i = 0; f[i] != 0; i++) { while (n % f[i] == 0 && d % f[i] == 0) { d /= f[i]; n /= f[i]; } } } *numerator = n; *denominator = d; return 1; } static int RRGetMscRate(Display *dpy, int32_t *numerator, int32_t *denominator) { int ret = 0; Window root = RootWindow(dpy, DefaultScreen(dpy)); XRRScreenResources *res; int rr_event, rr_error; RROutput primary; RRMode mode = 0; int n; if (!XRRQueryExtension(dpy, &rr_event, &rr_error)) return ret; res = XRRGetScreenResourcesCurrent(dpy, root); if (res == NULL) return ret; /* Use the primary output if specified, otherwise * use the mode on the first enabled crtc. */ primary = XRRGetOutputPrimary(dpy, root); if (primary) { XRROutputInfo *output; output = XRRGetOutputInfo(dpy, res, primary); if (output != NULL) { if (output->crtc) { XRRCrtcInfo *crtc; crtc = XRRGetCrtcInfo(dpy, res, output->crtc); if (crtc) { mode = crtc->mode; XRRFreeCrtcInfo(crtc); } } XRRFreeOutputInfo(output); } } for (n = 0; mode == 0 && n < res->ncrtc; n++) { XRRCrtcInfo *crtc; crtc = XRRGetCrtcInfo(dpy, res, res->crtcs[n]); if (crtc) { mode = crtc->mode; XRRFreeCrtcInfo(crtc); } } for (n = 0; n < res->nmode; n++) { if (res->modes[n].id == mode) { ret = compute_refresh_rate_from_mode(res->modes[n].dotClock, res->modes[n].hTotal*res->modes[n].vTotal, res->modes[n].modeFlags, numerator, denominator); break; } } XRRFreeScreenResources(res); return ret; } static int VMGetMscRate(Display *dpy, int32_t *numerator, int32_t *denominator) { XF86VidModeModeLine mode_line; int dot_clock; int i; if (XF86VidModeQueryVersion(dpy, &i, &i) && XF86VidModeGetModeLine(dpy, DefaultScreen(dpy), &dot_clock, &mode_line)) return compute_refresh_rate_from_mode(dot_clock * 1000, mode_line.vtotal * mode_line.htotal, mode_line.flags, numerator, denominator); return 0; } static int get_refresh_rate(Display *dpy, int32_t *numerator, int32_t *denominator) { if (RRGetMscRate(dpy, numerator, denominator)) return 1; if (VMGetMscRate(dpy, numerator, denominator)) return 1; return 0; } static void info(const char *dpyname) { Display *dpy; int device; int32_t numerator, denominator; dpy = XOpenDisplay(dpyname); if (dpy == NULL) { printf("Unable to connect to display '%s'\n", dpyname ?: getenv("DISPLAY") ?: "unset"); return; } printf("Display '%s'\n", DisplayString(dpy)); device = dri3_open(dpy); if (device < 0) { printf("\tUnable to connect to DRI3\n"); } else { char device_path[1024]; char driver_name[1024]; get_device_path(device, device_path, sizeof(device_path)); get_driver_name(device, driver_name, sizeof(driver_name)); printf("Connected to DRI3, using fd %d which matches %s, driver %s\n", device, device_path, driver_name); close(device); } if (get_refresh_rate(dpy, &numerator, &denominator)) printf("\tPrimary refresh rate: %d/%d (%.1fHz)\n", numerator, denominator, numerator/(float)denominator); XCloseDisplay(dpy); } int main(int argc, char **argv) { int i; if (argc > 1) { for (i = 1; i < argc; i++) info(argv[i]); } else info(NULL); return 0; } xserver-xorg-video-intel-2.99.917+git20160325/tools/intel-virtual-output.man000066400000000000000000000022641267532330400262710ustar00rootroot00000000000000.\" shorthand for double quote that works everywhere. .ds q \N'34' .TH intel-virtual-output __drivermansuffix__ __vendorversion__ .SH NAME intel-virtual-output \- Utility for connecting the Integrated Intel GPU to discrete outputs .SH SYNOPSIS .nf .B "intel-virtual-output [] ..." .fi .SH DESCRIPTION .B intel-virtual-output is a utility for Intel integrated graphics chipsets on hybrid systems. The tool connects local VirtualHeads to a remote output, allowing the primary display to extend onto the remote outputs. .SH REPORTING BUGS The xf86-video-intel driver is part of the X.Org and Freedesktop.org umbrella projects. Details on bug reporting can be found at https://01.org/linuxgraphics/documentation/how-report-bugs. Mailing lists are also commonly used to report experiences and ask questions about configuration and other topics. See lists.freedesktop.org for more information (the xorg@lists.freedesktop.org mailing list is the most appropriate place to ask X.Org and driver related questions). .SH "SEE ALSO" intel(__drivermansuffix__), __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) org.x.xf86-video-intel.backlight-helper.policy.in000066400000000000000000000015361267532330400324570ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/tools The X.Org project https://01.org/linuxgraphics/community/xf86-video-intel brightness Modify lcd panel brightness Authentication is required to modify the lcd panel brightness no no yes @LIBEXEC_PATH@/xf86-video-intel-backlight-helper xserver-xorg-video-intel-2.99.917+git20160325/tools/virtual.c000066400000000000000000002762051267532330400233010ustar00rootroot00000000000000/* * Copyright © 2013 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #if HAVE_X11_EXTENSIONS_SHMPROTO_H #include #elif HAVE_X11_EXTENSIONS_SHMSTR_H #include #else #error Failed to find the right header for X11 MIT-SHM protocol definitions #endif #include #if HAVE_X11_EXTENSIONS_XINERAMA_H #include #define USE_XINERAMA #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define FORCE_FULL_REDRAW 0 #define FORCE_16BIT_XFER 0 #define DBG(v, x) if (verbose & v) printf x static int verbose; #define X11 0x1 #define XRR 0x1 #define TIMER 0x4 #define DRAW 0x8 #define DAMAGE 0x10 #define CURSOR 0x20 #define SCREEN 0x40 #define POLL 0x80 struct display { Display *dpy; struct clone *clone; struct context *ctx; int saver_event, saver_error, saver_active; int damage_event, damage_error; int xfixes_event, xfixes_error; int rr_event, rr_error, rr_active; int xinerama_event, xinerama_error, xinerama_active; int dri3_active; Window root; Visual *visual; Damage damage; int width; int height; int depth; int active; XRenderPictFormat *root_format; XRenderPictFormat *rgb16_format; XRenderPictFormat *rgb24_format; int has_shm; int has_shm_pixmap; int shm_opcode; int shm_event; Cursor invisible_cursor; Cursor visible_cursor; XcursorImage cursor_image; /* first only */ int cursor_serial; int cursor_x; int cursor_y; int cursor_moved; int cursor_visible; int cursor; int flush; int send; int skip_clone; int skip_frame; struct { int timeout; int interval; int prefer_blank; int allow_exp; } saver; }; struct output { struct display *display; Display *dpy; char *name; RROutput rr_output; RRCrtc rr_crtc; Window window; Picture win_picture; Picture pix_picture; Pixmap pixmap; GC gc; long serial; int use_shm; int use_shm_pixmap; XShmSegmentInfo shm; XRenderPictFormat *use_render; int x, y; int width, height; XRRModeInfo mode; Rotation rotation; }; struct clone { struct clone *next; struct clone *active; struct output src, dst; long timestamp; XShmSegmentInfo shm; XImage image; int width, height, depth; struct { int x1, x2, y1, y2; } damaged; int rr_update; struct dri3_fence { XID xid; void *addr; } dri3; }; struct context { struct display *display; struct clone *clones; struct clone *active; struct pollfd *pfd; #define timer pfd[0].fd Display *record; int nclone; int ndisplay; int nfd; int timer_active; long timestamp; long configTimestamp; Atom singleton; char command[1024]; int command_continuation; }; static inline int is_power_of_2(unsigned long n) { return n && ((n & (n - 1)) == 0); } static int xlib_vendor_is_xorg(Display *dpy) { const char *const vendor = ServerVendor(dpy); return strstr(vendor, "X.Org") || strstr(vendor, "Xorg"); } static inline XRRScreenResources *_XRRGetScreenResourcesCurrent(Display *dpy, Window window) { XRRScreenResources *res; res = XRRGetScreenResourcesCurrent(dpy, window); if (res == NULL) res = XRRGetScreenResources(dpy, window); return res; } #define XORG_VERSION_ENCODE(major,minor,patch,snap) \ (((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap) static int _x_error_occurred; static int _io_error_handler(Display *display) { fprintf(stderr, "XIO error on display %s\n", DisplayString(display)); abort(); } static int _check_error_handler(Display *display, XErrorEvent *event) { DBG(X11, ("X11 error from display %s, serial=%ld, error=%d, req=%d.%d\n", DisplayString(display), event->serial, event->error_code, event->request_code, event->minor_code)); _x_error_occurred = 1; return False; /* ignored */ } static int can_use_shm(Display *dpy, Window window, int *shm_event, int *shm_opcode, int *shm_pixmap) { XShmSegmentInfo shm; Status success; XExtCodes *codes; int major, minor, has_shm, has_pixmap; *shm_event = 0; *shm_opcode = 0; *shm_pixmap = 0; if (!XShmQueryExtension(dpy)) return 0; XShmQueryVersion(dpy, &major, &minor, &has_pixmap); shm.shmid = shmget(IPC_PRIVATE, 0x1000, IPC_CREAT | 0600); if (shm.shmid == -1) return 0; shm.readOnly = 0; shm.shmaddr = shmat(shm.shmid, NULL, 0); if (shm.shmaddr == (char *) -1) { shmctl(shm.shmid, IPC_RMID, NULL); return 0; } XSync(dpy, False); _x_error_occurred = 0; success = XShmAttach(dpy, &shm); XSync(dpy, False); has_shm = success && _x_error_occurred == 0; /* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent, * the Xserver may crash if it does not take care when processing * the event type. For instance versions of Xorg prior to 1.11.1 * exhibited this bug, and was fixed by: * * commit 2d2dce558d24eeea0eb011ec9ebaa6c5c2273c39 * Author: Sam Spilsbury * Date: Wed Sep 14 09:58:34 2011 +0800 * * Remove the SendEvent bit (0x80) before doing range checks on event type. */ codes = 0; if (has_shm) codes = XInitExtension(dpy, SHMNAME); if (xlib_vendor_is_xorg(dpy) && VendorRelease(dpy) < XORG_VERSION_ENCODE(1,11,0,1)) codes = 0; if (codes) { XShmCompletionEvent e; memset(&e, 0, sizeof(e)); e.type = codes->first_event; e.send_event = 1; e.serial = 1; e.drawable = window; e.major_code = codes->major_opcode; e.minor_code = X_ShmPutImage; e.shmseg = shm.shmid; e.offset = 0; XSendEvent(dpy, e.drawable, False, 0, (XEvent *)&e); XSync(dpy, False); if (_x_error_occurred == 0) { *shm_opcode = codes->major_opcode; *shm_event = codes->first_event; *shm_pixmap = has_pixmap; } } XShmDetach(dpy, &shm); shmctl(shm.shmid, IPC_RMID, NULL); shmdt(shm.shmaddr); return has_shm; } #ifdef DRI3 #include #include #include #include #include #include static Pixmap dri3_create_pixmap(Display *dpy, Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_pixmap_t pixmap = xcb_generate_id(c); xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); return pixmap; } static int dri3_create_fd(Display *dpy, Pixmap pixmap, int *stride) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_buffer_from_pixmap_cookie_t cookie; xcb_dri3_buffer_from_pixmap_reply_t *reply; cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); if (!reply) return -1; if (reply->nfd != 1) return -1; *stride = reply->stride; return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; } static int dri3_query_version(Display *dpy, int *major, int *minor) { xcb_connection_t *c = XGetXCBConnection(dpy); xcb_dri3_query_version_reply_t *reply; xcb_generic_error_t *error; *major = *minor = -1; reply = xcb_dri3_query_version_reply(c, xcb_dri3_query_version(c, XCB_DRI3_MAJOR_VERSION, XCB_DRI3_MINOR_VERSION), &error); free(error); if (reply == NULL) return -1; *major = reply->major_version; *minor = reply->minor_version; free(reply); return 0; } static int dri3_exists(Display *dpy) { const xcb_query_extension_reply_t *ext; int major, minor; ext = xcb_get_extension_data(XGetXCBConnection(dpy), &xcb_dri3_id); if (ext == NULL || !ext->present) return 0; if (dri3_query_version(dpy, &major, &minor) < 0) return 0; return major >= 0; } static void dri3_create_fence(Display *dpy, Drawable d, struct dri3_fence *fence) { xcb_connection_t *c = XGetXCBConnection(dpy); struct dri3_fence f; int fd; fd = xshmfence_alloc_shm(); if (fd < 0) return; f.addr = xshmfence_map_shm(fd); if (f.addr == NULL) { close(fd); return; } f.xid = xcb_generate_id(c); xcb_dri3_fence_from_fd(c, d, f.xid, 0, fd); *fence = f; } static void dri3_fence_flush(Display *dpy, struct dri3_fence *fence) { xcb_sync_trigger_fence(XGetXCBConnection(dpy), fence->xid); } static void dri3_fence_free(Display *dpy, struct dri3_fence *fence) { xshmfence_unmap_shm(fence->addr); xcb_sync_destroy_fence(XGetXCBConnection(dpy), fence->xid); } #else static int dri3_exists(Display *dpy) { return 0; } static void dri3_create_fence(Display *dpy, Drawable d, struct dri3_fence *fence) { } static void dri3_fence_flush(Display *dpy, struct dri3_fence *fence) { } static void dri3_fence_free(Display *dpy, struct dri3_fence *fence) { } static Pixmap dri3_create_pixmap(Display *dpy, Drawable draw, int width, int height, int depth, int fd, int bpp, int stride, int size) { return None; } static int dri3_create_fd(Display *dpy, Pixmap pixmap, int *stride) { return -1; } #endif static int timerfd(int hz) { struct itimerspec it; int fd; fd = -1; #ifdef CLOCK_MONOTONIC_COARSE fd = timerfd_create(CLOCK_MONOTONIC_COARSE, TFD_NONBLOCK); #endif if (fd < 0) fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if (fd < 0) return -ETIME; it.it_interval.tv_sec = 0; it.it_interval.tv_nsec = 1000000000 / hz; it.it_value = it.it_interval; if (timerfd_settime(fd, 0, &it, NULL) < 0) { close(fd); return -ETIME; } return fd; } static int context_init(struct context *ctx) { struct pollfd *pfd; memset(ctx, 0, sizeof(*ctx)); ctx->pfd = malloc(2*sizeof(struct pollfd)); if (ctx->pfd == NULL) return -ENOMEM; ctx->clones = malloc(sizeof(struct clone)); if (ctx->clones == NULL) return -ENOMEM; ctx->display = malloc(sizeof(struct display)); if (ctx->display == NULL) return -ENOMEM; pfd = memset(&ctx->pfd[ctx->nfd++], 0, sizeof(struct pollfd)); pfd->fd = timerfd(60); if (pfd->fd < 0) return pfd->fd; pfd->events = POLLIN; return 0; } static void context_enable_timer(struct context *ctx) { uint64_t count; DBG(TIMER, ("%s timer active? %d\n", __func__, ctx->timer_active)); if (ctx->timer_active) return; /* reset timer */ count = read(ctx->timer, &count, sizeof(count)); ctx->timer_active = 1; } static int add_fd(struct context *ctx, int fd) { struct pollfd *pfd; if (fd < 0) return fd; if (is_power_of_2(ctx->nfd)) { ctx->pfd = realloc(ctx->pfd, 2*ctx->nfd*sizeof(struct pollfd)); if (ctx->pfd == NULL) return -ENOMEM; } pfd = memset(&ctx->pfd[ctx->nfd++], 0, sizeof(struct pollfd)); pfd->fd = fd; pfd->events = POLLIN; return 0; } static void display_mark_flush(struct display *display) { DBG(DRAW, ("%s mark flush (flush=%d)\n", DisplayString(display->dpy), display->flush)); if (display->flush) return; context_enable_timer(display->ctx); display->flush = 1; } static int mode_equal(const XRRModeInfo *a, const XRRModeInfo *b) { return (a->width == b->width && a->height == b->height && a->dotClock == b->dotClock && a->hSyncStart == b->hSyncStart && a->hSyncEnd == b->hSyncEnd && a->hTotal == b->hTotal && a->hSkew == b->hSkew && a->vSyncStart == b->vSyncStart && a->vSyncEnd == b->vSyncEnd && a->vTotal == b->vTotal && a->modeFlags == b->modeFlags); } static XRRModeInfo *lookup_mode(XRRScreenResources *res, int id) { int i; for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == id) return &res->modes[i]; } return NULL; } static void clone_update_edid(struct clone *clone) { unsigned long nitems, after; unsigned char *data; int format; Atom type; if (XRRGetOutputProperty(clone->dst.dpy, clone->dst.rr_output, XInternAtom(clone->dst.dpy, "EDID", False), 0, 100, False, False, AnyPropertyType, &type, &format, &nitems, &after, &data) == Success) { XRRChangeOutputProperty(clone->src.dpy, clone->src.rr_output, XInternAtom(clone->src.dpy, "EDID", False), type, format, PropModeReplace, data, nitems); } } static int disable_crtc(Display *dpy, XRRScreenResources *res, RRCrtc crtc) { XRRPanning panning; if (crtc) { XRRSetPanning(dpy, res, crtc, memset(&panning, 0, sizeof(panning))); if (XRRSetCrtcConfig(dpy, res, crtc, CurrentTime, 0, 0, None, RR_Rotate_0, NULL, 0) != Success) return 0; if (XRRSetPanning(dpy, res, crtc, memset(&panning, 0, sizeof(panning))) != Success) { DBG(XRR, ("%s failed to clear panning on CRTC:%ld\n", DisplayString(dpy), (long)crtc)); if (verbose) { XRRCrtcInfo *c; XRRPanning *p; c = XRRGetCrtcInfo(dpy, res, crtc); if (c) { DBG(XRR, ("%s CRTC:%ld x=%d, y=%d, rotation=%d, mode=%ld\n", DisplayString(dpy), (long)crtc, c->x, c->y, c->rotation, c->mode)); XRRFreeCrtcInfo(c); } p = XRRGetPanning(dpy, res, crtc); if (p) { DBG(XRR, ("%s CRTC:%ld panning (%d, %d)x(%d, %d), tracking (%d, %d)x(%d, %d), border (%d, %d),(%d, %d)\n", DisplayString(dpy), (long)crtc, p->left, p->top, p->width, p->height, p->track_left, p->track_top, p->track_width, p->track_height, p->border_left, p->border_top, p->border_right, p->border_bottom)); XRRFreePanning(p); } } } } return 1; } static int clone_update_modes__randr(struct clone *clone) { XRRScreenResources *from_res = NULL, *to_res = NULL; XRROutputInfo *from_info = NULL, *to_info = NULL; int i, j, ret = ENOENT; assert(clone->src.rr_output); assert(clone->dst.rr_output); assert(clone->dst.display->rr_event); from_res = _XRRGetScreenResourcesCurrent(clone->dst.dpy, clone->dst.window); if (from_res == NULL) goto err; from_info = XRRGetOutputInfo(clone->dst.dpy, from_res, clone->dst.rr_output); if (from_info == NULL) goto err; DBG(XRR, ("%s(%s-%s <- %s-%s): timestamp %ld (last %ld)\n", __func__, DisplayString(clone->src.dpy), clone->src.name, DisplayString(clone->dst.dpy), clone->dst.name, from_info->timestamp, clone->timestamp)); to_res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window); if (to_res == NULL) goto err; to_info = XRRGetOutputInfo(clone->src.dpy, to_res, clone->src.rr_output); if (to_info == NULL) goto err; DBG(XRR, ("%s: dst.rr_crtc=%ld, now %ld\n", __func__, (long)clone->dst.rr_crtc, (long)from_info->crtc)); if (clone->dst.rr_crtc == from_info->crtc) { for (i = 0; i < to_info->nmode; i++) { XRRModeInfo *mode, *old; mode = lookup_mode(to_res, to_info->modes[i]); if (mode == NULL) break; DBG(XRR, ("%s(%s-%s): lookup mode %s\n", __func__, DisplayString(clone->src.dpy), clone->src.name, mode->name)); for (j = 0; j < from_info->nmode; j++) { old = lookup_mode(from_res, from_info->modes[j]); if (old && mode_equal(mode, old)) { mode = NULL; break; } } if (mode) { DBG(XRR, ("%s(%s-%s): unknown mode %s\n", __func__, DisplayString(clone->src.dpy), clone->src.name, mode->name)); break; } } if (i == from_info->nmode && i == to_info->nmode) { DBG(XRR, ("%s(%s-%s): no change in output\n", __func__, DisplayString(clone->src.dpy), clone->src.name)); goto done; } } /* Disable the remote output */ if (from_info->crtc != clone->dst.rr_crtc) { DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__, DisplayString(clone->dst.dpy), clone->dst.name)); if (disable_crtc(clone->dst.dpy, from_res, from_info->crtc)) { clone->dst.rr_crtc = 0; clone->dst.mode.id = 0; } else { XRRCrtcInfo *c = XRRGetCrtcInfo(clone->dst.dpy, from_res, from_info->crtc); if (c) { clone->dst.x = c->x; clone->dst.y = c->y; clone->dst.rotation = c->rotation; clone->dst.mode.id = c->mode; XRRFreeCrtcInfo(c); } } } /* Create matching modes for the real output on the virtual */ XGrabServer(clone->src.dpy); /* Clear all current UserModes on the output, including any active ones */ if (to_info->crtc) { DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__, DisplayString(clone->src.dpy), clone->src.name)); disable_crtc(clone->src.dpy, to_res, to_info->crtc); } for (i = 0; i < to_info->nmode; i++) { DBG(XRR, ("%s(%s-%s): deleting mode %ld\n", __func__, DisplayString(clone->src.dpy), clone->src.name, (long)to_info->modes[i])); XRRDeleteOutputMode(clone->src.dpy, clone->src.rr_output, to_info->modes[i]); } clone->src.rr_crtc = 0; for (i = 0; i < from_info->nmode; i++) { XRRModeInfo *mode, *old; RRMode id; mode = lookup_mode(from_res, from_info->modes[i]); if (mode == NULL) continue; for (j = 0; j < i; j++) { old = lookup_mode(from_res, from_info->modes[j]); if (old && mode_equal(mode, old)) { mode = NULL; break; } } if (mode == NULL) continue; id = 0; for (j = 0; j < to_res->nmode; j++) { old = &to_res->modes[j]; if (mode_equal(mode, old)) { id = old->id; DBG(XRR, ("%s(%s-%s): reusing mode %ld: %s\n", __func__, DisplayString(clone->src.dpy), clone->src.name, id, mode->name)); break; } } if (id == 0) { XRRModeInfo m; char buf[256]; /* XXX User names must be unique! */ m = *mode; m.nameLength = snprintf(buf, sizeof(buf), "%s.%ld-%s", clone->src.name, (long)from_info->modes[i], mode->name); m.name = buf; id = XRRCreateMode(clone->src.dpy, clone->src.window, &m); DBG(XRR, ("%s(%s-%s): adding mode %ld: %s\n", __func__, DisplayString(clone->src.dpy), clone->src.name, id, mode->name)); } XRRAddOutputMode(clone->src.dpy, clone->src.rr_output, id); } clone_update_edid(clone); XUngrabServer(clone->src.dpy); done: ret = 0; clone->timestamp = from_info->timestamp; err: if (to_info) XRRFreeOutputInfo(to_info); if (to_res) XRRFreeScreenResources(to_res); if (from_info) XRRFreeOutputInfo(from_info); if (from_res) XRRFreeScreenResources(from_res); return ret; } static int clone_update_modes__fixed(struct clone *clone) { char mode_name[80]; XRRScreenResources *res = NULL; XRROutputInfo *info = NULL; XRRModeInfo mode; RRMode id; int i, j, ret = ENOENT; DBG(X11, ("%s-%s cloning modes fixed %dx%d\n", DisplayString(clone->dst.dpy), clone->dst.name, clone->dst.width, clone->dst.height)); assert(clone->src.rr_output); res = _XRRGetScreenResourcesCurrent(clone->src.dpy, clone->src.window); if (res == NULL) goto err; info = XRRGetOutputInfo(clone->src.dpy, res, clone->src.rr_output); if (info == NULL) goto err; XGrabServer(clone->src.dpy); /* Clear all current UserModes on the output, including any active ones */ if (info->crtc) { DBG(XRR, ("%s(%s-%s): disabling active CRTC\n", __func__, DisplayString(clone->src.dpy), clone->src.name)); disable_crtc(clone->src.dpy, res, info->crtc); } for (i = 0; i < info->nmode; i++) { DBG(XRR, ("%s(%s-%s): deleting mode %ld\n", __func__, DisplayString(clone->src.dpy), clone->src.name, (long)info->modes[i])); XRRDeleteOutputMode(clone->src.dpy, clone->src.rr_output, info->modes[i]); } clone->src.rr_crtc = 0; /* Create matching mode for the real output on the virtual */ memset(&mode, 0, sizeof(mode)); mode.width = clone->dst.width; mode.height = clone->dst.height; mode.nameLength = sprintf(mode_name, "FAKE-%dx%d", mode.width, mode.height); mode.name = mode_name; id = 0; for (j = 0; j < res->nmode; j++) { if (mode_equal(&mode, &res->modes[j])) { id = res->modes[j].id; break; } } if (id == 0) id = XRRCreateMode(clone->src.dpy, clone->src.window, &mode); XRRAddOutputMode(clone->src.dpy, clone->src.rr_output, id); XUngrabServer(clone->src.dpy); ret = 0; err: if (info) XRRFreeOutputInfo(info); if (res) XRRFreeScreenResources(res); return ret; } static RROutput claim_virtual(struct display *display, char *output_name, int nclone) { char mode_name[] = "ClaimVirtualHead"; Display *dpy = display->dpy; XRRScreenResources *res; XRROutputInfo *output; XRRModeInfo mode; RRMode id; RROutput rr_output = 0; int i; DBG(X11, ("%s(%d)\n", __func__, nclone)); XGrabServer(dpy); res = _XRRGetScreenResourcesCurrent(dpy, display->root); if (res == NULL) goto out; sprintf(output_name, "VIRTUAL%d", nclone); for (i = rr_output = 0; rr_output == 0 && i < res->noutput; i++) { output = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output == NULL) continue; if (strcmp(output->name, output_name) == 0) rr_output = res->outputs[i]; XRRFreeOutputInfo(output); } for (i = id = 0; id == 0 && i < res->nmode; i++) { if (strcmp(res->modes[i].name, mode_name) == 0) id = res->modes[i].id; } XRRFreeScreenResources(res); DBG(XRR, ("%s(%s): rr_output=%ld\n", __func__, output_name, (long)rr_output)); if (rr_output == 0) goto out; /* Set any mode on the VirtualHead to make the Xserver allocate another */ memset(&mode, 0, sizeof(mode)); mode.width = 1024; mode.height = 768; mode.name = mode_name; mode.nameLength = sizeof(mode_name) - 1; if (id == 0) id = XRRCreateMode(dpy, display->root, &mode); XRRAddOutputMode(dpy, rr_output, id); /* Force a redetection for the ddx to spot the new outputs */ res = XRRGetScreenResources(dpy, display->root); if (res == NULL) goto out; /* Some else may have interrupted us and installed that new mode! */ output = XRRGetOutputInfo(dpy, res, rr_output); if (output) { disable_crtc(dpy, res, output->crtc); XRRFreeOutputInfo(output); } XRRFreeScreenResources(res); XRRDeleteOutputMode(dpy, rr_output, id); XRRDestroyMode(dpy, id); /* And hide it again */ res = XRRGetScreenResources(dpy, display->root); if (res != NULL) XRRFreeScreenResources(res); out: XUngrabServer(dpy); return rr_output; } static int check_virtual(struct display *display) { XRRScreenResources *res; int found = -ENOENT; int i; res = _XRRGetScreenResourcesCurrent(display->dpy, display->root); if (res == NULL) return -ENOMEM; for (i = 0; found == -ENOENT && i < res->noutput; i++) { XRROutputInfo *output; output = XRRGetOutputInfo(display->dpy, res, res->outputs[i]); if (output == NULL) continue; if (strcmp(output->name, "VIRTUAL1") == 0) found = 0; XRRFreeOutputInfo(output); } XRRFreeScreenResources(res); DBG(XRR, ("%s(%s): has VIRTUAL1? %d\n", __func__, DisplayString(display->dpy), found)); return found; } static int stride_for_depth(int width, int depth) { if (depth == 24) depth = 32; return ((width * depth + 7) / 8 + 3) & ~3; } static void init_image(struct clone *clone) { XImage *image = &clone->image; int ret; image->width = clone->width; image->height = clone->height; image->format = ZPixmap; image->xoffset = 0; image->byte_order = LSBFirst; image->bitmap_unit = 32; image->bitmap_bit_order = LSBFirst; image->bitmap_pad = 32; image->data = clone->shm.shmaddr; image->bytes_per_line = stride_for_depth(clone->width, clone->depth); switch (clone->depth) { case 24: image->red_mask = 0xff << 16; image->green_mask = 0xff << 8; image->blue_mask = 0xff << 0;; image->depth = 24; image->bits_per_pixel = 32; break; case 16: image->red_mask = 0x1f << 11; image->green_mask = 0x3f << 5; image->blue_mask = 0x1f << 0;; image->depth = 16; image->bits_per_pixel = 16; break; } ret = XInitImage(image); assert(ret); (void)ret; } static int mode_height(const XRRModeInfo *mode, Rotation rotation) { switch (rotation & 0xf) { case RR_Rotate_0: case RR_Rotate_180: return mode->height; case RR_Rotate_90: case RR_Rotate_270: return mode->width; default: return 0; } } static int mode_width(const XRRModeInfo *mode, Rotation rotation) { switch (rotation & 0xf) { case RR_Rotate_0: case RR_Rotate_180: return mode->width; case RR_Rotate_90: case RR_Rotate_270: return mode->height; default: return 0; } } static void output_init_xfer(struct clone *clone, struct output *output) { if (output->pixmap == None && output->use_shm_pixmap) { DBG(DRAW, ("%s-%s: creating shm pixmap\n", DisplayString(output->dpy), output->name)); XSync(output->dpy, False); _x_error_occurred = 0; output->pixmap = XShmCreatePixmap(output->dpy, output->window, clone->shm.shmaddr, &output->shm, clone->width, clone->height, clone->depth); if (output->pix_picture) { XRenderFreePicture(output->dpy, output->pix_picture); output->pix_picture = None; } XSync(output->dpy, False); if (_x_error_occurred) { XFreePixmap(output->dpy, output->pixmap); output->pixmap = None; output->use_shm_pixmap = 0; } } if (output->use_render) { DBG(DRAW, ("%s-%s: creating picture\n", DisplayString(output->dpy), output->name)); if (output->win_picture == None) output->win_picture = XRenderCreatePicture(output->dpy, output->window, output->display->root_format, 0, NULL); if (output->pixmap == None) output->pixmap = XCreatePixmap(output->dpy, output->window, clone->width, clone->height, clone->depth); if (output->pix_picture == None) output->pix_picture = XRenderCreatePicture(output->dpy, output->pixmap, output->use_render, 0, NULL); } if (output->gc == None) { XGCValues gcv; DBG(DRAW, ("%s-%s: creating gc\n", DisplayString(output->dpy), output->name)); gcv.graphics_exposures = False; gcv.subwindow_mode = IncludeInferiors; output->gc = XCreateGC(output->dpy, output->pixmap ?: output->window, GCGraphicsExposures | GCSubwindowMode, &gcv); } } static int bpp_for_depth(int depth) { switch (depth) { case 1: return 1; case 8: return 8; case 15: return 16; case 16: return 16; case 24: return 24; case 32: return 32; default: return 0; } } static int clone_init_xfer(struct clone *clone) { int width, height; if (clone->dst.mode.id == 0) { width = 0; height = 0; } else if (clone->dri3.xid) { width = clone->dst.width; height = clone->dst.height; } else { width = mode_width(&clone->src.mode, clone->src.rotation); height = mode_height(&clone->src.mode, clone->src.rotation); } DBG(DRAW, ("%s-%s create xfer, %dx%d (currently %dx%d)\n", DisplayString(clone->dst.dpy), clone->dst.name, width, height, clone->width, clone->height)); if (width == clone->width && height == clone->height) return 0; if (clone->shm.shmaddr) { if (clone->src.use_shm) XShmDetach(clone->src.dpy, &clone->src.shm); if (clone->dst.use_shm) XShmDetach(clone->dst.dpy, &clone->dst.shm); shmdt(clone->shm.shmaddr); clone->shm.shmaddr = NULL; } if (clone->src.pixmap) { XFreePixmap(clone->src.dpy, clone->src.pixmap); clone->src.pixmap = 0; } if (clone->dst.pixmap) { XFreePixmap(clone->dst.dpy, clone->dst.pixmap); clone->dst.pixmap = 0; } if ((width | height) == 0) { clone->damaged.x2 = clone->damaged.y2 = INT_MIN; clone->damaged.x1 = clone->damaged.y1 = INT_MAX; return 0; } if (clone->dri3.xid) { int fd, stride; Pixmap src; _x_error_occurred = 0; DBG(DRAW, ("%s-%s create xfer, trying DRI3\n", DisplayString(clone->dst.dpy), clone->dst.name)); fd = dri3_create_fd(clone->dst.dpy, clone->dst.window, &stride); if (fd < 0) goto disable_dri3; DBG(DRAW, ("%s-%s create xfer, DRI3 fd=%d, stride=%d\n", DisplayString(clone->dst.dpy), clone->dst.name, fd, stride)); src = dri3_create_pixmap(clone->src.dpy, clone->src.window, width, height, clone->depth, fd, bpp_for_depth(clone->depth), stride, lseek(fd, 0, SEEK_END)); XSync(clone->src.dpy, False); if (!_x_error_occurred) { clone->src.pixmap = src; clone->width = width; clone->height = height; } else { XFreePixmap(clone->src.dpy, src); close(fd); disable_dri3: dri3_fence_free(clone->src.dpy, &clone->dri3); clone->dri3.xid = 0; DBG(DRAW, ("%s-%s create xfer, DRI3 failed\n", DisplayString(clone->dst.dpy), clone->dst.name)); } } width = mode_width(&clone->src.mode, clone->src.rotation); height = mode_height(&clone->src.mode, clone->src.rotation); if (!clone->dri3.xid) { DBG(DRAW, ("%s-%s create xfer, trying SHM\n", DisplayString(clone->dst.dpy), clone->dst.name)); clone->shm.shmid = shmget(IPC_PRIVATE, height * stride_for_depth(width, clone->depth), IPC_CREAT | 0666); if (clone->shm.shmid == -1) return errno; clone->shm.shmaddr = shmat(clone->shm.shmid, 0, 0); if (clone->shm.shmaddr == (char *) -1) { shmctl(clone->shm.shmid, IPC_RMID, NULL); return ENOMEM; } if (clone->src.use_shm) { clone->src.shm = clone->shm; clone->src.shm.readOnly = False; XShmAttach(clone->src.dpy, &clone->src.shm); XSync(clone->src.dpy, False); } if (clone->dst.use_shm) { clone->dst.shm = clone->shm; clone->dst.shm.readOnly = !clone->dst.use_shm_pixmap; XShmAttach(clone->dst.dpy, &clone->dst.shm); XSync(clone->dst.dpy, False); } shmctl(clone->shm.shmid, IPC_RMID, NULL); clone->width = width; clone->height = height; init_image(clone); } output_init_xfer(clone, &clone->src); output_init_xfer(clone, &clone->dst); clone->damaged.x1 = clone->src.x; clone->damaged.x2 = clone->src.x + width; clone->damaged.y1 = clone->src.y; clone->damaged.y2 = clone->src.y + height; display_mark_flush(clone->dst.display); return 0; } static void clone_update(struct clone *clone) { if (!clone->rr_update) return; DBG(X11, ("%s-%s cloning modes\n", DisplayString(clone->dst.dpy), clone->dst.name)); clone_update_modes__randr(clone); clone->rr_update = 0; } static void screensaver_save(struct display *display) { display->saver_active = XScreenSaverQueryExtension(display->dpy, &display->saver_event, &display->saver_error); DBG(SCREEN, ("%s screen saver active? %d [event=%d, error=%d]\n", DisplayString(display->dpy), display->saver_active, display->saver_event, display->saver_error)); XGetScreenSaver(display->dpy, &display->saver.timeout, &display->saver.interval, &display->saver.prefer_blank, &display->saver.allow_exp); DBG(SCREEN, ("%s saving screen saver defaults: timeout=%d interval=%d prefer_blank=%d allow_exp=%d\n", DisplayString(display->dpy), display->saver.timeout, display->saver.interval, display->saver.prefer_blank, display->saver.allow_exp)); } static void screensaver_disable(struct display *display) { DBG(SCREEN, ("%s disabling screen saver\n", DisplayString(display->dpy))); XSetScreenSaver(display->dpy, 0, 0, DefaultBlanking, DefaultExposures); display_mark_flush(display); } static void screensaver_restore(struct display *display) { DBG(SCREEN, ("%s restoring screen saver\n", DisplayString(display->dpy))); XSetScreenSaver(display->dpy, display->saver.timeout, display->saver.interval, display->saver.prefer_blank, display->saver.allow_exp); display_mark_flush(display); } static int context_update(struct context *ctx) { Display *dpy = ctx->display->dpy; XRRScreenResources *res; int context_changed = 0; int i, n; DBG(X11, ("%s\n", __func__)); res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root); if (res == NULL) return 0; DBG(XRR, ("%s timestamp %ld (last %ld), config %ld (last %ld)\n", DisplayString(dpy), res->timestamp, ctx->timestamp, res->configTimestamp, ctx->configTimestamp)); if (res->timestamp == ctx->timestamp && res->configTimestamp == ctx->configTimestamp && res->timestamp != res->configTimestamp) { /* mutter be damned */ XRRFreeScreenResources(res); return 0; } ctx->timestamp = res->timestamp; ctx->configTimestamp = res->configTimestamp; for (n = 0; n < ctx->nclone; n++) { struct output *output = &ctx->clones[n].src; XRROutputInfo *o; XRRCrtcInfo *c; RRMode mode = 0; int changed = 0; o = XRRGetOutputInfo(dpy, res, output->rr_output); if (o == NULL) continue; c = NULL; if (o->crtc) c = XRRGetCrtcInfo(dpy, res, o->crtc); if (c) { DBG(XRR, ("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> (x=%d, y=%d, rotation=%d, mode=%ld)\n", DisplayString(dpy), output->name, output->x, output->y, output->rotation, output->mode.id, c->x, c->y, c->rotation, c->mode)); changed |= output->rotation != c->rotation; output->rotation = c->rotation; changed |= output->x != c->x; output->x = c->x; changed |= output->y != c->y; output->y = c->y; changed |= output->mode.id != c->mode; mode = c->mode; XRRFreeCrtcInfo(c); } else { DBG(XRR, ("%s-%s: (x=%d, y=%d, rotation=%d, mode=%ld) -> off\n", DisplayString(dpy), output->name, output->x, output->y, output->rotation, output->mode.id)); } output->rr_crtc = o->crtc; XRRFreeOutputInfo(o); DBG(XRR, ("%s-%s crtc changed? %d\n", DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed)); if (mode) { if (output->mode.id != mode) { for (i = 0; i < res->nmode; i++) { if (res->modes[i].id == mode) { output->mode = res->modes[i]; break; } } } } else { changed = output->mode.id != 0; output->mode.id = 0; } DBG(XRR, ("%s-%s output changed? %d\n", DisplayString(ctx->clones[n].dst.display->dpy), ctx->clones[n].dst.name, changed)); context_changed |= changed; } XRRFreeScreenResources(res); DBG(XRR, ("%s changed? %d\n", DisplayString(dpy), context_changed)); if (!context_changed) return 0; for (n = 1; n < ctx->ndisplay; n++) { struct display *display = &ctx->display[n]; struct clone *clone; int x1, x2, y1, y2; if (display->rr_active == 0) { for (clone = display->clone; clone; clone = clone->next) { struct output *output = &clone->src; if (output->mode.id) { clone->dst.mode.id = -1; clone->dst.rr_crtc = -1; } else { clone->dst.mode.id = 0; clone->dst.rr_crtc = 0; } } continue; } x1 = y1 = INT_MAX; x2 = y2 = INT_MIN; for (clone = display->clone; clone; clone = clone->next) { struct output *output = &clone->src; int v; assert(clone->dst.display == display); if (output->mode.id == 0) continue; DBG(XRR, ("%s: source %s enabled (%d, %d)x(%d, %d)\n", DisplayString(clone->dst.dpy), output->name, output->x, output->y, mode_width(&output->mode, output->rotation), mode_height(&output->mode, output->rotation))); if (output->x < x1) x1 = output->x; if (output->y < y1) y1 = output->y; v = (int)output->x + mode_width(&output->mode, output->rotation); if (v > x2) x2 = v; v = (int)output->y + mode_height(&output->mode, output->rotation); if (v > y2) y2 = v; } DBG(XRR, ("%s fb bounds (%d, %d)x(%d, %d)\n", DisplayString(display->dpy), x1, y1, x2, y2)); XGrabServer(display->dpy); res = _XRRGetScreenResourcesCurrent(display->dpy, display->root); if (res == NULL) goto ungrab; if (x2 <= x1 || y2 <= y1) { /* Nothing enabled, preserve the current fb, and turn everything off */ for (clone = display->clone; clone; clone = clone->next) { struct output *dst = &clone->dst; if (!dst->rr_crtc) continue; DBG(XRR, ("%s: disabling output '%s'\n", DisplayString(display->dpy), dst->name)); assert(clone->dst.display == display); if (disable_crtc(display->dpy, res, dst->rr_crtc)) { dst->rr_crtc = 0; dst->mode.id = 0; } } goto free_res; } x2 -= x1; y2 -= y1; DBG(XRR, ("%s: current size %dx%d, need %dx%d\n", DisplayString(display->dpy), display->width, display->height, x2, y2)); if (display->width != x2 || display->height != y2) { /* When shrinking we have to manually resize the fb */ for (clone = display->clone; clone; clone = clone->next) { struct output *dst = &clone->dst; if (!dst->rr_crtc) continue; DBG(XRR, ("%s: disabling output '%s'\n", DisplayString(display->dpy), dst->name)); assert(clone->dst.display == display); if (disable_crtc(display->dpy, res, dst->rr_crtc)) { dst->rr_crtc = 0; dst->mode.id = 0; } } DBG(XRR, ("%s: XRRSetScreenSize %dx%d\n", DisplayString(display->dpy), x2, y2)); XRRSetScreenSize(display->dpy, display->root, x2, y2, x2 * 96 / 25.4, y2 * 96 / 25.4); display->width = x2; display->height = y2; } for (clone = display->clone; clone; clone = clone->next) { struct output *src = &clone->src; struct output *dst = &clone->dst; XRROutputInfo *o; XRRPanning panning; struct clone *set; RRCrtc rr_crtc; Status ret; DBG(XRR, ("%s: copying configuration from %s (mode=%ld: %dx%d) to %s\n", DisplayString(display->dpy), src->name, (long)src->mode.id, src->mode.width, src->mode.height, dst->name)); if (src->mode.id == 0) { err: if (dst->rr_crtc) { DBG(XRR, ("%s: disabling unused output '%s'\n", DisplayString(display->dpy), dst->name)); assert(clone->dst.display == display); if (disable_crtc(display->dpy, res, dst->rr_crtc)) { dst->rr_crtc = 0; dst->mode.id = 0; } } continue; } dst->x = src->x - x1; dst->y = src->y - y1; dst->rotation = src->rotation; dst->mode = src->mode; dst->mode.id = 0; for (i = 0; i < res->nmode; i++) { if (mode_equal(&src->mode, &res->modes[i])) { dst->mode.id = res->modes[i].id; break; } } if (dst->mode.id == 0) { XRRModeInfo m; char buf[256]; RRMode id; /* XXX User names must be unique! */ m = src->mode; m.nameLength = snprintf(buf, sizeof(buf), "%s.%ld-%dx%d", src->name, (long)src->mode.id, src->mode.width, src->mode.height); m.name = buf; id = XRRCreateMode(dst->dpy, dst->window, &m); if (id) { DBG(XRR, ("%s: adding mode %ld: %dx%d to %s, new mode %ld\n", DisplayString(dst->dpy), (long)src->mode.id, src->mode.width, src->mode.height, dst->name, (long)id)); XRRAddOutputMode(dst->dpy, dst->rr_output, id); dst->mode.id = id; } else { DBG(XRR, ("%s: failed to find suitable mode for %s\n", DisplayString(dst->dpy), dst->name)); goto err; } } rr_crtc = dst->rr_crtc; if (rr_crtc) { for (set = display->clone; set != clone; set = set->next) { if (set->dst.rr_crtc == rr_crtc) { DBG(XRR, ("%s: CRTC reassigned from %s\n", DisplayString(dst->dpy), dst->name)); rr_crtc = 0; break; } } } if (rr_crtc == 0) { o = XRRGetOutputInfo(dst->dpy, res, dst->rr_output); for (i = 0; i < o->ncrtc; i++) { DBG(XRR, ("%s: checking whether CRTC:%ld is available\n", DisplayString(dst->dpy), (long)o->crtcs[i])); for (set = display->clone; set != clone; set = set->next) { if (set->dst.rr_crtc == o->crtcs[i]) { DBG(XRR, ("%s: CRTC:%ld already assigned to %s\n", DisplayString(dst->dpy), (long)o->crtcs[i], set->dst.name)); break; } } if (set == clone) { rr_crtc = o->crtcs[i]; break; } } XRRFreeOutputInfo(o); } if (rr_crtc == 0) { DBG(XRR, ("%s: failed to find available CRTC for %s\n", DisplayString(dst->dpy), dst->name)); goto err; } DBG(XRR, ("%s: enabling output '%s' (%d,%d)x(%d,%d), rotation %d, on CRTC:%ld, using mode %ld\n", DisplayString(dst->dpy), dst->name, dst->x, dst->y, dst->mode.width, dst->mode.height, dst->rotation, (long)rr_crtc, dst->mode.id)); ret = XRRSetPanning(dst->dpy, res, rr_crtc, memset(&panning, 0, sizeof(panning))); DBG(XRR, ("%s-%s: XRRSetPanning %s\n", DisplayString(dst->dpy), dst->name, ret ? "failed" : "success")); (void)ret; ret = XRRSetCrtcConfig(dst->dpy, res, rr_crtc, CurrentTime, dst->x, dst->y, dst->mode.id, dst->rotation, &dst->rr_output, 1); DBG(XRR, ("%s-%s: XRRSetCrtcConfig %s\n", DisplayString(dst->dpy), dst->name, ret ? "failed" : "success")); if (ret) goto err; if (verbose & XRR) { XRRCrtcInfo *c; XRRPanning *p; c = XRRGetCrtcInfo(dst->dpy, res, rr_crtc); if (c) { DBG(XRR, ("%s-%s: x=%d, y=%d, rotation=%d, mode=%ld\n", DisplayString(dst->dpy), dst->name, c->x, c->y, c->rotation, c->mode)); XRRFreeCrtcInfo(c); } p = XRRGetPanning(dst->dpy, res, rr_crtc); if (p) { DBG(XRR, ("%s-%s: panning (%d, %d)x(%d, %d), tracking (%d, %d)x(%d, %d), border (%d, %d),(%d, %d)\n", DisplayString(dst->dpy), dst->name, p->left, p->top, p->width, p->height, p->track_left, p->track_top, p->track_width, p->track_height, p->border_left, p->border_top, p->border_right, p->border_bottom)); XRRFreePanning(p); } } dst->rr_crtc = rr_crtc; } free_res: XRRFreeScreenResources(res); ungrab: XUngrabServer(display->dpy); } for (n = 1; n < ctx->ndisplay; n++) { struct display *display = &ctx->display[n]; display->active = 0; screensaver_restore(display); } ctx->active = NULL; for (n = 0; n < ctx->nclone; n++) { struct clone *clone = &ctx->clones[n]; clone_init_xfer(clone); if (clone->dst.rr_crtc == 0) continue; DBG(XRR, ("%s-%s: added to active list\n", DisplayString(clone->dst.display->dpy), clone->dst.name)); if (clone->dst.display->active++ == 0) screensaver_disable(clone->dst.display); clone->active = ctx->active; ctx->active = clone; } return 1; } static Cursor display_load_invisible_cursor(struct display *display) { char zero[8] = {}; XColor black = {}; Pixmap bitmap = XCreateBitmapFromData(display->dpy, display->root, zero, 8, 8); return XCreatePixmapCursor(display->dpy, bitmap, bitmap, &black, &black, 0, 0); } static Cursor display_get_visible_cursor(struct display *display) { struct display *first = display->ctx->display; if (display->cursor_serial != first->cursor_serial) { DBG(CURSOR, ("%s updating cursor %dx%d, serial %d\n", DisplayString(display->dpy), first->cursor_image.width, first->cursor_image.height, first->cursor_serial)); if (display->visible_cursor) XFreeCursor(display->dpy, display->visible_cursor); display->visible_cursor = XcursorImageLoadCursor(display->dpy, &first->cursor_image); display->cursor_serial = first->cursor_serial; } return display->visible_cursor; } static void display_load_visible_cursor(struct display *display, XFixesCursorImage *cur) { unsigned long *src; /* XXX deep sigh */ XcursorPixel *dst; unsigned n; if (cur->width != display->cursor_image.width || cur->height != display->cursor_image.height) display->cursor_image.pixels = realloc(display->cursor_image.pixels, 4 * cur->width * cur->height); if (display->cursor_image.pixels == NULL) return; display->cursor_image.width = cur->width; display->cursor_image.height = cur->height; display->cursor_image.xhot = cur->xhot; display->cursor_image.yhot = cur->yhot; display->cursor_serial++; n = cur->width*cur->height; src = cur->pixels; dst = display->cursor_image.pixels; while (n--) *dst++ = *src++; if (verbose & CURSOR) { int x, y; printf("%s cursor image %dx%d, serial %d:\n", DisplayString(display->dpy), cur->width, cur->height, display->cursor_serial); dst = display->cursor_image.pixels; for (y = 0; y < cur->height; y++) { for (x = 0; x < cur->width; x++) { if (x == cur->xhot && y == cur->yhot) printf("+"); else printf("%c", *dst ? *dst >> 24 >= 127 ? 'x' : '.' : ' '); dst++; } printf("\n"); } } } static void display_cursor_move(struct display *display, int x, int y, int visible) { DBG(CURSOR, ("%s cursor moved (visible=%d, (%d, %d))\n", DisplayString(display->dpy), visible, x, y)); display->cursor_moved++; display->cursor_visible += visible; if (visible) { display->cursor_x = x; display->cursor_y = y; } context_enable_timer(display->ctx); } static void display_flush_cursor(struct display *display) { Cursor cursor; int x, y; if (!display->cursor_moved) return; if (display->cursor_visible) { x = display->cursor_x; y = display->cursor_y; } else { x = display->cursor_x++ & 31; y = display->cursor_y++ & 31; } DBG(CURSOR, ("%s setting cursor position (%d, %d), visible? %d\n", DisplayString(display->dpy), x, y, display->cursor_visible)); XWarpPointer(display->dpy, None, display->root, 0, 0, 0, 0, x, y); cursor = None; if (display->cursor_visible) cursor = display_get_visible_cursor(display); if (cursor == None) cursor = display->invisible_cursor; if (cursor != display->cursor) { DBG(CURSOR, ("%s setting cursor shape %lx\n", DisplayString(display->dpy), (long)cursor)); XDefineCursor(display->dpy, display->root, cursor); display->cursor = cursor; } display_mark_flush(display); display->cursor_moved = 0; display->cursor_visible = 0; } static void clone_move_cursor(struct clone *c, int x, int y) { int visible; DBG(CURSOR, ("%s-%s moving cursor (%d, %d) [(%d, %d), (%d, %d)]\n", DisplayString(c->dst.dpy), c->dst.name, x, y, c->src.x, c->src.y, c->src.x + c->width, c->src.y + c->height)); visible = (x >= c->src.x && x < c->src.x + c->width && y >= c->src.y && y < c->src.y + c->height); x += c->dst.x - c->src.x; y += c->dst.y - c->src.y; display_cursor_move(c->dst.display, x, y, visible); } static int clone_output_init(struct clone *clone, struct output *output, struct display *display, const char *name, RROutput rr_output) { Display *dpy = display->dpy; int depth; DBG(X11, ("%s(%s, %s)\n", __func__, DisplayString(dpy), name)); output->name = strdup(name); if (output->name == NULL) return -ENOMEM; output->display = display; output->dpy = dpy; output->rr_output = rr_output; output->rotation = RR_Rotate_0; output->window = display->root; output->use_shm = display->has_shm; output->use_shm_pixmap = display->has_shm_pixmap; DBG(X11, ("%s-%s use shm? %d (use shm pixmap? %d)\n", DisplayString(dpy), name, display->has_shm, display->has_shm_pixmap)); depth = output->use_shm && !FORCE_16BIT_XFER ? display->depth : 16; if (depth < clone->depth) clone->depth = depth; return 0; } static void ximage_prepare(XImage *image, int width, int height) { image->width = width; image->height = height; image->bytes_per_line = stride_for_depth(width, image->depth); } static void get_src(struct clone *c, const XRectangle *clip) { DBG(DRAW,("%s-%s get_src(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name, clip->x, clip->y, clip->width, clip->height)); c->image.obdata = (char *)&c->src.shm; if (c->src.use_render) { DBG(DRAW, ("%s-%s get_src via XRender\n", DisplayString(c->dst.dpy), c->dst.name)); XRenderComposite(c->src.dpy, PictOpSrc, c->src.win_picture, 0, c->src.pix_picture, clip->x, clip->y, 0, 0, 0, 0, clip->width, clip->height); if (c->src.use_shm_pixmap) { XSync(c->src.dpy, False); } else if (c->src.use_shm) { ximage_prepare(&c->image, clip->width, clip->height); XShmGetImage(c->src.dpy, c->src.pixmap, &c->image, clip->x, clip->y, AllPlanes); } else { ximage_prepare(&c->image, c->width, c->height); XGetSubImage(c->src.dpy, c->src.pixmap, clip->x, clip->y, clip->width, clip->height, AllPlanes, ZPixmap, &c->image, 0, 0); } } else if (c->src.pixmap) { DBG(DRAW, ("%s-%s get_src XCopyArea (SHM/DRI3)\n", DisplayString(c->dst.dpy), c->dst.name)); XCopyArea(c->src.dpy, c->src.window, c->src.pixmap, c->src.gc, clip->x, clip->y, clip->width, clip->height, 0, 0); XSync(c->src.dpy, False); } else if (c->src.use_shm) { DBG(DRAW, ("%s-%s get_src XShmGetImage\n", DisplayString(c->dst.dpy), c->dst.name)); ximage_prepare(&c->image, clip->width, clip->height); XShmGetImage(c->src.dpy, c->src.window, &c->image, clip->x, clip->y, AllPlanes); } else { DBG(DRAW, ("%s-%s get_src XGetSubImage (slow)\n", DisplayString(c->dst.dpy), c->dst.name)); ximage_prepare(&c->image, c->width, c->height); XGetSubImage(c->src.dpy, c->src.window, clip->x, clip->y, clip->width, clip->height, AllPlanes, ZPixmap, &c->image, 0, 0); } c->src.display->flush = 0; } static void put_dst(struct clone *c, const XRectangle *clip) { DBG(DRAW, ("%s-%s put_dst(%d,%d)x(%d,%d)\n", DisplayString(c->dst.dpy), c->dst.name, clip->x, clip->y, clip->width, clip->height)); c->image.obdata = (char *)&c->dst.shm; if (c->dst.use_render) { if (c->dst.use_shm_pixmap) { DBG(DRAW, ("%s-%s using SHM pixmap composite\n", DisplayString(c->dst.dpy), c->dst.name)); } else if (c->dst.use_shm) { DBG(DRAW, ("%s-%s using SHM image composite\n", DisplayString(c->dst.dpy), c->dst.name)); XShmPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image, 0, 0, 0, 0, clip->width, clip->height, False); } else { DBG(DRAW, ("%s-%s using composite\n", DisplayString(c->dst.dpy), c->dst.name)); XPutImage(c->dst.dpy, c->dst.pixmap, c->dst.gc, &c->image, 0, 0, 0, 0, clip->width, clip->height); } if (c->dst.use_shm) c->dst.serial = NextRequest(c->dst.dpy); XRenderComposite(c->dst.dpy, PictOpSrc, c->dst.pix_picture, 0, c->dst.win_picture, 0, 0, 0, 0, clip->x, clip->y, clip->width, clip->height); c->dst.display->send |= c->dst.use_shm; } else if (c->dst.pixmap) { DBG(DRAW, ("%s-%s using SHM or DRI3 pixmap\n", DisplayString(c->dst.dpy), c->dst.name)); c->dst.serial = NextRequest(c->dst.dpy); XCopyArea(c->dst.dpy, c->dst.pixmap, c->dst.window, c->dst.gc, 0, 0, clip->width, clip->height, clip->x, clip->y); c->dst.display->send = 1; } else if (c->dst.use_shm) { DBG(DRAW, ("%s-%s using SHM image\n", DisplayString(c->dst.dpy), c->dst.name)); c->dst.serial = NextRequest(c->dst.dpy); XShmPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image, 0, 0, clip->x, clip->y, clip->width, clip->height, True); } else { DBG(DRAW, ("%s-%s using image\n", DisplayString(c->dst.dpy), c->dst.name)); XPutImage(c->dst.dpy, c->dst.window, c->dst.gc, &c->image, 0, 0, clip->x, clip->y, clip->width, clip->height); c->dst.serial = 0; } } static int clone_paint(struct clone *c) { XRectangle clip; if (c->width == 0 || c->height == 0) return 0; DBG(DRAW, ("%s-%s paint clone, damaged (%d, %d), (%d, %d) [(%d, %d), (%d, %d)]\n", DisplayString(c->dst.dpy), c->dst.name, c->damaged.x1, c->damaged.y1, c->damaged.x2, c->damaged.y2, c->src.x, c->src.y, c->src.x + c->width, c->src.y + c->height)); if (c->damaged.x1 < c->src.x) c->damaged.x1 = c->src.x; if (c->damaged.x2 > c->src.x + c->width) c->damaged.x2 = c->src.x + c->width; if (c->damaged.x2 <= c->damaged.x1) goto done; if (c->damaged.y1 < c->src.y) c->damaged.y1 = c->src.y; if (c->damaged.y2 > c->src.y + c->height) c->damaged.y2 = c->src.y + c->height; if (c->damaged.y2 <= c->damaged.y1) goto done; DBG(DRAW, ("%s-%s is damaged, last SHM serial: %ld, now %ld\n", DisplayString(c->dst.dpy), c->dst.name, (long)c->dst.serial, (long)LastKnownRequestProcessed(c->dst.dpy))); if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) { struct pollfd pfd; pfd.fd = ConnectionNumber(c->dst.dpy); pfd.events = POLLIN; XEventsQueued(c->dst.dpy, poll(&pfd, 1, 0) ? QueuedAfterReading : QueuedAfterFlush); if (c->dst.serial > LastKnownRequestProcessed(c->dst.dpy)) { c->dst.display->skip_clone++; return EAGAIN; } } c->dst.display->skip_clone = 0; c->dst.display->skip_frame = 0; if (FORCE_FULL_REDRAW) { c->damaged.x1 = c->src.x; c->damaged.y1 = c->src.y; c->damaged.x2 = c->src.x + c->width; c->damaged.y2 = c->src.y + c->height; } if (c->dri3.xid) { if (c->src.use_render) { XRenderComposite(c->src.dpy, PictOpSrc, c->src.win_picture, 0, c->src.pix_picture, c->damaged.x1, c->damaged.y1, 0, 0, c->damaged.x1 + c->dst.x - c->src.x, c->damaged.y1 + c->dst.y - c->src.y, c->damaged.x2 - c->damaged.x1, c->damaged.y2 - c->damaged.y1); } else { XCopyArea(c->src.dpy, c->src.window, c->src.pixmap, c->src.gc, c->damaged.x1, c->damaged.y1, c->damaged.x2 - c->damaged.x1, c->damaged.y2 - c->damaged.y1, c->damaged.x1 + c->dst.x - c->src.x, c->damaged.y1 + c->dst.y - c->src.y); } dri3_fence_flush(c->src.dpy, &c->dri3); } else { clip.x = c->damaged.x1; clip.y = c->damaged.y1; clip.width = c->damaged.x2 - c->damaged.x1; clip.height = c->damaged.y2 - c->damaged.y1; get_src(c, &clip); DBG(DRAW, ("%s-%s target offset %dx%d\n", DisplayString(c->dst.dpy), c->dst.name, c->dst.x - c->src.x, c->dst.y - c->src.y)); clip.x += c->dst.x - c->src.x; clip.y += c->dst.y - c->src.y; put_dst(c, &clip); } display_mark_flush(c->dst.display); done: c->damaged.x2 = c->damaged.y2 = INT_MIN; c->damaged.x1 = c->damaged.y1 = INT_MAX; return 0; } static void clone_damage(struct clone *c, const XRectangle *rec) { int v; if ((v = rec->x) < c->damaged.x1) c->damaged.x1 = v; if ((v = (int)rec->x + rec->width) > c->damaged.x2) c->damaged.x2 = v; if ((v = rec->y) < c->damaged.y1) c->damaged.y1 = v; if ((v = (int)rec->y + rec->height) > c->damaged.y2) c->damaged.y2 = v; DBG(DAMAGE, ("%s-%s damaged: +(%d,%d)x(%d, %d) -> (%d, %d), (%d, %d)\n", DisplayString(c->dst.display->dpy), c->dst.name, rec->x, rec->y, rec->width, rec->height, c->damaged.x1, c->damaged.y1, c->damaged.x2, c->damaged.y2)); } static void usage(const char *arg0) { printf("Usage: %s [OPTION]... [TARGET_DISPLAY]...\n", arg0); printf(" -d source display\n"); printf(" -f keep in foreground (do not detach from console and daemonize)\n"); printf(" -b start bumblebee\n"); printf(" -a connect to all local displays (e.g. :1, :2, etc)\n"); printf(" -S disable use of a singleton and launch a fresh intel-virtual-output process\n"); printf(" -v all verbose output, implies -f\n"); printf(" -V specific verbose output, implies -f\n"); printf(" -h this help\n"); printf("If no target displays are parsed on the commandline, \n"); printf("intel-virtual-output will attempt to connect to any local display\n"); printf("and then start bumblebee.\n"); } static void record_callback(XPointer closure, XRecordInterceptData *data) { struct context *ctx = (struct context *)closure; DBG(X11, ("%s\n", __func__)); if (data->category == XRecordFromServer) { const xEvent *e = (const xEvent *)data->data; DBG(X11, ("%s -- from server, event type %d, root %ld (ours? %d)\n", __func__, e->u.u.type, (long)e->u.keyButtonPointer.root, ctx->display->root == e->u.keyButtonPointer.root)); if (e->u.u.type == MotionNotify && e->u.keyButtonPointer.root == ctx->display->root) { struct clone *clone; for (clone = ctx->active; clone; clone = clone->active) clone_move_cursor(clone, e->u.keyButtonPointer.rootX, e->u.keyButtonPointer.rootY); } } XRecordFreeData(data); } static int record_mouse(struct context *ctx) { Display *dpy; XRecordRange *rr; XRecordClientSpec rcs; XRecordContext rc; DBG(X11, ("%s(%s)\n", __func__, DisplayString(ctx->display->dpy))); dpy = XOpenDisplay(DisplayString(ctx->display->dpy)); if (dpy == NULL) return -ECONNREFUSED; rr = XRecordAllocRange(); if (rr == NULL) return -ENOMEM; rr->device_events.first = rr->device_events.last = MotionNotify; rcs = XRecordAllClients; rc = XRecordCreateContext(dpy, 0, &rcs, 1, &rr, 1); XSync(dpy, False); if (!XRecordEnableContextAsync(dpy, rc, record_callback, (XPointer)ctx)) return -EINVAL; ctx->record = dpy; return ConnectionNumber(dpy); } static int bad_visual(Visual *visual, int depth) { DBG(X11, ("%s? depth=%d, visual: class=%d, bits_per_rgb=%d, red_mask=%08lx, green_mask=%08lx, blue_mask=%08lx\n", __func__, depth, visual->class, visual->bits_per_rgb, visual->red_mask, visual->green_mask, visual->blue_mask)); if (!(visual->class == TrueColor || visual->class == DirectColor)) return 1; switch (depth) { case 16: return (/* visual->bits_per_rgb != 6 || */ visual->red_mask != 0x1f << 11 || visual->green_mask != 0x3f << 5 || visual->blue_mask != 0x1f << 0); case 24: return (/* visual->bits_per_rgb != 8 || */ visual->red_mask != 0xff << 16 || visual->green_mask != 0xff << 8 || visual->blue_mask != 0xff << 0); default: return 1; } } static XRenderPictFormat * find_xrender_format(Display *dpy, pixman_format_code_t format) { XRenderPictFormat tmpl; int mask; #define MASK(x) ((1<<(x))-1) memset(&tmpl, 0, sizeof(tmpl)); tmpl.depth = PIXMAN_FORMAT_DEPTH(format); mask = PictFormatType | PictFormatDepth; DBG(X11, ("%s(0x%08lx)\n", __func__, (long)format)); switch (PIXMAN_FORMAT_TYPE(format)) { case PIXMAN_TYPE_ARGB: tmpl.type = PictTypeDirect; if (PIXMAN_FORMAT_A(format)) { tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); tmpl.direct.alpha = (PIXMAN_FORMAT_R(format) + PIXMAN_FORMAT_G(format) + PIXMAN_FORMAT_B(format)); } tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); tmpl.direct.red = (PIXMAN_FORMAT_G(format) + PIXMAN_FORMAT_B(format)); tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); tmpl.direct.green = PIXMAN_FORMAT_B(format); tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); tmpl.direct.blue = 0; mask |= PictFormatRed | PictFormatRedMask; mask |= PictFormatGreen | PictFormatGreenMask; mask |= PictFormatBlue | PictFormatBlueMask; mask |= PictFormatAlpha | PictFormatAlphaMask; break; case PIXMAN_TYPE_ABGR: tmpl.type = PictTypeDirect; if (tmpl.direct.alphaMask) { tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); tmpl.direct.alpha = (PIXMAN_FORMAT_B(format) + PIXMAN_FORMAT_G(format) + PIXMAN_FORMAT_R(format)); } tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); tmpl.direct.blue = (PIXMAN_FORMAT_G(format) + PIXMAN_FORMAT_R(format)); tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); tmpl.direct.green = PIXMAN_FORMAT_R(format); tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); tmpl.direct.red = 0; mask |= PictFormatRed | PictFormatRedMask; mask |= PictFormatGreen | PictFormatGreenMask; mask |= PictFormatBlue | PictFormatBlueMask; mask |= PictFormatAlpha | PictFormatAlphaMask; break; case PIXMAN_TYPE_BGRA: tmpl.type = PictTypeDirect; tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); tmpl.direct.blue = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format)); tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); tmpl.direct.green = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) - PIXMAN_FORMAT_G(format)); tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); tmpl.direct.red = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) - PIXMAN_FORMAT_G(format) - PIXMAN_FORMAT_R(format)); if (tmpl.direct.alphaMask) { tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); tmpl.direct.alpha = 0; } mask |= PictFormatRed | PictFormatRedMask; mask |= PictFormatGreen | PictFormatGreenMask; mask |= PictFormatBlue | PictFormatBlueMask; mask |= PictFormatAlpha | PictFormatAlphaMask; break; case PIXMAN_TYPE_A: tmpl.type = PictTypeDirect; tmpl.direct.alpha = 0; tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); mask |= PictFormatAlpha | PictFormatAlphaMask; break; case PIXMAN_TYPE_COLOR: case PIXMAN_TYPE_GRAY: /* XXX Find matching visual/colormap */ tmpl.type = PictTypeIndexed; //tmpl.colormap = screen->visuals[PIXMAN_FORMAT_VIS(format)].vid; //mask |= PictFormatColormap; return NULL; } #undef MASK return XRenderFindFormat(dpy, mask, &tmpl, 0); } static int display_init_render(struct display *display, int depth, XRenderPictFormat **use_render) { Display *dpy = display->dpy; int major, minor; DBG(X11, ("%s is depth %d, want %d\n", DisplayString(dpy), display->depth, depth)); *use_render = 0; if (depth == display->depth && !bad_visual(display->visual, depth)) return 0; if (display->root_format == 0) { if (!XRenderQueryVersion(dpy, &major, &minor)) { fprintf(stderr, "Render extension not supported by %s\n", DisplayString(dpy)); return -EINVAL; } display->root_format = XRenderFindVisualFormat(dpy, display->visual); display->rgb16_format = find_xrender_format(dpy, PIXMAN_r5g6b5); display->rgb24_format = XRenderFindStandardFormat(dpy, PictStandardRGB24); DBG(X11, ("%s: root format=%lx, rgb16 format=%lx, rgb24 format=%lx\n", DisplayString(dpy), (long)display->root_format, (long)display->rgb16_format, (long)display->rgb24_format)); } switch (depth) { case 16: *use_render = display->rgb16_format; break; case 24: *use_render = display->rgb24_format; break; } if (*use_render == 0) return -ENOENT; return 0; } static int clone_init_depth(struct clone *clone) { int ret, depth; DBG(X11,("%s-%s wants depth %d\n", DisplayString(clone->dst.dpy), clone->dst.name, clone->depth)); ret = -1; for (depth = clone->depth; depth <= 24; depth += 8) { ret = display_init_render(clone->src.display, depth, &clone->src.use_render); if (ret) continue; ret = display_init_render(clone->dst.display, depth, &clone->dst.use_render); if (ret) continue; break; } if (ret) return ret; clone->depth = depth; DBG(X11, ("%s-%s using depth %d, requires xrender for src? %d, for dst? %d\n", DisplayString(clone->dst.dpy), clone->dst.name, clone->depth, clone->src.use_render != NULL, clone->dst.use_render != NULL)); if (!clone->dst.use_render && clone->src.display->dri3_active && clone->dst.display->dri3_active) dri3_create_fence(clone->src.dpy, clone->src.window, &clone->dri3); return 0; } #if defined(USE_XINERAMA) static int xinerama_active(struct display *display) { int active = 0; if (XineramaQueryExtension(display->dpy, &display->xinerama_event, &display->xinerama_error)) active = XineramaIsActive(display->dpy); return active; } #else #define xinerama_active(d) 0 #endif static int add_display(struct context *ctx, Display *dpy) { struct display *display; int first_display = ctx->ndisplay == 0; if (is_power_of_2(ctx->ndisplay)) { struct display *new_display; new_display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display)); if (new_display == NULL) return -ENOMEM; if (new_display != ctx->display) { int n; for (n = 0; n < ctx->nclone; n++) { struct clone *clone = &ctx->clones[n]; clone->src.display = new_display + (clone->src.display - ctx->display); clone->dst.display = new_display + (clone->dst.display - ctx->display); } } ctx->display = new_display; } display = memset(&ctx->display[ctx->ndisplay++], 0, sizeof(struct display)); display->dpy = dpy; display->ctx = ctx; display->root = DefaultRootWindow(dpy); display->depth = DefaultDepth(dpy, DefaultScreen(dpy)); display->visual = DefaultVisual(dpy, DefaultScreen(dpy)); XSelectInput(dpy, display->root, ExposureMask); display->has_shm = can_use_shm(dpy, display->root, &display->shm_event, &display->shm_opcode, &display->has_shm_pixmap); DBG(X11, ("%s: has_shm?=%d, event=%d, opcode=%d, has_pixmap?=%d\n", DisplayString(dpy), display->has_shm, display->shm_event, display->shm_opcode, display->has_shm_pixmap)); screensaver_save(display); display->rr_active = XRRQueryExtension(dpy, &display->rr_event, &display->rr_error); DBG(X11, ("%s: randr_active?=%d, event=%d, error=%d\n", DisplayString(dpy), display->rr_active, display->rr_event, display->rr_error)); display->xinerama_active = xinerama_active(display); DBG(X11, ("%s: xinerama_active?=%d, event=%d, error=%d\n", DisplayString(dpy), display->xinerama_active, display->xinerama_event, display->xinerama_error)); display->dri3_active = dri3_exists(dpy); DBG(X11, ("%s: dri3_active?=%d\n", DisplayString(dpy), display->dri3_active)); /* first display (source) is slightly special */ if (!first_display) { display->invisible_cursor = display_load_invisible_cursor(display); display_cursor_move(display, 0, 0, 0); } return ConnectionNumber(dpy); } static int display_open(struct context *ctx, const char *name) { Display *dpy; int n; DBG(X11, ("%s(%s)\n", __func__, name)); dpy = XOpenDisplay(name); if (dpy == NULL) return -ECONNREFUSED; /* Prevent cloning the same display twice */ for (n = 0; n < ctx->ndisplay; n++) { if (strcmp(DisplayString(dpy), DisplayString(ctx->display[n].dpy)) == 0) { DBG(X11, ("%s %s is already connected\n", __func__, name)); XCloseDisplay(dpy); return -EBUSY; } } return add_display(ctx, dpy); } static int bumblebee_open(struct context *ctx) { char buf[256]; struct sockaddr_un addr; int fd, len; fd = socket(PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { DBG(X11, ("%s unable to create a socket: %d\n", __func__, errno)); return -ECONNREFUSED; } addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", optarg && *optarg ? optarg : "/var/run/bumblebee.socket"); if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { DBG(X11, ("%s unable to create a socket: %d\n", __func__, errno)); goto err; } /* Ask bumblebee to start the second server */ buf[0] = 'C'; if (send(fd, &buf, 1, 0) != 1 || (len = recv(fd, &buf, 255, 0)) <= 0) { DBG(X11, ("%s startup send/recv failed: %d\n", __func__, errno)); goto err; } buf[len] = '\0'; /* Query the display name */ strcpy(buf, "Q VirtualDisplay"); if (send(fd, buf, 17, 0) != 17 || (len = recv(fd, buf, 255, 0)) <= 0) { DBG(X11, ("%s query send/recv failed: %d\n", __func__, errno)); goto err; } buf[len] = '\0'; DBG(X11, ("%s query result '%s'\n", __func__, buf)); if (strncmp(buf, "Value: ", 7)) goto err; len = 7; while (buf[len] != '\n' && buf[len] != '\0') len++; buf[len] = '\0'; /* XXX We must keep the control socket open whilst we want to keep * the display around. * * So what we need to do is listen for new bumblee Xservers and * bind only for their duration. */ return display_open(ctx, buf+7); err: close(fd); return -ECONNREFUSED; } static int display_init_damage(struct display *display) { DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy))); if (!XDamageQueryExtension(display->dpy, &display->damage_event, &display->damage_error) || !XFixesQueryExtension(display->dpy, &display->xfixes_event, &display->xfixes_error)) { fprintf(stderr, "Damage/Fixes extension not supported by %s\n", DisplayString(display->dpy)); return EINVAL; } display->damage = XDamageCreate(display->dpy, display->root, XDamageReportBoundingBox); if (display->damage == 0) return EACCES; return 0; } static void display_reset_damage(struct display *display) { Damage damage; damage = XDamageCreate(display->dpy, display->root, XDamageReportBoundingBox); if (damage) { XDamageDestroy(display->dpy, display->damage); display->damage = damage; XFlush(display->dpy); display->flush = 0; } } static void display_init_randr_hpd(struct display *display) { int major, minor; DBG(X11,("%s(%s)\n", __func__, DisplayString(display->dpy))); if (!XRRQueryVersion(display->dpy, &major, &minor)) return; DBG(X11, ("%s - randr version %d.%d\n", DisplayString(display->dpy), major, minor)); if (major > 1 || (major == 1 && minor >= 2)) XRRSelectInput(display->dpy, display->root, RROutputChangeNotifyMask); } static void rebuild_clones(struct context *ctx, struct clone *new_clones) { int n, m; for (n = 1; n < ctx->ndisplay; n++) { struct display *d = &ctx->display[n]; d->clone = NULL; for (m = 0; m < ctx->nclone; m++) { struct clone *c = &new_clones[m]; if (c->dst.display != d) continue; c->next = d->clone; d->clone = c; } } ctx->clones = new_clones; } static struct clone *add_clone(struct context *ctx) { if (is_power_of_2(ctx->nclone)) { struct clone *new_clones; new_clones = realloc(ctx->clones, 2*ctx->nclone*sizeof(struct clone)); if (new_clones == NULL) return NULL; if (new_clones != ctx->clones) rebuild_clones(ctx, new_clones); } return memset(&ctx->clones[ctx->nclone++], 0, sizeof(struct clone)); } static struct display *last_display(struct context *ctx) { return &ctx->display[ctx->ndisplay-1]; } static void reverse_clone_list(struct display *display) { struct clone *list = NULL; while (display->clone) { struct clone *clone = display->clone; display->clone = clone->next; clone->next = list; list = clone; } display->clone = list; } static int last_display_add_clones__randr(struct context *ctx) { struct display *display = last_display(ctx); XRRScreenResources *res; char buf[80]; int i, ret; DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy))); display_init_randr_hpd(display); /* Force a probe of outputs on initial connection */ res = XRRGetScreenResources(display->dpy, display->root); if (res == NULL) return -ENOMEM; DBG(X11, ("%s - noutputs=%d\n", DisplayString(display->dpy), res->noutput)); for (i = 0; i < res->noutput; i++) { XRROutputInfo *o = XRRGetOutputInfo(display->dpy, res, res->outputs[i]); struct clone *clone = add_clone(ctx); RROutput id; if (clone == NULL) return -ENOMEM; clone->depth = 24; clone->next = display->clone; display->clone = clone; id = claim_virtual(ctx->display, buf, ctx->nclone); if (id == 0) { fprintf(stderr, "Failed to find available VirtualHead \"%s\" for \"%s\" on display \"%s\"\n", buf, o->name, DisplayString(display->dpy)); return -ENOSPC; } ret = clone_output_init(clone, &clone->src, ctx->display, buf, id); if (ret) { fprintf(stderr, "Failed to add output \"%s\" on display \"%s\"\n", buf, DisplayString(ctx->display->dpy)); return ret; } ret = clone_output_init(clone, &clone->dst, display, o->name, res->outputs[i]); if (ret) { fprintf(stderr, "Failed to add output \"%s\" on display \"%s\"\n", o->name, DisplayString(display->dpy)); return ret; } ret = clone_init_depth(clone); if (ret) { fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n", DisplayString(display->dpy)); return ret; } clone->dst.x = 0; clone->dst.y = 0; clone->dst.width = display->width; clone->dst.height = display->height; ret = clone_update_modes__randr(clone); if (ret) { fprintf(stderr, "Failed to clone output \"%s\" from display \"%s\"\n", o->name, DisplayString(display->dpy)); return ret; } if (o->crtc) { DBG(X11, ("%s - disabling active output\n", DisplayString(display->dpy))); disable_crtc(display->dpy, res, o->crtc); } XRRFreeOutputInfo(o); } XRRFreeScreenResources(res); reverse_clone_list(display); return 0; } #if defined(USE_XINERAMA) static int last_display_add_clones__xinerama(struct context *ctx) { struct display *display = last_display(ctx); Display *dpy = display->dpy; XineramaScreenInfo *xi; char buf[80]; int n, count, ret; DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy))); count = 0; xi = XineramaQueryScreens(dpy, &count); for (n = 0; n < count; n++) { struct clone *clone = add_clone(ctx); RROutput id; if (clone == NULL) return -ENOMEM; if (xi[n].width == 0 || xi[n].height == 0) continue; clone->depth = 24; clone->next = display->clone; display->clone = clone; id = claim_virtual(ctx->display, buf, ctx->nclone); if (id == 0) { fprintf(stderr, "Failed to find available VirtualHead \"%s\" for Xinerama screen %d on display \"%s\"\n", buf, n, DisplayString(dpy)); } ret = clone_output_init(clone, &clone->src, ctx->display, buf, id); if (ret) { fprintf(stderr, "Failed to add Xinerama screen %d on display \"%s\"\n", n, DisplayString(ctx->display->dpy)); return ret; } sprintf(buf, "XINERAMA%d", n); ret = clone_output_init(clone, &clone->dst, display, buf, 0); if (ret) { fprintf(stderr, "Failed to add Xinerama screen %d on display \"%s\"\n", n, DisplayString(dpy)); return ret; } ret = clone_init_depth(clone); if (ret) { fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n", DisplayString(display->dpy)); return ret; } /* Replace the modes on the local VIRTUAL output with the remote Screen */ clone->dst.width = xi[n].width; clone->dst.height = xi[n].height; clone->dst.x = xi[n].x_org; clone->dst.y = xi[n].y_org; clone->dst.rr_crtc = -1; ret = clone_update_modes__fixed(clone); if (ret) { fprintf(stderr, "Failed to clone Xinerama screen %d from display \"%s\"\n", n, DisplayString(display->dpy)); return ret; } clone->active = ctx->active; ctx->active = clone; } XFree(xi); reverse_clone_list(display); return 0; } #else #define last_display_add_clones__xinerama(ctx) -1 #endif static int last_display_add_clones__display(struct context *ctx) { struct display *display = last_display(ctx); Display *dpy = display->dpy; struct clone *clone; Screen *scr; int count, s; char buf[80]; int ret; RROutput id; count = ScreenCount(dpy); DBG(X11, ("%s(%s) - %d screens\n", __func__, DisplayString(dpy), count)); for (s = 0; s < count; s++) { clone = add_clone(ctx); if (clone == NULL) return -ENOMEM; clone->depth = 24; clone->next = display->clone; display->clone = clone; id = claim_virtual(ctx->display, buf, ctx->nclone); if (id == 0) { fprintf(stderr, "Failed to find available VirtualHead \"%s\" for on display \"%s\"\n", buf, DisplayString(dpy)); } ret = clone_output_init(clone, &clone->src, ctx->display, buf, id); if (ret) { fprintf(stderr, "Failed to add display \"%s\"\n", DisplayString(ctx->display->dpy)); return ret; } sprintf(buf, "SCREEN%d", s); ret = clone_output_init(clone, &clone->dst, display, buf, 0); if (ret) { fprintf(stderr, "Failed to add display \"%s\"\n", DisplayString(dpy)); return ret; } ret = clone_init_depth(clone); if (ret) { fprintf(stderr, "Failed to negotiate image format for display \"%s\"\n", DisplayString(dpy)); return ret; } /* Replace the modes on the local VIRTUAL output with the remote Screen */ scr = ScreenOfDisplay(dpy, s); clone->dst.width = scr->width; clone->dst.height = scr->height; clone->dst.x = 0; clone->dst.y = 0; clone->dst.rr_crtc = -1; ret = clone_update_modes__fixed(clone); if (ret) { fprintf(stderr, "Failed to clone display \"%s\"\n", DisplayString(dpy)); return ret; } clone->active = ctx->active; ctx->active = clone; } return 0; } static int last_display_add_clones(struct context *ctx) { struct display *display = last_display(ctx); display->width = DisplayWidth(display->dpy, DefaultScreen(display->dpy)); display->height = DisplayHeight(display->dpy, DefaultScreen(display->dpy)); DBG(X11, ("%s - initial size %dx%d\n", DisplayString(display->dpy), display->width, display->height)); if (display->rr_active) return last_display_add_clones__randr(ctx); if (display->xinerama_active) return last_display_add_clones__xinerama(ctx); return last_display_add_clones__display(ctx); } static int last_display_clone(struct context *ctx, int fd) { fd = add_fd(ctx, fd); if (fd < 0) return fd; fd = last_display_add_clones(ctx); if (fd) return fd; return 0; } static int first_display_has_singleton(struct context *ctx) { struct display *display = ctx->display; unsigned long nitems, bytes; unsigned char *prop; int format; Atom type; ctx->singleton = XInternAtom(display->dpy, "intel-virtual-output-singleton", False); XGetWindowProperty(display->dpy, display->root, ctx->singleton, 0, 0, 0, AnyPropertyType, &type, &format, &nitems, &bytes, &prop); DBG(X11, ("%s: singleton registered? %d\n", DisplayString(display->dpy), type != None)); return type != None; } static int first_display_wait_for_ack(struct context *ctx, int timeout, int id) { struct display *display = ctx->display; struct pollfd pfd; char expect[6]; /* "1234R\0" */ sprintf(expect, "%04xR", id); DBG(X11, ("%s: wait for act '%c%c%c%c%c'\n", DisplayString(display->dpy), expect[0], expect[1], expect[2], expect[3], expect[4])); XFlush(display->dpy); pfd.fd = ConnectionNumber(display->dpy); pfd.events = POLLIN; do { if (poll(&pfd, 1, timeout) <= 0) return -ETIME; while (XPending(display->dpy)) { XEvent e; XClientMessageEvent *cme; XNextEvent(display->dpy, &e); DBG(X11, ("%s: reading event type %d\n", DisplayString(display->dpy), e.type)); if (e.type != ClientMessage) continue; cme = (XClientMessageEvent *)&e; if (cme->message_type != ctx->singleton) continue; if (cme->format != 8) continue; DBG(X11, ("%s: client message '%c%c%c%c%c'\n", DisplayString(display->dpy), cme->data.b[0], cme->data.b[1], cme->data.b[2], cme->data.b[3], cme->data.b[4])); if (memcmp(cme->data.b, expect, 5)) continue; return -atoi(cme->data.b + 5); } } while (1); } #if defined(__GNUC__) && (__GNUC__ > 3) __attribute__((format(gnu_printf, 3, 4))) #endif static int first_display_send_command(struct context *ctx, int timeout, const char *format, ...) { struct display *display = ctx->display; char buf[1024], *b; int len, id; va_list va; id = rand() & 0xffff; sprintf(buf, "%04x", id); va_start(va, format); len = vsnprintf(buf+4, sizeof(buf)-4, format, va)+5; va_end(va); assert(len < sizeof(buf)); DBG(X11, ("%s: send command '%s'\n", DisplayString(display->dpy), buf)); b = buf; while (len) { XClientMessageEvent msg; int n = len; if (n > sizeof(msg.data.b)) n = sizeof(msg.data.b); len -= n; msg.type = ClientMessage; msg.serial = 0; msg.message_type = ctx->singleton; msg.format = 8; memcpy(msg.data.b, b, n); b += n; XSendEvent(display->dpy, display->root, False, PropertyChangeMask, (XEvent *)&msg); } return first_display_wait_for_ack(ctx, timeout, id); } static void first_display_reply(struct context *ctx, int result) { struct display *display = ctx->display; XClientMessageEvent msg; sprintf(msg.data.b, "%c%c%c%cR%d", ctx->command[0], ctx->command[1], ctx->command[2], ctx->command[3], -result); DBG(X11, ("%s: send reply '%s'\n", DisplayString(display->dpy), msg.data.b)); msg.type = ClientMessage; msg.serial = 0; msg.message_type = ctx->singleton; msg.format = 8; XSendEvent(display->dpy, display->root, False, PropertyChangeMask, (XEvent *)&msg); XFlush(display->dpy); } static void first_display_handle_command(struct context *ctx, const char *msg) { int len; DBG(X11, ("client message!\n")); for (len = 0; len < 20 && msg[len]; len++) ; if (ctx->command_continuation + len > sizeof(ctx->command)) { ctx->command_continuation = 0; return; } memcpy(ctx->command + ctx->command_continuation, msg, len); ctx->command_continuation += len; if (len < 20) { ctx->command[ctx->command_continuation] = 0; DBG(X11, ("client command complete! '%s'\n", ctx->command)); switch (ctx->command[4]) { case 'B': first_display_reply(ctx, last_display_clone(ctx, bumblebee_open(ctx))); break; case 'C': first_display_reply(ctx, last_display_clone(ctx, display_open(ctx, ctx->command + 5))); break; case 'P': first_display_reply(ctx, 0); break; case 'R': break; } ctx->command_continuation = 0; return; } } static int first_display_register_as_singleton(struct context *ctx) { struct display *display = ctx->display; struct pollfd pfd; XChangeProperty(display->dpy, display->root, ctx->singleton, XA_STRING, 8, PropModeReplace, (unsigned char *)".", 1); XFlush(display->dpy); /* And eat the notify (presuming that it is ours!) */ pfd.fd = ConnectionNumber(display->dpy); pfd.events = POLLIN; do { if (poll(&pfd, 1, 1000) <= 0) { fprintf(stderr, "Failed to register as singleton\n"); return EBUSY; } while (XPending(display->dpy)) { XEvent e; XNextEvent(display->dpy, &e); DBG(X11, ("%s: reading event type %d\n", DisplayString(display->dpy), e.type)); if (e.type == PropertyNotify && ((XPropertyEvent *)&e)->atom == ctx->singleton) return 0; } } while (1); } static void display_flush_send(struct display *display) { XShmCompletionEvent e; if (!display->send) return; DBG(X11, ("%s flushing send (serial now %ld) (has shm send? %d)\n", DisplayString(display->dpy), (long)NextRequest(display->dpy), display->shm_event)); display->send = 0; if (display->shm_event == 0) { XSync(display->dpy, False); display->flush = 0; return; } memset(&e, 0, sizeof(e)); e.type = display->shm_event; e.send_event = 1; e.drawable = display->root; e.major_code = display->shm_opcode; e.minor_code = X_ShmPutImage; XSendEvent(display->dpy, display->root, False, 0, (XEvent *)&e); display_mark_flush(display); } static void display_sync(struct display *display) { if (display->skip_clone == 0) return; if (display->skip_frame++ < 2) return; DBG(X11, ("%s forcing sync\n", DisplayString(display->dpy))); XSync(display->dpy, False); display->flush = 0; display->send = 0; /* Event tracking proven unreliable, disable */ display->shm_event = 0; } static void display_flush(struct display *display) { display_flush_cursor(display); display_flush_send(display); display_sync(display); if (!display->flush) return; DBG(X11, ("%s(%s)\n", __func__, DisplayString(display->dpy))); XFlush(display->dpy); display->flush = 0; } static int first_display_first_sibling(struct context *ctx) { const char *str, *colon; int dpy, scr, len; str = DisplayString(ctx->display->dpy); colon = strrchr(str, ':'); if (colon == NULL) return -1; if (sscanf(colon + 1, "%d.%d", &dpy, &scr) == 1) scr = 0; len = (colon - str) + 1; memcpy(ctx->command, str, len); len += sprintf(ctx->command + len, "%d.", dpy); ctx->command_continuation = len; return scr + 1; } static int first_display_sibling(struct context *ctx, int i) { if (i < 0) return 0; sprintf(ctx->command + ctx->command_continuation, "%d", i); return 1; } #define first_display_for_each_sibling(CTX, i) \ for (i = first_display_first_sibling(CTX); first_display_sibling(CTX, i); i++) static void display_cleanup(struct display *display) { Display *dpy = display->dpy; XRRScreenResources *res; int n; XGrabServer(dpy); res = _XRRGetScreenResourcesCurrent(dpy, display->root); if (res != NULL) { for (n = 0; n < res->ncrtc; n++) disable_crtc(display->dpy, res, res->crtcs[n]); XRRFreeScreenResources(res); } XUngrabServer(dpy); } static void context_cleanup(struct context *ctx) { Display *dpy = ctx->display->dpy; XRRScreenResources *res; int i, j; for (i = 1; i < ctx->ndisplay; i++) display_cleanup(&ctx->display[i]); if (dpy == NULL) return; res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root); if (res == NULL) return; XGrabServer(dpy); for (i = 0; i < ctx->nclone; i++) { struct clone *clone = &ctx->clones[i]; XRROutputInfo *output; assert(clone->src.display == ctx->display); output = XRRGetOutputInfo(dpy, res, clone->src.rr_output); if (output == NULL) continue; disable_crtc(dpy, res, output->crtc); for (j = 0; j < output->nmode; j++) XRRDeleteOutputMode(dpy, clone->src.rr_output, output->modes[j]); XRRFreeOutputInfo(output); } for (i = 0; i < res->nmode; i++) { if (strncmp(res->modes[i].name, "VIRTUAL", 7) == 0) { XRRDestroyMode(dpy, res->modes[i].id); continue; } if (strcmp(res->modes[i].name, "ClaimVirtualHead") == 0) { XRRDestroyMode(dpy, res->modes[i].id); continue; } } XRRFreeScreenResources(res); /* And hide them again */ res = XRRGetScreenResources(dpy, ctx->display->root); if (res != NULL) XRRFreeScreenResources(res); XUngrabServer(dpy); if (ctx->singleton) XDeleteProperty(dpy, ctx->display->root, ctx->singleton); XCloseDisplay(dpy); } static void update_cursor_image(struct context *ctx) { XFixesCursorImage *cur; int i; DBG(CURSOR, ("%s cursor changed\n", DisplayString(ctx->display->dpy))); cur = XFixesGetCursorImage(ctx->display->dpy); if (cur == NULL) return; display_load_visible_cursor(&ctx->display[0], cur); for (i = 1; i < ctx->ndisplay; i++) { struct display *display = &ctx->display[i]; DBG(CURSOR, ("%s marking cursor changed\n", DisplayString(display->dpy))); display->cursor_moved++; if (display->cursor != display->invisible_cursor) { display->cursor_visible++; context_enable_timer(display->ctx); } } XFree(cur); } static int done; static void signal_handler(int sig) { done = sig; } int main(int argc, char **argv) { struct context ctx; const char *src_name = NULL; uint64_t count; int daemonize = 1, bumblebee = 0, siblings = 0, singleton = 1; int i, ret, open, fail; signal(SIGPIPE, SIG_IGN); while ((i = getopt(argc, argv, "abd:fhSvV:")) != -1) { switch (i) { case 'd': src_name = optarg; break; case 'f': daemonize = 0; break; case 'b': bumblebee = 1; break; case 's': siblings = 1; break; case 'S': singleton = 0; break; case 'v': verbose = ~0; daemonize = 0; break; case 'V': verbose = strtol(optarg, NULL, 0); daemonize = 0; break; case 'h': default: usage(argv[0]); exit(0); } } if (verbose) printf("intel-virtual-output: version %d.%d.%d\n", PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL); ret = context_init(&ctx); if (ret) return -ret; XSetErrorHandler(_check_error_handler); XSetIOErrorHandler(_io_error_handler); ret = add_fd(&ctx, display_open(&ctx, src_name)); if (ret) { fprintf(stderr, "Unable to connect to \"%s\".\n", src_name ?: getenv("DISPLAY") ?: ", set either the DISPLAY environment variable or pass -d on the commandline"); ret = -ret; goto out; } ret = check_virtual(ctx.display); if (ret) { fprintf(stderr, "No VIRTUAL outputs on \"%s\".\n", DisplayString(ctx.display->dpy)); goto out; } if (singleton) { XSelectInput(ctx.display->dpy, ctx.display->root, PropertyChangeMask); if (first_display_has_singleton(&ctx)) { DBG(X11, ("%s: pinging singleton\n", DisplayString(ctx.display->dpy))); ret = first_display_send_command(&ctx, 2000, "P"); if (ret) { if (ret != -ETIME) { ret = -ret; goto out; } DBG(X11, ("No reply from singleton; assuming control\n")); } else { DBG(X11, ("%s: singleton active, sending open commands\n", DisplayString(ctx.display->dpy))); open = fail = 0; for (i = optind; i < argc; i++) { ret = first_display_send_command(&ctx, 5000, "C%s", argv[i]); if (ret && ret != -EBUSY) { fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]); fail++; } else open++; } if (siblings || (optind == argc && !bumblebee)) { first_display_for_each_sibling(&ctx, i) { ret = first_display_send_command(&ctx, 5000, "C%s", ctx.command); if (ret && ret != -EBUSY) break; else open++; } } if (bumblebee || (optind == argc && !siblings)) { ret = first_display_send_command(&ctx, 5000, "B"); if (ret && ret != -EBUSY) { if (bumblebee) fprintf(stderr, "Unable to connect to bumblebee.\n"); fail++; } else open++; } ret = open || !fail ? 0 : ECONNREFUSED; goto out; } } ret = first_display_register_as_singleton(&ctx); if (ret) goto out; } ret = display_init_damage(ctx.display); if (ret) goto out; if (ctx.display->saver_active) XScreenSaverSelectInput(ctx.display->dpy, ctx.display->root, ScreenSaverNotifyMask); if ((ctx.display->rr_event | ctx.display->rr_error) == 0) { fprintf(stderr, "RandR extension not supported by %s\n", DisplayString(ctx.display->dpy)); ret = EINVAL; goto out; } XRRSelectInput(ctx.display->dpy, ctx.display->root, RRScreenChangeNotifyMask); XFixesSelectCursorInput(ctx.display->dpy, ctx.display->root, XFixesDisplayCursorNotifyMask); ret = add_fd(&ctx, record_mouse(&ctx)); if (ret) { fprintf(stderr, "XTEST extension not supported by display \"%s\"\n", DisplayString(ctx.display->dpy)); ret = -ret; goto out; } open = fail = 0; for (i = optind; i < argc; i++) { ret = last_display_clone(&ctx, display_open(&ctx, argv[i])); if (ret && ret != -EBUSY) { fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]); fail++; } else open++; } if (siblings || (optind == argc && !bumblebee)) { first_display_for_each_sibling(&ctx, i) { ret = last_display_clone(&ctx, display_open(&ctx, ctx.command)); if (ret && ret != -EBUSY) break; else open++; } } if (bumblebee || (optind == argc && !siblings)) { ret = last_display_clone(&ctx, bumblebee_open(&ctx)); if (ret && ret != -EBUSY) { if (bumblebee) fprintf(stderr, "Unable to connect to bumblebee.\n"); fail++; } else open++; } if (open == 0) { ret = fail ? ECONNREFUSED : 0; goto out; } if (daemonize && daemon(0, 0)) { ret = EINVAL; goto out; } signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); ctx.command_continuation = 0; update_cursor_image(&ctx); while (!done) { XEvent e; int reconfigure = 0; int rr_update = 0; DBG(POLL, ("polling - enable timer? %d, nfd=%d, ndisplay=%d\n", ctx.timer_active, ctx.nfd, ctx.ndisplay)); ret = poll(ctx.pfd + !ctx.timer_active, ctx.nfd - !ctx.timer_active, -1); if (ret <= 0) break; /* pfd[0] is the timer, pfd[1] is the local display, pfd[2] is the mouse, pfd[3+] are the remotes */ DBG(POLL, ("poll reports %d fd awake\n", ret)); if (ctx.pfd[1].revents || XPending(ctx.display[0].dpy)) { DBG(POLL,("%s woken up\n", DisplayString(ctx.display[0].dpy))); do { XNextEvent(ctx.display->dpy, &e); DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[0].dpy), e.type)); if (e.type == ctx.display->saver_event + ScreenSaverNotify) { const XScreenSaverNotifyEvent *se = (const XScreenSaverNotifyEvent *)&e; DBG(SCREEN, ("%s screen saver: state=%d, kind=%d, forced=%d\n", DisplayString(ctx.display->dpy), se->state, se->kind, se->forced)); for (i = 1; i < ctx.ndisplay; i++) { struct display *display = &ctx.display[i]; if (!display->active) continue; DBG(SCREEN, ("%s %s screen saver\n", DisplayString(display->dpy), se->state == ScreenSaverOn ? "activating" : "resetting\n")); if (se->state == ScreenSaverOn) XActivateScreenSaver(display->dpy); else XResetScreenSaver(display->dpy); XFlush(display->dpy); } } else if (e.type == ctx.display->damage_event + XDamageNotify) { const XDamageNotifyEvent *de = (const XDamageNotifyEvent *)&e; struct clone *clone; DBG(DAMAGE, ("%s damaged: (%d, %d)x(%d, %d)\n", DisplayString(ctx.display->dpy), de->area.x, de->area.y, de->area.width, de->area.height)); for (clone = ctx.active; clone; clone = clone->active) clone_damage(clone, &de->area); if (ctx.active) context_enable_timer(&ctx); } else if (e.type == ctx.display->xfixes_event + XFixesCursorNotify) { update_cursor_image(&ctx); } else if (e.type == ctx.display->rr_event + RRScreenChangeNotify) { DBG(XRR, ("%s screen changed (reconfigure pending? %d)\n", DisplayString(ctx.display->dpy), reconfigure)); reconfigure = 1; } else if (e.type == PropertyNotify) { XPropertyEvent *pe = (XPropertyEvent *)&e; if (pe->atom == ctx.singleton) { DBG(X11, ("lost control of singleton\n")); return 0; } } else if (e.type == ClientMessage) { XClientMessageEvent *cme; DBG(X11, ("%s client message\n", DisplayString(ctx.display->dpy))); cme = (XClientMessageEvent *)&e; if (cme->message_type != ctx.singleton) continue; if (cme->format != 8) continue; first_display_handle_command(&ctx, cme->data.b); } else { DBG(X11, ("unknown event %d\n", e.type)); } } while (XEventsQueued(ctx.display->dpy, QueuedAfterReading)); } for (i = 1; i < ctx.ndisplay; i++) { if (ctx.pfd[i+2].revents == 0 && !XPending(ctx.display[i].dpy)) continue; DBG(POLL, ("%s woken up\n", DisplayString(ctx.display[i].dpy))); do { XNextEvent(ctx.display[i].dpy, &e); DBG(POLL, ("%s received event %d\n", DisplayString(ctx.display[i].dpy), e.type)); if (e.type == Expose) { const XExposeEvent *xe = (XExposeEvent *)&e; struct clone *clone; int damaged = 0; DBG(DAMAGE, ("%s exposed: (%d, %d)x(%d, %d)\n", DisplayString(ctx.display[i].dpy), xe->x, xe->y, xe->width, xe->height)); for (clone = ctx.active; clone; clone = clone->active) { XRectangle r; if (clone->dst.display != &ctx.display[i]) continue; r.x = clone->src.x + xe->x; r.y = clone->src.y + xe->y; r.width = xe->width; r.height = xe->height; clone_damage(clone, &r); damaged++; } if (damaged) context_enable_timer(&ctx); } else if (ctx.display[i].rr_active && e.type == ctx.display[i].rr_event + RRNotify) { const XRRNotifyEvent *re = (XRRNotifyEvent *)&e; DBG(XRR, ("%s received RRNotify, type %d\n", DisplayString(ctx.display[i].dpy), re->subtype)); if (re->subtype == RRNotify_OutputChange) { XRROutputPropertyNotifyEvent *ro = (XRROutputPropertyNotifyEvent *)re; struct clone *clone; DBG(XRR, ("%s RRNotify_OutputChange, timestamp %ld\n", DisplayString(ctx.display[i].dpy), ro->timestamp)); for (clone = ctx.display[i].clone; clone; clone = clone->next) { if (clone->dst.rr_output == ro->output) rr_update = clone->rr_update = 1; } } } } while (XEventsQueued(ctx.display[i].dpy, QueuedAfterReading)); } if (rr_update) { for (i = 0; i < ctx.nclone; i++) clone_update(&ctx.clones[i]); } if (reconfigure && context_update(&ctx)) display_reset_damage(ctx.display); while (XPending(ctx.record)) /* discard all implicit events */ XNextEvent(ctx.record, &e); if (ctx.timer_active && read(ctx.timer, &count, sizeof(count)) > 0) { struct clone *clone; DBG(TIMER, ("%s timer expired (count=%ld)\n", DisplayString(ctx.display->dpy), (long)count)); ret = 0; if (ctx.active) { DBG(DAMAGE, ("%s clearing damage\n", DisplayString(ctx.display->dpy))); XDamageSubtract(ctx.display->dpy, ctx.display->damage, None, None); ctx.display->flush = 1; } for (clone = ctx.active; clone; clone = clone->active) ret |= clone_paint(clone); for (i = 0; i < ctx.ndisplay; i++) display_flush(&ctx.display[i]); DBG(TIMER, ("%s timer still active? %d\n", DisplayString(ctx.display->dpy), ret != 0)); ctx.timer_active = ret != 0; } } ret = 0; out: context_cleanup(&ctx); return ret; } xserver-xorg-video-intel-2.99.917+git20160325/xvmc/000077500000000000000000000000001267532330400212505ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/xvmc/Makefile.am000066400000000000000000000012311267532330400233010ustar00rootroot00000000000000if XVMC lib_LTLIBRARIES=libIntelXvMC.la endif SUBDIRS = shader libIntelXvMC_la_SOURCES = \ intel_xvmc.c \ intel_xvmc.h \ intel_xvmc_private.h \ intel_xvmc_dump.c \ i830_reg.h \ i915_reg.h \ i915_structs.h \ i915_program.h \ i915_xvmc.c \ i915_xvmc.h \ brw_defines.h \ brw_structs.h \ i965_reg.h \ i965_xvmc.c \ xvmc_vld.c \ intel_batchbuffer.c \ intel_batchbuffer.h \ $(NULL) AM_CFLAGS = $(XVMCLIB_CFLAGS) $(XORG_CFLAGS) -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0 libIntelXvMC_la_LDFLAGS = -version-number 1:0:0 libIntelXvMC_la_LIBADD = $(XVMCLIB_LIBS) -lpthread xserver-xorg-video-intel-2.99.917+git20160325/xvmc/brw_defines.h000066400000000000000000001061751267532330400237220ustar00rootroot00000000000000 /************************************************************************** * * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 BRW_DEFINES_H #define BRW_DEFINES_H /* */ #if 0 #define MI_NOOP 0x00 #define MI_USER_INTERRUPT 0x02 #define MI_WAIT_FOR_EVENT 0x03 #define MI_FLUSH 0x04 #define MI_REPORT_HEAD 0x07 #define MI_ARB_ON_OFF 0x08 #define MI_BATCH_BUFFER_END 0x0A #define MI_OVERLAY_FLIP 0x11 #define MI_LOAD_SCAN_LINES_INCL 0x12 #define MI_LOAD_SCAN_LINES_EXCL 0x13 #define MI_DISPLAY_BUFFER_INFO 0x14 #define MI_SET_CONTEXT 0x18 #define MI_STORE_DATA_IMM 0x20 #define MI_STORE_DATA_INDEX 0x21 #define MI_LOAD_REGISTER_IMM 0x22 #define MI_STORE_REGISTER_MEM 0x24 #define MI_BATCH_BUFFER_START 0x31 #define MI_SYNCHRONOUS_FLIP 0x0 #define MI_ASYNCHRONOUS_FLIP 0x1 #define MI_BUFFER_SECURE 0x0 #define MI_BUFFER_NONSECURE 0x1 #define MI_ARBITRATE_AT_CHAIN_POINTS 0x0 #define MI_ARBITRATE_BETWEEN_INSTS 0x1 #define MI_NO_ARBITRATION 0x3 #define MI_CONDITION_CODE_WAIT_DISABLED 0x0 #define MI_CONDITION_CODE_WAIT_0 0x1 #define MI_CONDITION_CODE_WAIT_1 0x2 #define MI_CONDITION_CODE_WAIT_2 0x3 #define MI_CONDITION_CODE_WAIT_3 0x4 #define MI_CONDITION_CODE_WAIT_4 0x5 #define MI_DISPLAY_PIPE_A 0x0 #define MI_DISPLAY_PIPE_B 0x1 #define MI_DISPLAY_PLANE_A 0x0 #define MI_DISPLAY_PLANE_B 0x1 #define MI_DISPLAY_PLANE_C 0x2 #define MI_STANDARD_FLIP 0x0 #define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD 0x1 #define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE 0x2 #define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER 0x3 #define MI_PHYSICAL_ADDRESS 0x0 #define MI_VIRTUAL_ADDRESS 0x1 #define MI_BUFFER_MEMORY_MAIN 0x0 #define MI_BUFFER_MEMORY_GTT 0x2 #define MI_BUFFER_MEMORY_PER_PROCESS_GTT 0x3 #define MI_FLIP_CONTINUE 0x0 #define MI_FLIP_ON 0x1 #define MI_FLIP_OFF 0x2 #define MI_UNTRUSTED_REGISTER_SPACE 0x0 #define MI_TRUSTED_REGISTER_SPACE 0x1 #endif /* 3D state: */ #define _3DOP_3DSTATE_PIPELINED 0x0 #define _3DOP_3DSTATE_NONPIPELINED 0x1 #define _3DOP_3DCONTROL 0x2 #define _3DOP_3DPRIMITIVE 0x3 #define _3DSTATE_PIPELINED_POINTERS 0x00 #define _3DSTATE_BINDING_TABLE_POINTERS 0x01 #define _3DSTATE_VERTEX_BUFFERS 0x08 #define _3DSTATE_VERTEX_ELEMENTS 0x09 #define _3DSTATE_INDEX_BUFFER 0x0A #define _3DSTATE_VF_STATISTICS 0x0B #define _3DSTATE_DRAWING_RECTANGLE 0x00 #define _3DSTATE_CONSTANT_COLOR 0x01 #define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 #define _3DSTATE_CHROMA_KEY 0x04 #define _3DSTATE_DEPTH_BUFFER 0x05 #define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 #define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 #define _3DSTATE_LINE_STIPPLE 0x08 #define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 #define _3DCONTROL 0x00 #define _3DPRIMITIVE 0x00 #define PIPE_CONTROL_NOWRITE 0x00 #define PIPE_CONTROL_WRITEIMMEDIATE 0x01 #define PIPE_CONTROL_WRITEDEPTH 0x02 #define PIPE_CONTROL_WRITETIMESTAMP 0x03 #define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00 #define PIPE_CONTROL_GTTWRITE_GLOBAL 0x01 #define _3DPRIM_POINTLIST 0x01 #define _3DPRIM_LINELIST 0x02 #define _3DPRIM_LINESTRIP 0x03 #define _3DPRIM_TRILIST 0x04 #define _3DPRIM_TRISTRIP 0x05 #define _3DPRIM_TRIFAN 0x06 #define _3DPRIM_QUADLIST 0x07 #define _3DPRIM_QUADSTRIP 0x08 #define _3DPRIM_LINELIST_ADJ 0x09 #define _3DPRIM_LINESTRIP_ADJ 0x0A #define _3DPRIM_TRILIST_ADJ 0x0B #define _3DPRIM_TRISTRIP_ADJ 0x0C #define _3DPRIM_TRISTRIP_REVERSE 0x0D #define _3DPRIM_POLYGON 0x0E #define _3DPRIM_RECTLIST 0x0F #define _3DPRIM_LINELOOP 0x10 #define _3DPRIM_POINTLIST_BF 0x11 #define _3DPRIM_LINESTRIP_CONT 0x12 #define _3DPRIM_LINESTRIP_BF 0x13 #define _3DPRIM_LINESTRIP_CONT_BF 0x14 #define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 #define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 #define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 #define BRW_ANISORATIO_2 0 #define BRW_ANISORATIO_4 1 #define BRW_ANISORATIO_6 2 #define BRW_ANISORATIO_8 3 #define BRW_ANISORATIO_10 4 #define BRW_ANISORATIO_12 5 #define BRW_ANISORATIO_14 6 #define BRW_ANISORATIO_16 7 #define BRW_BLENDFACTOR_ONE 0x1 #define BRW_BLENDFACTOR_SRC_COLOR 0x2 #define BRW_BLENDFACTOR_SRC_ALPHA 0x3 #define BRW_BLENDFACTOR_DST_ALPHA 0x4 #define BRW_BLENDFACTOR_DST_COLOR 0x5 #define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 #define BRW_BLENDFACTOR_CONST_COLOR 0x7 #define BRW_BLENDFACTOR_CONST_ALPHA 0x8 #define BRW_BLENDFACTOR_SRC1_COLOR 0x9 #define BRW_BLENDFACTOR_SRC1_ALPHA 0x0A #define BRW_BLENDFACTOR_ZERO 0x11 #define BRW_BLENDFACTOR_INV_SRC_COLOR 0x12 #define BRW_BLENDFACTOR_INV_SRC_ALPHA 0x13 #define BRW_BLENDFACTOR_INV_DST_ALPHA 0x14 #define BRW_BLENDFACTOR_INV_DST_COLOR 0x15 #define BRW_BLENDFACTOR_INV_CONST_COLOR 0x17 #define BRW_BLENDFACTOR_INV_CONST_ALPHA 0x18 #define BRW_BLENDFACTOR_INV_SRC1_COLOR 0x19 #define BRW_BLENDFACTOR_INV_SRC1_ALPHA 0x1A #define BRW_BLENDFUNCTION_ADD 0 #define BRW_BLENDFUNCTION_SUBTRACT 1 #define BRW_BLENDFUNCTION_REVERSE_SUBTRACT 2 #define BRW_BLENDFUNCTION_MIN 3 #define BRW_BLENDFUNCTION_MAX 4 #define BRW_ALPHATEST_FORMAT_UNORM8 0 #define BRW_ALPHATEST_FORMAT_FLOAT32 1 #define BRW_CHROMAKEY_KILL_ON_ANY_MATCH 0 #define BRW_CHROMAKEY_REPLACE_BLACK 1 #define BRW_CLIP_API_OGL 0 #define BRW_CLIP_API_DX 1 #define BRW_CLIPMODE_NORMAL 0 #define BRW_CLIPMODE_CLIP_ALL 1 #define BRW_CLIPMODE_CLIP_NON_REJECTED 2 #define BRW_CLIPMODE_REJECT_ALL 3 #define BRW_CLIPMODE_ACCEPT_ALL 4 #define BRW_CLIP_NDCSPACE 0 #define BRW_CLIP_SCREENSPACE 1 #define BRW_COMPAREFUNCTION_ALWAYS 0 #define BRW_COMPAREFUNCTION_NEVER 1 #define BRW_COMPAREFUNCTION_LESS 2 #define BRW_COMPAREFUNCTION_EQUAL 3 #define BRW_COMPAREFUNCTION_LEQUAL 4 #define BRW_COMPAREFUNCTION_GREATER 5 #define BRW_COMPAREFUNCTION_NOTEQUAL 6 #define BRW_COMPAREFUNCTION_GEQUAL 7 #define BRW_COVERAGE_PIXELS_HALF 0 #define BRW_COVERAGE_PIXELS_1 1 #define BRW_COVERAGE_PIXELS_2 2 #define BRW_COVERAGE_PIXELS_4 3 #define BRW_CULLMODE_BOTH 0 #define BRW_CULLMODE_NONE 1 #define BRW_CULLMODE_FRONT 2 #define BRW_CULLMODE_BACK 3 #define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM 0 #define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 #define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 #define BRW_DEPTHFORMAT_D32_FLOAT 1 #define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT 2 #define BRW_DEPTHFORMAT_D16_UNORM 5 #define BRW_FLOATING_POINT_IEEE_754 0 #define BRW_FLOATING_POINT_NON_IEEE_754 1 #define BRW_FRONTWINDING_CW 0 #define BRW_FRONTWINDING_CCW 1 #define BRW_INDEX_BYTE 0 #define BRW_INDEX_WORD 1 #define BRW_INDEX_DWORD 2 #define BRW_LOGICOPFUNCTION_CLEAR 0 #define BRW_LOGICOPFUNCTION_NOR 1 #define BRW_LOGICOPFUNCTION_AND_INVERTED 2 #define BRW_LOGICOPFUNCTION_COPY_INVERTED 3 #define BRW_LOGICOPFUNCTION_AND_REVERSE 4 #define BRW_LOGICOPFUNCTION_INVERT 5 #define BRW_LOGICOPFUNCTION_XOR 6 #define BRW_LOGICOPFUNCTION_NAND 7 #define BRW_LOGICOPFUNCTION_AND 8 #define BRW_LOGICOPFUNCTION_EQUIV 9 #define BRW_LOGICOPFUNCTION_NOOP 10 #define BRW_LOGICOPFUNCTION_OR_INVERTED 11 #define BRW_LOGICOPFUNCTION_COPY 12 #define BRW_LOGICOPFUNCTION_OR_REVERSE 13 #define BRW_LOGICOPFUNCTION_OR 14 #define BRW_LOGICOPFUNCTION_SET 15 #define BRW_MAPFILTER_NEAREST 0x0 #define BRW_MAPFILTER_LINEAR 0x1 #define BRW_MAPFILTER_ANISOTROPIC 0x2 #define BRW_MIPFILTER_NONE 0 #define BRW_MIPFILTER_NEAREST 1 #define BRW_MIPFILTER_LINEAR 3 #define BRW_POLYGON_FRONT_FACING 0 #define BRW_POLYGON_BACK_FACING 1 #define BRW_PREFILTER_ALWAYS 0x0 #define BRW_PREFILTER_NEVER 0x1 #define BRW_PREFILTER_LESS 0x2 #define BRW_PREFILTER_EQUAL 0x3 #define BRW_PREFILTER_LEQUAL 0x4 #define BRW_PREFILTER_GREATER 0x5 #define BRW_PREFILTER_NOTEQUAL 0x6 #define BRW_PREFILTER_GEQUAL 0x7 #define BRW_PROVOKING_VERTEX_0 0 #define BRW_PROVOKING_VERTEX_1 1 #define BRW_PROVOKING_VERTEX_2 2 #define BRW_RASTRULE_UPPER_LEFT 0 #define BRW_RASTRULE_UPPER_RIGHT 1 #define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0 #define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1 #define BRW_RENDERTARGET_CLAMPRANGE_FORMAT 2 #define BRW_STENCILOP_KEEP 0 #define BRW_STENCILOP_ZERO 1 #define BRW_STENCILOP_REPLACE 2 #define BRW_STENCILOP_INCRSAT 3 #define BRW_STENCILOP_DECRSAT 4 #define BRW_STENCILOP_INCR 5 #define BRW_STENCILOP_DECR 6 #define BRW_STENCILOP_INVERT 7 #define BRW_SURFACE_MIPMAPLAYOUT_BELOW 0 #define BRW_SURFACE_MIPMAPLAYOUT_RIGHT 1 #define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 #define BRW_SURFACEFORMAT_R32G32B32A32_SINT 0x001 #define BRW_SURFACEFORMAT_R32G32B32A32_UINT 0x002 #define BRW_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 #define BRW_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 #define BRW_SURFACEFORMAT_R64G64_FLOAT 0x005 #define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 #define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 #define BRW_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 #define BRW_SURFACEFORMAT_R32G32B32_FLOAT 0x040 #define BRW_SURFACEFORMAT_R32G32B32_SINT 0x041 #define BRW_SURFACEFORMAT_R32G32B32_UINT 0x042 #define BRW_SURFACEFORMAT_R32G32B32_UNORM 0x043 #define BRW_SURFACEFORMAT_R32G32B32_SNORM 0x044 #define BRW_SURFACEFORMAT_R32G32B32_SSCALED 0x045 #define BRW_SURFACEFORMAT_R32G32B32_USCALED 0x046 #define BRW_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 #define BRW_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 #define BRW_SURFACEFORMAT_R16G16B16A16_SINT 0x082 #define BRW_SURFACEFORMAT_R16G16B16A16_UINT 0x083 #define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 #define BRW_SURFACEFORMAT_R32G32_FLOAT 0x085 #define BRW_SURFACEFORMAT_R32G32_SINT 0x086 #define BRW_SURFACEFORMAT_R32G32_UINT 0x087 #define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 #define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 #define BRW_SURFACEFORMAT_L32A32_FLOAT 0x08A #define BRW_SURFACEFORMAT_R32G32_UNORM 0x08B #define BRW_SURFACEFORMAT_R32G32_SNORM 0x08C #define BRW_SURFACEFORMAT_R64_FLOAT 0x08D #define BRW_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E #define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F #define BRW_SURFACEFORMAT_A32X32_FLOAT 0x090 #define BRW_SURFACEFORMAT_L32X32_FLOAT 0x091 #define BRW_SURFACEFORMAT_I32X32_FLOAT 0x092 #define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 #define BRW_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 #define BRW_SURFACEFORMAT_R32G32_SSCALED 0x095 #define BRW_SURFACEFORMAT_R32G32_USCALED 0x096 #define BRW_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 #define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 #define BRW_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 #define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 #define BRW_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 #define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 #define BRW_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 #define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 #define BRW_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 #define BRW_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA #define BRW_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB #define BRW_SURFACEFORMAT_R16G16_UNORM 0x0CC #define BRW_SURFACEFORMAT_R16G16_SNORM 0x0CD #define BRW_SURFACEFORMAT_R16G16_SINT 0x0CE #define BRW_SURFACEFORMAT_R16G16_UINT 0x0CF #define BRW_SURFACEFORMAT_R16G16_FLOAT 0x0D0 #define BRW_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 #define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 #define BRW_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 #define BRW_SURFACEFORMAT_R32_SINT 0x0D6 #define BRW_SURFACEFORMAT_R32_UINT 0x0D7 #define BRW_SURFACEFORMAT_R32_FLOAT 0x0D8 #define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 #define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA #define BRW_SURFACEFORMAT_L16A16_UNORM 0x0DF #define BRW_SURFACEFORMAT_I24X8_UNORM 0x0E0 #define BRW_SURFACEFORMAT_L24X8_UNORM 0x0E1 #define BRW_SURFACEFORMAT_A24X8_UNORM 0x0E2 #define BRW_SURFACEFORMAT_I32_FLOAT 0x0E3 #define BRW_SURFACEFORMAT_L32_FLOAT 0x0E4 #define BRW_SURFACEFORMAT_A32_FLOAT 0x0E5 #define BRW_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 #define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA #define BRW_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB #define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC #define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED #define BRW_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE #define BRW_SURFACEFORMAT_L16A16_FLOAT 0x0F0 #define BRW_SURFACEFORMAT_R32_UNORM 0x0F1 #define BRW_SURFACEFORMAT_R32_SNORM 0x0F2 #define BRW_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 #define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 #define BRW_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 #define BRW_SURFACEFORMAT_R16G16_SSCALED 0x0F6 #define BRW_SURFACEFORMAT_R16G16_USCALED 0x0F7 #define BRW_SURFACEFORMAT_R32_SSCALED 0x0F8 #define BRW_SURFACEFORMAT_R32_USCALED 0x0F9 #define BRW_SURFACEFORMAT_B5G6R5_UNORM 0x100 #define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 #define BRW_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 #define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 #define BRW_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 #define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 #define BRW_SURFACEFORMAT_R8G8_UNORM 0x106 #define BRW_SURFACEFORMAT_R8G8_SNORM 0x107 #define BRW_SURFACEFORMAT_R8G8_SINT 0x108 #define BRW_SURFACEFORMAT_R8G8_UINT 0x109 #define BRW_SURFACEFORMAT_R16_UNORM 0x10A #define BRW_SURFACEFORMAT_R16_SNORM 0x10B #define BRW_SURFACEFORMAT_R16_SINT 0x10C #define BRW_SURFACEFORMAT_R16_UINT 0x10D #define BRW_SURFACEFORMAT_R16_FLOAT 0x10E #define BRW_SURFACEFORMAT_I16_UNORM 0x111 #define BRW_SURFACEFORMAT_L16_UNORM 0x112 #define BRW_SURFACEFORMAT_A16_UNORM 0x113 #define BRW_SURFACEFORMAT_L8A8_UNORM 0x114 #define BRW_SURFACEFORMAT_I16_FLOAT 0x115 #define BRW_SURFACEFORMAT_L16_FLOAT 0x116 #define BRW_SURFACEFORMAT_A16_FLOAT 0x117 #define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 #define BRW_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A #define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B #define BRW_SURFACEFORMAT_R8G8_SSCALED 0x11C #define BRW_SURFACEFORMAT_R8G8_USCALED 0x11D #define BRW_SURFACEFORMAT_R16_SSCALED 0x11E #define BRW_SURFACEFORMAT_R16_USCALED 0x11F #define BRW_SURFACEFORMAT_R8_UNORM 0x140 #define BRW_SURFACEFORMAT_R8_SNORM 0x141 #define BRW_SURFACEFORMAT_R8_SINT 0x142 #define BRW_SURFACEFORMAT_R8_UINT 0x143 #define BRW_SURFACEFORMAT_A8_UNORM 0x144 #define BRW_SURFACEFORMAT_I8_UNORM 0x145 #define BRW_SURFACEFORMAT_L8_UNORM 0x146 #define BRW_SURFACEFORMAT_P4A4_UNORM 0x147 #define BRW_SURFACEFORMAT_A4P4_UNORM 0x148 #define BRW_SURFACEFORMAT_R8_SSCALED 0x149 #define BRW_SURFACEFORMAT_R8_USCALED 0x14A #define BRW_SURFACEFORMAT_R1_UINT 0x181 #define BRW_SURFACEFORMAT_YCRCB_NORMAL 0x182 #define BRW_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 #define BRW_SURFACEFORMAT_BC1_UNORM 0x186 #define BRW_SURFACEFORMAT_BC2_UNORM 0x187 #define BRW_SURFACEFORMAT_BC3_UNORM 0x188 #define BRW_SURFACEFORMAT_BC4_UNORM 0x189 #define BRW_SURFACEFORMAT_BC5_UNORM 0x18A #define BRW_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B #define BRW_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C #define BRW_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D #define BRW_SURFACEFORMAT_MONO8 0x18E #define BRW_SURFACEFORMAT_YCRCB_SWAPUV 0x18F #define BRW_SURFACEFORMAT_YCRCB_SWAPY 0x190 #define BRW_SURFACEFORMAT_DXT1_RGB 0x191 #define BRW_SURFACEFORMAT_FXT1 0x192 #define BRW_SURFACEFORMAT_R8G8B8_UNORM 0x193 #define BRW_SURFACEFORMAT_R8G8B8_SNORM 0x194 #define BRW_SURFACEFORMAT_R8G8B8_SSCALED 0x195 #define BRW_SURFACEFORMAT_R8G8B8_USCALED 0x196 #define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 #define BRW_SURFACEFORMAT_R64G64B64_FLOAT 0x198 #define BRW_SURFACEFORMAT_BC4_SNORM 0x199 #define BRW_SURFACEFORMAT_BC5_SNORM 0x19A #define BRW_SURFACEFORMAT_R16G16B16_UNORM 0x19C #define BRW_SURFACEFORMAT_R16G16B16_SNORM 0x19D #define BRW_SURFACEFORMAT_R16G16B16_SSCALED 0x19E #define BRW_SURFACEFORMAT_R16G16B16_USCALED 0x19F #define BRW_SURFACERETURNFORMAT_FLOAT32 0 #define BRW_SURFACERETURNFORMAT_S1 1 #define BRW_SURFACE_1D 0 #define BRW_SURFACE_2D 1 #define BRW_SURFACE_3D 2 #define BRW_SURFACE_CUBE 3 #define BRW_SURFACE_BUFFER 4 #define BRW_SURFACE_NULL 7 #define BRW_BORDER_COLOR_MODE_DEFAULT 0 #define BRW_BORDER_COLOR_MODE_LEGACY 1 #define HSW_SCS_ZERO 0 #define HSW_SCS_ONE 1 #define HSW_SCS_RED 4 #define HSW_SCS_GREEN 5 #define HSW_SCS_BLUE 6 #define HSW_SCS_ALPHA 7 #define BRW_TEXCOORDMODE_WRAP 0 #define BRW_TEXCOORDMODE_MIRROR 1 #define BRW_TEXCOORDMODE_CLAMP 2 #define BRW_TEXCOORDMODE_CUBE 3 #define BRW_TEXCOORDMODE_CLAMP_BORDER 4 #define BRW_TEXCOORDMODE_MIRROR_ONCE 5 #define BRW_THREAD_PRIORITY_NORMAL 0 #define BRW_THREAD_PRIORITY_HIGH 1 #define BRW_TILEWALK_XMAJOR 0 #define BRW_TILEWALK_YMAJOR 1 #define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS 0 #define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS 1 #define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA 0 #define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 #define BRW_VFCOMPONENT_NOSTORE 0 #define BRW_VFCOMPONENT_STORE_SRC 1 #define BRW_VFCOMPONENT_STORE_0 2 #define BRW_VFCOMPONENT_STORE_1_FLT 3 #define BRW_VFCOMPONENT_STORE_1_INT 4 #define BRW_VFCOMPONENT_STORE_VID 5 #define BRW_VFCOMPONENT_STORE_IID 6 #define BRW_VFCOMPONENT_STORE_PID 7 /* Execution Unit (EU) defines */ #define BRW_ALIGN_1 0 #define BRW_ALIGN_16 1 #define BRW_ADDRESS_DIRECT 0 #define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1 #define BRW_CHANNEL_X 0 #define BRW_CHANNEL_Y 1 #define BRW_CHANNEL_Z 2 #define BRW_CHANNEL_W 3 #define BRW_COMPRESSION_NONE 0 #define BRW_COMPRESSION_2NDHALF 1 #define BRW_COMPRESSION_COMPRESSED 2 #define BRW_CONDITIONAL_NONE 0 #define BRW_CONDITIONAL_Z 1 #define BRW_CONDITIONAL_NZ 2 #define BRW_CONDITIONAL_EQ 1 /* Z */ #define BRW_CONDITIONAL_NEQ 2 /* NZ */ #define BRW_CONDITIONAL_G 3 #define BRW_CONDITIONAL_GE 4 #define BRW_CONDITIONAL_L 5 #define BRW_CONDITIONAL_LE 6 #define BRW_CONDITIONAL_C 7 #define BRW_CONDITIONAL_O 8 #define BRW_DEBUG_NONE 0 #define BRW_DEBUG_BREAKPOINT 1 #define BRW_DEPENDENCY_NORMAL 0 #define BRW_DEPENDENCY_NOTCLEARED 1 #define BRW_DEPENDENCY_NOTCHECKED 2 #define BRW_DEPENDENCY_DISABLE 3 #define BRW_EXECUTE_1 0 #define BRW_EXECUTE_2 1 #define BRW_EXECUTE_4 2 #define BRW_EXECUTE_8 3 #define BRW_EXECUTE_16 4 #define BRW_EXECUTE_32 5 #define BRW_HORIZONTAL_STRIDE_0 0 #define BRW_HORIZONTAL_STRIDE_1 1 #define BRW_HORIZONTAL_STRIDE_2 2 #define BRW_HORIZONTAL_STRIDE_4 3 #define BRW_INSTRUCTION_NORMAL 0 #define BRW_INSTRUCTION_SATURATE 1 #define BRW_MASK_ENABLE 0 #define BRW_MASK_DISABLE 1 #define BRW_OPCODE_MOV 1 #define BRW_OPCODE_SEL 2 #define BRW_OPCODE_NOT 4 #define BRW_OPCODE_AND 5 #define BRW_OPCODE_OR 6 #define BRW_OPCODE_XOR 7 #define BRW_OPCODE_SHR 8 #define BRW_OPCODE_SHL 9 #define BRW_OPCODE_RSR 10 #define BRW_OPCODE_RSL 11 #define BRW_OPCODE_ASR 12 #define BRW_OPCODE_CMP 16 #define BRW_OPCODE_JMPI 32 #define BRW_OPCODE_IF 34 #define BRW_OPCODE_IFF 35 #define BRW_OPCODE_ELSE 36 #define BRW_OPCODE_ENDIF 37 #define BRW_OPCODE_DO 38 #define BRW_OPCODE_WHILE 39 #define BRW_OPCODE_BREAK 40 #define BRW_OPCODE_CONTINUE 41 #define BRW_OPCODE_HALT 42 #define BRW_OPCODE_MSAVE 44 #define BRW_OPCODE_MRESTORE 45 #define BRW_OPCODE_PUSH 46 #define BRW_OPCODE_POP 47 #define BRW_OPCODE_WAIT 48 #define BRW_OPCODE_SEND 49 #define BRW_OPCODE_ADD 64 #define BRW_OPCODE_MUL 65 #define BRW_OPCODE_AVG 66 #define BRW_OPCODE_FRC 67 #define BRW_OPCODE_RNDU 68 #define BRW_OPCODE_RNDD 69 #define BRW_OPCODE_RNDE 70 #define BRW_OPCODE_RNDZ 71 #define BRW_OPCODE_MAC 72 #define BRW_OPCODE_MACH 73 #define BRW_OPCODE_LZD 74 #define BRW_OPCODE_SAD2 80 #define BRW_OPCODE_SADA2 81 #define BRW_OPCODE_DP4 84 #define BRW_OPCODE_DPH 85 #define BRW_OPCODE_DP3 86 #define BRW_OPCODE_DP2 87 #define BRW_OPCODE_DPA2 88 #define BRW_OPCODE_LINE 89 #define BRW_OPCODE_NOP 126 #define BRW_PREDICATE_NONE 0 #define BRW_PREDICATE_NORMAL 1 #define BRW_PREDICATE_ALIGN1_ANYV 2 #define BRW_PREDICATE_ALIGN1_ALLV 3 #define BRW_PREDICATE_ALIGN1_ANY2H 4 #define BRW_PREDICATE_ALIGN1_ALL2H 5 #define BRW_PREDICATE_ALIGN1_ANY4H 6 #define BRW_PREDICATE_ALIGN1_ALL4H 7 #define BRW_PREDICATE_ALIGN1_ANY8H 8 #define BRW_PREDICATE_ALIGN1_ALL8H 9 #define BRW_PREDICATE_ALIGN1_ANY16H 10 #define BRW_PREDICATE_ALIGN1_ALL16H 11 #define BRW_PREDICATE_ALIGN16_REPLICATE_X 2 #define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3 #define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4 #define BRW_PREDICATE_ALIGN16_REPLICATE_W 5 #define BRW_PREDICATE_ALIGN16_ANY4H 6 #define BRW_PREDICATE_ALIGN16_ALL4H 7 #define BRW_ARCHITECTURE_REGISTER_FILE 0 #define BRW_GENERAL_REGISTER_FILE 1 #define BRW_MESSAGE_REGISTER_FILE 2 #define BRW_IMMEDIATE_VALUE 3 #define BRW_REGISTER_TYPE_UD 0 #define BRW_REGISTER_TYPE_D 1 #define BRW_REGISTER_TYPE_UW 2 #define BRW_REGISTER_TYPE_W 3 #define BRW_REGISTER_TYPE_UB 4 #define BRW_REGISTER_TYPE_B 5 #define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ #define BRW_REGISTER_TYPE_HF 6 #define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ #define BRW_REGISTER_TYPE_F 7 #define BRW_ARF_NULL 0x00 #define BRW_ARF_ADDRESS 0x10 #define BRW_ARF_ACCUMULATOR 0x20 #define BRW_ARF_FLAG 0x30 #define BRW_ARF_MASK 0x40 #define BRW_ARF_MASK_STACK 0x50 #define BRW_ARF_MASK_STACK_DEPTH 0x60 #define BRW_ARF_STATE 0x70 #define BRW_ARF_CONTROL 0x80 #define BRW_ARF_NOTIFICATION_COUNT 0x90 #define BRW_ARF_IP 0xA0 #define BRW_AMASK 0 #define BRW_IMASK 1 #define BRW_LMASK 2 #define BRW_CMASK 3 #define BRW_THREAD_NORMAL 0 #define BRW_THREAD_ATOMIC 1 #define BRW_THREAD_SWITCH 2 #define BRW_VERTICAL_STRIDE_0 0 #define BRW_VERTICAL_STRIDE_1 1 #define BRW_VERTICAL_STRIDE_2 2 #define BRW_VERTICAL_STRIDE_4 3 #define BRW_VERTICAL_STRIDE_8 4 #define BRW_VERTICAL_STRIDE_16 5 #define BRW_VERTICAL_STRIDE_32 6 #define BRW_VERTICAL_STRIDE_64 7 #define BRW_VERTICAL_STRIDE_128 8 #define BRW_VERTICAL_STRIDE_256 9 #define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF #define BRW_WIDTH_1 0 #define BRW_WIDTH_2 1 #define BRW_WIDTH_4 2 #define BRW_WIDTH_8 3 #define BRW_WIDTH_16 4 #define BRW_STATELESS_BUFFER_BOUNDARY_1K 0 #define BRW_STATELESS_BUFFER_BOUNDARY_2K 1 #define BRW_STATELESS_BUFFER_BOUNDARY_4K 2 #define BRW_STATELESS_BUFFER_BOUNDARY_8K 3 #define BRW_STATELESS_BUFFER_BOUNDARY_16K 4 #define BRW_STATELESS_BUFFER_BOUNDARY_32K 5 #define BRW_STATELESS_BUFFER_BOUNDARY_64K 6 #define BRW_STATELESS_BUFFER_BOUNDARY_128K 7 #define BRW_STATELESS_BUFFER_BOUNDARY_256K 8 #define BRW_STATELESS_BUFFER_BOUNDARY_512K 9 #define BRW_STATELESS_BUFFER_BOUNDARY_1M 10 #define BRW_STATELESS_BUFFER_BOUNDARY_2M 11 #define BRW_POLYGON_FACING_FRONT 0 #define BRW_POLYGON_FACING_BACK 1 #define BRW_MESSAGE_TARGET_NULL 0 #define BRW_MESSAGE_TARGET_MATH 1 #define BRW_MESSAGE_TARGET_SAMPLER 2 #define BRW_MESSAGE_TARGET_GATEWAY 3 #define BRW_MESSAGE_TARGET_DATAPORT_READ 4 #define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5 #define BRW_MESSAGE_TARGET_URB 6 #define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7 #define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0 #define BRW_SAMPLER_RETURN_FORMAT_UINT32 2 #define BRW_SAMPLER_RETURN_FORMAT_SINT32 3 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 #define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 #define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2 #define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 #define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 #define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 #define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 #define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3 #define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 #define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 #define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 #define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 #define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 #define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 #define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0 #define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1 #define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 #define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 #define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 #define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 #define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 #define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 #define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 #define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 #define BRW_MATH_FUNCTION_INV 1 #define BRW_MATH_FUNCTION_LOG 2 #define BRW_MATH_FUNCTION_EXP 3 #define BRW_MATH_FUNCTION_SQRT 4 #define BRW_MATH_FUNCTION_RSQ 5 #define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ #define BRW_MATH_FUNCTION_COS 7 /* was 8 */ #define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ #define BRW_MATH_FUNCTION_TAN 9 #define BRW_MATH_FUNCTION_POW 10 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 #define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 #define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13 #define BRW_MATH_INTEGER_UNSIGNED 0 #define BRW_MATH_INTEGER_SIGNED 1 #define BRW_MATH_PRECISION_FULL 0 #define BRW_MATH_PRECISION_PARTIAL 1 #define BRW_MATH_SATURATE_NONE 0 #define BRW_MATH_SATURATE_SATURATE 1 #define BRW_MATH_DATA_VECTOR 0 #define BRW_MATH_DATA_SCALAR 1 #define BRW_URB_OPCODE_WRITE 0 #define BRW_URB_SWIZZLE_NONE 0 #define BRW_URB_SWIZZLE_INTERLEAVE 1 #define BRW_URB_SWIZZLE_TRANSPOSE 2 #define BRW_SCRATCH_SPACE_SIZE_1K 0 #define BRW_SCRATCH_SPACE_SIZE_2K 1 #define BRW_SCRATCH_SPACE_SIZE_4K 2 #define BRW_SCRATCH_SPACE_SIZE_8K 3 #define BRW_SCRATCH_SPACE_SIZE_16K 4 #define BRW_SCRATCH_SPACE_SIZE_32K 5 #define BRW_SCRATCH_SPACE_SIZE_64K 6 #define BRW_SCRATCH_SPACE_SIZE_128K 7 #define BRW_SCRATCH_SPACE_SIZE_256K 8 #define BRW_SCRATCH_SPACE_SIZE_512K 9 #define BRW_SCRATCH_SPACE_SIZE_1M 10 #define BRW_SCRATCH_SPACE_SIZE_2M 11 #define CMD_URB_FENCE 0x6000 #define CMD_CONST_BUFFER_STATE 0x6001 #define CMD_CONST_BUFFER 0x6002 #define CMD_STATE_BASE_ADDRESS 0x6101 #define CMD_STATE_INSN_POINTER 0x6102 #define CMD_PIPELINE_SELECT 0x6104 #define CMD_PIPELINED_STATE_POINTERS 0x7800 #define CMD_BINDING_TABLE_PTRS 0x7801 #define CMD_VERTEX_BUFFER 0x7808 #define CMD_VERTEX_ELEMENT 0x7809 #define CMD_INDEX_BUFFER 0x780a #define CMD_VF_STATISTICS 0x780b #define CMD_DRAW_RECT 0x7900 #define CMD_BLEND_CONSTANT_COLOR 0x7901 #define CMD_CHROMA_KEY 0x7904 #define CMD_DEPTH_BUFFER 0x7905 #define CMD_POLY_STIPPLE_OFFSET 0x7906 #define CMD_POLY_STIPPLE_PATTERN 0x7907 #define CMD_LINE_STIPPLE_PATTERN 0x7908 #define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7908 #define CMD_PIPE_CONTROL 0x7a00 #define CMD_3D_PRIM 0x7b00 #define CMD_MI_FLUSH 0x0200 /* Various values from the R0 vertex header: */ #define R02_PRIM_END 0x1 #define R02_PRIM_START 0x2 /* media pipeline */ #define BRW_VFE_MODE_GENERIC 0x0 #define BRW_VFE_MODE_VLD_MPEG2 0x1 #define BRW_VFE_MODE_IS 0x2 #define BRW_VFE_MODE_AVC_MC 0x4 #define BRW_VFE_MODE_AVC_IT 0x7 #define BRW_VFE_MODE_VC1_IT 0xB #define BRW_VFE_DEBUG_COUNTER_FREE 0 #define BRW_VFE_DEBUG_COUNTER_FROZEN 1 #define BRW_VFE_DEBUG_COUNTER_ONCE 2 #define BRW_VFE_DEBUG_COUNTER_ALWAYS 3 /* VLD_STATE */ #define BRW_MPEG_TOP_FIELD 1 #define BRW_MPEG_BOTTOM_FIELD 2 #define BRW_MPEG_FRAME 3 #define BRW_MPEG_QSCALE_LINEAR 0 #define BRW_MPEG_QSCALE_NONLINEAR 1 #define BRW_MPEG_ZIGZAG_SCAN 0 #define BRW_MPEG_ALTER_VERTICAL_SCAN 1 #define BRW_MPEG_I_PICTURE 1 #define BRW_MPEG_P_PICTURE 2 #define BRW_MPEG_B_PICTURE 3 #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/brw_structs.h000066400000000000000000001136111267532330400240050ustar00rootroot00000000000000 /************************************************************************** * * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 BRW_STRUCTS_H #define BRW_STRUCTS_H /* Command packets: */ struct header { unsigned int length:16; unsigned int opcode:16; }; union header_union { struct header bits; unsigned int dword; }; struct brw_3d_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:3; unsigned int wc_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } dest; unsigned int dword2; unsigned int dword3; }; struct brw_3d_primitive { struct { unsigned int length:8; unsigned int pad:2; unsigned int topology:5; unsigned int indexed:1; unsigned int opcode:16; } header; unsigned int verts_per_instance; unsigned int start_vert_location; unsigned int instance_count; unsigned int start_instance_location; unsigned int base_vert_location; }; /* These seem to be passed around as function args, so it works out * better to keep them as #defines: */ #define BRW_FLUSH_READ_CACHE 0x1 #define BRW_FLUSH_STATE_CACHE 0x2 #define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4 #define BRW_FLUSH_SNAPSHOT_COUNTERS 0x8 struct brw_mi_flush { unsigned int flags:4; unsigned int pad:12; unsigned int opcode:16; }; struct brw_vf_statistics { unsigned int statistics_enable:1; unsigned int pad:15; unsigned int opcode:16; }; struct brw_binding_table_pointers { struct header header; unsigned int vs; unsigned int gs; unsigned int clp; unsigned int sf; unsigned int wm; }; struct brw_blend_constant_color { struct header header; float blend_constant_color[4]; }; struct brw_depthbuffer { union header_union header; union { struct { unsigned int pitch:18; unsigned int format:3; unsigned int pad:4; unsigned int depth_offset_disable:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad2:1; unsigned int surface_type:3; } bits; unsigned int dword; } dword1; unsigned int dword2_base_addr; union { struct { unsigned int pad:1; unsigned int mipmap_layout:1; unsigned int lod:4; unsigned int width:13; unsigned int height:13; } bits; unsigned int dword; } dword3; union { struct { unsigned int pad:12; unsigned int min_array_element:9; unsigned int depth:11; } bits; unsigned int dword; } dword4; }; struct brw_drawrect { struct header header; unsigned int xmin:16; unsigned int ymin:16; unsigned int xmax:16; unsigned int ymax:16; unsigned int xorg:16; unsigned int yorg:16; }; struct brw_global_depth_offset_clamp { struct header header; float depth_offset_clamp; }; struct brw_indexbuffer { union { struct { unsigned int length:8; unsigned int index_format:2; unsigned int cut_index_enable:1; unsigned int pad:5; unsigned int opcode:16; } bits; unsigned int dword; } header; unsigned int buffer_start; unsigned int buffer_end; }; struct brw_line_stipple { struct header header; struct { unsigned int pattern:16; unsigned int pad:16; } bits0; struct { unsigned int repeat_count:9; unsigned int pad:7; unsigned int inverse_repeat_count:16; } bits1; }; struct brw_pipelined_state_pointers { struct header header; struct { unsigned int pad:5; unsigned int offset:27; } vs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } gs; struct { unsigned int enable:1; unsigned int pad:4; unsigned int offset:27; } clp; struct { unsigned int pad:5; unsigned int offset:27; } sf; struct { unsigned int pad:5; unsigned int offset:27; } wm; struct { unsigned int pad:5; unsigned int offset:27; /* KW: check me! */ } cc; }; struct brw_polygon_stipple_offset { struct header header; struct { unsigned int y_offset:5; unsigned int pad:3; unsigned int x_offset:5; unsigned int pad0:19; } bits0; }; struct brw_polygon_stipple { struct header header; unsigned int stipple[32]; }; struct brw_pipeline_select { struct { unsigned int pipeline_select:1; unsigned int pad:15; unsigned int opcode:16; } header; }; struct brw_pipe_control { struct { unsigned int length:8; unsigned int notify_enable:1; unsigned int pad:2; unsigned int instruction_state_cache_flush_enable:1; unsigned int write_cache_flush_enable:1; unsigned int depth_stall_enable:1; unsigned int post_sync_operation:2; unsigned int opcode:16; } header; struct { unsigned int pad:2; unsigned int dest_addr_type:1; unsigned int dest_addr:29; } bits1; unsigned int data0; unsigned int data1; }; struct brw_urb_fence { struct { unsigned int length:8; unsigned int vs_realloc:1; unsigned int gs_realloc:1; unsigned int clp_realloc:1; unsigned int sf_realloc:1; unsigned int vfe_realloc:1; unsigned int cs_realloc:1; unsigned int pad:2; unsigned int opcode:16; } header; struct { unsigned int vs_fence:10; unsigned int gs_fence:10; unsigned int clp_fence:10; unsigned int pad:2; } bits0; struct { unsigned int sf_fence:10; unsigned int vf_fence:10; unsigned int cs_fence:10; unsigned int pad:2; } bits1; }; struct brw_constant_buffer_state /* previously brw_command_streamer */ { struct header header; struct { unsigned int nr_urb_entries:3; unsigned int pad:1; unsigned int urb_entry_size:5; unsigned int pad0:23; } bits0; }; struct brw_constant_buffer { struct { unsigned int length:8; unsigned int valid:1; unsigned int pad:7; unsigned int opcode:16; } header; struct { unsigned int buffer_length:6; unsigned int buffer_address:26; } bits0; }; struct brw_state_base_address { struct header header; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int general_state_address:27; } bits0; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int surface_state_address:27; } bits1; struct { unsigned int modify_enable:1; unsigned int pad:4; unsigned int indirect_object_state_address:27; } bits2; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int general_state_upper_bound:20; } bits3; struct { unsigned int modify_enable:1; unsigned int pad:11; unsigned int indirect_object_state_upper_bound:20; } bits4; }; struct brw_state_prefetch { struct header header; struct { unsigned int prefetch_count:3; unsigned int pad:3; unsigned int prefetch_pointer:26; } bits0; }; struct brw_system_instruction_pointer { struct header header; struct { unsigned int pad:4; unsigned int system_instruction_pointer:28; } bits0; }; /* State structs for the various fixed function units: */ struct thread0 { unsigned int pad0:1; unsigned int grf_reg_count:3; unsigned int pad1:2; unsigned int kernel_start_pointer:26; }; struct thread1 { unsigned int ext_halt_exception_enable:1; unsigned int sw_exception_enable:1; unsigned int mask_stack_exception_enable:1; unsigned int timeout_exception_enable:1; unsigned int illegal_op_exception_enable:1; unsigned int pad0:3; unsigned int depth_coef_urb_read_offset:6; /* WM only */ unsigned int pad1:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad3:5; unsigned int single_program_flow:1; }; struct thread2 { unsigned int per_thread_scratch_space:4; unsigned int pad0:6; unsigned int scratch_space_base_pointer:22; }; struct thread3 { unsigned int dispatch_grf_start_reg:4; unsigned int urb_entry_read_offset:6; unsigned int pad0:1; unsigned int urb_entry_read_length:6; unsigned int pad1:1; unsigned int const_urb_entry_read_offset:6; unsigned int pad2:1; unsigned int const_urb_entry_read_length:6; unsigned int pad3:1; }; struct brw_clip_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:9; unsigned int gs_output_stats:1; /* not always */ unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; /* may be less */ unsigned int pad3:1; } thread4; struct { unsigned int pad0:13; unsigned int clip_mode:3; unsigned int userclip_enable_flags:8; unsigned int userclip_must_clip:1; unsigned int pad1:1; unsigned int guard_band_enable:1; unsigned int viewport_z_clip_enable:1; unsigned int viewport_xy_clip_enable:1; unsigned int vertex_position_space:1; unsigned int api_mode:1; unsigned int pad2:1; } clip5; struct { unsigned int pad0:5; unsigned int clipper_viewport_state_ptr:27; } clip6; float viewport_xmin; float viewport_xmax; float viewport_ymin; float viewport_ymax; }; struct brw_cc_unit_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } cc0; struct { unsigned int bf_stencil_ref:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; unsigned int stencil_ref:8; } cc1; struct { unsigned int logicop_enable:1; unsigned int pad0:10; unsigned int depth_write_enable:1; unsigned int depth_test_function:3; unsigned int depth_test:1; unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; } cc2; struct { unsigned int pad0:8; unsigned int alpha_test_func:3; unsigned int alpha_test:1; unsigned int blend_enable:1; unsigned int ia_blend_enable:1; unsigned int pad1:1; unsigned int alpha_test_format:1; unsigned int pad2:16; } cc3; struct { unsigned int pad0:5; unsigned int cc_viewport_state_offset:27; } cc4; struct { unsigned int pad0:2; unsigned int ia_dest_blend_factor:5; unsigned int ia_src_blend_factor:5; unsigned int ia_blend_function:3; unsigned int statistics_enable:1; unsigned int logicop_func:4; unsigned int pad1:11; unsigned int dither_enable:1; } cc5; struct { unsigned int clamp_post_alpha_blend:1; unsigned int clamp_pre_alpha_blend:1; unsigned int clamp_range:2; unsigned int pad0:11; unsigned int y_dither_offset:2; unsigned int x_dither_offset:2; unsigned int dest_blend_factor:5; unsigned int src_blend_factor:5; unsigned int blend_function:3; } cc6; struct { union { float f; unsigned char ub[4]; } alpha_ref; } cc7; }; struct brw_sf_unit_state { struct thread0 thread0; struct { unsigned int pad0:7; unsigned int sw_exception_enable:1; unsigned int pad1:3; unsigned int mask_stack_exception_enable:1; unsigned int pad2:1; unsigned int illegal_op_exception_enable:1; unsigned int pad3:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int binding_table_entry_count:8; unsigned int pad4:5; unsigned int single_program_flow:1; } sf1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:6; unsigned int pad3:1; } thread4; struct { unsigned int front_winding:1; unsigned int viewport_transform:1; unsigned int pad0:3; unsigned int sf_viewport_state_offset:27; } sf5; struct { unsigned int pad0:9; unsigned int dest_org_vbias:4; unsigned int dest_org_hbias:4; unsigned int scissor:1; unsigned int disable_2x2_trifilter:1; unsigned int disable_zero_pix_trifilter:1; unsigned int point_rast_rule:2; unsigned int line_endcap_aa_region_width:2; unsigned int line_width:4; unsigned int fast_scissor_disable:1; unsigned int cull_mode:2; unsigned int aa_enable:1; } sf6; struct { unsigned int point_size:11; unsigned int use_point_size_state:1; unsigned int subpixel_precision:1; unsigned int sprite_point:1; unsigned int pad0:11; unsigned int trifan_pv:2; unsigned int linestrip_pv:2; unsigned int tristrip_pv:2; unsigned int line_last_pixel_enable:1; } sf7; }; struct brw_gs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:1; unsigned int pad3:6; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } gs5; struct { unsigned int max_vp_index:4; unsigned int pad0:26; unsigned int reorder_enable:1; unsigned int pad1:1; } gs6; }; struct brw_vs_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int pad0:10; unsigned int stats_enable:1; unsigned int nr_urb_entries:7; unsigned int pad1:1; unsigned int urb_entry_allocation_size:5; unsigned int pad2:1; unsigned int max_threads:4; unsigned int pad3:3; } thread4; struct { unsigned int sampler_count:3; unsigned int pad0:2; unsigned int sampler_state_pointer:27; } vs5; struct { unsigned int vs_enable:1; unsigned int vert_cache_disable:1; unsigned int pad0:30; } vs6; }; struct brw_wm_unit_state { struct thread0 thread0; struct thread1 thread1; struct thread2 thread2; struct thread3 thread3; struct { unsigned int stats_enable:1; unsigned int pad0:1; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } wm4; struct { unsigned int enable_8_pix:1; unsigned int enable_16_pix:1; unsigned int enable_32_pix:1; unsigned int pad0:7; unsigned int legacy_global_depth_bias:1; unsigned int line_stipple:1; unsigned int depth_offset:1; unsigned int polygon_stipple:1; unsigned int line_aa_region_width:2; unsigned int line_endcap_aa_region_width:2; unsigned int early_depth_test:1; unsigned int thread_dispatch_enable:1; unsigned int program_uses_depth:1; unsigned int program_computes_depth:1; unsigned int program_uses_killpixel:1; unsigned int legacy_line_rast: 1; unsigned int transposed_urb_read:1; unsigned int max_threads:7; } wm5; float global_depth_offset_constant; float global_depth_offset_scale; struct { unsigned int pad0:1; unsigned int grf_reg_count_1:3; unsigned int pad1:2; unsigned int kernel_start_pointer_1:26; } wm8; struct { unsigned int pad0:1; unsigned int grf_reg_count_2:3; unsigned int pad1:2; unsigned int kernel_start_pointer_2:26; } wm9; struct { unsigned int pad0:1; unsigned int grf_reg_count_3:3; unsigned int pad1:2; unsigned int kernel_start_pointer_3:26; } wm10; }; struct brw_wm_unit_state_padded { struct brw_wm_unit_state state; char pad[64 - sizeof(struct brw_wm_unit_state)]; }; /* The hardware supports two different modes for border color. The * default (OpenGL) mode uses floating-point color channels, while the * legacy mode uses 4 bytes. * * More significantly, the legacy mode respects the components of the * border color for channels not present in the source, (whereas the * default mode will ignore the border color's alpha channel and use * alpha==1 for an RGB source, for example). * * The legacy mode matches the semantics specified by the Render * extension. */ struct brw_sampler_default_border_color { float color[4]; }; struct brw_sampler_legacy_border_color { uint8_t color[4]; }; struct brw_sampler_state { struct { unsigned int shadow_function:3; unsigned int lod_bias:11; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad:1; unsigned int lod_preclamp:1; unsigned int border_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:3; unsigned int max_lod:10; unsigned int min_lod:10; } ss1; struct { unsigned int pad:5; unsigned int border_color_pointer:27; } ss2; struct { unsigned int pad:19; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int monochrome_filter_width:3; unsigned int monochrome_filter_height:3; } ss3; }; struct brw_clipper_viewport { float xmin; float xmax; float ymin; float ymax; }; struct brw_cc_viewport { float min_depth; float max_depth; }; struct brw_sf_viewport { struct { float m00; float m11; float m22; float m30; float m31; float m32; } viewport; struct { short xmin; short ymin; short xmax; short ymax; } scissor; }; /* Documented in the subsystem/shared-functions/sampler chapter... */ struct brw_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad:3; unsigned int render_cache_read_mode:1; unsigned int mipmap_layout_mode:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int color_blend:1; unsigned int writedisable_blue:1; unsigned int writedisable_green:1; unsigned int writedisable_red:1; unsigned int writedisable_alpha:1; unsigned int surface_format:9; unsigned int data_return_format:1; unsigned int pad0:1; unsigned int surface_type:3; } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int render_target_rotation:2; unsigned int mip_count:4; unsigned int width:13; unsigned int height:13; } ss2; struct { unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int pad:1; unsigned int pitch:18; unsigned int depth:11; } ss3; struct { unsigned int pad:19; unsigned int min_array_elt:9; unsigned int min_lod:4; } ss4; struct { unsigned int pad:20; unsigned int y_offset:4; unsigned int pad2:1; unsigned int x_offset:7; } ss5; }; struct brw_vertex_buffer_state { struct { unsigned int pitch:11; unsigned int pad:15; unsigned int access_type:1; unsigned int vb_index:5; } vb0; unsigned int start_addr; unsigned int max_index; #if 1 unsigned int instance_data_step_rate; /* not included for sequential/random vertices? */ #endif }; #define BRW_VBP_MAX 17 struct brw_vb_array_state { struct header header; struct brw_vertex_buffer_state vb[BRW_VBP_MAX]; }; struct brw_vertex_element_state { struct { unsigned int src_offset:11; unsigned int pad:5; unsigned int src_format:9; unsigned int pad0:1; unsigned int valid:1; unsigned int vertex_buffer_index:5; } ve0; struct { unsigned int dst_offset:8; unsigned int pad:8; unsigned int vfcomponent3:4; unsigned int vfcomponent2:4; unsigned int vfcomponent1:4; unsigned int vfcomponent0:4; } ve1; }; #define BRW_VEP_MAX 18 struct brw_vertex_element_packet { struct header header; struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */ }; struct brw_urb_immediate { unsigned int opcode:4; unsigned int offset:6; unsigned int swizzle_control:2; unsigned int pad:1; unsigned int allocate:1; unsigned int used:1; unsigned int complete:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; }; /* Instruction format for the execution units: */ struct brw_instruction { struct { unsigned int opcode:7; unsigned int pad:1; unsigned int access_mode:1; unsigned int mask_control:1; unsigned int dependency_control:2; unsigned int compression_control:2; unsigned int thread_control:2; unsigned int predicate_control:4; unsigned int predicate_inverse:1; unsigned int execution_size:3; unsigned int destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */ unsigned int pad0:2; unsigned int debug_control:1; unsigned int saturate:1; } header; union { struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad:1; unsigned int dest_subreg_nr:5; unsigned int dest_reg_nr:8; unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } da1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad:6; int dest_indirect_offset:10; /* offset against the deref'd address reg */ unsigned int dest_subreg_nr:3; /* subnr for the address reg a0.x */ unsigned int dest_horiz_stride:2; unsigned int dest_address_mode:1; } ia1; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int src1_reg_file:2; unsigned int src1_reg_type:3; unsigned int pad0:1; unsigned int dest_writemask:4; unsigned int dest_subreg_nr:1; unsigned int dest_reg_nr:8; unsigned int pad1:2; unsigned int dest_address_mode:1; } da16; struct { unsigned int dest_reg_file:2; unsigned int dest_reg_type:3; unsigned int src0_reg_file:2; unsigned int src0_reg_type:3; unsigned int pad0:6; unsigned int dest_writemask:4; int dest_indirect_offset:6; unsigned int dest_subreg_nr:3; unsigned int pad1:2; unsigned int dest_address_mode:1; } ia16; } bits1; union { struct { unsigned int src0_subreg_nr:5; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } da1; struct { int src0_indirect_offset:10; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_horiz_stride:2; unsigned int src0_width:3; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad:6; } ia1; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; unsigned int src0_subreg_nr:1; unsigned int src0_reg_nr:8; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } da16; struct { unsigned int src0_swz_x:2; unsigned int src0_swz_y:2; int src0_indirect_offset:6; unsigned int src0_subreg_nr:3; unsigned int src0_abs:1; unsigned int src0_negate:1; unsigned int src0_address_mode:1; unsigned int src0_swz_z:2; unsigned int src0_swz_w:2; unsigned int pad0:1; unsigned int src0_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia16; } bits2; union { struct { unsigned int src1_subreg_nr:5; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int pad0:7; } da1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; unsigned int src1_subreg_nr:1; unsigned int src1_reg_nr:8; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int pad2:7; } da16; struct { int src1_indirect_offset:10; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_horiz_stride:2; unsigned int src1_width:3; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad1:6; } ia1; struct { unsigned int src1_swz_x:2; unsigned int src1_swz_y:2; int src1_indirect_offset:6; unsigned int src1_subreg_nr:3; unsigned int src1_abs:1; unsigned int src1_negate:1; unsigned int pad0:1; unsigned int src1_swz_z:2; unsigned int src1_swz_w:2; unsigned int pad1:1; unsigned int src1_vert_stride:4; unsigned int flag_reg_nr:1; unsigned int pad2:6; } ia16; struct { int jump_count:16; /* note: signed */ unsigned int pop_count:4; unsigned int pad0:12; } if_else; struct { unsigned int function:4; unsigned int int_type:1; unsigned int precision:1; unsigned int saturate:1; unsigned int data_type:1; unsigned int pad0:8; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } math; struct { unsigned int binding_table_index:8; unsigned int sampler:4; unsigned int return_format:2; unsigned int msg_type:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } sampler; struct brw_urb_immediate urb; struct { unsigned int binding_table_index:8; unsigned int msg_control:4; unsigned int msg_type:2; unsigned int target_cache:2; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_read; struct { unsigned int binding_table_index:8; unsigned int msg_control:3; unsigned int pixel_scoreboard_clear:1; unsigned int msg_type:3; unsigned int send_commit_msg:1; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } dp_write; struct { unsigned int pad:16; unsigned int response_length:4; unsigned int msg_length:4; unsigned int msg_target:4; unsigned int pad1:3; unsigned int end_of_thread:1; } generic; unsigned int ud; } bits3; }; /* media pipeline */ struct brw_vfe_state { struct { unsigned int per_thread_scratch_space:4; unsigned int pad3:3; unsigned int extend_vfe_state_present:1; unsigned int pad2:2; unsigned int scratch_base:22; } vfe0; struct { unsigned int debug_counter_control:2; unsigned int children_present:1; unsigned int vfe_mode:4; unsigned int pad2:2; unsigned int num_urb_entries:7; unsigned int urb_entry_alloc_size:9; unsigned int max_threads:7; } vfe1; struct { unsigned int pad4:4; unsigned int interface_descriptor_base:28; } vfe2; }; struct brw_vld_state { struct { unsigned int pad6:6; unsigned int scan_order:1; unsigned int intra_vlc_format:1; unsigned int quantizer_scale_type:1; unsigned int concealment_motion_vector:1; unsigned int frame_predict_frame_dct:1; unsigned int top_field_first:1; unsigned int picture_structure:2; unsigned int intra_dc_precision:2; unsigned int f_code_0_0:4; unsigned int f_code_0_1:4; unsigned int f_code_1_0:4; unsigned int f_code_1_1:4; } vld0; struct { unsigned int pad2:9; unsigned int picture_coding_type:2; unsigned int pad:21; } vld1; struct { unsigned int index_0:4; unsigned int index_1:4; unsigned int index_2:4; unsigned int index_3:4; unsigned int index_4:4; unsigned int index_5:4; unsigned int index_6:4; unsigned int index_7:4; } desc_remap_table0; struct { unsigned int index_8:4; unsigned int index_9:4; unsigned int index_10:4; unsigned int index_11:4; unsigned int index_12:4; unsigned int index_13:4; unsigned int index_14:4; unsigned int index_15:4; } desc_remap_table1; }; struct brw_interface_descriptor { struct { unsigned int grf_reg_blocks:4; unsigned int pad:2; unsigned int kernel_start_pointer:26; } desc0; struct { unsigned int pad:7; unsigned int software_exception:1; unsigned int pad2:3; unsigned int maskstack_exception:1; unsigned int pad3:1; unsigned int illegal_opcode_exception:1; unsigned int pad4:2; unsigned int floating_point_mode:1; unsigned int thread_priority:1; unsigned int single_program_flow:1; unsigned int pad5:1; unsigned int const_urb_entry_read_offset:6; unsigned int const_urb_entry_read_len:6; } desc1; struct { unsigned int pad:2; unsigned int sampler_count:3; unsigned int sampler_state_pointer:27; } desc2; struct { unsigned int binding_table_entry_count:5; unsigned int binding_table_pointer:27; } desc3; }; struct gen6_blend_state { struct { unsigned int dest_blend_factor:5; unsigned int source_blend_factor:5; unsigned int pad3:1; unsigned int blend_func:3; unsigned int pad2:1; unsigned int ia_dest_blend_factor:5; unsigned int ia_source_blend_factor:5; unsigned int pad1:1; unsigned int ia_blend_func:3; unsigned int pad0:1; unsigned int ia_blend_enable:1; unsigned int blend_enable:1; } blend0; struct { unsigned int post_blend_clamp_enable:1; unsigned int pre_blend_clamp_enable:1; unsigned int clamp_range:2; unsigned int pad0:4; unsigned int x_dither_offset:2; unsigned int y_dither_offset:2; unsigned int dither_enable:1; unsigned int alpha_test_func:3; unsigned int alpha_test_enable:1; unsigned int pad1:1; unsigned int logic_op_func:4; unsigned int logic_op_enable:1; unsigned int pad2:1; unsigned int write_disable_b:1; unsigned int write_disable_g:1; unsigned int write_disable_r:1; unsigned int write_disable_a:1; unsigned int pad3:1; unsigned int alpha_to_coverage_dither:1; unsigned int alpha_to_one:1; unsigned int alpha_to_coverage:1; } blend1; }; struct gen6_color_calc_state { struct { unsigned int alpha_test_format:1; unsigned int pad0:14; unsigned int round_disable:1; unsigned int bf_stencil_ref:8; unsigned int stencil_ref:8; } cc0; union { float alpha_ref_f; struct { unsigned int ui:8; unsigned int pad0:24; } alpha_ref_fi; } cc1; float constant_r; float constant_g; float constant_b; float constant_a; }; struct gen6_depth_stencil_state { struct { unsigned int pad0:3; unsigned int bf_stencil_pass_depth_pass_op:3; unsigned int bf_stencil_pass_depth_fail_op:3; unsigned int bf_stencil_fail_op:3; unsigned int bf_stencil_func:3; unsigned int bf_stencil_enable:1; unsigned int pad1:2; unsigned int stencil_write_enable:1; unsigned int stencil_pass_depth_pass_op:3; unsigned int stencil_pass_depth_fail_op:3; unsigned int stencil_fail_op:3; unsigned int stencil_func:3; unsigned int stencil_enable:1; } ds0; struct { unsigned int bf_stencil_write_mask:8; unsigned int bf_stencil_test_mask:8; unsigned int stencil_write_mask:8; unsigned int stencil_test_mask:8; } ds1; struct { unsigned int pad0:26; unsigned int depth_write_enable:1; unsigned int depth_test_func:3; unsigned int pad1:1; unsigned int depth_test_enable:1; } ds2; }; struct gen7_surface_state { struct { unsigned int cube_pos_z:1; unsigned int cube_neg_z:1; unsigned int cube_pos_y:1; unsigned int cube_neg_y:1; unsigned int cube_pos_x:1; unsigned int cube_neg_x:1; unsigned int pad2:2; unsigned int render_cache_read_write:1; unsigned int pad1:1; unsigned int surface_array_spacing:1; unsigned int vert_line_stride_ofs:1; unsigned int vert_line_stride:1; unsigned int tile_walk:1; unsigned int tiled_surface:1; unsigned int horizontal_alignment:1; unsigned int vertical_alignment:2; unsigned int surface_format:9; /**< BRW_SURFACEFORMAT_x */ unsigned int pad0:1; unsigned int is_array:1; unsigned int surface_type:3; /**< BRW_SURFACE_1D/2D/3D/CUBE */ } ss0; struct { unsigned int base_addr; } ss1; struct { unsigned int width:14; unsigned int pad1:2; unsigned int height:14; unsigned int pad0:2; } ss2; struct { unsigned int pitch:18; unsigned int pad:3; unsigned int depth:11; } ss3; struct { unsigned int multisample_position_palette_index:3; unsigned int num_multisamples:3; unsigned int multisampled_surface_storage_format:1; unsigned int render_target_view_extent:11; unsigned int min_array_elt:11; unsigned int rotation:2; unsigned int pad0:1; } ss4; struct { unsigned int mip_count:4; unsigned int min_lod:4; unsigned int pad1:12; unsigned int y_offset:4; unsigned int pad0:1; unsigned int x_offset:7; } ss5; struct { unsigned int pad; /* Multisample Control Surface stuff */ } ss6; struct { unsigned int resource_min_lod:12; unsigned int pad0:4; unsigned int shader_chanel_select_a:3; unsigned int shader_chanel_select_b:3; unsigned int shader_chanel_select_g:3; unsigned int shader_chanel_select_r:3; unsigned int alpha_clear_color:1; unsigned int blue_clear_color:1; unsigned int green_clear_color:1; unsigned int red_clear_color:1; } ss7; }; struct gen7_sampler_state { struct { unsigned int aniso_algorithm:1; unsigned int lod_bias:13; unsigned int min_filter:3; unsigned int mag_filter:3; unsigned int mip_filter:2; unsigned int base_level:5; unsigned int pad1:1; unsigned int lod_preclamp:1; unsigned int default_color_mode:1; unsigned int pad0:1; unsigned int disable:1; } ss0; struct { unsigned int cube_control_mode:1; unsigned int shadow_function:3; unsigned int pad:4; unsigned int max_lod:12; unsigned int min_lod:12; } ss1; struct { unsigned int pad:5; unsigned int default_color_pointer:27; } ss2; struct { unsigned int r_wrap_mode:3; unsigned int t_wrap_mode:3; unsigned int s_wrap_mode:3; unsigned int pad:1; unsigned int non_normalized_coord:1; unsigned int trilinear_quality:2; unsigned int address_round:6; unsigned int max_aniso:3; unsigned int chroma_key_mode:1; unsigned int chroma_key_index:2; unsigned int chroma_key_enable:1; unsigned int pad0:6; } ss3; }; #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i830_reg.h000066400000000000000000000703031267532330400227440ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 _I830_REG_H_ #define _I830_REG_H_ #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) /* Flush */ #define MI_FLUSH (0x04<<23) #define MI_FLUSH_DW (0x26<<23) #define MI_WRITE_DIRTY_STATE (1<<4) #define MI_END_SCENE (1<<3) #define MI_GLOBAL_SNAPSHOT_COUNT_RESET (1<<3) #define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2) #define MI_STATE_INSTRUCTION_CACHE_FLUSH (1<<1) #define MI_INVALIDATE_MAP_CACHE (1<<0) /* broadwater flush bits */ #define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3) #define MI_BATCH_BUFFER_END (0xA << 23) /* Noop */ #define MI_NOOP 0x00 #define MI_NOOP_WRITE_ID (1<<22) #define MI_NOOP_ID_MASK (1<<22 - 1) /* Wait for Events */ #define MI_WAIT_FOR_EVENT (0x03<<23) #define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18) #define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17) #define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) #define MI_WAIT_FOR_PIPEB_VBLANK (1<<7) #define MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW (1<<5) #define MI_WAIT_FOR_PIPEA_VBLANK (1<<3) #define MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW (1<<1) /* Set the scan line for MI_WAIT_FOR_PIPE?_SCAN_LINE_WINDOW */ #define MI_LOAD_SCAN_LINES_INCL (0x12<<23) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEA (0) #define MI_LOAD_SCAN_LINES_DISPLAY_PIPEB (0x1<<20) /* BLT commands */ #define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) #define COLOR_BLT_WRITE_ALPHA (1<<21) #define COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4)) #define XY_COLOR_BLT_WRITE_ALPHA (1<<21) #define XY_COLOR_BLT_WRITE_RGB (1<<20) #define XY_COLOR_BLT_TILED (1<<11) #define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1) #define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_SRC_COPY_BLT_SRC_TILED (1<<15) #define XY_SRC_COPY_BLT_DST_TILED (1<<11) #define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4) #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define SRC_COPY_BLT_WRITE_RGB (1<<20) #define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22)) #define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7) #define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) #define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) #define XY_MONO_PAT_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_PAT_BLT_WRITE_RGB (1<<20) #define XY_MONO_SRC_BLT_CMD ((0x2<<29)|(0x54<<22)|(0x6)) #define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21) #define XY_MONO_SRC_BLT_WRITE_RGB (1<<20) #define CMD_3D (0x3<<29) #define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) #define PRIM3D_TRILIST (0x0<<18) #define PRIM3D_TRISTRIP (0x1<<18) #define PRIM3D_TRISTRIP_RVRSE (0x2<<18) #define PRIM3D_TRIFAN (0x3<<18) #define PRIM3D_POLY (0x4<<18) #define PRIM3D_LINELIST (0x5<<18) #define PRIM3D_LINESTRIP (0x6<<18) #define PRIM3D_RECTLIST (0x7<<18) #define PRIM3D_POINTLIST (0x8<<18) #define PRIM3D_DIB (0x9<<18) #define PRIM3D_CLEAR_RECT (0xa<<18) #define PRIM3D_ZONE_INIT (0xd<<18) #define PRIM3D_MASK (0x1f<<18) #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) #define AA_LINE_ENABLE ((1<<1) | 1) #define AA_LINE_DISABLE (1<<1) #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) #define BUF_3D_PITCH(x) (((x)/4)<<2) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) #define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) #define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ ((0x90+(stage))<<16)) #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) #define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define DEPTH_IS_Z 0 #define DEPTH_IS_W (1<<6) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 0 #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((x)<<16) #define DRAW_XMIN(x) (x) /* Dword 3 */ #define DRAW_YMAX(x) ((x)<<16) #define DRAW_XMAX(x) (x) /* Dword 4 */ #define DRAW_YORG(x) ((x)<<16) #define DRAW_XORG(x) (x) #define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) #define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) #define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) #define DISABLE_LOGIC_OP (1<<23) #define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) #define DISABLE_STENCIL_TEST (1<<21) #define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) #define DISABLE_DEPTH_BIAS (1<<11) #define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) #define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) #define DISABLE_SPEC_ADD (1<<9) #define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) #define ENABLE_FOG ((1<<7)|(1<<6)) #define DISABLE_FOG (1<<7) #define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) #define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) #define DISABLE_ALPHA_TEST (1<<5) #define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) #define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) #define DISABLE_COLOR_BLEND (1<<3) #define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) #define ENABLE_DEPTH_TEST ((1<<1)|1) #define DISABLE_DEPTH_TEST (1<<1) /* _3DSTATE_ENABLES_2, p138 */ #define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) #define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) #define DISABLE_STENCIL_WRITE (1<<21) #define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) #define DISABLE_TEX_CACHE (1<<17) #define ENABLE_DITHER ((1<<9)|(1<<8)) #define DISABLE_DITHER (1<<9) #define ENABLE_COLOR_MASK (1<<10) #define WRITEMASK_ALPHA (1<<7) #define WRITEMASK_ALPHA_SHIFT 7 #define WRITEMASK_RED (1<<6) #define WRITEMASK_RED_SHIFT 6 #define WRITEMASK_GREEN (1<<5) #define WRITEMASK_GREEN_SHIFT 5 #define WRITEMASK_BLUE (1<<4) #define WRITEMASK_BLUE_SHIFT 4 #define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) #define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) #define DISABLE_COLOR_WRITE (1<<3) #define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 #define ENABLE_DEPTH_WRITE ((1<<1)|1) #define DISABLE_DEPTH_WRITE (1<<1) /* _3DSTATE_FOG_COLOR, p139 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p140 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FOGFUNC_ENABLE (1<<31) #define FOGFUNC_VERTEX 0 #define FOGFUNC_PIXEL_EXP (1<<28) #define FOGFUNC_PIXEL_EXP2 (2<<28) #define FOGFUNC_PIXEL_LINEAR (3<<28) #define FOGSRC_INDEX_Z (1<<27) #define FOGSRC_INDEX_W ((1<<27)|(1<<25)) #define FOG_LINEAR_CONST (1<<24) #define FOG_CONST_1(x) ((x)<<4) #define ENABLE_FOG_DENSITY (1<<23) /* Dword 2 */ #define FOG_CONST_2(x) (x) /* Dword 3 */ #define FOG_DENSITY(x) (x) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ #define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) #define DISABLE_INDPT_ALPHA_BLEND (1<<23) #define ALPHA_BLENDFUNC_MASK 0x3f0000 #define ENABLE_ALPHA_BLENDFUNC (1<<21) #define ABLENDFUNC_ADD 0 #define ABLENDFUNC_SUB (1<<16) #define ABLENDFUNC_RVSE_SUB (2<<16) #define ABLENDFUNC_MIN (3<<16) #define ABLENDFUNC_MAX (4<<16) #define SRC_DST_ABLEND_MASK 0xfff #define ENABLE_SRC_ABLEND_FACTOR (1<<11) #define SRC_ABLEND_FACT(x) ((x)<<6) #define ENABLE_DST_ABLEND_FACTOR (1<<5) #define DST_ABLEND_FACT(x) (x) #define BLENDFACTOR_ZERO 0x01 #define BLENDFACTOR_ONE 0x02 #define BLENDFACTOR_SRC_COLR 0x03 #define BLENDFACTOR_INV_SRC_COLR 0x04 #define BLENDFACTOR_SRC_ALPHA 0x05 #define BLENDFACTOR_INV_SRC_ALPHA 0x06 #define BLENDFACTOR_DST_ALPHA 0x07 #define BLENDFACTOR_INV_DST_ALPHA 0x08 #define BLENDFACTOR_DST_COLR 0x09 #define BLENDFACTOR_INV_DST_COLR 0x0a #define BLENDFACTOR_SRC_ALPHA_SATURATE 0x0b #define BLENDFACTOR_CONST_COLOR 0x0c #define BLENDFACTOR_INV_CONST_COLOR 0x0d #define BLENDFACTOR_CONST_ALPHA 0x0e #define BLENDFACTOR_INV_CONST_ALPHA 0x0f #define BLENDFACTOR_MASK 0x0f /* _3DSTATE_MAP_BLEND_ARG, p152 */ #define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) #define TEXPIPE_COLOR 0 #define TEXPIPE_ALPHA (1<<18) #define TEXPIPE_KILL (2<<18) #define TEXBLEND_ARG0 0 #define TEXBLEND_ARG1 (1<<15) #define TEXBLEND_ARG2 (2<<15) #define TEXBLEND_ARG3 (3<<15) #define TEXBLENDARG_MODIFY_PARMS (1<<6) #define TEXBLENDARG_REPLICATE_ALPHA (1<<5) #define TEXBLENDARG_INV_ARG (1<<4) #define TEXBLENDARG_ONE 0 #define TEXBLENDARG_FACTOR 0x01 #define TEXBLENDARG_ACCUM 0x02 #define TEXBLENDARG_DIFFUSE 0x03 #define TEXBLENDARG_SPEC 0x04 #define TEXBLENDARG_CURRENT 0x05 #define TEXBLENDARG_TEXEL0 0x06 #define TEXBLENDARG_TEXEL1 0x07 #define TEXBLENDARG_TEXEL2 0x08 #define TEXBLENDARG_TEXEL3 0x09 #define TEXBLENDARG_FACTOR_N 0x0e /* _3DSTATE_MAP_BLEND_OP, p155 */ #define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) #if 0 # define TEXPIPE_COLOR 0 # define TEXPIPE_ALPHA (1<<18) # define TEXPIPE_KILL (2<<18) #endif #define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) #define TEXOP_OUTPUT_CURRENT 0 #define TEXOP_OUTPUT_ACCUM (1<<15) #define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) #define DISABLE_TEX_CNTRL_STAGE (1<<12) #define TEXOP_SCALE_SHIFT 9 #define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) #define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) #define TEXOP_MODIFY_PARMS (1<<8) #define TEXOP_LAST_STAGE (1<<7) #define TEXBLENDOP_KILLPIXEL 0x02 #define TEXBLENDOP_ARG1 0x01 #define TEXBLENDOP_ARG2 0x02 #define TEXBLENDOP_MODULATE 0x03 #define TEXBLENDOP_ADD 0x06 #define TEXBLENDOP_ADDSIGNED 0x07 #define TEXBLENDOP_BLEND 0x08 #define TEXBLENDOP_BLEND_AND_ADD 0x09 #define TEXBLENDOP_SUBTRACT 0x0a #define TEXBLENDOP_DOT3 0x0b #define TEXBLENDOP_DOT4 0x0c #define TEXBLENDOP_MODULATE_AND_ADD 0x0d #define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e #define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f /* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ /* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ #define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) #define DISABLE_TEX_TRANSFORM (1<<28) #define TEXTURE_SET(x) (x<<29) #define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define DISABLE_PERSPECTIVE_DIVIDE (1<<29) /* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ #define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) #define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) #define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) #define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) #define TEXBIND_SET3(x) ((x)<<12) #define TEXBIND_SET2(x) ((x)<<8) #define TEXBIND_SET1(x) ((x)<<4) #define TEXBIND_SET0(x) (x) #define TEXCOORDSRC_KEEP 0 #define TEXCOORDSRC_DEFAULT 0x01 #define TEXCOORDSRC_VTXSET_0 0x08 #define TEXCOORDSRC_VTXSET_1 0x09 #define TEXCOORDSRC_VTXSET_2 0x0a #define TEXCOORDSRC_VTXSET_3 0x0b #define TEXCOORDSRC_VTXSET_4 0x0c #define TEXCOORDSRC_VTXSET_5 0x0d #define TEXCOORDSRC_VTXSET_6 0x0e #define TEXCOORDSRC_VTXSET_7 0x0f #define MAP_UNIT(unit) ((unit)<<16) #define MAP_UNIT_MASK (0x7<<16) /* _3DSTATE_MAP_COORD_SETS, p164 */ #define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) #define TEXCOORD_SET(n) ((n)<<16) #define ENABLE_TEXCOORD_PARAMS (1<<15) #define TEXCOORDS_ARE_NORMAL (1<<14) #define TEXCOORDS_ARE_IN_TEXELUNITS 0 #define TEXCOORDTYPE_CARTESIAN 0 #define TEXCOORDTYPE_HOMOGENEOUS (1<<11) #define TEXCOORDTYPE_VECTOR (2<<11) #define TEXCOORDTYPE_MASK (0x7<<11) #define ENABLE_ADDR_V_CNTL (1<<7) #define ENABLE_ADDR_U_CNTL (1<<3) #define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) #define TEXCOORD_ADDR_U_MODE(x) (x) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP 2 #define TEXCOORDMODE_WRAP_SHORTEST 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORD_ADDR_V_MASK 0x70 #define TEXCOORD_ADDR_U_MASK 0x7 /* _3DSTATE_MAP_CUBE, p168 TODO */ #define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) #define CUBE_NEGX_ENABLE (1<<5) #define CUBE_POSX_ENABLE (1<<4) #define CUBE_NEGY_ENABLE (1<<3) #define CUBE_POSY_ENABLE (1<<2) #define CUBE_NEGZ_ENABLE (1<<1) #define CUBE_POSZ_ENABLE (1<<0) #define _3DSTATE_MAP_INFO_CMD (CMD_3D|(0x1d<<24)|(0x0<<16)|3) #define TEXMAP_INDEX(x) ((x)<<28) #define MAP_SURFACE_8BIT (1<<24) #define MAP_SURFACE_16BIT (2<<24) #define MAP_SURFACE_32BIT (3<<24) #define MAP_FORMAT_2D (0) #define MAP_FORMAT_3D_CUBE (1<<11) /* _3DSTATE_MODES_1, p190 */ #define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) #define BLENDFUNC_MASK 0x3f0000 #define ENABLE_COLR_BLND_FUNC (1<<21) #define BLENDFUNC_ADD 0 #define BLENDFUNC_SUB (1<<16) #define BLENDFUNC_RVRSE_SUB (2<<16) #define BLENDFUNC_MIN (3<<16) #define BLENDFUNC_MAX (4<<16) #define SRC_DST_BLND_MASK 0xfff #define ENABLE_SRC_BLND_FACTOR (1<<11) #define ENABLE_DST_BLND_FACTOR (1<<5) #define SRC_BLND_FACT(x) ((x)<<6) #define DST_BLND_FACT(x) (x) /* _3DSTATE_MODES_2, p192 */ #define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) #define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) #define GLOBAL_DEPTH_BIAS(x) ((x)<<14) #define ENABLE_ALPHA_TEST_FUNC (1<<13) #define ENABLE_ALPHA_REF_VALUE (1<<8) #define ALPHA_TEST_FUNC(x) ((x)<<9) #define ALPHA_REF_VALUE(x) (x) #define ALPHA_TEST_REF_MASK 0x3fff /* _3DSTATE_MODES_3, p193 */ #define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) #define DEPTH_TEST_FUNC_MASK 0x1f0000 #define ENABLE_DEPTH_TEST_FUNC (1<<20) /* Uses COMPAREFUNC */ #define DEPTH_TEST_FUNC(x) ((x)<<16) #define ENABLE_ALPHA_SHADE_MODE (1<<11) #define ENABLE_FOG_SHADE_MODE (1<<9) #define ENABLE_SPEC_SHADE_MODE (1<<7) #define ENABLE_COLOR_SHADE_MODE (1<<5) #define ALPHA_SHADE_MODE(x) ((x)<<10) #define FOG_SHADE_MODE(x) ((x)<<8) #define SPEC_SHADE_MODE(x) ((x)<<6) #define COLOR_SHADE_MODE(x) ((x)<<4) #define CULLMODE_MASK 0xf #define ENABLE_CULL_MODE (1<<3) #define CULLMODE_BOTH 0 #define CULLMODE_NONE 1 #define CULLMODE_CW 2 #define CULLMODE_CCW 3 #define SHADE_MODE_LINEAR 0 #define SHADE_MODE_FLAT 0x1 /* _3DSTATE_MODES_4, p195 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) #define LOGICOP_CLEAR 0 #define LOGICOP_NOR 0x1 #define LOGICOP_AND_INV 0x2 #define LOGICOP_COPY_INV 0x3 #define LOGICOP_AND_RVRSE 0x4 #define LOGICOP_INV 0x5 #define LOGICOP_XOR 0x6 #define LOGICOP_NAND 0x7 #define LOGICOP_AND 0x8 #define LOGICOP_EQUIV 0x9 #define LOGICOP_NOOP 0xa #define LOGICOP_OR_INV 0xb #define LOGICOP_COPY 0xc #define LOGICOP_OR_RVRSE 0xd #define LOGICOP_OR 0xe #define LOGICOP_SET 0xf #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p196 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define ENABLE_SPRITE_POINT_TEX (1<<23) #define SPRITE_POINT_TEX_ON (1<<22) #define SPRITE_POINT_TEX_OFF 0 #define FLUSH_RENDER_CACHE (1<<18) #define FLUSH_TEXTURE_CACHE (1<<16) #define FIXED_LINE_WIDTH_MASK 0xfc00 #define ENABLE_FIXED_LINE_WIDTH (1<<15) #define FIXED_LINE_WIDTH(x) ((x)<<10) #define FIXED_POINT_WIDTH_MASK 0x3ff #define ENABLE_FIXED_POINT_WIDTH (1<<9) #define FIXED_POINT_WIDTH(x) (x) /* _3DSTATE_RASTERIZATION_RULES, p198 */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) #define TRI_STRIP_PROVOKE_VRTX(x) (x) /* _3DSTATE_SCISSOR_ENABLE, p200 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* _3DSTATE_STENCIL_TEST, p202 */ #define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) #define ENABLE_STENCIL_PARMS (1<<23) #define STENCIL_OPS_MASK (0xffc000) #define STENCIL_FAIL_OP(x) ((x)<<20) #define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) #define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) #define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) #define ENABLE_STENCIL_TEST_FUNC (1<<13) /* Uses COMPAREFUNC */ #define STENCIL_TEST_FUNC(x) ((x)<<9) #define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) #define ENABLE_STENCIL_REF_VALUE (1<<8) #define STENCIL_REF_VALUE(x) (x) /* _3DSTATE_VERTEX_FORMAT, p204 */ #define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) #define VFT0_POINT_WIDTH (1<<12) #define VFT0_TEX_COUNT_MASK (7<<8) #define VFT0_TEX_COUNT_SHIFT 8 #define VFT0_TEX_COUNT(x) ((x)<<8) #define VFT0_SPEC (1<<7) #define VFT0_DIFFUSE (1<<6) #define VFT0_DEPTH_OFFSET (1<<5) #define VFT0_XYZ (1<<1) #define VFT0_XYZW (2<<1) #define VFT0_XY (3<<1) #define VFT0_XYW (4<<1) #define VFT0_XYZW_MASK (7<<1) /* _3DSTATE_VERTEX_FORMAT_2, p206 */ #define _3DSTATE_VERTEX_FORMAT_2_CMD (CMD_3D|(0x0a<<24)) #define VFT1_TEX7_FMT(x) ((x)<<14) #define VFT1_TEX6_FMT(x) ((x)<<12) #define VFT1_TEX5_FMT(x) ((x)<<10) #define VFT1_TEX4_FMT(x) ((x)<<8) #define VFT1_TEX3_FMT(x) ((x)<<6) #define VFT1_TEX2_FMT(x) ((x)<<4) #define VFT1_TEX1_FMT(x) ((x)<<2) #define VFT1_TEX0_FMT(x) (x) #define VFT1_TEX0_MASK 3 #define VFT1_TEX1_SHIFT 2 #define TEXCOORDFMT_2D 0 #define TEXCOORDFMT_3D 1 #define TEXCOORDFMT_4D 2 #define TEXCOORDFMT_1D 3 /*New stuff picked up along the way */ #define MLC_LOD_BIAS_MASK ((1<<7)-1) /* _3DSTATE_VERTEX_TRANSFORM, p207 */ #define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) #define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) /* Dword 1 */ #define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) #define DISABLE_VIEWPORT_TRANSFORM (1<<31) #define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) #define DISABLE_PERSP_DIVIDE (1<<29) #define VRTX_TRANS_LOAD_MATRICES 0x7421 #define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 /* Dword 2 -> 7 are matrix elements */ /* _3DSTATE_W_STATE, p209 */ #define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) /* Dword 1 */ #define MAGIC_W_STATE_DWORD1 0x00000008 /* Dword 2 */ #define WFAR_VALUE(x) (x) /* Stipple command, carried over from the i810, apparently: */ #define _3DSTATE_STIPPLE (CMD_3D|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<((n)+4)) #define S3_POINT_WIDTH_SHIFT 23 #define S3_LINE_WIDTH_SHIFT 19 #define S3_ALPHA_SHADE_MODE_SHIFT 18 #define S3_FOG_SHADE_MODE_SHIFT 17 #define S3_SPEC_SHADE_MODE_SHIFT 16 #define S3_COLOR_SHADE_MODE_SHIFT 15 #define S3_CULL_MODE_SHIFT 13 #define S3_CULLMODE_BOTH (0) #define S3_CULLMODE_NONE (1<<13) #define S3_CULLMODE_CW (2<<13) #define S3_CULLMODE_CCW (3<<13) #define S3_POINT_WIDTH_PRESENT (1<<12) #define S3_SPEC_FOG_PRESENT (1<<11) #define S3_DIFFUSE_PRESENT (1<<10) #define S3_DEPTH_OFFSET_PRESENT (1<<9) #define S3_POSITION_SHIFT 6 #define S3_VERTEXHAS_XYZ (1<<6) #define S3_VERTEXHAS_XYZW (2<<6) #define S3_VERTEXHAS_XY (3<<6) #define S3_VERTEXHAS_XYW (4<<6) #define S3_ENABLE_SPEC_ADD (1<<5) #define S3_ENABLE_FOG (1<<4) #define S3_ENABLE_LOCAL_DEPTH_BIAS (1<<3) #define S3_ENABLE_SPRITE_POINT (1<<1) #define S3_ENABLE_ANTIALIASING 1 #define S8_ENABLE_ALPHA_TEST (1<<31) #define S8_ALPHA_TEST_FUNC_SHIFT 28 #define S8_ALPHA_REFVALUE_SHIFT 20 #define S8_ENABLE_DEPTH_TEST (1<<19) #define S8_DEPTH_TEST_FUNC_SHIFT 16 #define S8_ENABLE_COLOR_BLEND (1<<15) #define S8_COLOR_BLEND_FUNC_SHIFT 12 #define S8_BLENDFUNC_ADD (0) #define S8_BLENDFUNC_SUB (1<<12) #define S8_BLENDFUNC_RVRSE_SUB (2<<12) #define S8_BLENDFUNC_MIN (3<<12) #define S8_BLENDFUNC_MAX (4<<12) #define S8_SRC_BLEND_FACTOR_SHIFT 8 #define S8_DST_BLEND_FACTOR_SHIFT 4 #define S8_ENABLE_DEPTH_BUFFER_WRITE (1<<3) #define S8_ENABLE_COLOR_BUFFER_WRITE (1<<2) #define _3DSTATE_LOAD_STATE_IMMEDIATE_2 (CMD_3D|(0x1d<<24)|(0x03<<16)) #define LOAD_TEXTURE_MAP(x) (1<<((x)+11)) #define LOAD_TEXTURE_BLEND_STAGE(x) (1<<((x)+7)) #define LOAD_GLOBAL_COLOR_FACTOR (1<<6) #define TM0S0_ADDRESS_MASK 0xfffffffc #define TM0S0_USE_FENCE (1<<1) #define TM0S1_HEIGHT_SHIFT 21 #define TM0S1_WIDTH_SHIFT 10 #define TM0S1_PALETTE_SELECT (1<<9) #define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) #define TM0S1_MAPSURF_FORMAT_SHIFT 6 #define MAPSURF_8BIT_INDEXED (0<<6) #define MAPSURF_8BIT (1<<6) #define MAPSURF_16BIT (2<<6) #define MAPSURF_32BIT (3<<6) #define MAPSURF_411 (4<<6) #define MAPSURF_422 (5<<6) #define MAPSURF_COMPRESSED (6<<6) #define MAPSURF_4BIT_INDEXED (7<<6) #define TM0S1_MT_FORMAT_MASK (0x7 << 3) #define TM0S1_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ #define MT_8BIT_IDX_ARGB1555 (1<<3) #define MT_8BIT_IDX_ARGB4444 (2<<3) #define MT_8BIT_IDX_AY88 (3<<3) #define MT_8BIT_IDX_ABGR8888 (4<<3) #define MT_8BIT_IDX_BUMP_88DVDU (5<<3) #define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) #define MT_8BIT_IDX_ARGB8888 (7<<3) #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_DIB_ARGB1555_8888 (4<<3) #define MT_16BIT_BUMP_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_DIB_RGB565_8888 (7<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) #define MT_32BIT_DIB_8888 (7<<3) #define MT_411_YUV411 (0<<3) /* SURFACE_411 */ #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define TM0S1_COLORSPACE_CONVERSION (1 << 2) #define TM0S1_TILED_SURFACE (1 << 1) #define TM0S1_TILE_WALK (1 << 0) #define TM0S2_PITCH_SHIFT 21 #define TM0S2_CUBE_FACE_ENA_SHIFT 15 #define TM0S2_CUBE_FACE_ENA_MASK (1<<15) #define TM0S2_MAP_FORMAT (1<<14) #define TM0S2_MAP_2D (0<<14) #define TM0S2_MAP_3D_CUBE (1<<14) #define TM0S2_VERTICAL_LINE_STRIDE (1<<13) #define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) #define TM0S2_OUTPUT_CHAN_SHIFT 10 #define TM0S2_OUTPUT_CHAN_MASK (3<<10) #define TM0S3_MIP_FILTER_MASK (0x3<<30) #define TM0S3_MIP_FILTER_SHIFT 30 #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define TM0S3_MAG_FILTER_MASK (0x3<<28) #define TM0S3_MAG_FILTER_SHIFT 28 #define TM0S3_MIN_FILTER_MASK (0x3<<26) #define TM0S3_MIN_FILTER_SHIFT 26 #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define TM0S3_LOD_BIAS_SHIFT 17 #define TM0S3_LOD_BIAS_MASK (0x1ff<<17) #define TM0S3_MAX_MIP_SHIFT 9 #define TM0S3_MAX_MIP_MASK (0xff<<9) #define TM0S3_MIN_MIP_SHIFT 3 #define TM0S3_MIN_MIP_MASK (0x3f<<3) #define TM0S3_KILL_PIXEL (1<<2) #define TM0S3_KEYED_FILTER (1<<1) #define TM0S3_CHROMA_KEY (1<<0) /* _3DSTATE_MAP_TEXEL_STREAM, p188 */ #define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) #define DISABLE_TEX_STREAM_BUMP (1<<12) #define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) #define TEX_MODIFY_UNIT_0 0 #define TEX_MODIFY_UNIT_1 (1<<8) #define ENABLE_TEX_STREAM_COORD_SET (1<<7) #define TEX_STREAM_COORD_SET(x) ((x)<<4) #define ENABLE_TEX_STREAM_MAP_IDX (1<<3) #define TEX_STREAM_MAP_IDX(x) (x) #define FLUSH_MAP_CACHE (1<<0) #define _3DSTATE_MAP_FILTER_CMD (CMD_3D|(0x1c<<24)|(0x02<<19)) #define FILTER_TEXMAP_INDEX(x) ((x) << 16) #define MAG_MODE_FILTER_ENABLE (1 << 5) #define MIN_MODE_FILTER_ENABLE (1 << 2) #define MAG_MAPFILTER_NEAREST (0 << 3) #define MAG_MAPFILTER_LINEAR (1 << 3) #define MAG_MAPFILTER_ANISOTROPIC (2 << 3) #define MIN_MAPFILTER_NEAREST (0) #define MIN_MAPFILTER_LINEAR (1) #define MIN_MAPFILTER_ANISOTROPIC (2) #define ENABLE_KEYS (1<<15) #define DISABLE_COLOR_KEY 0 #define DISABLE_CHROMA_KEY 0 #define DISABLE_KILL_PIXEL 0 #define ENABLE_MIP_MODE_FILTER (1 << 9) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i915_program.h000066400000000000000000000255471267532330400236540ustar00rootroot00000000000000#ifndef _I915_PROGRAM_H #define _I915_PROGRAM_H #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Having zero and one in here makes the definition of swizzle a lot * easier. */ #define UREG_TYPE_SHIFT 29 #define UREG_NR_SHIFT 24 #define UREG_CHANNEL_X_NEGATE_SHIFT 23 #define UREG_CHANNEL_X_SHIFT 20 #define UREG_CHANNEL_Y_NEGATE_SHIFT 19 #define UREG_CHANNEL_Y_SHIFT 16 #define UREG_CHANNEL_Z_NEGATE_SHIFT 15 #define UREG_CHANNEL_Z_SHIFT 12 #define UREG_CHANNEL_W_NEGATE_SHIFT 11 #define UREG_CHANNEL_W_SHIFT 8 #define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 #define UREG_CHANNEL_ZERO_SHIFT 4 #define UREG_CHANNEL_ONE_NEGATE_MBZ 1 #define UREG_CHANNEL_ONE_SHIFT 0 #define UREG_BAD 0xffffffff /* not a valid ureg */ #define X SRC_X #define Y SRC_Y #define Z SRC_Z #define W SRC_W #define ZERO SRC_ZERO #define ONE SRC_ONE /* Construct a ureg: */ #define UREG(type, nr) (((type) << UREG_TYPE_SHIFT) | \ ((nr) << UREG_NR_SHIFT) | \ (X << UREG_CHANNEL_X_SHIFT) | \ (Y << UREG_CHANNEL_Y_SHIFT) | \ (Z << UREG_CHANNEL_Z_SHIFT) | \ (W << UREG_CHANNEL_W_SHIFT) | \ (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ (ONE << UREG_CHANNEL_ONE_SHIFT)) #define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) #define CHANNEL_SRC( src, channel ) (src>>(channel*4)) #define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK) #define GET_UREG_NR(reg) (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK) #define UREG_XYZW_CHANNEL_MASK 0x00ffff00 #define A0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) #define D0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) #define T0_DEST(reg) (((reg) & UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) #define A0_SRC0(reg) (((reg) & UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT) #define A1_SRC0(reg) (((reg) & UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT) #define A1_SRC1(reg) (((reg) & UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT) #define A2_SRC1(reg) (((reg) & UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT) #define A2_SRC2(reg) (((reg) & UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT) /* These are special, and don't have swizzle/negate bits. */ #define T0_SAMPLER( reg ) (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT) #define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \ (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT)) /* Macros for translating UREG's into the various register fields used * by the I915 programmable unit. */ #define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) #define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) #define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) #define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) #define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) #define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) #define UREG_MASK 0xffffff00 #define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \ (REG_NR_MASK << UREG_NR_SHIFT)) #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i915_reg.h000066400000000000000000000776261267532330400227670ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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 _I915_REG_H_ #define _I915_REG_H_ #define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) #define CMD_3D (0x3<<29) #define PRIM3D (CMD_3D | (0x1f<<24)) #define PRIM3D_INDIRECT_SEQUENTIAL ((1<<23) | (0<<17)) #define PRIM3D_TRILIST (PRIM3D | (0x0<<18)) #define PRIM3D_TRISTRIP (PRIM3D | (0x1<<18)) #define PRIM3D_TRISTRIP_RVRSE (PRIM3D | (0x2<<18)) #define PRIM3D_TRIFAN (PRIM3D | (0x3<<18)) #define PRIM3D_POLY (PRIM3D | (0x4<<18)) #define PRIM3D_LINELIST (PRIM3D | (0x5<<18)) #define PRIM3D_LINESTRIP (PRIM3D | (0x6<<18)) #define PRIM3D_RECTLIST (PRIM3D | (0x7<<18)) #define PRIM3D_POINTLIST (PRIM3D | (0x8<<18)) #define PRIM3D_DIB (PRIM3D | (0x9<<18)) #define PRIM3D_CLEAR_RECT (PRIM3D | (0xa<<18)) #define PRIM3D_ZONE_INIT (PRIM3D | (0xd<<18)) #define PRIM3D_MASK (0x1f<<18) /* p137 */ #define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) #define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) #define AA_LINE_ECAAR_WIDTH_0_5 0 #define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) #define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) #define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) #define AA_LINE_REGION_WIDTH_ENABLE (1<<8) #define AA_LINE_REGION_WIDTH_0_5 0 #define AA_LINE_REGION_WIDTH_1_0 (1<<6) #define AA_LINE_REGION_WIDTH_2_0 (2<<6) #define AA_LINE_REGION_WIDTH_4_0 (3<<6) /* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ #define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) #define BFO_ENABLE_STENCIL_REF (1<<23) #define BFO_STENCIL_REF_SHIFT 15 #define BFO_STENCIL_REF_MASK (0xff<<15) #define BFO_ENABLE_STENCIL_FUNCS (1<<14) #define BFO_STENCIL_TEST_SHIFT 11 #define BFO_STENCIL_TEST_MASK (0x7<<11) #define BFO_STENCIL_FAIL_SHIFT 8 #define BFO_STENCIL_FAIL_MASK (0x7<<8) #define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 #define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) #define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 #define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) #define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) #define BFO_STENCIL_TWO_SIDE (1<<0) /* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ #define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) #define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) #define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) #define BFM_STENCIL_TEST_MASK_SHIFT 8 #define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) #define BFM_STENCIL_WRITE_MASK_SHIFT 0 #define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) /* 3DSTATE_BIN_CONTROL p141 */ /* p143 */ #define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) /* Dword 1 */ #define BUF_3D_ID_COLOR_BACK (0x3<<24) #define BUF_3D_ID_DEPTH (0x7<<24) #define BUF_3D_USE_FENCE (1<<23) #define BUF_3D_TILED_SURFACE (1<<22) #define BUF_3D_TILE_WALK_X 0 #define BUF_3D_TILE_WALK_Y (1<<21) #define BUF_3D_PITCH(x) (((x)/4)<<2) /* Dword 2 */ #define BUF_3D_ADDR(x) ((x) & ~0x3) /* 3DSTATE_CHROMA_KEY */ /* 3DSTATE_CLEAR_PARAMETERS, p150 */ #define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) /* Dword 1 */ #define CLEARPARAM_CLEAR_RECT (1 << 16) #define CLEARPARAM_ZONE_INIT (0 << 16) #define CLEARPARAM_WRITE_COLOR (1 << 2) #define CLEARPARAM_WRITE_DEPTH (1 << 1) #define CLEARPARAM_WRITE_STENCIL (1 << 0) /* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) /* 3DSTATE_COORD_SET_BINDINGS, p154 */ #define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) #define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) /* p156 */ #define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) /* p157 */ #define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) /* p158 */ #define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) /* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ #define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) /* scale in dword 1 */ /* The depth subrectangle is not supported, but must be disabled. */ /* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ #define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | (1 << 1) | (0 << 0)) /* p161 */ #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ #define TEX_DEFAULT_COLOR_OGL (0<<30) #define TEX_DEFAULT_COLOR_D3D (1<<30) #define ZR_EARLY_DEPTH (1<<29) #define LOD_PRECLAMP_OGL (1<<28) #define LOD_PRECLAMP_D3D (0<<28) #define DITHER_FULL_ALWAYS (0<<26) #define DITHER_FULL_ON_FB_BLEND (1<<26) #define DITHER_CLAMPED_ALWAYS (2<<26) #define LINEAR_GAMMA_BLEND_32BPP (1<<25) #define DEBUG_DISABLE_ENH_DITHER (1<<24) #define DSTORG_HORT_BIAS(x) ((x)<<20) #define DSTORG_VERT_BIAS(x) ((x)<<16) #define COLOR_4_2_2_CHNL_WRT_ALL 0 #define COLOR_4_2_2_CHNL_WRT_Y (1<<12) #define COLOR_4_2_2_CHNL_WRT_CR (2<<12) #define COLOR_4_2_2_CHNL_WRT_CB (3<<12) #define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) #define COLR_BUF_8BIT 0 #define COLR_BUF_RGB555 (1<<8) #define COLR_BUF_RGB565 (2<<8) #define COLR_BUF_ARGB8888 (3<<8) #define COLR_BUF_ARGB4444 (8<<8) #define COLR_BUF_ARGB1555 (9<<8) #define COLR_BUF_ARGB2AAA (0xa<<8) #define DEPTH_FRMT_16_FIXED 0 #define DEPTH_FRMT_16_FLOAT (1<<2) #define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) #define VERT_LINE_STRIDE_1 (1<<1) #define VERT_LINE_STRIDE_0 (0<<1) #define VERT_LINE_STRIDE_OFS_1 1 #define VERT_LINE_STRIDE_OFS_0 0 /* p166 */ #define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) /* Dword 1 */ #define DRAW_RECT_DIS_DEPTH_OFS (1<<30) #define DRAW_DITHER_OFS_X(x) ((x)<<26) #define DRAW_DITHER_OFS_Y(x) ((x)<<24) /* Dword 2 */ #define DRAW_YMIN(x) ((x)<<16) #define DRAW_XMIN(x) (x) /* Dword 3 */ #define DRAW_YMAX(x) ((x)<<16) #define DRAW_XMAX(x) (x) /* Dword 4 */ #define DRAW_YORG(x) ((x)<<16) #define DRAW_XORG(x) (x) /* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ /* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ /* _3DSTATE_FOG_COLOR, p173 */ #define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) #define FOG_COLOR_RED(x) ((x)<<16) #define FOG_COLOR_GREEN(x) ((x)<<8) #define FOG_COLOR_BLUE(x) (x) /* _3DSTATE_FOG_MODE, p174 */ #define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) /* Dword 1 */ #define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) #define FMC1_FOGFUNC_VERTEX (0<<28) #define FMC1_FOGFUNC_PIXEL_EXP (1<<28) #define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) #define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) #define FMC1_FOGFUNC_MASK (3<<28) #define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) #define FMC1_FOGINDEX_Z (0<<25) #define FMC1_FOGINDEX_W (1<<25) #define FMC1_C1_C2_MODIFY_ENABLE (1<<24) #define FMC1_DENSITY_MODIFY_ENABLE (1<<23) #define FMC1_C1_ONE (1<<13) #define FMC1_C1_MASK (0xffff<<4) /* Dword 2 */ #define FMC2_C2_ONE (1<<16) /* Dword 3 */ #define FMC3_D_ONE (1<<16) /* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ #define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) #define IAB_MODIFY_ENABLE (1<<23) #define IAB_ENABLE (1<<22) #define IAB_MODIFY_FUNC (1<<21) #define IAB_FUNC_SHIFT 16 #define IAB_MODIFY_SRC_FACTOR (1<<11) #define IAB_SRC_FACTOR_SHIFT 6 #define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) #define IAB_MODIFY_DST_FACTOR (1<<5) #define IAB_DST_FACTOR_SHIFT 0 #define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) #define BLENDFACT_ZERO 0x01 #define BLENDFACT_ONE 0x02 #define BLENDFACT_SRC_COLR 0x03 #define BLENDFACT_INV_SRC_COLR 0x04 #define BLENDFACT_SRC_ALPHA 0x05 #define BLENDFACT_INV_SRC_ALPHA 0x06 #define BLENDFACT_DST_ALPHA 0x07 #define BLENDFACT_INV_DST_ALPHA 0x08 #define BLENDFACT_DST_COLR 0x09 #define BLENDFACT_INV_DST_COLR 0x0a #define BLENDFACT_SRC_ALPHA_SATURATE 0x0b #define BLENDFACT_CONST_COLOR 0x0c #define BLENDFACT_INV_CONST_COLOR 0x0d #define BLENDFACT_CONST_ALPHA 0x0e #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f #define BLENDFUNC_ADD 0x0 #define BLENDFUNC_SUBTRACT 0x1 #define BLENDFUNC_REVERSE_SUBTRACT 0x2 #define BLENDFUNC_MIN 0x3 #define BLENDFUNC_MAX 0x4 #define BLENDFUNC_MASK 0x7 /* 3DSTATE_LOAD_INDIRECT, p180 */ #define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) #define LI0_STATE_STATIC_INDIRECT (0x01<<8) #define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) #define LI0_STATE_SAMPLER (0x04<<8) #define LI0_STATE_MAP (0x08<<8) #define LI0_STATE_PROGRAM (0x10<<8) #define LI0_STATE_CONSTANTS (0x20<<8) #define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SIS0_FORCE_LOAD (1<<1) #define SIS0_BUFFER_VALID (1<<0) #define SIS1_BUFFER_LENGTH(x) ((x)&0xff) #define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) #define DIS0_BUFFER_RESET (1<<1) #define DIS0_BUFFER_VALID (1<<0) #define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define SSB0_FORCE_LOAD (1<<1) #define SSB0_BUFFER_VALID (1<<0) #define SSB1_BUFFER_LENGTH(x) ((x)&0xff) #define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) #define MSB0_FORCE_LOAD (1<<1) #define MSB0_BUFFER_VALID (1<<0) #define MSB1_BUFFER_LENGTH(x) ((x)&0xff) #define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSP0_FORCE_LOAD (1<<1) #define PSP0_BUFFER_VALID (1<<0) #define PSP1_BUFFER_LENGTH(x) ((x)&0xff) #define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) #define PSC0_FORCE_LOAD (1<<1) #define PSC0_BUFFER_VALID (1<<0) #define PSC1_BUFFER_LENGTH(x) ((x)&0xff) /* _3DSTATE_RASTERIZATION_RULES */ #define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) #define ENABLE_POINT_RASTER_RULE (1<<15) #define OGL_POINT_RASTER_RULE (1<<13) #define ENABLE_TEXKILL_3D_4D (1<<10) #define TEXKILL_3D (0<<9) #define TEXKILL_4D (1<<9) #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) #define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) #define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) #define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) /* _3DSTATE_SCISSOR_ENABLE, p256 */ #define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) #define ENABLE_SCISSOR_RECT ((1<<1) | 1) #define DISABLE_SCISSOR_RECT (1<<1) /* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ #define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) /* Dword 1 */ #define SCISSOR_RECT_0_YMIN(x) ((x)<<16) #define SCISSOR_RECT_0_XMIN(x) (x) /* Dword 2 */ #define SCISSOR_RECT_0_YMAX(x) ((x)<<16) #define SCISSOR_RECT_0_XMAX(x) (x) /* p189 */ #define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) #define I1_LOAD_S(n) (1<<(4+n)) #define S0_VB_OFFSET_MASK 0xffffffc #define S0_AUTO_CACHE_INV_DISABLE (1<<0) #define S1_VERTEX_WIDTH_SHIFT 24 #define S1_VERTEX_WIDTH_MASK (0x3f<<24) #define S1_VERTEX_PITCH_SHIFT 16 #define S1_VERTEX_PITCH_MASK (0x3f<<16) #define TEXCOORDFMT_2D 0x0 #define TEXCOORDFMT_3D 0x1 #define TEXCOORDFMT_4D 0x2 #define TEXCOORDFMT_1D 0x3 #define TEXCOORDFMT_2D_16 0x4 #define TEXCOORDFMT_4D_16 0x5 #define TEXCOORDFMT_NOT_PRESENT 0xf #define S2_TEXCOORD_FMT0_MASK 0xf #define S2_TEXCOORD_FMT1_SHIFT 4 #define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) #define S2_TEXCOORD_NONE (~0) #define TEXCOORD_WRAP_SHORTEST_TCX 8 #define TEXCOORD_WRAP_SHORTEST_TCY 4 #define TEXCOORD_WRAP_SHORTEST_TCZ 2 #define TEXCOORD_PERSPECTIVE_DISABLE 1 #define S3_WRAP_SHORTEST_TCX(unit) (TEXCOORD_WRAP_SHORTEST_TCX << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCY(unit) (TEXCOORD_WRAP_SHORTEST_TCY << ((unit) * 4)) #define S3_WRAP_SHORTEST_TCZ(unit) (TEXCOORD_WRAP_SHORTEST_TCZ << ((unit) * 4)) #define S3_PERSPECTIVE_DISABLE(unit) (TEXCOORD_PERSPECTIVE_DISABLE << ((unit) * 4)) /* S3 not interesting */ #define S4_POINT_WIDTH_SHIFT 23 #define S4_POINT_WIDTH_MASK (0x1ff<<23) #define S4_LINE_WIDTH_SHIFT 19 #define S4_LINE_WIDTH_ONE (0x2<<19) #define S4_LINE_WIDTH_MASK (0xf<<19) #define S4_FLATSHADE_ALPHA (1<<18) #define S4_FLATSHADE_FOG (1<<17) #define S4_FLATSHADE_SPECULAR (1<<16) #define S4_FLATSHADE_COLOR (1<<15) #define S4_CULLMODE_BOTH (0<<13) #define S4_CULLMODE_NONE (1<<13) #define S4_CULLMODE_CW (2<<13) #define S4_CULLMODE_CCW (3<<13) #define S4_CULLMODE_MASK (3<<13) #define S4_VFMT_POINT_WIDTH (1<<12) #define S4_VFMT_SPEC_FOG (1<<11) #define S4_VFMT_COLOR (1<<10) #define S4_VFMT_DEPTH_OFFSET (1<<9) #define S4_VFMT_XYZ (1<<6) #define S4_VFMT_XYZW (2<<6) #define S4_VFMT_XY (3<<6) #define S4_VFMT_XYW (4<<6) #define S4_VFMT_XYZW_MASK (7<<6) #define S4_FORCE_DEFAULT_DIFFUSE (1<<5) #define S4_FORCE_DEFAULT_SPECULAR (1<<4) #define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) #define S4_VFMT_FOG_PARAM (1<<2) #define S4_SPRITE_POINT_ENABLE (1<<1) #define S4_LINE_ANTIALIAS_ENABLE (1<<0) #define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ S4_VFMT_SPEC_FOG | \ S4_VFMT_COLOR | \ S4_VFMT_DEPTH_OFFSET | \ S4_VFMT_XYZW_MASK | \ S4_VFMT_FOG_PARAM) #define S5_WRITEDISABLE_ALPHA (1<<31) #define S5_WRITEDISABLE_RED (1<<30) #define S5_WRITEDISABLE_GREEN (1<<29) #define S5_WRITEDISABLE_BLUE (1<<28) #define S5_WRITEDISABLE_MASK (0xf<<28) #define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) #define S5_LAST_PIXEL_ENABLE (1<<26) #define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) #define S5_FOG_ENABLE (1<<24) #define S5_STENCIL_REF_SHIFT 16 #define S5_STENCIL_REF_MASK (0xff<<16) #define S5_STENCIL_TEST_FUNC_SHIFT 13 #define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) #define S5_STENCIL_FAIL_SHIFT 10 #define S5_STENCIL_FAIL_MASK (0x7<<10) #define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 #define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) #define S5_STENCIL_PASS_Z_PASS_SHIFT 4 #define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) #define S5_STENCIL_WRITE_ENABLE (1<<3) #define S5_STENCIL_TEST_ENABLE (1<<2) #define S5_COLOR_DITHER_ENABLE (1<<1) #define S5_LOGICOP_ENABLE (1<<0) #define S6_ALPHA_TEST_ENABLE (1<<31) #define S6_ALPHA_TEST_FUNC_SHIFT 28 #define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) #define S6_ALPHA_REF_SHIFT 20 #define S6_ALPHA_REF_MASK (0xff<<20) #define S6_DEPTH_TEST_ENABLE (1<<19) #define S6_DEPTH_TEST_FUNC_SHIFT 16 #define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) #define S6_CBUF_BLEND_ENABLE (1<<15) #define S6_CBUF_BLEND_FUNC_SHIFT 12 #define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) #define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 #define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) #define S6_CBUF_DST_BLEND_FACT_SHIFT 4 #define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) #define S6_DEPTH_WRITE_ENABLE (1<<3) #define S6_COLOR_WRITE_ENABLE (1<<2) #define S6_TRISTRIP_PV_SHIFT 0 #define S6_TRISTRIP_PV_MASK (0x3<<0) #define S7_DEPTH_OFFSET_CONST_MASK ~0 /* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ /* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ /* _3DSTATE_MODES_4, p218 */ #define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) #define ENABLE_LOGIC_OP_FUNC (1<<23) #define LOGIC_OP_FUNC(x) ((x)<<18) #define LOGICOP_MASK (0xf<<18) #define LOGICOP_COPY 0xc #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) #define STENCIL_TEST_MASK(x) ((x)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) #define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p220 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) #define PIPELINE_FLUSH_RENDER_CACHE (1<<18) #define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) /* p221 */ #define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) #define PS1_REG(n) (1<<(n)) #define PS2_CONST_X(n) (n) #define PS3_CONST_Y(n) (n) #define PS4_CONST_Z(n) (n) #define PS5_CONST_W(n) (n) /* p222 */ #define I915_MAX_TEX_INDIRECT 4 #define I915_MAX_TEX_INSN 32 #define I915_MAX_ALU_INSN 64 #define I915_MAX_DECL_INSN 27 #define I915_MAX_TEMPORARY 16 /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. */ #define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) #define REG_TYPE_R 0 /* temporary regs, no need to * dcl, must be written before * read -- Preserved between * phases. */ #define REG_TYPE_T 1 /* Interpolated values, must be * dcl'ed before use. * * 0..7: texture coord, * 8: diffuse spec, * 9: specular color, * 10: fog parameter in w. */ #define REG_TYPE_CONST 2 /* Restriction: only one const * can be referenced per * instruction, though it may be * selected for multiple inputs. * Constants not initialized * default to zero. */ #define REG_TYPE_S 3 /* sampler */ #define REG_TYPE_OC 4 /* output color (rgba) */ #define REG_TYPE_OD 5 /* output depth (w), xyz are * temporaries. If not written, * interpolated depth is used? */ #define REG_TYPE_U 6 /* unpreserved temporaries */ #define REG_TYPE_MASK 0x7 #define REG_NR_MASK 0xf /* REG_TYPE_T: */ #define T_TEX0 0 #define T_TEX1 1 #define T_TEX2 2 #define T_TEX3 3 #define T_TEX4 4 #define T_TEX5 5 #define T_TEX6 6 #define T_TEX7 7 #define T_DIFFUSE 8 #define T_SPECULAR 9 #define T_FOG_W 10 /* interpolated fog is in W coord */ /* Arithmetic instructions */ /* .replicate_swizzle == selection and replication of a particular * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww */ #define A0_NOP (0x0<<24) /* no operation */ #define A0_ADD (0x1<<24) /* dst = src0 + src1 */ #define A0_MOV (0x2<<24) /* dst = src0 */ #define A0_MUL (0x3<<24) /* dst = src0 * src1 */ #define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ #define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ #define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ #define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ #define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ #define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ #define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ #define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ #define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ #define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ #define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ #define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ #define A0_FLR (0x10<<24) /* dst = floor(src0) */ #define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ #define A0_TRC (0x12<<24) /* dst = int(src0) */ #define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ #define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ #define A0_DEST_SATURATE (1<<22) #define A0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ #define A0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define A0_DEST_CHANNEL_X (1<<10) #define A0_DEST_CHANNEL_Y (2<<10) #define A0_DEST_CHANNEL_Z (4<<10) #define A0_DEST_CHANNEL_W (8<<10) #define A0_DEST_CHANNEL_ALL (0xf<<10) #define A0_DEST_CHANNEL_SHIFT 10 #define A0_SRC0_TYPE_SHIFT 7 #define A0_SRC0_NR_SHIFT 2 #define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) #define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) #define SRC_X 0 #define SRC_Y 1 #define SRC_Z 2 #define SRC_W 3 #define SRC_ZERO 4 #define SRC_ONE 5 #define A1_SRC0_CHANNEL_X_NEGATE (1<<31) #define A1_SRC0_CHANNEL_X_SHIFT 28 #define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) #define A1_SRC0_CHANNEL_Y_SHIFT 24 #define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) #define A1_SRC0_CHANNEL_Z_SHIFT 20 #define A1_SRC0_CHANNEL_W_NEGATE (1<<19) #define A1_SRC0_CHANNEL_W_SHIFT 16 #define A1_SRC1_TYPE_SHIFT 13 #define A1_SRC1_NR_SHIFT 8 #define A1_SRC1_CHANNEL_X_NEGATE (1<<7) #define A1_SRC1_CHANNEL_X_SHIFT 4 #define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) #define A1_SRC1_CHANNEL_Y_SHIFT 0 #define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) #define A2_SRC1_CHANNEL_Z_SHIFT 28 #define A2_SRC1_CHANNEL_W_NEGATE (1<<27) #define A2_SRC1_CHANNEL_W_SHIFT 24 #define A2_SRC2_TYPE_SHIFT 21 #define A2_SRC2_NR_SHIFT 16 #define A2_SRC2_CHANNEL_X_NEGATE (1<<15) #define A2_SRC2_CHANNEL_X_SHIFT 12 #define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) #define A2_SRC2_CHANNEL_Y_SHIFT 8 #define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) #define A2_SRC2_CHANNEL_Z_SHIFT 4 #define A2_SRC2_CHANNEL_W_NEGATE (1<<3) #define A2_SRC2_CHANNEL_W_SHIFT 0 /* Texture instructions */ #define T0_TEXLD (0x15<<24) /* Sample texture using predeclared * sampler and address, and output * filtered texel data to destination * register */ #define T0_TEXLDP (0x16<<24) /* Same as texld but performs a * perspective divide of the texture * coordinate .xyz values by .w before * sampling. */ #define T0_TEXLDB (0x17<<24) /* Same as texld but biases the * computed LOD by w. Only S4.6 two's * comp is used. This implies that a * float to fixed conversion is * done. */ #define T0_TEXKILL (0x18<<24) /* Does not perform a sampling * operation. Simply kills the pixel * if any channel of the address * register is < 0.0. */ #define T0_DEST_TYPE_SHIFT 19 /* Allow: R, OC, OD, U */ /* Note: U (unpreserved) regs do not retain their values between * phases (cannot be used for feedback) * * Note: oC and OD registers can only be used as the destination of a * texture instruction once per phase (this is an implementation * restriction). */ #define T0_DEST_NR_SHIFT 14 /* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ #define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ #define T0_SAMPLER_NR_MASK (0xf<<0) #define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ /* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ #define T1_ADDRESS_REG_NR_SHIFT 17 #define T2_MBZ 0 /* Declaration instructions */ #define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) * register or an s (sampler) * register. */ #define D0_SAMPLE_TYPE_SHIFT 22 #define D0_SAMPLE_TYPE_2D (0x0<<22) #define D0_SAMPLE_TYPE_CUBE (0x1<<22) #define D0_SAMPLE_TYPE_VOLUME (0x2<<22) #define D0_SAMPLE_TYPE_MASK (0x3<<22) #define D0_TYPE_SHIFT 19 /* Allow: T, S */ #define D0_NR_SHIFT 14 /* Allow T: 0..10, S: 0..15 */ #define D0_CHANNEL_X (1<<10) #define D0_CHANNEL_Y (2<<10) #define D0_CHANNEL_Z (4<<10) #define D0_CHANNEL_W (8<<10) #define D0_CHANNEL_ALL (0xf<<10) #define D0_CHANNEL_NONE (0<<10) #define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) #define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) /* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse * or specular declarations. * * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) * * Must be zero for S (sampler) dcls */ #define D1_MBZ 0 #define D2_MBZ 0 /* p207. * The DWORD count is 3 times the number of bits set in MS1_MAPMASK_MASK */ #define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) #define MS1_MAPMASK_SHIFT 0 #define MS1_MAPMASK_MASK (0x8fff<<0) #define MS2_UNTRUSTED_SURFACE (1<<31) #define MS2_ADDRESS_MASK 0xfffffffc #define MS2_VERTICAL_LINE_STRIDE (1<<1) #define MS2_VERTICAL_OFFSET (1<<1) #define MS3_HEIGHT_SHIFT 21 #define MS3_WIDTH_SHIFT 10 #define MS3_PALETTE_SELECT (1<<9) #define MS3_MAPSURF_FORMAT_SHIFT 7 #define MS3_MAPSURF_FORMAT_MASK (0x7<<7) #define MAPSURF_8BIT (1<<7) #define MAPSURF_16BIT (2<<7) #define MAPSURF_32BIT (3<<7) #define MAPSURF_422 (5<<7) #define MAPSURF_COMPRESSED (6<<7) #define MAPSURF_4BIT_INDEXED (7<<7) #define MS3_MT_FORMAT_MASK (0x7 << 3) #define MS3_MT_FORMAT_SHIFT 3 #define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ #define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ #define MT_8BIT_L8 (1<<3) #define MT_8BIT_A8 (4<<3) #define MT_8BIT_MONO8 (5<<3) #define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ #define MT_16BIT_ARGB1555 (1<<3) #define MT_16BIT_ARGB4444 (2<<3) #define MT_16BIT_AY88 (3<<3) #define MT_16BIT_88DVDU (5<<3) #define MT_16BIT_BUMP_655LDVDU (6<<3) #define MT_16BIT_I16 (7<<3) #define MT_16BIT_L16 (8<<3) #define MT_16BIT_A16 (9<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) #define MT_32BIT_XRGB8888 (2<<3) #define MT_32BIT_XBGR8888 (3<<3) #define MT_32BIT_QWVU8888 (4<<3) #define MT_32BIT_AXVU8888 (5<<3) #define MT_32BIT_LXVU8888 (6<<3) #define MT_32BIT_XLVU8888 (7<<3) #define MT_32BIT_ARGB2101010 (8<<3) #define MT_32BIT_ABGR2101010 (9<<3) #define MT_32BIT_AWVU2101010 (0xA<<3) #define MT_32BIT_GR1616 (0xB<<3) #define MT_32BIT_VU1616 (0xC<<3) #define MT_32BIT_xI824 (0xD<<3) #define MT_32BIT_xA824 (0xE<<3) #define MT_32BIT_xL824 (0xF<<3) #define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ #define MT_422_YCRCB_NORMAL (1<<3) #define MT_422_YCRCB_SWAPUV (2<<3) #define MT_422_YCRCB_SWAPUVY (3<<3) #define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ #define MT_COMPRESS_DXT2_3 (1<<3) #define MT_COMPRESS_DXT4_5 (2<<3) #define MT_COMPRESS_FXT1 (3<<3) #define MT_COMPRESS_DXT1_RGB (4<<3) #define MS3_USE_FENCE_REGS (1<<2) #define MS3_TILED_SURFACE (1<<1) #define MS3_TILE_WALK (1<<0) /* The pitch is the pitch measured in DWORDS, minus 1 */ #define MS4_PITCH_SHIFT 21 #define MS4_CUBE_FACE_ENA_NEGX (1<<20) #define MS4_CUBE_FACE_ENA_POSX (1<<19) #define MS4_CUBE_FACE_ENA_NEGY (1<<18) #define MS4_CUBE_FACE_ENA_POSY (1<<17) #define MS4_CUBE_FACE_ENA_NEGZ (1<<16) #define MS4_CUBE_FACE_ENA_POSZ (1<<15) #define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) #define MS4_MAX_LOD_SHIFT 9 #define MS4_MAX_LOD_MASK (0x3f<<9) #define MS4_MIP_LAYOUT_LEGACY (0<<8) #define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) #define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) #define MS4_VOLUME_DEPTH_SHIFT 0 #define MS4_VOLUME_DEPTH_MASK (0xff<<0) /* p244. * The DWORD count is 3 times the number of bits set in SS1_MAPMASK_MASK. */ #define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) #define SS1_MAPMASK_SHIFT 0 #define SS1_MAPMASK_MASK (0x8fff<<0) #define SS2_REVERSE_GAMMA_ENABLE (1<<31) #define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) #define SS2_COLORSPACE_CONVERSION (1<<29) #define SS2_CHROMAKEY_SHIFT 27 #define SS2_BASE_MIP_LEVEL_SHIFT 22 #define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) #define SS2_MIP_FILTER_SHIFT 20 #define SS2_MIP_FILTER_MASK (0x3<<20) #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define SS2_MAG_FILTER_SHIFT 17 #define SS2_MAG_FILTER_MASK (0x7<<17) #define FILTER_NEAREST 0 #define FILTER_LINEAR 1 #define FILTER_ANISOTROPIC 2 #define FILTER_4X4_1 3 #define FILTER_4X4_2 4 #define FILTER_4X4_FLAT 5 #define FILTER_6X5_MONO 6 /* XXX - check */ #define SS2_MIN_FILTER_SHIFT 14 #define SS2_MIN_FILTER_MASK (0x7<<14) #define SS2_LOD_BIAS_SHIFT 5 #define SS2_LOD_BIAS_ONE (0x10<<5) #define SS2_LOD_BIAS_MASK (0x1ff<<5) /* Shadow requires: * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format * FILTER_4X4_x MIN and MAG filters */ #define SS2_SHADOW_ENABLE (1<<4) #define SS2_MAX_ANISO_MASK (1<<3) #define SS2_MAX_ANISO_2 (0<<3) #define SS2_MAX_ANISO_4 (1<<3) #define SS2_SHADOW_FUNC_SHIFT 0 #define SS2_SHADOW_FUNC_MASK (0x7<<0) /* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ #define SS3_MIN_LOD_SHIFT 24 #define SS3_MIN_LOD_ONE (0x10<<24) #define SS3_MIN_LOD_MASK (0xff<<24) #define SS3_KILL_PIXEL_ENABLE (1<<17) #define SS3_TCX_ADDR_MODE_SHIFT 12 #define SS3_TCX_ADDR_MODE_MASK (0x7<<12) #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP_EDGE 2 #define TEXCOORDMODE_CUBE 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORDMODE_MIRROR_ONCE 5 #define SS3_TCY_ADDR_MODE_SHIFT 9 #define SS3_TCY_ADDR_MODE_MASK (0x7<<9) #define SS3_TCZ_ADDR_MODE_SHIFT 6 #define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) #define SS3_NORMALIZED_COORDS (1<<5) #define SS3_TEXTUREMAP_INDEX_SHIFT 1 #define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) #define SS3_DEINTERLACER_ENABLE (1<<0) #define SS4_BORDER_COLOR_MASK (~0) /* 3DSTATE_SPAN_STIPPLE, p258 */ #define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) #define FLUSH_MAP_CACHE (1<<0) #define FLUSH_RENDER_CACHE (1<<1) #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i915_structs.h000066400000000000000000000525001267532330400237010ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Xiang Haihao * */ #ifndef _I915_STRUCTS_H #define _I915_STRUCTS_H #include /* BLT */ #define CMD_2D 0x02 #define OPC_COLOR_BLT (0x40) struct i915_color_blt { struct { unsigned length:5; unsigned pad0:15; unsigned bpp_mask:2; unsigned opcode:7; unsigned type:3; } dw0; struct { unsigned pitch:16; unsigned rop:8; unsigned color_depth:2; unsigned pad0:6; } dw1; struct { unsigned width:16; unsigned height:16; } dw2; struct { unsigned address; } dw3; struct { unsigned pattern; } dw4; }; /* 3D_INSTRUCTION */ #define CMD_3D 0x03 #define OPCODE_3D(x) (CMD_3D << 29 | (x) << 16) #define OPC_3DMPEG_MACROBLOCK_IPICTURE (0x01 + (0x1e << 5)) #define OPC_3DMPEG_SET_ORIGIN (0x10 + (0x1e << 5)) #define OPC_3DMPEG_MACROBLOCK (0x11 + (0x1e << 5)) #define OPC_3DMPEG_SLICE (0x12 + (0x1e << 5)) #define OPC_3DMPEG_QM_PALETTE_LOAD (0x13 + (0x1e << 5)) #define OPC_3DSTATE_SCISSOR_ENABLE (0x10 + (0x1c << 5)) #define OPC_3DSTATE_MAP_STATE (0x00 + (0x1d << 8)) #define OPC_3DSTATE_SAMPLER_STATE (0x01 + (0x1d << 8)) #define OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1 (0x04 + (0x1d << 8)) #define OP_3D_LOAD_STATE_IMMEDIATE_1 OPCODE_3D(OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1) #define OPC_3DSTATE_PIXEL_SHADER_PROGRAM (0x05 + (0x1d << 8)) #define OPC_3DSTATE_PIXEL_SHADER_CONSTANTS (0x06 + (0x1d << 8)) #define OPC_3DSTATE_LOAD_INDIRECT (0x07 + (0x1d << 8)) #define OP_3D_LOAD_INDIRECT OPCODE_3D(OPC_3DSTATE_LOAD_INDIRECT) #define OPC_3DSTATE_MODES_5 (0x0c) #define OPC_3DSTATE_COORD_SET_BINDINGS (0x16) #define OPC_3DPRIMITIVE (0x1f) #define OPC_3DSTATE_DRAWING_RECTANGLE (0x80 + (0x1d << 8)) #define OPC_3DSTATE_SCISSOR_RECTANGLE (0x81 + (0x1d << 8)) #define OPC_3DSTATE_DEST_BUFFER_VARIABLES (0x85 + (0x1d << 8)) #define OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG (0x87 + (0x1d << 8)) #define OPC_3DSTATE_BUFFER_INFO (0x8e + (0x1d << 8)) /* * 3DMPEG instructions */ struct i915_3dmpeg_macroblock_header { struct { unsigned length:19; unsigned opcode:10; unsigned type:3; } dw0; struct { unsigned mb_intra:1; unsigned forward:1; unsigned backward:1; unsigned h263_4mv:1; unsigned pad0:1; unsigned dct_type:1; unsigned pad1:2; unsigned motion_type:2; unsigned pad2:2; unsigned vertical_field_select:4; unsigned coded_block_pattern:6; unsigned pad3:2; unsigned skipped_macroblocks:7; unsigned pad4:1; } dw1; }; struct i915_3dmpeg_macroblock_0mv { struct i915_3dmpeg_macroblock_header header; }; struct i915_3dmpeg_macroblock_1fbmv { struct i915_3dmpeg_macroblock_header header; unsigned dw2; unsigned dw3; }; struct i915_3dmpeg_macroblock_2fbmv { struct i915_3dmpeg_macroblock_header header; unsigned dw2; unsigned dw3; unsigned dw4; unsigned dw5; }; struct i915_3dmpeg_macroblock_5fmv { struct i915_3dmpeg_macroblock_header header; unsigned dw2; unsigned dw3; unsigned dw4; unsigned dw5; unsigned dw6; }; struct i915_3dmpeg_macroblock_ipicture { struct { unsigned pad0:5; unsigned dct_type:1; unsigned pad1:13; unsigned opcode:10; unsigned type:3; } dw0; }; struct i915_3dmpeg_set_origin { struct { unsigned length:19; unsigned opcode:10; unsigned type:3; } dw0; struct { unsigned v_origin:7; unsigned pad0:1; unsigned h_origin:7; unsigned pad1:17; } dw1; }; struct i915_3dmpeg_slice { struct { unsigned length:19; unsigned opcode:10; unsigned type:3; } dw0; struct { unsigned fst_mb_bit_off:3; unsigned pad0:5; unsigned mb_count:7; unsigned pad1:1; unsigned v_position:7; unsigned pad2:1; unsigned h_position:7; unsigned pad3:1; } dw1; struct { unsigned length_minus_one:17; unsigned pad0:7; unsigned qt_scale_code:5; unsigned pad1:3; } dw2; }; struct i915_3dmpeg_qm_palette_load { struct { unsigned length:4; unsigned pad0:15; unsigned opcode:10; unsigned type:3; } dw0; unsigned quantmatrix[16]; }; /* * 3DSTATE instruction */ #define BUFFERID_COLOR_BACK 3 #define BUFFERID_COLOR_AUX 4 #define BUFFERID_MC_INTRA_CORR 5 #define BUFFERID_DEPTH 7 #define TILEWALK_XMAJOR 0 #define TILEWALK_YMAJOR 1 struct i915_3dstate_buffer_info { struct { unsigned length:16; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned pad0:2; unsigned pitch:12; unsigned pad1:7; unsigned walk:1; unsigned tiled_surface:1; unsigned fence_regs:1; unsigned buffer_id:4; unsigned aux_id:1; unsigned pad2:3; } dw1; struct { unsigned pad0:2; unsigned base_address:27; unsigned pad1:3; } dw2; }; #define COLORBUFFER_8BIT 0x00 #define COLORBUFFER_X1R5G5B5 0x01 #define COLORBUFFER_R5G6B5 0x02 #define COLORBUFFER_A8R8G8B8 0x03 #define COLORBUFFER_YCRCB_SWAP 0x04 #define COLORBUFFER_YCRCB_NORMAL 0x05 #define COLORBUFFER_YCRCB_SWAPUV 0x06 #define COLORBUFFER_YCRCB_SWAPUVY 0x07 #define COLORBUFFER_A4R4G4B4 0x08 #define COLORBUFFER_A1R5G5B5 0x09 #define COLORBUFFER_A2R10G10B10 0x0a struct i915_3dstate_dest_buffer_variables { struct { unsigned length:16; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned v_ls_offset:1; unsigned v_ls:1; unsigned depth_fmt:2; unsigned pad0:4; unsigned color_fmt:4; unsigned yuv422_select:3; unsigned pad1:1; unsigned dest_v_bias:4; unsigned dest_h_bias:4; unsigned dither_enhancement:1; unsigned linear_gamma:1; unsigned dither_pattern:2; unsigned lod_preclamp:1; unsigned edt_zone:1; /* early depth test in zone rendering */ unsigned texture_default_color:1; unsigned edt_classic:1; /* early depth test in classic mode */ } dw1; }; #define MPEG_DECODE_MC 0 #define MPEG_DECODE_VLD_IDCT_MC 1 #define MPEG_I_PICTURE 1 #define MPEG_P_PICTURE 2 #define MPEG_B_PICTURE 3 #define MC_SUB_1H 0 #define MC_SUB_2H 1 #define MC_SUB_4H 2 #define MC_SUB_1V 0 #define MC_SUB_2V 1 struct i915_3dstate_dest_buffer_variables_mpeg { struct { unsigned length:16; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned picture_width:7; unsigned pad0:1; unsigned v_subsample_factor:2; unsigned h_subsample_factor:2; unsigned tff:1; unsigned mismatch:1; unsigned pad1:1; unsigned intra8:1; unsigned abort_on_error:8; unsigned pad2:4; unsigned bidir_avrg_control:1; unsigned rcontrol:1; unsigned decode_mode:2; } dw1; struct { unsigned pad0:1; unsigned picture_coding_type:2; unsigned pad1:2; unsigned scan_order:1; unsigned pad2:2; unsigned q_scale_type:1; unsigned concealment:1; unsigned fpf_dct:1; unsigned pad3:2; unsigned intra_dc:2; unsigned intra_vlc:1; unsigned f_code00:4; unsigned f_code01:4; unsigned f_code10:4; unsigned f_code11:4; } dw2; }; struct i915_mc_static_indirect_state_buffer { struct i915_3dstate_buffer_info dest_y; struct i915_3dstate_buffer_info dest_u; struct i915_3dstate_buffer_info dest_v; struct i915_3dstate_dest_buffer_variables dest_buf; struct i915_3dstate_dest_buffer_variables_mpeg dest_buf_mpeg; struct i915_3dstate_buffer_info corr; }; #define MAP_MAP0 0x0001 #define MAP_MAP1 0x0002 #define MAP_MAP2 0x0004 #define MAP_MAP3 0x0008 #define MAP_MAP4 0x0010 #define MAP_MAP5 0x0020 #define MAP_MAP6 0x0040 #define MAP_MAP7 0x0080 #define MAP_MAP8 0x0100 #define MAP_MAP9 0x0200 #define MAP_MAP10 0x0400 #define MAP_MAP11 0x0800 #define MAP_MAP12 0x1000 #define MAP_MAP13 0x2000 #define MAP_MAP14 0x4000 #define MAP_MAP15 0x8000 struct texture_map { struct { unsigned v_ls_offset:1; unsigned v_ls:1; unsigned base_address:27; unsigned pad0:2; unsigned untrusted:1; } tm0; struct { unsigned tile_walk:1; unsigned tiled_surface:1; unsigned utilize_fence_regs:1; unsigned texel_fmt:4; unsigned surface_fmt:3; unsigned width:11; unsigned height:11; } tm1; struct { unsigned depth:8; unsigned mipmap_layout:1; unsigned max_lod:6; unsigned cube_face:6; unsigned pitch:11; } tm2; }; struct i915_3dstate_map_state { struct { unsigned length:6; unsigned pad0:9; unsigned retain:1; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned map_mask:16; unsigned pad0:16; } dw1; }; struct i915_mc_map_state { struct i915_3dstate_map_state y_map; struct texture_map y_forward; struct texture_map y_backward; struct i915_3dstate_map_state u_map; struct texture_map u_forward; struct texture_map u_backward; struct i915_3dstate_map_state v_map; struct texture_map v_forward; struct texture_map v_backward; }; #define SAMPLER_SAMPLER0 0x0001 #define SAMPLER_SAMPLER1 0x0002 #define SAMPLER_SAMPLER2 0x0004 #define SAMPLER_SAMPLER3 0x0008 #define SAMPLER_SAMPLER4 0x0010 #define SAMPLER_SAMPLER5 0x0020 #define SAMPLER_SAMPLER6 0x0040 #define SAMPLER_SAMPLER7 0x0080 #define SAMPLER_SAMPLER8 0x0100 #define SAMPLER_SAMPLER9 0x0200 #define SAMPLER_SAMPLER10 0x0400 #define SAMPLER_SAMPLER11 0x0800 #define SAMPLER_SAMPLER12 0x1000 #define SAMPLER_SAMPLER13 0x2000 #define SAMPLER_SAMPLER14 0x4000 #define SAMPLER_SAMPLER15 0x8000 #define MIPFILTER_NONE 0 #define MIPFILTER_NEAREST 1 #define MIPFILTER_LINEAR 3 #define MAPFILTER_NEAREST 0 #define MAPFILTER_LINEAR 1 #define MAPFILTER_ANISOTROPIC 2 #define MAPFILTER_4X4_1 3 #define MAPFILTER_4X4_2 4 #define MAPFILTER_4X4_FLAT 5 #define MAPFILTER_MONO 6 #define ANISORATIO_2 0 #define ANISORATIO_4 1 #define PREFILTEROP_ALWAYS 0 #define PREFILTEROP_NEVER 1 #define PREFILTEROP_LESS 2 #define PREFILTEROP_EQUAL 3 #define PREFILTEROP_LEQUAL 4 #define PREFILTEROP_GREATER 5 #define PREFILTEROP_NOTEQUAL 6 #define PREFILTEROP_GEQUAL 7 #define TEXCOORDMODE_WRAP 0 #define TEXCOORDMODE_MIRROR 1 #define TEXCOORDMODE_CLAMP 2 #define TEXCOORDMODE_CUBE 3 #define TEXCOORDMODE_CLAMP_BORDER 4 #define TEXCOORDMODE_MIRROR_ONCE 5 struct texture_sampler { struct { unsigned shadow_function:3; unsigned max_anisotropy:1; unsigned shadow_enable:1; unsigned lod_bias:9; unsigned min_filter:3; unsigned mag_filter:3; unsigned mip_filter:2; unsigned base_level:5; unsigned chromakey_index:2; unsigned color_conversion:1; unsigned planar2packet:1; unsigned reverse_gamma:1; } ts0; struct { unsigned east_deinterlacer:1; unsigned map_index:4; unsigned normalized_coor:1; unsigned tcz_control:3; unsigned tcy_control:3; unsigned tcx_control:3; unsigned chromakey_enable:1; unsigned keyed_texture_filter:1; unsigned kill_pixel:1; unsigned pad0:6; unsigned min_lod:8; } ts1; struct { unsigned default_color; } ts2; }; struct i915_3dstate_sampler_state { struct { unsigned length:6; unsigned pad0:10; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned sampler_masker:16; unsigned pad0:16; } dw1; /* we always use two samplers for mc */ struct texture_sampler sampler0; struct texture_sampler sampler1; }; struct arithmetic_inst { struct { unsigned pad0:2; unsigned src0_reg:5; unsigned src0_reg_t:3; unsigned dest_channel_mask:4; unsigned dest_reg:4; unsigned pad1:1; unsigned dest_reg_t:3; unsigned dest_saturate:1; unsigned pad2:1; unsigned opcode:5; unsigned pad3:3; } dw0; struct { unsigned src1_y_select:3; unsigned src1_y_negate:1; unsigned src1_x_select:3; unsigned src1_x_negate:1; unsigned src1_reg:5; unsigned src1_reg_t:3; unsigned src0_w_select:3; unsigned src0_w_negate:1; unsigned src0_z_select:3; unsigned src0_z_negate:1; unsigned src0_y_select:3; unsigned src0_y_negate:1; unsigned src0_x_select:3; unsigned src0_x_negate:1; } dw1; struct { unsigned src2_w_select:3; unsigned src2_w_negate:1; unsigned src2_z_select:3; unsigned src2_z_negate:1; unsigned src2_y_select:3; unsigned src2_y_negate:1; unsigned src2_x_select:3; unsigned src2_x_negate:1; unsigned src2_reg:5; unsigned src2_reg_t:3; unsigned src1_w_select:3; unsigned src1_w_negate:1; unsigned src1_z_select:3; unsigned src1_z_negate:1; } dw2; }; struct texture_inst { struct { unsigned sampler_reg:4; unsigned pad0:10; unsigned dest_reg:4; unsigned pad1:1; unsigned dest_reg_t:3; unsigned pad2:2; unsigned opcode:5; unsigned pad3:3; } dw0; struct { unsigned pad0:16; unsigned address_reg:5; unsigned pad1:3; unsigned address_reg_t:3; unsigned pad2:5; } dw1; struct { unsigned pad0; } dw2; }; struct declaration_inst { struct { unsigned pad0:10; unsigned decl_channel_mask:4; unsigned decl_reg:4; unsigned pad1:1; unsigned decl_reg_t:2; unsigned pad2:1; unsigned sampler_type:2; unsigned opcode:5; unsigned pad3:3; } dw0; struct { unsigned pad0; } dw1; struct { unsigned pad0; } dw2; }; union shader_inst { struct arithmetic_inst a; struct texture_inst t; struct declaration_inst d; }; struct i915_3dstate_pixel_shader_header { unsigned length:9; unsigned pad0:6; unsigned retain:1; unsigned opcode:13; unsigned type:3; }; struct i915_3dstate_pixel_shader_program { struct i915_3dstate_pixel_shader_header shader0; /* mov oC, c0.0000 */ uint32_t inst0[3]; struct i915_3dstate_pixel_shader_header shader1; /* dcl t0.xy */ /* dcl t1.xy */ /* dcl_2D s0 */ /* texld r0, t0, s0 */ /* mov oC, r0 */ uint32_t inst1[3 * 5]; struct i915_3dstate_pixel_shader_header shader2; /* dcl t2.xy */ /* dcl t3.xy */ /* dcl_2D s1 */ /* texld r0, t2, s1 */ /* mov oC, r0 */ uint32_t inst2[3 * 5]; struct i915_3dstate_pixel_shader_header shader3; /* dcl t0.xy */ /* dcl t1.xy */ /* dcl t2.xy */ /* dcl t3.xy */ /* dcl_2D s0 */ /* dcl_2D s1 */ /* texld r0, t0, s0 */ /* texld r0, t2, s1 */ /* add r0, r0, r1 */ /* mov oC, r0 */ uint32_t inst3[3 * 10]; }; #define REG_CR0 0x00000001 #define REG_CR1 0x00000002 #define REG_CR2 0x00000004 #define REG_CR3 0x00000008 #define REG_CR4 0x00000010 #define REG_CR5 0x00000020 #define REG_CR6 0x00000040 #define REG_CR7 0x00000080 #define REG_CR8 0x00000100 #define REG_CR9 0x00000200 #define REG_CR10 0x00000400 #define REG_CR11 0x00000800 #define REG_CR12 0x00001000 #define REG_CR13 0x00002000 #define REG_CR14 0x00004000 #define REG_CR15 0x00008000 #define REG_CR16 0x00010000 #define REG_CR17 0x00020000 #define REG_CR18 0x00040000 #define REG_CR19 0x00080000 #define REG_CR20 0x00100000 #define REG_CR21 0x00200000 #define REG_CR22 0x00400000 #define REG_CR23 0x00800000 #define REG_CR24 0x01000000 #define REG_CR25 0x02000000 #define REG_CR26 0x04000000 #define REG_CR27 0x08000000 #define REG_CR28 0x10000000 #define REG_CR29 0x20000000 #define REG_CR30 0x40000000 #define REG_CR31 0x80000000 struct shader_constant { float x; float y; float z; float w; }; struct i915_3dstate_pixel_shader_constants { struct { unsigned length:8; unsigned pad0:8; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned reg_mask; } dw1; /* we only need one constant */ struct shader_constant value; }; #define BLOCK_SIS 0x01 #define BLOCK_DIS 0x02 #define BLOCK_SSB 0x04 #define BLOCK_MSB 0x08 #define BLOCK_PSP 0x10 #define BLOCK_PSC 0x20 #define BLOCK_MASK_SHIFT 8 typedef struct _state_ddword { struct { unsigned valid:1; unsigned force:1; unsigned buffer_address:30; } dw0; struct { unsigned length:9; unsigned pad0:23; } dw1; } sis_state, msb_state; #define STATE_VALID 0x1 #define STATE_FORCE 0x2 struct i915_3dstate_load_indirect { struct { unsigned length:8; unsigned block_mask:6; unsigned mem_select:1; unsigned pad0:1; unsigned opcode:13; unsigned type:3; } dw0; }; #define OP_3D_LOAD_INDIRECT_GFX_ADDR (1 << 14) #define TEXCOORDFMT_2FP 0x00 #define TEXCOORDFMT_3FP 0x01 #define TEXCOORDFMT_4FP 0x02 #define TEXCOORDFMT_1FP 0x03 #define TEXCOORDFMT_2FP_16 0x04 #define TEXCOORDFMT_4FP_16 0x05 #define TEXCOORDFMT_NOT_PRESENT 0x0f struct s2_dword { unsigned set0_texcoord_fmt:4; unsigned set1_texcoord_fmt:4; unsigned set2_texcoord_fmt:4; unsigned set3_texcoord_fmt:4; unsigned set4_texcoord_fmt:4; unsigned set5_texcoord_fmt:4; unsigned set6_texcoord_fmt:4; unsigned set7_texcoord_fmt:4; }; #define S3_SET0_PCD (1 << 0*4) #define S3_SET1_PCD (1 << 1*4) #define S3_SET2_PCD (1 << 2*4) #define S3_SET3_PCD (1 << 3*4) #define S3_SET4_PCD (1 << 4*4) #define S3_SET5_PCD (1 << 5*4) #define S3_SET6_PCD (1 << 6*4) #define S3_SET7_PCD (1 << 7*4) #define VERTEXHAS_XYZ 1 #define VERTEXHAS_XYZW 2 #define VERTEXHAS_XY 3 #define VERTEXHAS_XYW 4 #define CULLMODE_BOTH 0 #define CULLMODE_NONE 1 #define CULLMODE_CW 2 #define CULLMODE_CCW 3 #define SHADEMODE_LINEAR 0 #define SHADEMODE_FLAT 1 struct s4_dword { unsigned anti_aliasing_enable:1; unsigned sprite_point_enable:1; unsigned fog_parameter_present:1; unsigned local_depth_offset_enable:1; unsigned force_specular_diffuse_color:1; unsigned force_default_diffuse_color:1; unsigned position_mask:3; unsigned local_depth_offset_present:1; unsigned diffuse_color_presetn:1; unsigned specular_color_fog_factor_present:1; unsigned point_width_present:1; unsigned cull_mode:2; unsigned color_shade_mode:1; unsigned specular_shade_mode:1; unsigned fog_shade_mode:1; unsigned alpha_shade_mode:1; unsigned line_width:4; unsigned point_width:9; }; struct s5_dword { unsigned logic_op_enable:1; unsigned color_dither_enable:1; unsigned stencil_test_enable:1; unsigned stencil_buffer_write_enable:1; unsigned stencil_pass_depth_pass_op:3; unsigned stencil_pass_depth_fail_op:3; unsigned stencil_fail_op:3; unsigned stencil_test_function:3; unsigned stencil_reference_value:8; unsigned fog_enable:1; unsigned global_depth_offset_enable:1; unsigned last_pixel_enable:1; unsigned force_default_point_width:1; unsigned color_buffer_component_write_disable:4; }; #define S6_COLOR_BUFFER_WRITE (1 << 2) #define S6_DST_BLEND_FACTOR_SHIFT 4 #define S6_SRC_BLEND_FACTOR_SHIFT 8 #define S6_DEPTH_TEST_ENABLE (1 << 19) struct s7_dword { unsigned global_depth_offset_const; }; #define OP_3D_LOAD_STATE_IMM_LOAD_S0 (1 << 4) #define OP_3D_LOAD_STATE_IMM_LOAD_S1 (1 << 5) #define OP_3D_LOAD_STATE_IMM_LOAD_S2 (1 << 6) #define OP_3D_LOAD_STATE_IMM_LOAD_S3 (1 << 7) #define OP_3D_LOAD_STATE_IMM_LOAD_S4 (1 << 8) #define OP_3D_LOAD_STATE_IMM_LOAD_S5 (1 << 9) #define OP_3D_LOAD_STATE_IMM_LOAD_S6 (1 << 10) #define OP_3D_LOAD_STATE_IMM_LOAD_S7 (1 << 11) struct i915_3dstate_scissor_rectangle { struct { unsigned length:16; unsigned opcode:13; unsigned type:3; } dw0; struct { unsigned min_x:16; unsigned min_y:16; } dw1; struct { unsigned max_x:16; unsigned max_y:16; } dw2; }; #define VERTEX_INLINE 0x00 #define VERTEX_INDIRECT 0x01 #define PRIM_TRILIST 0x00 #define PRIM_TRISTRIP 0x01 #define PRIM_TRISTRIP_REVERSE 0x02 #define PRIM_TRIFAN 0x03 #define PRIM_POLYGON 0x04 #define PRIM_LINELIST 0x05 #define PRIM_LINESTRIP 0x06 #define PRIM_RECTLIST 0x07 #define PRIM_POINTLIST 0x08 #define PRIM_DIB 0x09 #define PRIM_CLEAR_RECT 0x0a #define PRIM_ZONE_INIT 0x0d struct texture_coordinate_set { unsigned tcx; unsigned tcy; }; struct vertex_data { unsigned x; unsigned y; struct texture_coordinate_set tc0; struct texture_coordinate_set tc1; }; struct i915_3dprimitive { union { struct { unsigned length:18; unsigned prim:5; unsigned vertex_location:1; unsigned opcode:5; unsigned type:3; } inline_prim; struct { unsigned vertex_count:16; unsigned pad0:1; unsigned vertex_access_mode:1; unsigned prim:5; unsigned vertex_location:1; unsigned opcode:5; unsigned type:3; } indirect_prim; } dw0; }; #endif /*_I915_STRUCTS_H */ xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i915_xvmc.c000066400000000000000000001203061267532330400231420ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Xiang Haihao * */ #include #include "i915_xvmc.h" #include "i915_structs.h" #include "i915_program.h" #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define STRIDE(w) (ALIGN((w), 1024)) #define SIZE_Y420(w, h) (h * STRIDE(w)) #define SIZE_UV420(w, h) ((h >> 1) * STRIDE(w >> 1)) #define SIZE_YUV420(w, h) (SIZE_Y420(w,h) + SIZE_UV420(w,h) * 2) #define UOFFSET(context) (SIZE_Y420(context->width, context->height)) #define VOFFSET(context) (SIZE_Y420(context->width, context->height) + \ SIZE_UV420(context->width, context->height)) typedef union { int16_t component[2]; int32_t v; } vector_t; static void i915_inst_arith(unsigned int *inst, unsigned int op, unsigned int dest, unsigned int mask, unsigned int saturate, unsigned int src0, unsigned int src1, unsigned int src2) { dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); inst++; *inst = (A1_SRC0(src0) | A1_SRC1(src1)); inst++; *inst = (A2_SRC1(src1) | A2_SRC2(src2)); } static void i915_inst_decl(unsigned int *inst, unsigned int type, unsigned int nr, unsigned int d0_flags) { unsigned int reg = UREG(type, nr); *inst = (D0_DCL | D0_DEST(reg) | d0_flags); inst++; *inst = D1_MBZ; inst++; *inst = D2_MBZ; } static void i915_inst_texld(unsigned int *inst, unsigned int op, unsigned int dest, unsigned int coord, unsigned int sampler) { dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler)); inst++; *inst = T1_ADDRESS_REG(coord); inst++; *inst = T2_MBZ; } static void i915_mc_one_time_context_init(XvMCContext * context) { unsigned int dest, src0, src1, src2; i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; int i; struct i915_3dstate_sampler_state *sampler_state; struct i915_3dstate_pixel_shader_program *pixel_shader_program; struct i915_3dstate_pixel_shader_constants *pixel_shader_constants; /* sampler static state */ drm_intel_gem_bo_map_gtt(pI915XvMC->ssb_bo); sampler_state = pI915XvMC->ssb_bo->virtual; memset(sampler_state, 0, sizeof(*sampler_state)); sampler_state->dw0.type = CMD_3D; sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE; sampler_state->dw0.length = 6; sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1; sampler_state->sampler0.ts0.reverse_gamma = 0; sampler_state->sampler0.ts0.planar2packet = 0; sampler_state->sampler0.ts0.color_conversion = 0; sampler_state->sampler0.ts0.chromakey_index = 0; sampler_state->sampler0.ts0.base_level = 0; sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */ sampler_state->sampler0.ts0.shadow_enable = 0; sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2; sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS; sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ sampler_state->sampler0.ts1.kill_pixel = 0; sampler_state->sampler0.ts1.keyed_texture_filter = 0; sampler_state->sampler0.ts1.chromakey_enable = 0; sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP; sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP; sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP; sampler_state->sampler0.ts1.normalized_coor = 0; sampler_state->sampler0.ts1.map_index = 0; sampler_state->sampler0.ts1.east_deinterlacer = 0; sampler_state->sampler0.ts2.default_color = 0; sampler_state->sampler1.ts0.reverse_gamma = 0; sampler_state->sampler1.ts0.planar2packet = 0; sampler_state->sampler1.ts0.color_conversion = 0; sampler_state->sampler1.ts0.chromakey_index = 0; sampler_state->sampler1.ts0.base_level = 0; sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */ sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */ sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */ sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */ sampler_state->sampler1.ts0.shadow_enable = 0; sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2; sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS; sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */ sampler_state->sampler1.ts1.kill_pixel = 0; sampler_state->sampler1.ts1.keyed_texture_filter = 0; sampler_state->sampler1.ts1.chromakey_enable = 0; sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP; sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP; sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP; sampler_state->sampler1.ts1.normalized_coor = 0; sampler_state->sampler1.ts1.map_index = 1; sampler_state->sampler1.ts1.east_deinterlacer = 0; sampler_state->sampler1.ts2.default_color = 0; drm_intel_gem_bo_unmap_gtt(pI915XvMC->ssb_bo); /* pixel shader static state */ drm_intel_gem_bo_map_gtt(pI915XvMC->psp_bo); pixel_shader_program = pI915XvMC->psp_bo->virtual; memset(pixel_shader_program, 0, sizeof(*pixel_shader_program)); pixel_shader_program->shader0.type = CMD_3D; pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; pixel_shader_program->shader0.retain = 1; pixel_shader_program->shader0.length = 2; /* 1 inst */ i = 0; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_CONST, 0); src1 = 0; src2 = 0; i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); pixel_shader_program->shader1.type = CMD_3D; pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; pixel_shader_program->shader1.retain = 1; pixel_shader_program->shader1.length = 14; /* 5 inst */ i = 0; /* dcl t0.xy */ i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); i += 3; /* dcl t1.xy */ i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl_2D s0 */ i += 3; i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); pixel_shader_program->shader2.type = CMD_3D; pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; pixel_shader_program->shader2.retain = 1; pixel_shader_program->shader2.length = 14; /* 5 inst */ i = 0; /* dcl t2.xy */ i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ i += 3; i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s1 */ i += 3; i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t2, s1 */ i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1); /* mov oC, r0 */ i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = src2 = 0; i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); /* Shader 3 */ pixel_shader_program->shader3.type = CMD_3D; pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM; pixel_shader_program->shader3.retain = 1; pixel_shader_program->shader3.length = 29; /* 10 inst */ i = 0; /* dcl t0.xy */ i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY); /* dcl t1.xy */ i += 3; i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY); /* dcl t2.xy */ i += 3; i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY); /* dcl t3.xy */ i += 3; i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY); /* dcl_2D s0 */ i += 3; i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D); /* dcl_2D s1 */ i += 3; i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D); /* texld r0, t0, s0 */ i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_T, 0); /* COORD */ src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */ i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* texld r1, t2, s1 */ i += 3; dest = UREG(REG_TYPE_R, 1); src0 = UREG(REG_TYPE_T, 2); /* COORD */ src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */ i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1); /* add r0, r0, r1 */ i += 3; dest = UREG(REG_TYPE_R, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_R, 1); src2 = 0; i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL, 0 /* A0_DEST_SATURATE */ , src0, src1, src2); /* mul oC, r0, c0 */ i += 3; dest = UREG(REG_TYPE_OC, 0); src0 = UREG(REG_TYPE_R, 0); src1 = UREG(REG_TYPE_CONST, 0); src2 = 0; i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2); drm_intel_gem_bo_unmap_gtt(pI915XvMC->psp_bo); /* pixel shader contant static state */ drm_intel_gem_bo_map_gtt(pI915XvMC->psc_bo); pixel_shader_constants = pI915XvMC->psc_bo->virtual; memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants)); pixel_shader_constants->dw0.type = CMD_3D; pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS; pixel_shader_constants->dw0.length = 4; pixel_shader_constants->dw1.reg_mask = REG_CR0; pixel_shader_constants->value.x = 0.5; pixel_shader_constants->value.y = 0.5; pixel_shader_constants->value.z = 0.5; pixel_shader_constants->value.w = 0.5; drm_intel_gem_bo_unmap_gtt(pI915XvMC->psc_bo); } static void i915_mc_one_time_state_emit(XvMCContext * context) { i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; uint32_t load_state_immediate_1, load_indirect, s3_dword, s6_dword; int mem_select; BATCH_LOCALS; /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */ BEGIN_BATCH(3 + 8); load_state_immediate_1 = OP_3D_LOAD_STATE_IMMEDIATE_1; load_state_immediate_1 |= OP_3D_LOAD_STATE_IMM_LOAD_S3; load_state_immediate_1 |= OP_3D_LOAD_STATE_IMM_LOAD_S6; load_state_immediate_1 |= 3 - 2; /* length */ OUT_BATCH(load_state_immediate_1); s3_dword = S3_SET0_PCD | S3_SET1_PCD | S3_SET2_PCD | S3_SET3_PCD | S3_SET4_PCD | S3_SET5_PCD | S3_SET6_PCD | S3_SET7_PCD; OUT_BATCH(s3_dword); s6_dword = S6_COLOR_BUFFER_WRITE | S6_DEPTH_TEST_ENABLE; s6_dword |= 1 << S6_SRC_BLEND_FACTOR_SHIFT; s6_dword |= 1 << S6_DST_BLEND_FACTOR_SHIFT; OUT_BATCH(s6_dword); /* 3DSTATE_LOAD_INDIRECT */ load_indirect = OP_3D_LOAD_INDIRECT; load_indirect |= (BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC) << BLOCK_MASK_SHIFT; load_indirect |= 8 - 2; /* length */ if (pI915XvMC->use_phys_addr) mem_select = 0; /* use physical address */ else { load_indirect |= OP_3D_LOAD_INDIRECT_GFX_ADDR; mem_select = 1; /* use gfx address */ } OUT_BATCH(load_indirect); /* Dynamic indirect state buffer */ OUT_BATCH(0); /* no dynamic indirect state */ /* Sample state buffer */ OUT_RELOC(pI915XvMC->ssb_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, STATE_VALID | STATE_FORCE); OUT_BATCH(7); /* 8 - 1 */ /* Pixel shader program buffer */ OUT_RELOC(pI915XvMC->psp_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, STATE_VALID | STATE_FORCE); OUT_BATCH(66); /* 4 + 16 + 16 + 31 - 1 */ /* Pixel shader constant buffer */ OUT_RELOC(pI915XvMC->psc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, STATE_VALID | STATE_FORCE); OUT_BATCH(5); /* 6 - 1 */ ADVANCE_BATCH(); } static void i915_mc_static_indirect_state_set(XvMCContext * context, XvMCSurface * dest, unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type) { i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; struct intel_xvmc_surface *intel_surf = dest->privData; struct i915_mc_static_indirect_state_buffer *buffer_info; drm_intel_gem_bo_map_gtt(pI915XvMC->sis_bo); buffer_info = pI915XvMC->sis_bo->virtual; memset(buffer_info, 0, sizeof(*buffer_info)); /* dest Y */ buffer_info->dest_y.dw0.type = CMD_3D; buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; buffer_info->dest_y.dw0.length = 1; buffer_info->dest_y.dw1.aux_id = 0; buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK; buffer_info->dest_y.dw1.fence_regs = 0; /* disabled *//* FIXME: tiled y for performance */ buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */ buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR; buffer_info->dest_y.dw1.pitch = (pI915XvMC->yStride >> 2); /* in DWords */ buffer_info->dest_y.dw2.base_address = intel_surf->bo->offset >> 2; /* starting DWORD address */ drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, offsetof(typeof(*buffer_info),dest_y.dw2), intel_surf->bo, 0, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); /* dest U */ buffer_info->dest_u.dw0.type = CMD_3D; buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; buffer_info->dest_u.dw0.length = 1; buffer_info->dest_u.dw1.aux_id = 0; buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX; buffer_info->dest_u.dw1.fence_regs = 0; buffer_info->dest_u.dw1.tiled_surface = 0; buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR; buffer_info->dest_u.dw1.pitch = (pI915XvMC->uvStride >> 2); /* in DWords */ buffer_info->dest_u.dw2.base_address = (intel_surf->bo->offset + UOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, offsetof(typeof(*buffer_info),dest_u.dw2), intel_surf->bo, UOFFSET(context), I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); /* dest V */ buffer_info->dest_v.dw0.type = CMD_3D; buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; buffer_info->dest_v.dw0.length = 1; buffer_info->dest_v.dw1.aux_id = 1; buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX; buffer_info->dest_v.dw1.fence_regs = 0; buffer_info->dest_v.dw1.tiled_surface = 0; buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR; buffer_info->dest_v.dw1.pitch = (pI915XvMC->uvStride >> 2); /* in Dwords */ buffer_info->dest_v.dw2.base_address = (intel_surf->bo->offset + VOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, offsetof(typeof(*buffer_info),dest_v.dw2), intel_surf->bo, VOFFSET(context), I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); /* Dest buffer parameters */ buffer_info->dest_buf.dw0.type = CMD_3D; buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES; buffer_info->dest_buf.dw0.length = 0; buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */ buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */ buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT; buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */ buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */ if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { ; } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) { buffer_info->dest_buf.dw1.v_ls = 1; } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) { buffer_info->dest_buf.dw1.v_ls = 1; buffer_info->dest_buf.dw1.v_ls_offset = 1; } /* MPEG buffer parameters */ buffer_info->dest_buf_mpeg.dw0.type = CMD_3D; buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG; buffer_info->dest_buf_mpeg.dw0.length = 1; buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC; buffer_info->dest_buf_mpeg.dw1.rcontrol = 0; /* for MPEG-1/MPEG-2 */ buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0; /* for MPEG-1/MPEG-2/MPEG-4 */ buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1; buffer_info->dest_buf_mpeg.dw1.intra8 = 0; /* 16-bit formatted correction data */ buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */ buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V; buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H; if (picture_structure & XVMC_FRAME_PICTURE) { ; } else if (picture_structure & XVMC_TOP_FIELD) { if (flags & XVMC_SECOND_FIELD) buffer_info->dest_buf_mpeg.dw1.tff = 0; else buffer_info->dest_buf_mpeg.dw1.tff = 1; } else if (picture_structure & XVMC_BOTTOM_FIELD) { if (flags & XVMC_SECOND_FIELD) buffer_info->dest_buf_mpeg.dw1.tff = 1; else buffer_info->dest_buf_mpeg.dw1.tff = 0; } buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4); /* in macroblocks */ buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type; buffer_info->corr.dw0.type = CMD_3D; buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO; buffer_info->corr.dw0.length = 1; buffer_info->corr.dw1.aux_id = 0; buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR; buffer_info->corr.dw1.aux_id = 0; buffer_info->corr.dw1.fence_regs = 0; buffer_info->corr.dw1.tiled_surface = 0; buffer_info->corr.dw1.walk = 0; buffer_info->corr.dw1.pitch = 0; buffer_info->corr.dw2.base_address = pI915XvMC->corrdata_bo->offset >> 2; /* starting DWORD address */ drm_intel_bo_emit_reloc(pI915XvMC->sis_bo, offsetof(typeof(*buffer_info),corr.dw2), pI915XvMC->corrdata_bo, 0, I915_GEM_DOMAIN_RENDER, 0); drm_intel_gem_bo_unmap_gtt(pI915XvMC->sis_bo); } static void i915_mc_map_state_set(XvMCContext * context, struct intel_xvmc_surface * privPast, struct intel_xvmc_surface * privFuture) { i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; struct i915_mc_map_state *map_state; unsigned int w = context->width; unsigned int h = context->height; drm_intel_gem_bo_map_gtt(pI915XvMC->msb_bo); map_state = pI915XvMC->msb_bo->virtual; memset(map_state, 0, sizeof(*map_state)); /* 3DSATE_MAP_STATE: Y */ map_state->y_map.dw0.type = CMD_3D; map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; map_state->y_map.dw0.retain = 1; map_state->y_map.dw0.length = 6; map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; /* Y Forward (Past) */ map_state->y_forward.tm0.v_ls_offset = 0; map_state->y_forward.tm0.v_ls = 0; map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->y_forward.tm1.tiled_surface = 0; map_state->y_forward.tm1.utilize_fence_regs = 0; map_state->y_forward.tm1.texel_fmt = 0; /* 8bit */ map_state->y_forward.tm1.surface_fmt = 1; /* 8bit */ map_state->y_forward.tm1.width = w - 1; map_state->y_forward.tm1.height = h - 1; map_state->y_forward.tm2.depth = 0; map_state->y_forward.tm2.max_lod = 0; map_state->y_forward.tm2.cube_face = 0; map_state->y_forward.tm0.base_address = privPast->bo->offset >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),y_forward.tm0), privPast->bo, 0, I915_GEM_DOMAIN_SAMPLER, 0); map_state->y_forward.tm2.pitch = (pI915XvMC->yStride >> 2) - 1; /* in DWords - 1 */ /* Y Backward (Future) */ map_state->y_backward.tm0.v_ls_offset = 0; map_state->y_backward.tm0.v_ls = 0; map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->y_backward.tm1.tiled_surface = 0; map_state->y_backward.tm1.utilize_fence_regs = 0; map_state->y_backward.tm1.texel_fmt = 0; /* 8bit */ map_state->y_backward.tm1.surface_fmt = 1; /* 8bit */ map_state->y_backward.tm1.width = w - 1; map_state->y_backward.tm1.height = h - 1; map_state->y_backward.tm2.depth = 0; map_state->y_backward.tm2.max_lod = 0; map_state->y_backward.tm2.cube_face = 0; map_state->y_backward.tm0.base_address = privFuture->bo->offset >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),y_backward.tm0), privFuture->bo, 0, I915_GEM_DOMAIN_SAMPLER, 0); map_state->y_backward.tm2.pitch = (pI915XvMC->yStride >> 2) - 1; /* 3DSATE_MAP_STATE: U */ map_state->u_map.dw0.type = CMD_3D; map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; map_state->u_map.dw0.retain = 1; map_state->u_map.dw0.length = 6; map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; /* U Forward */ map_state->u_forward.tm0.v_ls_offset = 0; map_state->u_forward.tm0.v_ls = 0; map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->u_forward.tm1.tiled_surface = 0; map_state->u_forward.tm1.utilize_fence_regs = 0; map_state->u_forward.tm1.texel_fmt = 0; /* 8bit */ map_state->u_forward.tm1.surface_fmt = 1; /* 8bit */ map_state->u_forward.tm1.width = (w >> 1) - 1; map_state->u_forward.tm1.height = (h >> 1) - 1; map_state->u_forward.tm2.depth = 0; map_state->u_forward.tm2.max_lod = 0; map_state->u_forward.tm2.cube_face = 0; map_state->u_forward.tm0.base_address = (privPast->bo->offset + UOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),u_forward.tm0), privPast->bo, UOFFSET(context), I915_GEM_DOMAIN_SAMPLER, 0); map_state->u_forward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; /* in DWords - 1 */ /* U Backward */ map_state->u_backward.tm0.v_ls_offset = 0; map_state->u_backward.tm0.v_ls = 0; map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->u_backward.tm1.tiled_surface = 0; map_state->u_backward.tm1.utilize_fence_regs = 0; map_state->u_backward.tm1.texel_fmt = 0; map_state->u_backward.tm1.surface_fmt = 1; map_state->u_backward.tm1.width = (w >> 1) - 1; map_state->u_backward.tm1.height = (h >> 1) - 1; map_state->u_backward.tm2.depth = 0; map_state->u_backward.tm2.max_lod = 0; map_state->u_backward.tm2.cube_face = 0; map_state->u_backward.tm0.base_address = (privFuture->bo->offset + UOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),u_backward.tm0), privFuture->bo, UOFFSET(context), I915_GEM_DOMAIN_SAMPLER, 0); map_state->u_backward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; /* 3DSATE_MAP_STATE: V */ map_state->v_map.dw0.type = CMD_3D; map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE; map_state->v_map.dw0.retain = 1; map_state->v_map.dw0.length = 6; map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1; /* V Forward */ map_state->v_forward.tm0.v_ls_offset = 0; map_state->v_forward.tm0.v_ls = 0; map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->v_forward.tm1.tiled_surface = 0; map_state->v_forward.tm1.utilize_fence_regs = 0; map_state->v_forward.tm1.texel_fmt = 0; map_state->v_forward.tm1.surface_fmt = 1; map_state->v_forward.tm1.width = (w >> 1) - 1; map_state->v_forward.tm1.height = (h >> 1) - 1; map_state->v_forward.tm2.depth = 0; map_state->v_forward.tm2.max_lod = 0; map_state->v_forward.tm2.cube_face = 0; map_state->v_forward.tm0.base_address = (privPast->bo->offset + VOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),v_forward.tm0), privPast->bo, VOFFSET(context), I915_GEM_DOMAIN_SAMPLER, 0); map_state->v_forward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; /* in DWords - 1 */ /* V Backward */ map_state->v_backward.tm0.v_ls_offset = 0; map_state->v_backward.tm0.v_ls = 0; map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR; map_state->v_backward.tm1.tiled_surface = 0; map_state->v_backward.tm1.utilize_fence_regs = 0; map_state->v_backward.tm1.texel_fmt = 0; map_state->v_backward.tm1.surface_fmt = 1; map_state->v_backward.tm1.width = (w >> 1) - 1; map_state->v_backward.tm1.height = (h >> 1) - 1; map_state->v_backward.tm2.depth = 0; map_state->v_backward.tm2.max_lod = 0; map_state->v_backward.tm2.cube_face = 0; map_state->v_backward.tm0.base_address = (privFuture->bo->offset + VOFFSET(context)) >> 2; drm_intel_bo_emit_reloc(pI915XvMC->msb_bo, offsetof(typeof(*map_state),v_backward.tm0), privFuture->bo, VOFFSET(context), I915_GEM_DOMAIN_SAMPLER, 0); map_state->v_backward.tm2.pitch = (pI915XvMC->uvStride >> 2) - 1; drm_intel_gem_bo_unmap_gtt(pI915XvMC->msb_bo); } static void i915_mc_load_indirect_render_emit(XvMCContext * context) { i915XvMCContext *pI915XvMC = (i915XvMCContext *) context->privData; int mem_select; uint32_t load_indirect; BATCH_LOCALS; BEGIN_BATCH(5); load_indirect = OP_3D_LOAD_INDIRECT; load_indirect |= (BLOCK_SIS | BLOCK_MSB) << BLOCK_MASK_SHIFT; load_indirect |= 5 - 2; /* length */ if (pI915XvMC->use_phys_addr) mem_select = 0; /* use physical address */ else { load_indirect |= OP_3D_LOAD_INDIRECT_GFX_ADDR; mem_select = 1; /* use gfx address */ } OUT_BATCH(load_indirect); /* Static Indirect state buffer (dest buffer info) */ OUT_RELOC(pI915XvMC->sis_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, STATE_VALID | STATE_FORCE); OUT_BATCH(16); /* 4 * 3 + 2 + 3 - 1 */ /* Map state buffer (reference buffer info) */ OUT_RELOC(pI915XvMC->msb_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, STATE_VALID | STATE_FORCE); OUT_BATCH(23); /* 3 * 8 - 1 */ ADVANCE_BATCH(); } static void i915_mc_mpeg_set_origin(XvMCContext * context, XvMCMacroBlock * mb) { struct i915_3dmpeg_set_origin set_origin; /* 3DMPEG_SET_ORIGIN */ memset(&set_origin, 0, sizeof(set_origin)); set_origin.dw0.type = CMD_3D; set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN; set_origin.dw0.length = 0; set_origin.dw1.h_origin = mb->x; set_origin.dw1.v_origin = mb->y; intelBatchbufferData(&set_origin, sizeof(set_origin), 0); } static void i915_mc_mpeg_macroblock_ipicture(XvMCContext * context, XvMCMacroBlock * mb) { struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture; /* 3DMPEG_MACROBLOCK_IPICTURE */ memset(¯oblock_ipicture, 0, sizeof(macroblock_ipicture)); macroblock_ipicture.dw0.type = CMD_3D; macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE; macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); intelBatchbufferData(¯oblock_ipicture, sizeof(macroblock_ipicture), 0); } static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext * context, XvMCMacroBlock * mb) { struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv; vector_t mv0[2]; /* 3DMPEG_MACROBLOCK(1fbmv) */ memset(¯oblock_1fbmv, 0, sizeof(macroblock_1fbmv)); macroblock_1fbmv.header.dw0.type = CMD_3D; macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; macroblock_1fbmv.header.dw0.length = 2; macroblock_1fbmv.header.dw1.mb_intra = 0; /* should be 0 */ macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); macroblock_1fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); if (!(mb->coded_block_pattern & 0x3f)) macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; macroblock_1fbmv.header.dw1.skipped_macroblocks = 0; mv0[0].component[0] = mb->PMV[0][0][0]; mv0[0].component[1] = mb->PMV[0][0][1]; mv0[1].component[0] = mb->PMV[0][1][0]; mv0[1].component[1] = mb->PMV[0][1][1]; macroblock_1fbmv.dw2 = mv0[0].v; macroblock_1fbmv.dw3 = mv0[1].v; intelBatchbufferData(¯oblock_1fbmv, sizeof(macroblock_1fbmv), 0); } static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext * context, XvMCMacroBlock * mb, unsigned int ps) { struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv; vector_t mv0[2]; vector_t mv1[2]; /* 3DMPEG_MACROBLOCK(2fbmv) */ memset(¯oblock_2fbmv, 0, sizeof(macroblock_2fbmv)); macroblock_2fbmv.header.dw0.type = CMD_3D; macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK; macroblock_2fbmv.header.dw0.length = 4; macroblock_2fbmv.header.dw1.mb_intra = 0; /* should be 0 */ macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0); macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0); macroblock_2fbmv.header.dw1.h263_4mv = 0; /* should be 0 */ macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD); if (!(mb->coded_block_pattern & 0x3f)) macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME; macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03); macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f); macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern; macroblock_2fbmv.header.dw1.skipped_macroblocks = 0; mv0[0].component[0] = mb->PMV[0][0][0]; mv0[0].component[1] = mb->PMV[0][0][1]; mv0[1].component[0] = mb->PMV[0][1][0]; mv0[1].component[1] = mb->PMV[0][1][1]; mv1[0].component[0] = mb->PMV[1][0][0]; mv1[0].component[1] = mb->PMV[1][0][1]; mv1[1].component[0] = mb->PMV[1][1][0]; mv1[1].component[1] = mb->PMV[1][1][1]; if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { mv0[0].component[1] = mb->PMV[0][0][1] >> 1; mv0[1].component[1] = mb->PMV[0][1][1] >> 1; mv1[0].component[1] = mb->PMV[1][0][1] >> 1; mv1[1].component[1] = mb->PMV[1][1][1] >> 1; } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) { mv0[0].component[1] = mb->PMV[0][0][1] >> 1; mv0[1].component[1] = mb->PMV[0][1][1] >> 1; // MPEG2 MV[0][1] isn't used mv1[0].component[1] = mb->PMV[1][0][1] >> 1; mv1[1].component[1] = mb->PMV[1][1][1] >> 1; } } macroblock_2fbmv.dw2 = mv0[0].v; macroblock_2fbmv.dw3 = mv0[1].v; macroblock_2fbmv.dw4 = mv1[0].v; macroblock_2fbmv.dw5 = mv1[1].v; intelBatchbufferData(¯oblock_2fbmv, sizeof(macroblock_2fbmv), 0); } static int i915_xvmc_alloc_one_time_buffers(i915XvMCContext *pI915XvMC) { pI915XvMC->ssb_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "ssb", GTT_PAGE_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->ssb_bo) return 0; pI915XvMC->psp_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "psp", GTT_PAGE_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->psp_bo) return 0; pI915XvMC->psc_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "psc", GTT_PAGE_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->psc_bo) return 0; return 1; } static void i915_xvmc_free_one_time_buffers(i915XvMCContext *pI915XvMC) { drm_intel_bo_unreference(pI915XvMC->ssb_bo); drm_intel_bo_unreference(pI915XvMC->psp_bo); drm_intel_bo_unreference(pI915XvMC->psc_bo); } /* * Function: i915_release_resource */ static void i915_release_resource(Display * display, XvMCContext * context) { i915XvMCContext *pI915XvMC; if (!(pI915XvMC = context->privData)) return; i915_xvmc_free_one_time_buffers(pI915XvMC); free(pI915XvMC); context->privData = NULL; } static Status i915_xvmc_mc_create_context(Display * display, XvMCContext * context, int priv_count, CARD32 * priv_data) { i915XvMCContext *pI915XvMC = NULL; struct intel_xvmc_hw_context *tmpComm = NULL; if (priv_count != (sizeof(struct intel_xvmc_hw_context) >> 2)) { XVMC_ERR ("_xvmc_create_context() returned incorrect data size!"); XVMC_INFO("\tExpected %d, got %d", (int)(sizeof(struct intel_xvmc_hw_context) >> 2), priv_count); _xvmc_destroy_context(display, context); XFree(priv_data); context->privData = NULL; return BadValue; } context->privData = (void *)calloc(1, sizeof(i915XvMCContext)); if (!context->privData) { XVMC_ERR("Unable to allocate resources for XvMC context."); return BadAlloc; } pI915XvMC = (i915XvMCContext *) context->privData; tmpComm = (struct intel_xvmc_hw_context *) priv_data; pI915XvMC->use_phys_addr = tmpComm->i915.use_phys_addr; pI915XvMC->comm.surface_bo_size = SIZE_YUV420(context->width, context->height); /* Must free the private data we were passed from X */ XFree(priv_data); priv_data = NULL; if (!i915_xvmc_alloc_one_time_buffers(pI915XvMC)) goto free_one_time_buffers; /* Initialize private context values */ pI915XvMC->yStride = STRIDE(context->width); pI915XvMC->uvStride = STRIDE(context->width >> 1); /* pre-init state buffers */ i915_mc_one_time_context_init(context); return Success; free_one_time_buffers: i915_xvmc_free_one_time_buffers(pI915XvMC); free(pI915XvMC); context->privData = NULL; return BadAlloc; } static int i915_xvmc_mc_destroy_context(Display * display, XvMCContext * context) { i915XvMCContext *pI915XvMC; if (!(pI915XvMC = context->privData)) return XvMCBadContext; /* Pass Control to the X server to destroy the drm_context_t */ i915_release_resource(display, context); return Success; } static int i915_xvmc_alloc_render_state_buffers(i915XvMCContext *pI915XvMC) { pI915XvMC->sis_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "sis", GTT_PAGE_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->sis_bo) return 0; pI915XvMC->msb_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "msb", GTT_PAGE_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->msb_bo) return 0; pI915XvMC->corrdata_bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "corrdata", CORRDATA_SIZE, GTT_PAGE_SIZE); if (!pI915XvMC->corrdata_bo) return 0; return 1; } static void i915_xvmc_free_render_state_buffers(i915XvMCContext *pI915XvMC) { drm_intel_bo_unreference(pI915XvMC->sis_bo); drm_intel_bo_unreference(pI915XvMC->msb_bo); drm_intel_bo_unreference(pI915XvMC->corrdata_bo); } static int i915_xvmc_mc_render_surface(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) { int i; int picture_coding_type = MPEG_I_PICTURE; /* correction data buffer */ char *corrdata_ptr; int corrdata_size = 0; /* Block Pointer */ short *block_ptr; /* Current Macroblock Pointer */ XvMCMacroBlock *mb; intel_xvmc_context_ptr intel_ctx; struct intel_xvmc_surface *privTarget = NULL; struct intel_xvmc_surface *privFuture = NULL; struct intel_xvmc_surface *privPast = NULL; i915XvMCContext *pI915XvMC = NULL; /* Check Parameters for validity */ if (!display || !context || !target_surface) { XVMC_ERR("Invalid Display, Context or Target!"); return BadValue; } if (!num_macroblocks) return Success; if (!macroblock_array || !blocks) { XVMC_ERR("Invalid block data!"); return BadValue; } if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) { XVMC_ERR("Too many macroblocks requested for MB array size."); return BadValue; } if (!(pI915XvMC = context->privData)) return XvMCBadContext; if (!(privTarget = target_surface->privData)) return XvMCBadSurface; if (!i915_xvmc_alloc_render_state_buffers(pI915XvMC)) return BadAlloc; intel_ctx = context->privData; if (!intel_ctx) { XVMC_ERR("Can't find intel xvmc context\n"); return BadValue; } /* P Frame Test */ if (!past_surface) { /* Just to avoid some ifs later. */ privPast = privTarget; } else { if (!(privPast = past_surface->privData)) { return XvMCBadSurface; } picture_coding_type = MPEG_P_PICTURE; } /* B Frame Test */ if (!future_surface) { privFuture = privPast; // privTarget; } else { if (!past_surface) { XVMC_ERR("No Past Surface!"); return BadValue; } if (!(privFuture = future_surface->privData)) { XVMC_ERR("Invalid Future Surface!"); return XvMCBadSurface; } picture_coding_type = MPEG_B_PICTURE; } LOCK_HARDWARE(intel_ctx->hw_context); drm_intel_gem_bo_map_gtt(pI915XvMC->corrdata_bo); corrdata_ptr = pI915XvMC->corrdata_bo->virtual; corrdata_size = 0; for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { int bspm = 0; mb = ¯oblock_array->macro_blocks[i]; block_ptr = &(blocks->blocks[mb->index << 6]); /* Lockup can happen if the coordinates are too far out of range */ if (mb->x > (target_surface->width >> 4)) { mb->x = 0; XVMC_INFO("reset x"); } if (mb->y > (target_surface->height >> 4)) { mb->y = 0; XVMC_INFO("reset y"); } /* Catch no pattern case */ if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) && !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) && mb->coded_block_pattern) { mb->coded_block_pattern = 0; XVMC_INFO("no coded blocks present!"); } bspm = mb_bytes_420[mb->coded_block_pattern]; if (!bspm) continue; corrdata_size += bspm; if (corrdata_size > CORRDATA_SIZE) { XVMC_ERR("correction data buffer overflow."); break; } memcpy(corrdata_ptr, block_ptr, bspm); corrdata_ptr += bspm; } drm_intel_gem_bo_unmap_gtt(pI915XvMC->corrdata_bo); // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC); i915_mc_one_time_state_emit(context); i915_mc_static_indirect_state_set(context, target_surface, picture_structure, flags, picture_coding_type); /* setup reference surfaces */ i915_mc_map_state_set(context, privPast, privFuture); i915_mc_load_indirect_render_emit(context); i915_mc_mpeg_set_origin(context, ¯oblock_array->macro_blocks [first_macroblock]); for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) { mb = ¯oblock_array->macro_blocks[i]; /* Intra Blocks */ if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { i915_mc_mpeg_macroblock_ipicture(context, mb); } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) { /* Frame Picture */ switch (mb->motion_type & 3) { case XVMC_PREDICTION_FIELD: /* Field Based */ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); break; case XVMC_PREDICTION_FRAME: /* Frame Based */ i915_mc_mpeg_macroblock_1fbmv(context, mb); break; case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); break; default: /* No Motion Type */ XVMC_ERR ("Invalid Macroblock Parameters found."); break; } } else { /* Field Picture */ switch (mb->motion_type & 3) { case XVMC_PREDICTION_FIELD: /* Field Based */ i915_mc_mpeg_macroblock_1fbmv(context, mb); break; case XVMC_PREDICTION_16x8: /* 16x8 MC */ i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure); break; case XVMC_PREDICTION_DUAL_PRIME: /* Dual Prime */ i915_mc_mpeg_macroblock_1fbmv(context, mb); break; default: /* No Motion Type */ XVMC_ERR ("Invalid Macroblock Parameters found."); break; } } } intelFlushBatch(); i915_xvmc_free_render_state_buffers(pI915XvMC); UNLOCK_HARDWARE(intel_ctx->hw_context); return 0; } struct _intel_xvmc_driver i915_xvmc_mc_driver = { .type = XVMC_I915_MPEG2_MC, .num_ctx = 0, .ctx_list = NULL, .create_context = i915_xvmc_mc_create_context, .destroy_context = i915_xvmc_mc_destroy_context, .render_surface = i915_xvmc_mc_render_surface, }; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i915_xvmc.h000066400000000000000000000052021267532330400231440ustar00rootroot00000000000000/* * Copyright © 2006 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Xiang Haihao * */ #ifndef _I915XVMC_H #define _I915XVMC_H #include "intel_xvmc_private.h" #define I915_SUBPIC_PALETTE_SIZE 16 #define MAX_SUBCONTEXT_LEN 1024 #define PCI_CHIP_I915_G 0x2582 #define PCI_CHIP_I915_GM 0x2592 #define PCI_CHIP_I945_G 0x2772 #define PCI_CHIP_I945_GM 0x27A2 #define PCI_CHIP_I945_GME 0x27AE #define PCI_CHIP_G33_G 0x29C2 #define PCI_CHIP_Q35_G 0x29B2 #define PCI_CHIP_Q33_G 0x29D2 #define CORRDATA_SIZE 128*GTT_PAGE_SIZE /* * i915XvMCContext: * Private Context data referenced via the privData * pointer in the XvMCContext structure. */ typedef struct _i915XvMCContext { struct intel_xvmc_context comm; unsigned int yStride; unsigned int uvStride; unsigned int use_phys_addr; drm_intel_bo *sis_bo; drm_intel_bo *msb_bo; drm_intel_bo *ssb_bo; drm_intel_bo *psp_bo; drm_intel_bo *psc_bo; drm_intel_bo *corrdata_bo; } i915XvMCContext; /* * i915XvMCSubpicture: * Private data structure for each XvMCSubpicture. This * structure is referenced by the privData pointer in the XvMCSubpicture * structure. */ typedef struct _i915XvMCSubpicture { unsigned int srfNo; unsigned int pitch; unsigned char palette[3][16]; intel_xvmc_drm_map_t srf; i915XvMCContext *privContext; } i915XvMCSubpicture; /* Number of YUV buffers per surface */ #define I830_MAX_BUFS 2 #endif /* _I915XVMC_H */ xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i965_reg.h000066400000000000000000000503251267532330400227570ustar00rootroot00000000000000/* * New regs for broadwater -- we need to split this file up sensibly somehow. */ #define BRW_3D(Pipeline,Opcode,Subopcode) ((3 << 29) | \ ((Pipeline) << 27) | \ ((Opcode) << 24) | \ ((Subopcode) << 16)) #define BRW_URB_FENCE BRW_3D(0, 0, 0) #define BRW_CS_URB_STATE BRW_3D(0, 0, 1) #define BRW_CONSTANT_BUFFER BRW_3D(0, 0, 2) #define BRW_STATE_PREFETCH BRW_3D(0, 0, 3) #define BRW_STATE_BASE_ADDRESS BRW_3D(0, 1, 1) #define BRW_STATE_SIP BRW_3D(0, 1, 2) #define BRW_PIPELINE_SELECT BRW_3D(0, 1, 4) #define NEW_PIPELINE_SELECT BRW_3D(1, 1, 4) #define BRW_MEDIA_STATE_POINTERS BRW_3D(2, 0, 0) #define BRW_MEDIA_OBJECT BRW_3D(2, 1, 0) #define BRW_3DSTATE_PIPELINED_POINTERS BRW_3D(3, 0, 0) #define BRW_3DSTATE_BINDING_TABLE_POINTERS BRW_3D(3, 0, 1) # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_PS (1 << 12)/* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_GS (1 << 9) /* for GEN6 */ # define GEN6_3DSTATE_BINDING_TABLE_MODIFY_VS (1 << 8) /* for GEN6 */ #define BRW_3DSTATE_VERTEX_BUFFERS BRW_3D(3, 0, 8) #define BRW_3DSTATE_VERTEX_ELEMENTS BRW_3D(3, 0, 9) #define BRW_3DSTATE_INDEX_BUFFER BRW_3D(3, 0, 0xa) #define BRW_3DSTATE_VF_STATISTICS BRW_3D(3, 0, 0xb) #define BRW_3DSTATE_DRAWING_RECTANGLE BRW_3D(3, 1, 0) #define BRW_3DSTATE_CONSTANT_COLOR BRW_3D(3, 1, 1) #define BRW_3DSTATE_SAMPLER_PALETTE_LOAD BRW_3D(3, 1, 2) #define BRW_3DSTATE_CHROMA_KEY BRW_3D(3, 1, 4) #define BRW_3DSTATE_DEPTH_BUFFER BRW_3D(3, 1, 5) # define BRW_3DSTATE_DEPTH_BUFFER_TYPE_SHIFT 29 # define BRW_3DSTATE_DEPTH_BUFFER_FORMAT_SHIFT 18 #define BRW_3DSTATE_POLY_STIPPLE_OFFSET BRW_3D(3, 1, 6) #define BRW_3DSTATE_POLY_STIPPLE_PATTERN BRW_3D(3, 1, 7) #define BRW_3DSTATE_LINE_STIPPLE BRW_3D(3, 1, 8) #define BRW_3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP BRW_3D(3, 1, 9) /* These two are BLC and CTG only, not BW or CL */ #define BRW_3DSTATE_AA_LINE_PARAMS BRW_3D(3, 1, 0xa) #define BRW_3DSTATE_GS_SVB_INDEX BRW_3D(3, 1, 0xb) #define BRW_PIPE_CONTROL BRW_3D(3, 2, 0) #define BRW_3DPRIMITIVE BRW_3D(3, 3, 0) #define BRW_3DSTATE_CLEAR_PARAMS BRW_3D(3, 1, 0x10) /* DW1 */ # define BRW_3DSTATE_DEPTH_CLEAR_VALID (1 << 15) /* for GEN6+ */ #define GEN6_3DSTATE_SAMPLER_STATE_POINTERS BRW_3D(3, 0, 0x02) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_PS (1 << 12) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_GS (1 << 9) # define GEN6_3DSTATE_SAMPLER_STATE_MODIFY_VS (1 << 8) #define GEN6_3DSTATE_URB BRW_3D(3, 0, 0x05) /* DW1 */ # define GEN6_3DSTATE_URB_VS_SIZE_SHIFT 16 # define GEN6_3DSTATE_URB_VS_ENTRIES_SHIFT 0 /* DW2 */ # define GEN6_3DSTATE_URB_GS_ENTRIES_SHIFT 8 # define GEN6_3DSTATE_URB_GS_SIZE_SHIFT 0 #define GEN6_3DSTATE_VIEWPORT_STATE_POINTERS BRW_3D(3, 0, 0x0d) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CC (1 << 12) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_SF (1 << 11) # define GEN6_3DSTATE_VIEWPORT_STATE_MODIFY_CLIP (1 << 10) #define GEN6_3DSTATE_CC_STATE_POINTERS BRW_3D(3, 0, 0x0e) #define GEN6_3DSTATE_VS BRW_3D(3, 0, 0x10) #define GEN6_3DSTATE_GS BRW_3D(3, 0, 0x11) /* DW4 */ # define GEN6_3DSTATE_GS_DISPATCH_START_GRF_SHIFT 0 #define GEN6_3DSTATE_CLIP BRW_3D(3, 0, 0x12) #define GEN6_3DSTATE_SF BRW_3D(3, 0, 0x13) /* DW1 */ # define GEN6_3DSTATE_SF_NUM_OUTPUTS_SHIFT 22 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN6_3DSTATE_SF_URB_ENTRY_READ_OFFSET_SHIFT 4 /* DW2 */ /* DW3 */ # define GEN6_3DSTATE_SF_CULL_BOTH (0 << 29) # define GEN6_3DSTATE_SF_CULL_NONE (1 << 29) # define GEN6_3DSTATE_SF_CULL_FRONT (2 << 29) # define GEN6_3DSTATE_SF_CULL_BACK (3 << 29) /* DW4 */ # define GEN6_3DSTATE_SF_TRI_PROVOKE_SHIFT 29 # define GEN6_3DSTATE_SF_LINE_PROVOKE_SHIFT 27 # define GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT 25 #define GEN6_3DSTATE_WM BRW_3D(3, 0, 0x14) /* DW2 */ # define GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF 27 # define GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 /* DW4 */ # define GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT 16 /* DW5 */ # define GEN6_3DSTATE_WM_MAX_THREADS_SHIFT 25 # define GEN6_3DSTATE_WM_DISPATCH_ENABLE (1 << 19) # define GEN6_3DSTATE_WM_16_DISPATCH_ENABLE (1 << 1) # define GEN6_3DSTATE_WM_8_DISPATCH_ENABLE (1 << 0) /* DW6 */ # define GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT 20 # define GEN6_3DSTATE_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 15) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 14) # define GEN6_3DSTATE_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 13) # define GEN6_3DSTATE_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 12) # define GEN6_3DSTATE_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 11) # define GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 10) #define GEN6_3DSTATE_CONSTANT_VS BRW_3D(3, 0, 0x15) #define GEN6_3DSTATE_CONSTANT_GS BRW_3D(3, 0, 0x16) #define GEN6_3DSTATE_CONSTANT_PS BRW_3D(3, 0, 0x17) #define GEN6_3DSTATE_SAMPLE_MASK BRW_3D(3, 0, 0x18) #define GEN6_3DSTATE_MULTISAMPLE BRW_3D(3, 1, 0x0d) /* DW1 */ # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER (0 << 4) # define GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_UPPER_LEFT (1 << 4) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1 (0 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_4 (2 << 1) # define GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_8 (3 << 1) /* on GEN7+ */ /* _3DSTATE_VERTEX_BUFFERS on GEN7*/ /* DW1 */ #define GEN7_VB0_ADDRESS_MODIFYENABLE (1 << 14) /* _3DPRIMITIVE on GEN7 */ /* DW1 */ # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8) # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM (1 << 8) /* 3DSTATE_WM on GEN7 */ /* DW1 */ # define GEN7_WM_STATISTICS_ENABLE (1 << 31) # define GEN7_WM_DEPTH_CLEAR (1 << 30) # define GEN7_WM_DISPATCH_ENABLE (1 << 29) # define GEN6_WM_DEPTH_RESOLVE (1 << 28) # define GEN7_WM_HIERARCHICAL_DEPTH_RESOLVE (1 << 27) # define GEN7_WM_KILL_ENABLE (1 << 25) # define GEN7_WM_PSCDEPTH_OFF (0 << 23) # define GEN7_WM_PSCDEPTH_ON (1 << 23) # define GEN7_WM_PSCDEPTH_ON_GE (2 << 23) # define GEN7_WM_PSCDEPTH_ON_LE (3 << 23) # define GEN7_WM_USES_SOURCE_DEPTH (1 << 20) # define GEN7_WM_USES_SOURCE_W (1 << 19) # define GEN7_WM_POSITION_ZW_PIXEL (0 << 17) # define GEN7_WM_POSITION_ZW_CENTROID (2 << 17) # define GEN7_WM_POSITION_ZW_SAMPLE (3 << 17) # define GEN7_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 16) # define GEN7_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC (1 << 15) # define GEN7_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC (1 << 14) # define GEN7_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC (1 << 13) # define GEN7_WM_PERSPECTIVE_CENTROID_BARYCENTRIC (1 << 12) # define GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC (1 << 11) # define GEN7_WM_USES_INPUT_COVERAGE_MASK (1 << 10) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_0_5 (0 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_1_0 (1 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_2_0 (2 << 8) # define GEN7_WM_LINE_END_CAP_AA_WIDTH_4_0 (3 << 8) # define GEN7_WM_LINE_AA_WIDTH_0_5 (0 << 6) # define GEN7_WM_LINE_AA_WIDTH_1_0 (1 << 6) # define GEN7_WM_LINE_AA_WIDTH_2_0 (2 << 6) # define GEN7_WM_LINE_AA_WIDTH_4_0 (3 << 6) # define GEN7_WM_POLYGON_STIPPLE_ENABLE (1 << 4) # define GEN7_WM_LINE_STIPPLE_ENABLE (1 << 3) # define GEN7_WM_POINT_RASTRULE_UPPER_RIGHT (1 << 2) # define GEN7_WM_MSRAST_OFF_PIXEL (0 << 0) # define GEN7_WM_MSRAST_OFF_PATTERN (1 << 0) # define GEN7_WM_MSRAST_ON_PIXEL (2 << 0) # define GEN7_WM_MSRAST_ON_PATTERN (3 << 0) /* DW2 */ # define GEN7_WM_MSDISPMODE_PERPIXEL (1 << 31) #define GEN7_3DSTATE_CLEAR_PARAMS BRW_3D(3, 0, 0x04) #define GEN7_3DSTATE_DEPTH_BUFFER BRW_3D(3, 0, 0x05) #define GEN7_3DSTATE_CONSTANT_HS BRW_3D(3, 0, 0x19) #define GEN7_3DSTATE_CONSTANT_DS BRW_3D(3, 0, 0x1a) #define GEN7_3DSTATE_HS BRW_3D(3, 0, 0x1b) #define GEN7_3DSTATE_TE BRW_3D(3, 0, 0x1c) #define GEN7_3DSTATE_DS BRW_3D(3, 0, 0x1d) #define GEN7_3DSTATE_STREAMOUT BRW_3D(3, 0, 0x1e) #define GEN7_3DSTATE_SBE BRW_3D(3, 0, 0x1f) /* DW1 */ # define GEN7_SBE_SWIZZLE_CONTROL_MODE (1 << 28) # define GEN7_SBE_NUM_OUTPUTS_SHIFT 22 # define GEN7_SBE_SWIZZLE_ENABLE (1 << 21) # define GEN7_SBE_POINT_SPRITE_LOWERLEFT (1 << 20) # define GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT 11 # define GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT 4 #define GEN7_3DSTATE_PS BRW_3D(3, 0, 0x20) /* DW1: kernel pointer */ /* DW2 */ # define GEN7_PS_SPF_MODE (1 << 31) # define GEN7_PS_VECTOR_MASK_ENABLE (1 << 30) # define GEN7_PS_SAMPLER_COUNT_SHIFT 27 # define GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT 18 # define GEN7_PS_FLOATING_POINT_MODE_IEEE_754 (0 << 16) # define GEN7_PS_FLOATING_POINT_MODE_ALT (1 << 16) /* DW3: scratch space */ /* DW4 */ # define GEN7_PS_MAX_THREADS_SHIFT_IVB 24 # define GEN7_PS_MAX_THREADS_SHIFT_HSW 23 # define GEN7_PS_SAMPLE_MASK_SHIFT_HSW 12 # define GEN7_PS_PUSH_CONSTANT_ENABLE (1 << 11) # define GEN7_PS_ATTRIBUTE_ENABLE (1 << 10) # define GEN7_PS_OMASK_TO_RENDER_TARGET (1 << 9) # define GEN7_PS_DUAL_SOURCE_BLEND_ENABLE (1 << 7) # define GEN7_PS_POSOFFSET_NONE (0 << 3) # define GEN7_PS_POSOFFSET_CENTROID (2 << 3) # define GEN7_PS_POSOFFSET_SAMPLE (3 << 3) # define GEN7_PS_32_DISPATCH_ENABLE (1 << 2) # define GEN7_PS_16_DISPATCH_ENABLE (1 << 1) # define GEN7_PS_8_DISPATCH_ENABLE (1 << 0) /* DW5 */ # define GEN7_PS_DISPATCH_START_GRF_SHIFT_0 16 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_1 8 # define GEN7_PS_DISPATCH_START_GRF_SHIFT_2 0 /* DW6: kernel 1 pointer */ /* DW7: kernel 2 pointer */ #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL BRW_3D(3, 0, 0x21) #define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC BRW_3D(3, 0, 0x23) #define GEN7_3DSTATE_BLEND_STATE_POINTERS BRW_3D(3, 0, 0x24) #define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS BRW_3D(3, 0, 0x25) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS BRW_3D(3, 0, 0x26) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS BRW_3D(3, 0, 0x27) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS BRW_3D(3, 0, 0x28) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS BRW_3D(3, 0, 0x29) #define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS BRW_3D(3, 0, 0x2a) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS BRW_3D(3, 0, 0x2b) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS BRW_3D(3, 0, 0x2e) #define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS BRW_3D(3, 0, 0x2f) #define GEN7_3DSTATE_URB_VS BRW_3D(3, 0, 0x30) #define GEN7_3DSTATE_URB_HS BRW_3D(3, 0, 0x31) #define GEN7_3DSTATE_URB_DS BRW_3D(3, 0, 0x32) #define GEN7_3DSTATE_URB_GS BRW_3D(3, 0, 0x33) /* DW1 */ # define GEN7_URB_ENTRY_NUMBER_SHIFT 0 # define GEN7_URB_ENTRY_SIZE_SHIFT 16 # define GEN7_URB_STARTING_ADDRESS_SHIFT 25 #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS BRW_3D(3, 1, 0x12) #define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS BRW_3D(3, 1, 0x16) /* DW1 */ # define GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT 16 #define PIPELINE_SELECT_3D 0 #define PIPELINE_SELECT_MEDIA 1 #define UF0_CS_REALLOC (1 << 13) #define UF0_VFE_REALLOC (1 << 12) #define UF0_SF_REALLOC (1 << 11) #define UF0_CLIP_REALLOC (1 << 10) #define UF0_GS_REALLOC (1 << 9) #define UF0_VS_REALLOC (1 << 8) #define UF1_CLIP_FENCE_SHIFT 20 #define UF1_GS_FENCE_SHIFT 10 #define UF1_VS_FENCE_SHIFT 0 #define UF2_CS_FENCE_SHIFT 20 #define UF2_VFE_FENCE_SHIFT 10 #define UF2_SF_FENCE_SHIFT 0 /* for BRW_STATE_BASE_ADDRESS */ #define BASE_ADDRESS_MODIFY (1 << 0) /* for BRW_3DSTATE_PIPELINED_POINTERS */ #define BRW_GS_DISABLE 0 #define BRW_GS_ENABLE 1 #define BRW_CLIP_DISABLE 0 #define BRW_CLIP_ENABLE 1 /* for BRW_PIPE_CONTROL */ #define BRW_PIPE_CONTROL_CS_STALL (1 << 20) #define BRW_PIPE_CONTROL_NOWRITE (0 << 14) #define BRW_PIPE_CONTROL_WRITE_QWORD (1 << 14) #define BRW_PIPE_CONTROL_WRITE_DEPTH (2 << 14) #define BRW_PIPE_CONTROL_WRITE_TIME (3 << 14) #define BRW_PIPE_CONTROL_DEPTH_STALL (1 << 13) #define BRW_PIPE_CONTROL_WC_FLUSH (1 << 12) #define BRW_PIPE_CONTROL_IS_FLUSH (1 << 11) #define BRW_PIPE_CONTROL_TC_FLUSH (1 << 10) #define BRW_PIPE_CONTROL_NOTIFY_ENABLE (1 << 8) #define BRW_PIPE_CONTROL_GLOBAL_GTT (1 << 2) #define BRW_PIPE_CONTROL_LOCAL_PGTT (0 << 2) #define BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD (1 << 1) #define BRW_PIPE_CONTROL_DEPTH_CACHE_FLUSH (1 << 0) /* VERTEX_BUFFER_STATE Structure */ #define VB0_BUFFER_INDEX_SHIFT 27 #define GEN6_VB0_BUFFER_INDEX_SHIFT 26 #define VB0_VERTEXDATA (0 << 26) #define VB0_INSTANCEDATA (1 << 26) #define GEN6_VB0_VERTEXDATA (0 << 20) #define GEN6_VB0_INSTANCEDATA (1 << 20) #define VB0_BUFFER_PITCH_SHIFT 0 /* VERTEX_ELEMENT_STATE Structure */ #define VE0_VERTEX_BUFFER_INDEX_SHIFT 27 #define GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT 26 /* for GEN6 */ #define VE0_VALID (1 << 26) #define GEN6_VE0_VALID (1 << 25) /* for GEN6 */ #define VE0_FORMAT_SHIFT 16 #define VE0_OFFSET_SHIFT 0 #define VE1_VFCOMPONENT_0_SHIFT 28 #define VE1_VFCOMPONENT_1_SHIFT 24 #define VE1_VFCOMPONENT_2_SHIFT 20 #define VE1_VFCOMPONENT_3_SHIFT 16 #define VE1_DESTINATION_ELEMENT_OFFSET_SHIFT 0 /* 3DPRIMITIVE bits */ #define BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL (0 << 15) #define BRW_3DPRIMITIVE_VERTEX_RANDOM (1 << 15) /* Primitive types are in brw_defines.h */ #define BRW_3DPRIMITIVE_TOPOLOGY_SHIFT 10 #define BRW_SVG_CTL 0x7400 #define BRW_SVG_CTL_GS_BA (0 << 8) #define BRW_SVG_CTL_SS_BA (1 << 8) #define BRW_SVG_CTL_IO_BA (2 << 8) #define BRW_SVG_CTL_GS_AUB (3 << 8) #define BRW_SVG_CTL_IO_AUB (4 << 8) #define BRW_SVG_CTL_SIP (5 << 8) #define BRW_SVG_RDATA 0x7404 #define BRW_SVG_WORK_CTL 0x7408 #define BRW_VF_CTL 0x7500 #define BRW_VF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID (0 << 8) #define BRW_VF_CTL_SNAPSHOT_MUX_SELECT_VF_DEBUG (1 << 8) #define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_SEQUENCE (0 << 4) #define BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX (1 << 4) #define BRW_VF_CTL_SKIP_INITIAL_PRIMITIVES (1 << 3) #define BRW_VF_CTL_MAX_PRIMITIVES_LIMIT_ENABLE (1 << 2) #define BRW_VF_CTL_VERTEX_RANGE_LIMIT_ENABLE (1 << 1) #define BRW_VF_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_VF_STRG_VAL 0x7504 #define BRW_VF_STR_VL_OVR 0x7508 #define BRW_VF_VC_OVR 0x750c #define BRW_VF_STR_PSKIP 0x7510 #define BRW_VF_MAX_PRIM 0x7514 #define BRW_VF_RDATA 0x7518 #define BRW_VS_CTL 0x7600 #define BRW_VS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_0 (0 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VERTEX_1 (1 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT (2 << 8) #define BRW_VS_CTL_SNAPSHOT_MUX_VS_KERNEL_POINTER (3 << 8) #define BRW_VS_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_VS_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_VS_STRG_VAL 0x7604 #define BRW_VS_RDATA 0x7608 #define BRW_SF_CTL 0x7b00 #define BRW_SF_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_FF_ID (0 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_0_REL_COUNT (1 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_FF_ID (2 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_1_REL_COUNT (3 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_FF_ID (4 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_2_REL_COUNT (5 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT (6 << 8) #define BRW_SF_CTL_SNAPSHOT_MUX_SF_KERNEL_POINTER (7 << 8) #define BRW_SF_CTL_MIN_MAX_PRIMITIVE_RANGE_ENABLE (1 << 4) #define BRW_SF_CTL_DEBUG_CLIP_RECTANGLE_ENABLE (1 << 3) #define BRW_SF_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_SF_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_SF_STRG_VAL 0x7b04 #define BRW_SF_RDATA 0x7b18 #define BRW_WIZ_CTL 0x7c00 #define BRW_WIZ_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_WIZ_CTL_SUBSPAN_INSTANCE_SHIFT 16 #define BRW_WIZ_CTL_SNAPSHOT_MUX_WIZ_KERNEL_POINTER (0 << 8) #define BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE (1 << 8) #define BRW_WIZ_CTL_SNAPSHOT_MUX_PRIMITIVE_SEQUENCE (2 << 8) #define BRW_WIZ_CTL_SINGLE_SUBSPAN_DISPATCH (1 << 6) #define BRW_WIZ_CTL_IGNORE_COLOR_SCOREBOARD_STALLS (1 << 5) #define BRW_WIZ_CTL_ENABLE_SUBSPAN_INSTANCE_COMPARE (1 << 4) #define BRW_WIZ_CTL_USE_UPSTREAM_SNAPSHOT_FLAG (1 << 3) #define BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS (1 << 2) #define BRW_WIZ_CTL_THREAD_SNAPSHOT_ENABLE (1 << 1) #define BRW_WIZ_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_WIZ_STRG_VAL 0x7c04 #define BRW_WIZ_RDATA 0x7c18 #define BRW_TS_CTL 0x7e00 #define BRW_TS_CTL_SNAPSHOT_COMPLETE (1 << 31) #define BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR (0 << 8) #define BRW_TS_CTL_SNAPSHOT_INTERFACE_DESCRIPTOR (3 << 8) #define BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS (1 << 2) #define BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS (1 << 1) #define BRW_TS_CTL_SNAPSHOT_ENABLE (1 << 0) #define BRW_TS_STRG_VAL 0x7e04 #define BRW_TS_RDATA 0x7e08 #define BRW_TD_CTL 0x8000 #define BRW_TD_CTL_MUX_SHIFT 8 #define BRW_TD_CTL_EXTERNAL_HALT_R0_DEBUG_MATCH (1 << 7) #define BRW_TD_CTL_FORCE_EXTERNAL_HALT (1 << 6) #define BRW_TD_CTL_EXCEPTION_MASK_OVERRIDE (1 << 5) #define BRW_TD_CTL_FORCE_THREAD_BREAKPOINT_ENABLE (1 << 4) #define BRW_TD_CTL_BREAKPOINT_ENABLE (1 << 2) #define BRW_TD_CTL2 0x8004 #define BRW_TD_CTL2_ILLEGAL_OPCODE_EXCEPTION_OVERRIDE (1 << 28) #define BRW_TD_CTL2_MASKSTACK_EXCEPTION_OVERRIDE (1 << 26) #define BRW_TD_CTL2_SOFTWARE_EXCEPTION_OVERRIDE (1 << 25) #define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_SHIFT 16 #define BRW_TD_CTL2_ACTIVE_THREAD_LIMIT_ENABLE (1 << 8) #define BRW_TD_CTL2_THREAD_SPAWNER_EXECUTION_MASK_ENABLE (1 << 7) #define BRW_TD_CTL2_WIZ_EXECUTION_MASK_ENABLE (1 << 6) #define BRW_TD_CTL2_SF_EXECUTION_MASK_ENABLE (1 << 5) #define BRW_TD_CTL2_CLIPPER_EXECUTION_MASK_ENABLE (1 << 4) #define BRW_TD_CTL2_GS_EXECUTION_MASK_ENABLE (1 << 3) #define BRW_TD_CTL2_VS_EXECUTION_MASK_ENABLE (1 << 0) #define BRW_TD_VF_VS_EMSK 0x8008 #define BRW_TD_GS_EMSK 0x800c #define BRW_TD_CLIP_EMSK 0x8010 #define BRW_TD_SF_EMSK 0x8014 #define BRW_TD_WIZ_EMSK 0x8018 #define BRW_TD_0_6_EHTRG_VAL 0x801c #define BRW_TD_0_7_EHTRG_VAL 0x8020 #define BRW_TD_0_6_EHTRG_MSK 0x8024 #define BRW_TD_0_7_EHTRG_MSK 0x8028 #define BRW_TD_RDATA 0x802c #define BRW_TD_TS_EMSK 0x8030 #define BRW_EU_CTL 0x8800 #define BRW_EU_CTL_SELECT_SHIFT 16 #define BRW_EU_CTL_DATA_MUX_SHIFT 8 #define BRW_EU_ATT_0 0x8810 #define BRW_EU_ATT_1 0x8814 #define BRW_EU_ATT_DATA_0 0x8820 #define BRW_EU_ATT_DATA_1 0x8824 #define BRW_EU_ATT_CLR_0 0x8830 #define BRW_EU_ATT_CLR_1 0x8834 #define BRW_EU_RDATA 0x8840 /* End regs for broadwater */ xserver-xorg-video-intel-2.99.917+git20160325/xvmc/i965_xvmc.c000066400000000000000000000605441267532330400231560ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * */ #include "intel_xvmc_private.h" #include "i830_reg.h" #include "i965_reg.h" #include "brw_defines.h" #include "brw_structs.h" #define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0) #define URB_SIZE 256 /* XXX */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) enum interface { INTRA_INTERFACE = 0, /* non field intra */ NULL_INTERFACE, /* fill with white, do nothing, for debug */ FORWARD_INTERFACE, /* non field forward predict */ BACKWARD_INTERFACE, /* non field backward predict */ F_B_INTERFACE, /* non field forward and backward predict */ FIELD_FORWARD_INTERFACE, /* field forward predict */ FIELD_BACKWARD_INTERFACE, /* field backward predict */ FIELD_F_B_INTERFACE, /* field forward and backward predict */ DUAL_PRIME_INTERFACE }; static const uint32_t ipicture_kernel_static[][4] = { #include "shader/mc/ipicture.g4b" }; static const uint32_t null_kernel_static[][4] = { #include "shader/mc/null.g4b" }; static const uint32_t frame_forward_kernel_static[][4] = { #include "shader/mc/frame_forward.g4b" }; static const uint32_t frame_backward_kernel_static[][4] = { #include "shader/mc/frame_backward.g4b" }; static const uint32_t frame_f_b_kernel_static[][4] = { #include "shader/mc/frame_f_b.g4b" }; static const uint32_t field_forward_kernel_static[][4] = { #include "shader/mc/field_forward.g4b" }; static const uint32_t field_backward_kernel_static[][4] = { #include "shader/mc/field_backward.g4b" }; static const uint32_t field_f_b_kernel_static[][4] = { #include "shader/mc/field_f_b.g4b" }; static const uint32_t dual_prime_kernel_static[][4] = { #include "shader/mc/dual_prime.g4b" }; static const uint32_t frame_forward_igd_kernel_static[][4] = { #include "shader/mc/frame_forward_igd.g4b" }; static const uint32_t frame_backward_igd_kernel_static[][4] = { #include "shader/mc/frame_backward_igd.g4b" }; static const uint32_t frame_f_b_igd_kernel_static[][4] = { #include "shader/mc/frame_f_b_igd.g4b" }; static const uint32_t field_forward_igd_kernel_static[][4] = { #include "shader/mc/field_forward_igd.g4b" }; static const uint32_t field_backward_igd_kernel_static[][4] = { #include "shader/mc/field_backward_igd.g4b" }; static const uint32_t field_f_b_igd_kernel_static[][4] = { #include "shader/mc/field_f_b_igd.g4b" }; static const uint32_t dual_prime_igd_kernel_static[][4] = { #include "shader/mc/dual_prime_igd.g4b" }; struct kernel_struct { const uint32_t(*bin)[4]; uint32_t size; }; struct kernel_struct kernels_igd[] = { {ipicture_kernel_static, sizeof(ipicture_kernel_static)} , {null_kernel_static, sizeof(null_kernel_static)} , {frame_forward_igd_kernel_static, sizeof(frame_forward_igd_kernel_static)} , {frame_backward_igd_kernel_static, sizeof(frame_backward_igd_kernel_static)} , {frame_f_b_igd_kernel_static, sizeof(frame_f_b_igd_kernel_static)} , {field_forward_igd_kernel_static, sizeof(field_forward_igd_kernel_static)} , {field_backward_igd_kernel_static, sizeof(field_backward_igd_kernel_static)} , {field_f_b_igd_kernel_static, sizeof(field_f_b_igd_kernel_static)} , {dual_prime_igd_kernel_static, sizeof(dual_prime_igd_kernel_static)} }; struct kernel_struct kernels_965[] = { {ipicture_kernel_static, sizeof(ipicture_kernel_static)} , {null_kernel_static, sizeof(null_kernel_static)} , {frame_forward_kernel_static, sizeof(frame_forward_kernel_static)} , {frame_backward_kernel_static, sizeof(frame_backward_kernel_static)} , {frame_f_b_kernel_static, sizeof(frame_f_b_kernel_static)} , {field_forward_kernel_static, sizeof(field_forward_kernel_static)} , {field_backward_kernel_static, sizeof(field_backward_kernel_static)} , {field_f_b_kernel_static, sizeof(field_f_b_kernel_static)} , {dual_prime_kernel_static, sizeof(dual_prime_kernel_static)} }; #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define MAX_SURFACE_NUM 10 #define DESCRIPTOR_NUM 12 struct media_kernel_obj { dri_bo *bo; }; struct interface_descriptor_obj { dri_bo *bo; struct media_kernel_obj kernels[DESCRIPTOR_NUM]; }; struct vfe_state_obj { dri_bo *bo; struct interface_descriptor_obj interface; }; struct surface_obj { dri_bo *bo; }; struct surface_state_obj { struct surface_obj surface; dri_bo *bo; }; struct binding_table_obj { dri_bo *bo; struct surface_state_obj surface_states[MAX_SURFACE_NUM]; }; struct indirect_data_obj { dri_bo *bo; }; struct media_state { unsigned int is_g4x:1; unsigned int is_965_q:1; struct vfe_state_obj vfe_state; struct binding_table_obj binding_table; struct indirect_data_obj indirect_data; }; struct media_state media_state; static void free_object(struct media_state *s) { int i; #define FREE_ONE_BO(bo) drm_intel_bo_unreference(bo) FREE_ONE_BO(s->vfe_state.bo); FREE_ONE_BO(s->vfe_state.interface.bo); for (i = 0; i < DESCRIPTOR_NUM; i++) FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo); FREE_ONE_BO(s->binding_table.bo); for (i = 0; i < MAX_SURFACE_NUM; i++) FREE_ONE_BO(s->binding_table.surface_states[i].bo); FREE_ONE_BO(s->indirect_data.bo); } static int alloc_object(struct media_state *s) { int i; for (i = 0; i < MAX_SURFACE_NUM; i++) { s->binding_table.surface_states[i].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", sizeof(struct brw_surface_state), 0x1000); if (!s->binding_table.surface_states[i].bo) goto out; } return 0; out: free_object(s); return BadAlloc; } static Status destroy_context(Display * display, XvMCContext * context) { struct intel_xvmc_context *intel_ctx; intel_ctx = context->privData; free(intel_ctx->hw); free(intel_ctx); return Success; } #define STRIDE(w) (w) #define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) static void flush() { struct brw_mi_flush flush; memset(&flush, 0, sizeof(flush)); flush.opcode = CMD_MI_FLUSH; flush.flags = (1 << 1); BATCH_STRUCT(flush); } static void clear_sf_state() { struct brw_sf_unit_state sf; memset(&sf, 0, sizeof(sf)); /* TODO */ } /* urb fence must be aligned to cacheline */ static void align_urb_fence() { BATCH_LOCALS; int i, offset_to_next_cacheline; unsigned long batch_offset; BEGIN_BATCH(3); batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr; offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset; if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) { for (i = 0; i < offset_to_next_cacheline / 4; i++) OUT_BATCH(0); ADVANCE_BATCH(); } } /* setup urb layout for media */ static void urb_layout() { BATCH_LOCALS; align_urb_fence(); BEGIN_BATCH(3); OUT_BATCH(BRW_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) | (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT)); OUT_BATCH(((URB_SIZE) << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */ ((URB_SIZE) << UF2_CS_FENCE_SHIFT)); /* CS_SIZE is 0 */ ADVANCE_BATCH(); } static void media_state_pointers(struct media_state *media_state) { BATCH_LOCALS; BEGIN_BATCH(3); OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1); OUT_BATCH(0); OUT_RELOC(media_state->vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); ADVANCE_BATCH(); } /* setup 2D surface for media_read or media_write */ static Status setup_media_surface(struct media_state *media_state, int surface_num, dri_bo * bo, unsigned long offset, int w, int h, Bool write) { struct brw_surface_state s, *ss = &s; memset(ss, 0, sizeof(struct brw_surface_state)); ss->ss0.surface_type = BRW_SURFACE_2D; ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT; ss->ss1.base_addr = offset + bo->offset; ss->ss2.width = w - 1; ss->ss2.height = h - 1; ss->ss3.pitch = w - 1; if (media_state->binding_table.surface_states[surface_num].bo) drm_intel_bo_unreference(media_state-> binding_table.surface_states [surface_num].bo); media_state->binding_table.surface_states[surface_num].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", sizeof(struct brw_surface_state), 0x1000); if (!media_state->binding_table.surface_states[surface_num].bo) return BadAlloc; drm_intel_bo_subdata(media_state-> binding_table.surface_states[surface_num].bo, 0, sizeof(*ss), ss); drm_intel_bo_emit_reloc(media_state-> binding_table.surface_states[surface_num].bo, offsetof(struct brw_surface_state, ss1), bo, offset, I915_GEM_DOMAIN_RENDER, write ? I915_GEM_DOMAIN_RENDER : 0); return Success; } static Status setup_surfaces(struct media_state *media_state, dri_bo * dst_bo, dri_bo * past_bo, dri_bo * future_bo, int w, int h) { Status ret; ret = setup_media_surface(media_state, 0, dst_bo, 0, w, h, TRUE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 1, dst_bo, w * h, w / 2, h / 2, TRUE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 2, dst_bo, w * h + w * h / 4, w / 2, h / 2, TRUE); if (ret != Success) return ret; if (past_bo) { ret = setup_media_surface(media_state, 4, past_bo, 0, w, h, FALSE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 5, past_bo, w * h, w / 2, h / 2, FALSE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 6, past_bo, w * h + w * h / 4, w / 2, h / 2, FALSE); if (ret != Success) return ret; } if (future_bo) { ret = setup_media_surface(media_state, 7, future_bo, 0, w, h, FALSE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 8, future_bo, w * h, w / 2, h / 2, FALSE); if (ret != Success) return ret; ret = setup_media_surface(media_state, 9, future_bo, w * h + w * h / 4, w / 2, h / 2, FALSE); if (ret != Success) return ret; } return Success; } /* BUFFER SURFACE has a strange format * the size of the surface is in part of w h and d component */ static Status setup_blocks(struct media_state *media_state, unsigned int block_size) { union element { struct { unsigned int w:7; unsigned int h:13; unsigned int d:7; unsigned int pad:7; } whd; unsigned int size; } e; struct brw_surface_state ss; memset(&ss, 0, sizeof(struct brw_surface_state)); ss.ss0.surface_type = BRW_SURFACE_BUFFER; ss.ss0.surface_format = BRW_SURFACEFORMAT_R8_UINT; ss.ss1.base_addr = media_state->indirect_data.bo->offset; e.size = block_size - 1; ss.ss2.width = e.whd.w; ss.ss2.height = e.whd.h; ss.ss3.depth = e.whd.d; ss.ss3.pitch = block_size - 1; if (media_state->binding_table.surface_states[3].bo) drm_intel_bo_unreference(media_state-> binding_table.surface_states[3].bo); media_state->binding_table.surface_states[3].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", sizeof(struct brw_surface_state), 0x1000); if (!media_state->binding_table.surface_states[3].bo) return BadAlloc; drm_intel_bo_subdata(media_state->binding_table.surface_states[3].bo, 0, sizeof(ss), &ss); drm_intel_bo_emit_reloc(media_state->binding_table.surface_states[3].bo, offsetof(struct brw_surface_state, ss1), media_state->indirect_data.bo, 0, I915_GEM_DOMAIN_SAMPLER, 0); return Success; } /* setup state base address */ static void state_base_address() { BATCH_LOCALS; BEGIN_BATCH(6); OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0xFFFFF000 | BASE_ADDRESS_MODIFY); ADVANCE_BATCH(); } /* select media pipeline */ static void pipeline_select(struct media_state *media_state) { BATCH_LOCALS; BEGIN_BATCH(1); if (media_state->is_g4x) OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); else OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); ADVANCE_BATCH(); } /* kick media object to gpu */ static void send_media_object(XvMCMacroBlock * mb, int offset, enum interface interface) { BATCH_LOCALS; BEGIN_BATCH(13); OUT_BATCH(BRW_MEDIA_OBJECT | 11); OUT_BATCH(interface); if (media_state.is_965_q) { OUT_BATCH(0); OUT_BATCH(0); } else { OUT_BATCH(6 * 128); OUT_RELOC(media_state.indirect_data.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); } OUT_BATCH(mb->x << 4); //g1.0 OUT_BATCH(mb->y << 4); OUT_RELOC(media_state.indirect_data.bo, //g1.8 I915_GEM_DOMAIN_INSTRUCTION, 0, offset); OUT_BATCH_SHORT(mb->coded_block_pattern); //g1.12 OUT_BATCH_SHORT(mb->PMV[0][0][0]); //g1.14 OUT_BATCH_SHORT(mb->PMV[0][0][1]); //g1.16 OUT_BATCH_SHORT(mb->PMV[0][1][0]); //g1.18 OUT_BATCH_SHORT(mb->PMV[0][1][1]); //g1.20 OUT_BATCH_SHORT(mb->PMV[1][0][0]); //g1.22 OUT_BATCH_SHORT(mb->PMV[1][0][1]); //g1.24 OUT_BATCH_SHORT(mb->PMV[1][1][0]); //g1.26 OUT_BATCH_SHORT(mb->PMV[1][1][1]); //g1.28 OUT_BATCH_CHAR(mb->dct_type); //g1.30 OUT_BATCH_CHAR(mb->motion_vertical_field_select); //g1.31 if (media_state.is_965_q) OUT_BATCH(0x0); else OUT_BATCH(0xffffffff); ADVANCE_BATCH(); } static Status binding_tables(struct media_state *media_state) { unsigned int binding_table[MAX_SURFACE_NUM]; int i; if (media_state->binding_table.bo) drm_intel_bo_unreference(media_state->binding_table.bo); media_state->binding_table.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table", MAX_SURFACE_NUM * 4, 0x1000); if (!media_state->binding_table.bo) return BadAlloc; for (i = 0; i < MAX_SURFACE_NUM; i++) binding_table[i] = media_state->binding_table.surface_states[i].bo->offset; drm_intel_bo_subdata(media_state->binding_table.bo, 0, sizeof(binding_table), binding_table); for (i = 0; i < MAX_SURFACE_NUM; i++) drm_intel_bo_emit_reloc(media_state->binding_table.bo, i * sizeof(unsigned int), media_state-> binding_table.surface_states[i].bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0); return Success; } static int media_kernels(struct media_state *media_state) { struct kernel_struct *kernels; int kernel_array_size, i; if (media_state->is_g4x) { kernels = kernels_igd; kernel_array_size = ARRAY_SIZE(kernels_igd); } else { kernels = kernels_965; kernel_array_size = ARRAY_SIZE(kernels_965); } for (i = 0; i < kernel_array_size; i++) { media_state->vfe_state.interface.kernels[i].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", kernels[i].size, 0x1000); if (!media_state->vfe_state.interface.kernels[i].bo) goto out; } for (i = 0; i < kernel_array_size; i++) { dri_bo *bo = media_state->vfe_state.interface.kernels[i].bo; drm_intel_bo_subdata(bo, 0, kernels[i].size, kernels[i].bin); } return 0; out: free_object(media_state); return BadAlloc; } static void setup_interface(struct media_state *media_state, enum interface i) { struct brw_interface_descriptor desc; memset(&desc, 0, sizeof(desc)); desc.desc0.grf_reg_blocks = 15; desc.desc0.kernel_start_pointer = media_state->vfe_state.interface.kernels[i].bo->offset >> 6; desc.desc1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; /* use same binding table for all interface * may change this if it affect performance */ desc.desc3.binding_table_entry_count = MAX_SURFACE_NUM; desc.desc3.binding_table_pointer = media_state->binding_table.bo->offset >> 5; drm_intel_bo_subdata(media_state->vfe_state.interface.bo, i * sizeof(desc), sizeof(desc), &desc); drm_intel_bo_emit_reloc(media_state->vfe_state.interface.bo, i * sizeof(desc) + offsetof(struct brw_interface_descriptor, desc0), media_state->vfe_state.interface.kernels[i].bo, desc.desc0.grf_reg_blocks, I915_GEM_DOMAIN_INSTRUCTION, 0); drm_intel_bo_emit_reloc(media_state->vfe_state.interface.bo, i * sizeof(desc) + offsetof(struct brw_interface_descriptor, desc3), media_state->binding_table.bo, desc.desc3.binding_table_entry_count, I915_GEM_DOMAIN_INSTRUCTION, 0); } static Status interface_descriptor(struct media_state *media_state) { if (media_state->vfe_state.interface.bo) drm_intel_bo_unreference(media_state->vfe_state.interface.bo); media_state->vfe_state.interface.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces", DESCRIPTOR_NUM * sizeof(struct brw_interface_descriptor), 0x1000); if (!media_state->vfe_state.interface.bo) return BadAlloc; setup_interface(media_state, INTRA_INTERFACE); setup_interface(media_state, NULL_INTERFACE); setup_interface(media_state, FORWARD_INTERFACE); setup_interface(media_state, FIELD_FORWARD_INTERFACE); setup_interface(media_state, BACKWARD_INTERFACE); setup_interface(media_state, FIELD_BACKWARD_INTERFACE); setup_interface(media_state, F_B_INTERFACE); setup_interface(media_state, FIELD_F_B_INTERFACE); setup_interface(media_state, DUAL_PRIME_INTERFACE); return Success; } static Status vfe_state(struct media_state *media_state) { struct brw_vfe_state state; memset(&state, 0, sizeof(state)); /* no scratch space */ state.vfe1.vfe_mode = VFE_GENERIC_MODE; state.vfe1.num_urb_entries = 1; /* XXX TODO */ /* should carefully caculate those values for performance */ state.vfe1.urb_entry_alloc_size = 2; state.vfe1.max_threads = 31; state.vfe2.interface_descriptor_base = media_state->vfe_state.interface.bo->offset >> 4; if (media_state->vfe_state.bo) drm_intel_bo_unreference(media_state->vfe_state.bo); media_state->vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "vfe state", sizeof(struct brw_vfe_state), 0x1000); if (!media_state->vfe_state.bo) return BadAlloc; drm_intel_bo_subdata(media_state->vfe_state.bo, 0, sizeof(state), &state); drm_intel_bo_emit_reloc(media_state->vfe_state.bo, offsetof(struct brw_vfe_state, vfe2), media_state->vfe_state.interface.bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0); return Success; } static Status render_surface(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) { intel_xvmc_context_ptr intel_ctx; int i, j; struct i965_xvmc_context *i965_ctx; XvMCMacroBlock *mb; struct intel_xvmc_surface *priv_target_surface = target_surface->privData; struct intel_xvmc_surface *priv_past_surface = past_surface ? past_surface->privData : 0; struct intel_xvmc_surface *priv_future_surface = future_surface ? future_surface->privData : 0; unsigned short *block_ptr; intel_ctx = context->privData; i965_ctx = context->privData; if (!intel_ctx) { XVMC_ERR("Can't find intel xvmc context\n"); return BadValue; } if (media_state.indirect_data.bo) { drm_intel_gem_bo_unmap_gtt(media_state. indirect_data.bo); drm_intel_bo_unreference(media_state.indirect_data.bo); } media_state.indirect_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "indirect data", 128 * 6 * num_macroblocks, 64); if (!media_state.indirect_data.bo) return BadAlloc; setup_surfaces(&media_state, priv_target_surface->bo, past_surface ? priv_past_surface->bo : NULL, future_surface ? priv_future_surface->bo : NULL, context->width, context->height); setup_blocks(&media_state, 128 * 6 * num_macroblocks); binding_tables(&media_state); interface_descriptor(&media_state); vfe_state(&media_state); drm_intel_gem_bo_map_gtt(media_state.indirect_data.bo); block_ptr = media_state.indirect_data.bo->virtual; for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) { unsigned short *mb_block_ptr; mb = ¯oblock_array->macro_blocks[i]; mb_block_ptr = &blocks->blocks[(mb->index << 6)]; if (mb->coded_block_pattern & 0x20) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } if (mb->coded_block_pattern & 0x10) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j + 8, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } block_ptr += 2 * 64; if (mb->coded_block_pattern & 0x08) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } if (mb->coded_block_pattern & 0x04) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j + 8, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } block_ptr += 2 * 64; if (mb->coded_block_pattern & 0x2) { memcpy(block_ptr, mb_block_ptr, 128); mb_block_ptr += 64; } block_ptr += 64; if (mb->coded_block_pattern & 0x1) memcpy(block_ptr, mb_block_ptr, 128); block_ptr += 64; } { int block_offset = 0; LOCK_HARDWARE(intel_ctx->hw_context); state_base_address(); flush(); clear_sf_state(); pipeline_select(&media_state); urb_layout(); media_state_pointers(&media_state); for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++, block_offset += 128 * 6) { mb = ¯oblock_array->macro_blocks[i]; if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { send_media_object(mb, block_offset, INTRA_INTERFACE); } else { if (((mb->motion_type & 3) == XVMC_PREDICTION_FRAME)) { if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD)) { if (((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD))) send_media_object(mb, block_offset, F_B_INTERFACE); else send_media_object(mb, block_offset, FORWARD_INTERFACE); } else if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)) { send_media_object(mb, block_offset, BACKWARD_INTERFACE); } } else if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD)) { if (((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD))) send_media_object(mb, block_offset, FIELD_F_B_INTERFACE); else send_media_object(mb, block_offset, FIELD_FORWARD_INTERFACE); } else if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)) { send_media_object(mb, block_offset, FIELD_BACKWARD_INTERFACE); } } else { send_media_object(mb, block_offset, DUAL_PRIME_INTERFACE); } } } intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); } return Success; } static Status create_context(Display * display, XvMCContext * context, int priv_count, CARD32 * priv_data) { struct intel_xvmc_context *intel_ctx; struct intel_xvmc_hw_context *hw_ctx; hw_ctx = (struct intel_xvmc_hw_context *)priv_data; intel_ctx = calloc(1, sizeof(struct intel_xvmc_context)); if (!intel_ctx) return BadAlloc; intel_ctx->hw = hw_ctx; intel_ctx->surface_bo_size = SIZE_YUV420(context->width, context->height); context->privData = intel_ctx; media_state.is_g4x = hw_ctx->i965.is_g4x; media_state.is_965_q = hw_ctx->i965.is_965_q; if (alloc_object(&media_state)) return BadAlloc; if (media_kernels(&media_state)) return BadAlloc; return Success; } struct _intel_xvmc_driver i965_xvmc_mc_driver = { .type = XVMC_I965_MPEG2_MC, .create_context = create_context, .destroy_context = destroy_context, .render_surface = render_surface, }; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_batchbuffer.c000066400000000000000000000100311267532330400250550ustar00rootroot00000000000000/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 TUNGSTEN 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. * **************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "intel_xvmc_private.h" #include "intel_batchbuffer.h" #include "brw_defines.h" #include "brw_structs.h" #define MI_BATCH_BUFFER_END (0xA << 23) #define BATCH_SIZE 8*1024 /* one bo is allocated each time, so the size can be small */ static void i965_end_batch(void) { unsigned int size = xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr; if ((size & 4) == 0) { *(unsigned int *)xvmc_driver->batch.ptr = 0; xvmc_driver->batch.ptr += 4; } *(unsigned int *)xvmc_driver->batch.ptr = MI_BATCH_BUFFER_END; xvmc_driver->batch.ptr += 4; } static void reset_batch(void) { dri_bo *bo = xvmc_driver->batch.buf; xvmc_driver->batch.ptr = xvmc_driver->batch.init_ptr = bo->virtual; xvmc_driver->batch.size = bo->size; xvmc_driver->batch.space = bo->size - 8; } Bool intelInitBatchBuffer(void) { if ((xvmc_driver->batch.buf = drm_intel_bo_alloc(xvmc_driver->bufmgr, "batch buffer", BATCH_SIZE, 0x1000)) == NULL) { fprintf(stderr, "unable to alloc batch buffer\n"); return False; } if (drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf)) { drm_intel_bo_unreference(xvmc_driver->batch.buf); return False; } reset_batch(); return True; } void intelFiniBatchBuffer(void) { if (xvmc_driver->batch.buf == NULL) return; drm_intel_bo_unreference(xvmc_driver->batch.buf); } void intelFlushBatch(void) { dri_bo *bo; i965_end_batch(); drm_intel_bo_exec(xvmc_driver->batch.buf, xvmc_driver->batch.ptr - xvmc_driver->batch.init_ptr, 0, 0, 0); bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "batch buffer", BATCH_SIZE, 0x1000); if (bo != NULL && drm_intel_gem_bo_map_gtt(bo) == 0) { drm_intel_bo_unreference(xvmc_driver->batch.buf); xvmc_driver->batch.buf = bo; } else { if (bo != NULL) drm_intel_bo_unreference(bo); drm_intel_gem_bo_map_gtt(xvmc_driver->batch.buf); } reset_batch(); } void intelBatchbufferData(const void *data, unsigned bytes, unsigned flags) { assert(bytes <= xvmc_driver->batch.space); memcpy(xvmc_driver->batch.ptr, data, bytes); xvmc_driver->batch.ptr += bytes; xvmc_driver->batch.space -= bytes; } void intel_batch_emit_reloc(dri_bo * bo, uint32_t read_domain, uint32_t write_domain, uint32_t delta, unsigned char *ptr) { drm_intel_bo_emit_reloc(xvmc_driver->batch.buf, ptr - xvmc_driver->batch.init_ptr, bo, delta, read_domain, write_domain); } xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_batchbuffer.h000066400000000000000000000045531267532330400250760ustar00rootroot00000000000000#ifndef _INTEL_BATCHBUFFER_H #define _INTEL_BATCHBUFFER_H /* #define VERBOSE 0 */ #ifndef VERBOSE extern int VERBOSE; #endif #define BATCH_LOCALS unsigned char *batch_ptr; #define BEGIN_BATCH(n) \ do { \ assert(xvmc_driver->batch.space >= (n) *4); \ batch_ptr = xvmc_driver->batch.ptr; \ } while (0) #define OUT_BATCH(n) \ do { \ *(unsigned int *)batch_ptr = (n); \ batch_ptr += 4; \ } while (0) #define OUT_RELOC(bo,read_domains,write_domains,delta) \ do { \ *(unsigned int *)batch_ptr = (delta) + bo->offset; \ intel_batch_emit_reloc(bo, read_domains, write_domains, delta, batch_ptr); \ batch_ptr += 4; \ } while (0) #define OUT_BATCH_SHORT(n) \ do { \ *(short *)batch_ptr = (n); \ batch_ptr += 2; \ } while (0) #define OUT_BATCH_CHAR(n) \ do { \ *(char *)batch_ptr = (n); \ batch_ptr ++; \ } while (0) #define ADVANCE_BATCH() \ do { \ xvmc_driver->batch.space -= (batch_ptr - xvmc_driver->batch.ptr);\ xvmc_driver->batch.ptr = batch_ptr; \ } while(0) extern void intelFlushBatch(void); extern void intelBatchbufferData(const void *, unsigned, unsigned); extern Bool intelInitBatchBuffer(void); extern void intelFiniBatchBuffer(void); extern void intelCmdIoctl(char *, unsigned); extern void intel_batch_emit_reloc(dri_bo * bo, uint32_t read_domain, uint32_t write_domain, uint32_t delta, unsigned char *); #endif /* _INTEL_BATCHBUFFER_H */ xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_xvmc.c000066400000000000000000000713641267532330400235770ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #include "intel_xvmc_private.h" #include #include #include #include #include /* global */ struct _intel_xvmc_driver *xvmc_driver = NULL; /* Lookup tables to speed common calculations for coded_block_pattern */ /* each block is ((8*8) * sizeof(short)) */ unsigned int mb_bytes_420[] = { 0, /* 0 */ 128, /* 1 */ 128, /* 10 */ 256, /* 11 */ 128, /* 100 */ 256, /* 101 */ 256, /* 110 */ 384, /* 111 */ 128, /* 1000 */ 256, /* 1001 */ 256, /* 1010 */ 384, /* 1011 */ 256, /* 1100 */ 384, /* 1101 */ 384, /* 1110 */ 512, /* 1111 */ 128, /* 10000 */ 256, /* 10001 */ 256, /* 10010 */ 384, /* 10011 */ 256, /* 10100 */ 384, /* 10101 */ 384, /* 10110 */ 512, /* 10111 */ 256, /* 11000 */ 384, /* 11001 */ 384, /* 11010 */ 512, /* 11011 */ 384, /* 11100 */ 512, /* 11101 */ 512, /* 11110 */ 640, /* 11111 */ 128, /* 100000 */ 256, /* 100001 */ 256, /* 100010 */ 384, /* 100011 */ 256, /* 100100 */ 384, /* 100101 */ 384, /* 100110 */ 512, /* 100111 */ 256, /* 101000 */ 384, /* 101001 */ 384, /* 101010 */ 512, /* 101011 */ 384, /* 101100 */ 512, /* 101101 */ 512, /* 101110 */ 640, /* 101111 */ 256, /* 110000 */ 384, /* 110001 */ 384, /* 110010 */ 512, /* 110011 */ 384, /* 110100 */ 512, /* 110101 */ 512, /* 110110 */ 640, /* 110111 */ 384, /* 111000 */ 512, /* 111001 */ 512, /* 111010 */ 640, /* 111011 */ 512, /* 111100 */ 640, /* 111101 */ 640, /* 111110 */ 768 /* 111111 */ }; static int dri2_connect(Display *display) { xcb_dri2_query_version_cookie_t query_version_cookie; xcb_dri2_query_version_reply_t *query_version_reply; xcb_dri2_connect_cookie_t connect_cookie; xcb_dri2_connect_reply_t *connect_reply; xcb_dri2_authenticate_cookie_t auth_cookie; xcb_dri2_authenticate_reply_t *auth_reply; xcb_screen_t *root; xcb_connection_t *c = XGetXCBConnection(display); drm_magic_t magic; const xcb_query_extension_reply_t *dri2_reply; char *device_name; int len; root = xcb_aux_get_screen(c, DefaultScreen(display)); dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id); if (!dri2_reply) { XVMC_ERR("DRI2 required"); return BadValue; } /* Query the extension and make our first use of it at the same time. */ query_version_cookie = xcb_dri2_query_version(c, 1, 0); connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI); query_version_reply = xcb_dri2_query_version_reply(c, query_version_cookie, NULL); connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL); if (!query_version_reply) { XVMC_ERR("DRI2 required"); return BadValue; } free(query_version_reply); len = xcb_dri2_connect_device_name_length(connect_reply); device_name = malloc(len + 1); if (!device_name) { XVMC_ERR("malloc failure"); return BadAlloc; } strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len); device_name[len] = 0; xvmc_driver->fd = open(device_name, O_RDWR); free(device_name); free(connect_reply); if (xvmc_driver->fd < 0) { XVMC_ERR("Failed to open drm device: %s\n", strerror(errno)); return BadValue; } if (drmGetMagic(xvmc_driver->fd, &magic)) { XVMC_ERR("Failed to get magic\n"); return BadValue; } auth_cookie = xcb_dri2_authenticate(c, root->root, magic); auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL); if (!auth_reply) { XVMC_ERR("Failed to authenticate magic %d\n", magic); return BadValue; } free(auth_reply); return Success; } /* * Function: XvMCCreateContext * Description: Create a XvMC context for the given surface parameters. * Arguments: * display - Connection to the X server. * port - XvPortID to use as avertised by the X connection. * surface_type_id - Unique identifier for the Surface type. * width - Width of the surfaces. * height - Height of the surfaces. * flags - one or more of the following * XVMC_DIRECT - A direct rendered context is requested. * * Notes: surface_type_id and width/height parameters must match those * returned by XvMCListSurfaceTypes. * Returns: Status */ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext * context) { Status ret; CARD32 *priv_data = NULL; struct intel_xvmc_hw_context *comm; int major, minor; int error_base; int event_base; int priv_count; /* Verify Obvious things first */ if (!display || !context) return BadValue; if (!(flags & XVMC_DIRECT)) { XVMC_ERR("Indirect Rendering not supported! Using Direct."); return BadValue; } /* Width, Height, and flags are checked against surface_type_id and port for validity inside the X server, no need to check 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; if (!XvMCQueryExtension(display, &event_base, &error_base)) { XVMC_ERR("XvMCExtension is not available!"); return BadValue; } ret = XvMCQueryVersion(display, &major, &minor); if (ret) { XVMC_ERR ("XvMCQueryVersion Failed, unable to determine protocol version."); return ret; } /* XXX: major and minor could be checked in future for XvMC * protocol capability (i.e H.264/AVC decode available) */ /* Pass control to the X server to create a drm_context_t for us and validate the with/height and flags. */ if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMC Context."); return ret; } comm = (struct intel_xvmc_hw_context *)priv_data; if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { switch (comm->type) { case XVMC_I915_MPEG2_MC: xvmc_driver = &i915_xvmc_mc_driver; break; case XVMC_I965_MPEG2_MC: xvmc_driver = &i965_xvmc_mc_driver; break; case XVMC_I965_MPEG2_VLD: xvmc_driver = &xvmc_vld_driver; break; case XVMC_I945_MPEG2_VLD: default: XVMC_ERR("unimplemented xvmc type %d", comm->type); XFree(priv_data); priv_data = NULL; return BadValue; } } if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); return BadValue; } XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); /* check DRI2 */ ret = Success; xvmc_driver->fd = -1; ret = dri2_connect(display); if (ret != Success) { XFree(priv_data); context->privData = NULL; if (xvmc_driver->fd >= 0) close(xvmc_driver->fd); xvmc_driver = NULL; return ret; } if ((xvmc_driver->bufmgr = intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) { XVMC_ERR("Can't init bufmgr\n"); return BadAlloc; } drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); if (!intelInitBatchBuffer()) { XFree(priv_data); context->privData = NULL; dri_bufmgr_destroy(xvmc_driver->bufmgr); xvmc_driver = NULL; return BadAlloc; } /* call driver hook. * driver hook should free priv_data after return if success.*/ ret = (xvmc_driver->create_context) (display, context, priv_count, priv_data); if (ret) { XVMC_ERR("driver create context failed\n"); intelFiniBatchBuffer(); XFree(priv_data); context->privData = NULL; dri_bufmgr_destroy(xvmc_driver->bufmgr); xvmc_driver = NULL; return ret; } sigfillset(&xvmc_driver->sa_mask); sigdelset(&xvmc_driver->sa_mask, SIGFPE); sigdelset(&xvmc_driver->sa_mask, SIGILL); sigdelset(&xvmc_driver->sa_mask, SIGSEGV); sigdelset(&xvmc_driver->sa_mask, SIGBUS); sigdelset(&xvmc_driver->sa_mask, SIGKILL); pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); intel_xvmc_dump_open(); return Success; } /* * Function: XvMCDestroyContext * Description: Destorys the specified context. * * Arguments: * display - Specifies the connection to the server. * context - The context to be destroyed. * */ _X_EXPORT Status XvMCDestroyContext(Display * display, XvMCContext * context) { Status ret; int screen; if (!display || !context) return XvMCBadContext; screen = DefaultScreen(display); ret = (xvmc_driver->destroy_context) (display, context); if (ret) { XVMC_ERR("destroy context fail\n"); return ret; } intelFiniBatchBuffer(); dri_bufmgr_destroy(xvmc_driver->bufmgr); ret = _xvmc_destroy_context(display, context); if (ret != Success) { XVMC_ERR("_xvmc_destroy_context fail\n"); return ret; } if (xvmc_driver->num_ctx == 0) { pthread_mutex_destroy(&xvmc_driver->ctxmutex); if (xvmc_driver->fd >= 0) close(xvmc_driver->fd); xvmc_driver->fd = -1; intel_xvmc_dump_close(); } return Success; } /* * Function: XvMCCreateSurface */ _X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context, XvMCSurface * surface) { Status ret; int priv_count; CARD32 *priv_data; intel_xvmc_surface_ptr intel_surf = NULL; struct intel_xvmc_context *intel_ctx; if (!display || !context) return XvMCBadContext; if (!surface) return XvMCBadSurface; intel_ctx = context->privData; if ((ret = _xvmc_create_surface(display, context, surface, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMCSurface."); return ret; } XFree(priv_data); surface->privData = calloc(1, sizeof(struct intel_xvmc_surface)); if (!(intel_surf = surface->privData)) goto out_xvmc; intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface", intel_ctx->surface_bo_size, GTT_PAGE_SIZE); if (!intel_surf->bo) goto out_surf; if (drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle)) goto out_bo; intel_surf = surface->privData; intel_surf->context = context; intel_surf->image = XvCreateImage(display, context->port, FOURCC_XVMC, (char *) &intel_surf->gem_handle, surface->width, surface->height); if (!intel_surf->image) { XVMC_ERR("Can't create XvImage for surface\n"); goto out_bo; } return Success; out_bo: drm_intel_bo_unreference(intel_surf->bo); out_surf: free(intel_surf); out_xvmc: _xvmc_destroy_surface(display, surface); return BadAlloc; } /* * Function: XvMCDestroySurface */ _X_EXPORT Status XvMCDestroySurface(Display * display, XvMCSurface * surface) { intel_xvmc_surface_ptr intel_surf; if (!display || !surface) return XvMCBadSurface; intel_surf = surface->privData; if (!intel_surf) return XvMCBadSurface; XFree(intel_surf->image); if (intel_surf->gc_init) XFreeGC(display, intel_surf->gc); drm_intel_bo_unreference(intel_surf->bo); free(intel_surf); _xvmc_destroy_surface(display, surface); return Success; } /* * Function: XvMCCreateBlocks */ _X_EXPORT Status XvMCCreateBlocks(Display * display, XvMCContext * context, unsigned int num_blocks, XvMCBlockArray * block) { if (!display || !context || !num_blocks || !block) return BadValue; memset(block, 0, sizeof(XvMCBlockArray)); if (! (block->blocks = (short *)malloc((num_blocks << 6) * sizeof(short)))) return BadAlloc; block->num_blocks = num_blocks; block->context_id = context->context_id; block->privData = NULL; return Success; } /* * Function: XvMCDestroyBlocks */ _X_EXPORT Status XvMCDestroyBlocks(Display * display, XvMCBlockArray * block) { if (!display || !block) return BadValue; if (block->blocks) free(block->blocks); block->context_id = 0; block->num_blocks = 0; block->blocks = NULL; block->privData = NULL; return Success; } /* * Function: XvMCCreateMacroBlocks */ _X_EXPORT Status XvMCCreateMacroBlocks(Display * display, XvMCContext * context, unsigned int num_blocks, XvMCMacroBlockArray * blocks) { if (!display || !context || !blocks || !num_blocks) return BadValue; memset(blocks, 0, sizeof(XvMCMacroBlockArray)); blocks->macro_blocks = (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock)); if (!blocks->macro_blocks) return BadAlloc; blocks->num_blocks = num_blocks; blocks->context_id = context->context_id; blocks->privData = NULL; return Success; } /* * Function: XvMCDestroyMacroBlocks */ _X_EXPORT Status XvMCDestroyMacroBlocks(Display * display, XvMCMacroBlockArray * block) { if (!display || !block) return BadValue; if (block->macro_blocks) free(block->macro_blocks); block->context_id = 0; block->num_blocks = 0; block->macro_blocks = NULL; block->privData = NULL; return Success; } /* * Function: XvMCRenderSurface * * Description: This function does the actual HWMC. Given a list of * macroblock structures it dispatched the hardware commands to execute * them. */ _X_EXPORT 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) { Status ret; if (!display || !context) { XVMC_ERR("Invalid Display, Context or Target!"); return XvMCBadContext; } if (!target_surface) return XvMCBadSurface; intel_xvmc_dump_render(context, picture_structure, target_surface, past_surface, future_surface, flags, num_macroblocks, first_macroblock, macroblock_array, blocks); ret = (xvmc_driver->render_surface) (display, context, picture_structure, target_surface, past_surface, future_surface, flags, num_macroblocks, first_macroblock, macroblock_array, blocks); if (ret) { XVMC_ERR("render surface fail\n"); return ret; } return Success; } /* * Function: XvMCPutSurface * * Description: * Arguments: * display: Connection to X server * surface: Surface to be displayed * draw: X Drawable on which to display the surface * srcx: X coordinate of the top left corner of the region to be * displayed within the surface. * srcy: Y coordinate of the top left corner of the region to be * displayed within the surface. * srcw: Width of the region to be displayed. * srch: Height of the region to be displayed. * destx: X cordinate of the top left corner of the destination region * in the drawable coordinates. * desty: Y cordinate of the top left corner of the destination region * in the drawable coordinates. * destw: Width of the destination region. * desth: Height of the destination region. * flags: One or more of the following. * XVMC_TOP_FIELD - Display only the Top field of the surface. * XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. * XVMC_FRAME_PICTURE - Display both fields or frame. */ _X_EXPORT 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) { XvMCContext *context; intel_xvmc_surface_ptr intel_surf; if (!display || !surface) return XvMCBadSurface; intel_surf = surface->privData; if (!intel_surf) return XvMCBadSurface; context = intel_surf->context; if (!context) return XvMCBadSurface; if (intel_surf->gc_init == FALSE) { intel_surf->gc = XCreateGC(display, draw, 0, NULL); intel_surf->gc_init = TRUE; } else if (draw != intel_surf->last_draw) { XFreeGC(display, intel_surf->gc); intel_surf->gc = XCreateGC(display, draw, 0, NULL); } intel_surf->last_draw = draw; return XvPutImage(display, context->port, draw, intel_surf->gc, intel_surf->image, srcx, srcy, srcw, srch, destx, desty, destw, desth); } /* * Function: XvMCSyncSurface * Arguments: * display - Connection to the X server * surface - The surface to synchronize */ _X_EXPORT Status XvMCSyncSurface(Display * display, XvMCSurface * surface) { if (!display || !surface) return XvMCBadSurface; return Success; } /* * Function: XvMCFlushSurface * Description: * This function commits pending rendering requests to ensure that they * wll be completed in a finite amount of time. * Arguments: * display - Connection to X server * surface - Surface to flush * Returns: Status */ _X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface * surface) { if (!display || !surface) return XvMCBadSurface; return Success; } /* * Function: XvMCGetSurfaceStatus * Description: * Arguments: * display: connection to X server * surface: The surface to query * stat: One of the Following * XVMC_RENDERING - The last XvMCRenderSurface command has not * completed. * XVMC_DISPLAYING - The surface is currently being displayed or a * display is pending. */ _X_EXPORT Status XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface, int *stat) { if (!display || !surface || !stat) return XvMCBadSurface; *stat = 0; return Success; } /* * Function: XvMCHideSurface * Description: Stops the display of a surface. * Arguments: * display - Connection to the X server. * surface - surface to be hidden. * * Returns: Status */ _X_EXPORT Status XvMCHideSurface(Display * display, XvMCSurface * surface) { if (!display || !surface) return XvMCBadSurface; return Success; } /* * Function: XvMCCreateSubpicture * Description: This creates a subpicture by filling out the XvMCSubpicture * structure passed to it and returning Success. * Arguments: * display - Connection to the X server. * context - The context to create the subpicture for. * subpicture - Pre-allocated XvMCSubpicture structure to be filled in. * width - of subpicture * height - of subpicture * xvimage_id - The id describing the XvImage format. * * Returns: Status */ _X_EXPORT Status XvMCCreateSubpicture(Display * display, XvMCContext * context, XvMCSubpicture * subpicture, unsigned short width, unsigned short height, int xvimage_id) { XVMC_ERR("XvMCCreateSubpicture not implemented!\n"); return BadValue; } /* * Function: XvMCClearSubpicture * Description: Clear the area of the given subpicture to "color". * structure passed to it and returning Success. * Arguments: * display - Connection to the X server. * subpicture - Subpicture to clear. * x, y, width, height - rectangle in the subpicture to clear. * color - The data to file the rectangle with. * * Returns: Status */ _X_EXPORT Status XvMCClearSubpicture(Display * display, XvMCSubpicture * subpicture, short x, short y, unsigned short width, unsigned short height, unsigned int color) { XVMC_ERR("XvMCClearSubpicture not implemented!"); return BadValue; } /* * Function: XvMCCompositeSubpicture * Description: Composite the XvImae on the subpicture. This composit uses * non-premultiplied alpha. Destination alpha is utilized * except for with indexed subpictures. Indexed subpictures * use a simple "replace". * Arguments: * display - Connection to the X server. * subpicture - Subpicture to clear. * image - the XvImage to be used as the source of the composite. * srcx, srcy, width, height - The rectangle from the image to be used. * dstx, dsty - location in the subpicture to composite the source. * * Returns: Status */ _X_EXPORT Status XvMCCompositeSubpicture(Display * display, XvMCSubpicture * subpicture, XvImage * image, short srcx, short srcy, unsigned short width, unsigned short height, short dstx, short dsty) { XVMC_ERR("XvMCCompositeSubpicture not implemented!"); return BadValue; } /* * Function: XvMCDestroySubpicture * Description: Destroys the specified subpicture. * Arguments: * display - Connection to the X server. * subpicture - Subpicture to be destroyed. * * Returns: Status */ _X_EXPORT Status XvMCDestroySubpicture(Display * display, XvMCSubpicture * subpicture) { XVMC_ERR("XvMCDestroySubpicture not implemented!"); return BadValue; } /* * Function: XvMCSetSubpicturePalette * Description: Set the subpictures palette * Arguments: * display - Connection to the X server. * subpicture - Subpiture to set palette for. * palette - A pointer to an array holding the palette data. The array * is num_palette_entries * entry_bytes in size. * Returns: Status */ _X_EXPORT Status XvMCSetSubpicturePalette(Display * display, XvMCSubpicture * subpicture, unsigned char *palette) { XVMC_ERR("XvMCSetSubpicturePalette not implemented!"); return BadValue; } /* * Function: XvMCBlendSubpicture * Description: * The behavior of this function is different depending on whether * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. * i915 only support frontend behavior. * * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): * * XvMCBlendSubpicture is a no-op in this case. * * Arguments: * display - Connection to the X server. * subpicture - The subpicture to be blended into the video. * target_surface - The surface to be displayed with the blended subpic. * source_surface - Source surface prior to blending. * subx, suby, subw, subh - The rectangle from the subpicture to use. * surfx, surfy, surfw, surfh - The rectangle in the surface to blend * blend the subpicture rectangle into. Scaling can ocure if * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. * * Returns: Status */ _X_EXPORT 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) { XVMC_ERR("XvMCBlendSubpicture not implemented!"); return BadValue; } /* * Function: XvMCBlendSubpicture2 * Description: * The behavior of this function is different depending on whether * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. * i915 only supports frontend blending. * * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): * * XvMCBlendSubpicture2 blends the source_surface and subpicture and * puts it in the target_surface. This does not effect the status of * the source surface but will cause the target_surface to query * XVMC_RENDERING until the blend is completed. * * Arguments: * display - Connection to the X server. * subpicture - The subpicture to be blended into the video. * target_surface - The surface to be displayed with the blended subpic. * source_surface - Source surface prior to blending. * subx, suby, subw, subh - The rectangle from the subpicture to use. * surfx, surfy, surfw, surfh - The rectangle in the surface to blend * blend the subpicture rectangle into. Scaling can ocure if * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. * * Returns: Status */ _X_EXPORT 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) { XVMC_ERR("XvMCBlendSubpicture2 not implemented!"); return BadValue; } /* * Function: XvMCSyncSubpicture * Description: This function blocks until all composite/clear requests on * the subpicture have been complete. * Arguments: * display - Connection to the X server. * subpicture - The subpicture to synchronize * * Returns: Status */ _X_EXPORT Status XvMCSyncSubpicture(Display * display, XvMCSubpicture * subpicture) { XVMC_ERR("XvMCSyncSubpicture not implemented!"); return BadValue; } /* * Function: XvMCFlushSubpicture * Description: This function commits pending composite/clear requests to * ensure that they will be completed in a finite amount of * time. * Arguments: * display - Connection to the X server. * subpicture - The subpicture whos compsiting should be flushed * * Returns: Status */ _X_EXPORT Status XvMCFlushSubpicture(Display * display, XvMCSubpicture * subpicture) { XVMC_ERR("XvMCFlushSubpicture not implemented!"); return BadValue; } /* * Function: XvMCGetSubpictureStatus * Description: This function gets the current status of a subpicture * * Arguments: * display - Connection to the X server. * subpicture - The subpicture whos status is being queried * stat - The status of the subpicture. It can be any of the following * OR'd together: * XVMC_RENDERING - Last composite or clear request not completed * XVMC_DISPLAYING - Suppicture currently being displayed. * * Returns: Status */ _X_EXPORT Status XvMCGetSubpictureStatus(Display * display, XvMCSubpicture * subpicture, int *stat) { XVMC_ERR("XvMCGetSubpictureStatus not implemented!"); return BadValue; } /* * Function: XvMCQueryAttributes * Description: An array of XvAttributes of size "number" is returned by * this function. If there are no attributes, NULL is returned and number * is set to 0. The array may be freed with free(). * * Arguments: * display - Connection to the X server. * context - The context whos attributes we are querying. * number - The returned number of recognized atoms * * Returns: * An array of XvAttributes. */ _X_EXPORT XvAttribute *XvMCQueryAttributes(Display * display, XvMCContext * context, int *number) { /* now XvMC has no extra attribs than Xv */ *number = 0; return NULL; } /* * Function: XvMCSetAttribute * Description: This function sets a context-specific attribute. * * Arguments: * display - Connection to the X server. * context - The context whos attributes we are querying. * attribute - The X atom of the attribute to be changed. * value - The new value for the attribute. * * Returns: * Status */ _X_EXPORT Status XvMCSetAttribute(Display * display, XvMCContext * context, Atom attribute, int value) { return Success; } /* * Function: XvMCGetAttribute * Description: This function queries a context-specific attribute and * returns the value. * * Arguments: * display - Connection to the X server. * context - The context whos attributes we are querying. * attribute - The X atom of the attribute to be queried * value - The returned attribute value * * Returns: * Status */ _X_EXPORT Status XvMCGetAttribute(Display * display, XvMCContext * context, Atom attribute, int *value) { return Success; } _X_EXPORT Status XvMCBeginSurface(Display * display, XvMCContext * context, XvMCSurface * target, XvMCSurface * past, XvMCSurface * future, const XvMCMpegControl * control) { if (xvmc_driver->begin_surface(display, context, target, past, future, control)) { XVMC_ERR("BeginSurface fail\n"); return BadValue; } return Success; } _X_EXPORT Status XvMCLoadQMatrix(Display * display, XvMCContext * context, const XvMCQMatrix * qmx) { if (xvmc_driver->load_qmatrix(display, context, qmx)) { XVMC_ERR("LoadQMatrix fail\n"); return BadValue; } return Success; } _X_EXPORT Status XvMCPutSlice(Display * display, XvMCContext * context, char *slice, int nbytes) { if (xvmc_driver->put_slice(display, context, (unsigned char *) slice, nbytes)) { XVMC_ERR("PutSlice fail\n"); return BadValue; } return Success; } _X_EXPORT Status XvMCPutSlice2(Display * display, XvMCContext * context, char *slice, int nbytes, int slice_code) { if (xvmc_driver->put_slice2 (display, context, (unsigned char *) slice, nbytes, slice_code)) { XVMC_ERR("PutSlice2 fail\n"); return BadValue; } return Success; } xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_xvmc.h000066400000000000000000000042331267532330400235730ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #ifndef I830_HWMC_H #define I830_HWMC_H #define INTEL_XVMC_LIBNAME "IntelXvMC" #define INTEL_XVMC_MAJOR 0 #define INTEL_XVMC_MINOR 1 #define INTEL_XVMC_PATCHLEVEL 0 #define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X') /* * Commands that client submits through XvPutImage: */ #define INTEL_XVMC_COMMAND_DISPLAY 0x00 #define INTEL_XVMC_COMMAND_UNDISPLAY 0x01 /* hw xvmc support type */ #define XVMC_I915_MPEG2_MC 0x01 #define XVMC_I965_MPEG2_MC 0x02 #define XVMC_I945_MPEG2_VLD 0x04 #define XVMC_I965_MPEG2_VLD 0x08 struct intel_xvmc_hw_context { unsigned int type; union { struct { unsigned int use_phys_addr : 1; } i915; struct { unsigned int is_g4x:1; unsigned int is_965_q:1; unsigned int is_igdng:1; } i965; }; }; /* Intel private XvMC command to DDX driver */ struct intel_xvmc_command { uint32_t handle; }; #ifdef _INTEL_XVMC_SERVER_ #include extern Bool intel_xvmc_adaptor_init(ScreenPtr); #endif #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_xvmc_dump.c000066400000000000000000000116601267532330400246150ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #include "intel_xvmc_private.h" #define DUMPFILE "./intel_xvmc_dump" static int xvmc_dump = 0; static FILE *fp = NULL; void intel_xvmc_dump_open(void) { char *d = NULL; if (xvmc_dump) return; if ((d = getenv("INTEL_XVMC_DUMP"))) xvmc_dump = 1; if (xvmc_dump) { fp = fopen(DUMPFILE, "a"); if (!fp) xvmc_dump = 0; } } void intel_xvmc_dump_close(void) { if (xvmc_dump) { fclose(fp); xvmc_dump = 0; } } void intel_xvmc_dump_render(XvMCContext * context, unsigned int picture_structure, XvMCSurface * target, XvMCSurface * past, XvMCSurface * future, unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock, XvMCMacroBlockArray * macroblock_array, XvMCBlockArray * blocks) { int i; XvMCMacroBlock *mb; if (!xvmc_dump) return; fprintf(fp, "========== new surface rendering ==========\n"); fprintf(fp, "Context (id:%d) (surface_type_id:%d) (width:%d) (height:%d)\n", (int)context->context_id, context->surface_type_id, context->width, context->height); if (picture_structure == XVMC_FRAME_PICTURE) fprintf(fp, "picture structure: frame picture\n"); else if (picture_structure == XVMC_TOP_FIELD) fprintf(fp, "picture structure: top field picture (%s)\n", (flags == XVMC_SECOND_FIELD) ? "second" : "first"); else if (picture_structure == XVMC_BOTTOM_FIELD) fprintf(fp, "picture structure: bottom field picture (%s)\n", (flags == XVMC_SECOND_FIELD) ? "second" : "first"); if (!past && !future) fprintf(fp, "picture type: I\n"); else if (past && !future) fprintf(fp, "picture type: P\n"); else if (past && future) fprintf(fp, "picture type: B\n"); else fprintf(fp, "picture type: Bad!\n"); fprintf(fp, "target picture: id (%d) width (%d) height (%d)\n", (int)target->surface_id, target->width, target->height); if (past) fprintf(fp, "past picture: id (%d) width (%d) height (%d)\n", (int)past->surface_id, past->width, past->height); if (future) fprintf(fp, "future picture: id (%d) width (%d) height (%d)\n", (int)future->surface_id, future->width, future->height); fprintf(fp, "num macroblocks: %d, first macroblocks %d\n", num_macroblocks, first_macroblock); for (i = first_macroblock; i < (first_macroblock + num_macroblocks); i++) { mb = ¯oblock_array->macro_blocks[i]; fprintf(fp, "- MB(%d): ", i); fprintf(fp, "x (%d) y (%d) ", mb->x, mb->y); fprintf(fp, "macroblock type ("); if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) fprintf(fp, "motion_forward "); if (mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) fprintf(fp, "motion_backward "); if (mb->macroblock_type & XVMC_MB_TYPE_PATTERN) fprintf(fp, "pattern "); if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) fprintf(fp, "intra "); fprintf(fp, ") "); fprintf(fp, "mc type "); if (picture_structure == XVMC_FRAME_PICTURE) { if (mb->motion_type & XVMC_PREDICTION_FIELD) fprintf(fp, "(field) "); else if (mb->motion_type & XVMC_PREDICTION_FRAME) fprintf(fp, "(frame) "); else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) fprintf(fp, "(dual-prime) "); else fprintf(fp, "(unknown %d) ", mb->motion_type); } else { /* field */ if (mb->motion_type & XVMC_PREDICTION_FIELD) fprintf(fp, "(field) "); else if (mb->motion_type & XVMC_PREDICTION_DUAL_PRIME) fprintf(fp, "(dual-prime) "); else if (mb->motion_type & XVMC_PREDICTION_16x8) fprintf(fp, "(16x8) "); else fprintf(fp, "(unknown %d) ", mb->motion_type); } if (mb->dct_type == XVMC_DCT_TYPE_FRAME) fprintf(fp, "dct type (frame) "); else if (mb->dct_type == XVMC_DCT_TYPE_FIELD) fprintf(fp, "dct type (field) "); fprintf(fp, "coded_block_pattern (0x%x)\n", mb->coded_block_pattern); /* XXX mv dump */ } } xserver-xorg-video-intel-2.99.917+git20160325/xvmc/intel_xvmc_private.h000066400000000000000000000160351267532330400253300ustar00rootroot00000000000000/* * Copyright © 2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Authors: * Zhenyu Wang * */ #ifndef INTEL_XVMC_H #define INTEL_XVMC_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "i915_drm.h" #include "intel_bufmgr.h" #include "intel_xvmc.h" #include "intel_batchbuffer.h" #define GTT_PAGE_SIZE 4*1024 #define XVMC_ERR(s, arg...) \ do { \ fprintf(stderr, "[intel_xvmc] err: " s "\n", ##arg); \ } while (0) #define XVMC_INFO(s, arg...) \ do { \ fprintf(stderr, "[intel_xvmc] info: " s "\n", ##arg); \ } while (0) /* Subpicture fourcc */ #define FOURCC_IA44 0x34344149 /* Definitions for temporary wire protocol hooks to be replaced when a HW independent libXvMC is created. */ extern Status _xvmc_create_context(Display * dpy, XvMCContext * context, int *priv_count, CARD32 ** 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, CARD32 ** 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); struct intel_xvmc_context { struct intel_xvmc_hw_context *hw; uint32_t surface_bo_size; drm_context_t hw_context; /* context id to kernel drm */ }; typedef struct intel_xvmc_context *intel_xvmc_context_ptr; struct intel_xvmc_surface { XvMCContext *context; XvImage *image; GC gc; Bool gc_init; Drawable last_draw; drm_intel_bo *bo; uint32_t gem_handle; }; typedef struct intel_xvmc_surface *intel_xvmc_surface_ptr; typedef struct _intel_xvmc_drm_map { drm_handle_t handle; unsigned long offset; unsigned long size; unsigned long bus_addr; drmAddress map; } intel_xvmc_drm_map_t, *intel_xvmc_drm_map_ptr; typedef struct _intel_xvmc_driver { int type; /* hw xvmc type - i830_hwmc.h */ int screen; /* current screen num */ int fd; /* drm file handler */ dri_bufmgr *bufmgr; struct { unsigned int init_offset; unsigned int size; unsigned int space; unsigned char *ptr; unsigned char *init_ptr; dri_bo *buf; } batch; struct { void *ptr; unsigned int size; unsigned int offset; unsigned int active_buf; unsigned int irq_emitted; } alloc; intel_xvmc_drm_map_t batchbuffer; sigset_t sa_mask, old_mask; pthread_mutex_t ctxmutex; int num_ctx; intel_xvmc_context_ptr ctx_list; int num_surf; struct intel_xvmc_surface * surf_list; void *private; /* driver specific xvmc callbacks */ Status(*create_context) (Display * display, XvMCContext * context, int priv_count, CARD32 * priv_data); Status(*destroy_context) (Display * display, XvMCContext * context); Status(*render_surface) (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); Status(*begin_surface) (Display * display, XvMCContext * context, XvMCSurface * target_surface, XvMCSurface * past_surface, XvMCSurface * future_surface, const XvMCMpegControl * control); Status(*load_qmatrix) (Display * display, XvMCContext * context, const XvMCQMatrix * qmx); Status(*put_slice) (Display * display, XvMCContext * context, unsigned char *slice, int bytes); Status(*put_slice2) (Display * display, XvMCContext * context, unsigned char *slice, int bytes, int slice_code); } intel_xvmc_driver_t, *intel_xvmc_driver_ptr; extern struct _intel_xvmc_driver i915_xvmc_mc_driver; extern struct _intel_xvmc_driver i965_xvmc_mc_driver; extern struct _intel_xvmc_driver xvmc_vld_driver; extern struct _intel_xvmc_driver *xvmc_driver; static inline void LOCK_HARDWARE(drm_context_t ctx) { pthread_mutex_lock(&xvmc_driver->ctxmutex); pthread_sigmask(SIG_SETMASK, &xvmc_driver->sa_mask, &xvmc_driver->old_mask); } static inline void UNLOCK_HARDWARE(drm_context_t ctx) { pthread_sigmask(SIG_SETMASK, &xvmc_driver->old_mask, NULL); pthread_mutex_unlock(&xvmc_driver->ctxmutex); } static inline const char *intel_xvmc_decoder_string(int flag) { switch (flag) { case XVMC_I915_MPEG2_MC: return "i915/945 MPEG2 MC decoder"; case XVMC_I965_MPEG2_MC: return "i965 MPEG2 MC decoder"; case XVMC_I945_MPEG2_VLD: return "i945 MPEG2 VLD decoder"; case XVMC_I965_MPEG2_VLD: return "i965 MPEG2 VLD decoder"; default: return "Unknown decoder"; } } extern unsigned int mb_bytes_420[64]; /* dump function */ extern void intel_xvmc_dump_open(void); extern void intel_xvmc_dump_close(void); extern void intel_xvmc_dump_render(XvMCContext * context, unsigned int picture_structure, XvMCSurface * target_surface, XvMCSurface * past_surface, XvMCSurface * future_surface, unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock, XvMCMacroBlockArray * macroblock_array, XvMCBlockArray * blocks); #define VFE_GENERIC_MODE 0x0 #define VFE_VLD_MODE 0x1 #define VFE_IS_MODE 0x2 #define VFE_AVC_MC_MODE 0x4 #define VFE_AVC_IT_MODE 0x7 #define VFE_VC1_IT_MODE 0x7 #endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/000077500000000000000000000000001267532330400225165ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/Makefile.am000066400000000000000000000000221267532330400245440ustar00rootroot00000000000000SUBDIRS = mc vld xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/000077500000000000000000000000001267532330400231155ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/Makefile.am000066400000000000000000000111631267532330400251530ustar00rootroot00000000000000 INTEL_G4A = dual_prime_igd.g4a \ field_backward_igd.g4a \ field_f_b_igd.g4a \ field_forward_igd.g4a \ frame_backward_igd.g4a \ frame_f_b_igd.g4a \ frame_forward_igd.g4a \ dual_prime.g4a \ field_backward.g4a \ field_f_b.g4a \ field_forward.g4a \ frame_backward.g4a \ frame_f_b.g4a \ frame_forward.g4a \ lib_igd.g4a \ ipicture.g4a \ ipicture_igd.g4a \ null.g4a INTEL_G4I = addidct.g4i \ addidct_igd.g4i \ block_clear.g4i \ read_frame_x0y0_y.g4i \ read_frame_x0y1_y.g4i \ read_frame_x1y0_y.g4i \ read_frame_x1y1_y.g4i \ read_frame_x0y0_uv.g4i \ read_frame_x0y1_uv.g4i \ read_frame_x1y0_uv.g4i \ read_frame_x1y1_uv.g4i \ read_frame_x0y0_y_igd.g4i \ read_frame_x0y1_y_igd.g4i \ read_frame_x1y0_y_igd.g4i \ read_frame_x1y1_y_igd.g4i \ read_frame_x0y0_uv_igd.g4i \ read_frame_x0y1_uv_igd.g4i \ read_frame_x1y0_uv_igd.g4i \ read_frame_x1y1_uv_igd.g4i \ motion_frame_y.g4i \ motion_frame_uv.g4i \ read_field_x0y0_y.g4i \ read_field_x0y1_y.g4i \ read_field_x1y0_y.g4i \ read_field_x1y1_y.g4i \ read_field_x0y0_uv.g4i \ read_field_x0y1_uv.g4i \ read_field_x1y0_uv.g4i \ read_field_x1y1_uv.g4i \ read_field_x0y0_y_igd.g4i \ read_field_x0y1_y_igd.g4i \ read_field_x1y0_y_igd.g4i \ read_field_x1y1_y_igd.g4i \ read_field_x0y0_uv_igd.g4i \ read_field_x0y1_uv_igd.g4i \ read_field_x1y0_uv_igd.g4i \ read_field_x1y1_uv_igd.g4i \ motion_field_y.g4i \ motion_field_uv.g4i \ motion_field_uv_igd.g4i \ motion_field_y_igd.g4i \ motion_frame_uv_igd.g4i \ motion_frame_y_igd.g4i INTEL_G4B = dual_prime.g4b \ field_backward.g4b \ field_f_b.g4b \ field_forward.g4b \ frame_backward.g4b \ frame_f_b.g4b \ frame_forward.g4b \ dual_prime_igd.g4b \ field_backward_igd.g4b \ field_f_b_igd.g4b \ field_forward_igd.g4b \ frame_backward_igd.g4b \ frame_f_b_igd.g4b \ frame_forward_igd.g4b \ ipicture.g4b \ ipicture_igd.g4b \ lib_igd.g4b \ null.g4b INTEL_G4B_GEN5 = dual_prime.g4b.gen5 \ field_backward.g4b.gen5 \ field_f_b.g4b.gen5 \ field_forward.g4b.gen5 \ frame_backward.g4b.gen5 \ frame_f_b.g4b.gen5 \ frame_forward.g4b.gen5 \ dual_prime_igd.g4b.gen5 \ field_backward_igd.g4b.gen5 \ field_f_b_igd.g4b.gen5 \ field_forward_igd.g4b.gen5 \ frame_backward_igd.g4b.gen5 \ frame_f_b_igd.g4b.gen5 \ frame_forward_igd.g4b.gen5 \ ipicture.g4b.gen5 \ ipicture_igd.g4b.gen5 \ lib_igd.g4b.gen5 \ null.g4b.gen5 EXTRA_DIST = $(INTEL_G4A) \ $(INTEL_G4I) \ $(INTEL_G4B) \ $(INTEL_G4B_GEN5) if HAVE_GEN4ASM SUFFIXES = .g4a .g4b .g4a.g4b: $(AM_V_GEN)m4 -I$(srcdir) $(srcdir)/$*.g4a > $*.g4m && @INTEL_GEN4ASM@ -o $@ $*.g4m && @INTEL_GEN4ASM@ -g 5 -o $@.gen5 $*.g4m && rm $*.g4m $(INTEL_G4B): $(INTEL_GEN4ASM) $(INTEL_G4I) BUILT_SOURCES= $(INTEL_G4B) clean-local: -rm -f $(INTEL_G4B) -rm -f $(INTEL_G4B_GEN5) endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/addidct.g4i000066400000000000000000000156331267532330400251260ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g1.0<1>UD g76.0<8,8,1>UD{align1}; //mov (8) g2.0<1>UD g77.0<8,8,1>UD{align1}; mov (16) g44.1<2>UB 0W {align1}; mov (16) g45.1<2>UB 0W {align1}; mov (16) g46.1<2>UB 0W {align1}; mov (16) g47.1<2>UB 0W {align1}; mov (16) g48.1<2>UB 0W {align1}; mov (16) g49.1<2>UB 0W {align1}; mov (16) g50.1<2>UB 0W {align1}; mov (16) g51.1<2>UB 0W {align1}; and.nz (1) null g1.30<1,1,1>UB 1UW {align1}; //dct_type (f0) jmpi field_dct; //jmpi field_dct; add (16) g28.0<1>W g3.0<16,16,1>W g28.0<16,16,2>UB {align1}; add (16) g29.0<1>W g4.0<16,16,1>W g29.0<16,16,2>UB {align1}; add (16) g30.0<1>W g5.0<16,16,1>W g30.0<16,16,2>UB {align1}; add (16) g31.0<1>W g6.0<16,16,1>W g31.0<16,16,2>UB {align1}; add (16) g32.0<1>W g7.0<16,16,1>W g32.0<16,16,2>UB {align1}; add (16) g33.0<1>W g8.0<16,16,1>W g33.0<16,16,2>UB {align1}; add (16) g34.0<1>W g9.0<16,16,1>W g34.0<16,16,2>UB {align1}; add (16) g35.0<1>W g10.0<16,16,1>W g35.0<16,16,2>UB {align1}; add (16) g36.0<1>W g11.0<16,16,1>W g36.0<16,16,2>UB {align1}; add (16) g37.0<1>W g12.0<16,16,1>W g37.0<16,16,2>UB {align1}; add (16) g38.0<1>W g13.0<16,16,1>W g38.0<16,16,2>UB {align1}; add (16) g39.0<1>W g14.0<16,16,1>W g39.0<16,16,2>UB {align1}; add (16) g40.0<1>W g15.0<16,16,1>W g40.0<16,16,2>UB {align1}; add (16) g41.0<1>W g16.0<16,16,1>W g41.0<16,16,2>UB {align1}; add (16) g42.0<1>W g17.0<16,16,1>W g42.0<16,16,2>UB {align1}; add (16) g43.0<1>W g18.0<16,16,1>W g43.0<16,16,2>UB {align1}; jmpi write_back; field_dct: add (16) g28.0<1>W g3.0<16,16,1>W g28.0<16,16,2>UB {align1}; add (16) g29.0<1>W g11.0<16,16,1>W g29.0<16,16,2>UB {align1}; add (16) g30.0<1>W g4.0<16,16,1>W g30.0<16,16,2>UB {align1}; add (16) g31.0<1>W g12.0<16,16,1>W g31.0<16,16,2>UB {align1}; add (16) g32.0<1>W g5.0<16,16,1>W g32.0<16,16,2>UB {align1}; add (16) g33.0<1>W g13.0<16,16,1>W g33.0<16,16,2>UB {align1}; add (16) g34.0<1>W g6.0<16,16,1>W g34.0<16,16,2>UB {align1}; add (16) g35.0<1>W g14.0<16,16,1>W g35.0<16,16,2>UB {align1}; add (16) g36.0<1>W g7.0<16,16,1>W g36.0<16,16,2>UB {align1}; add (16) g37.0<1>W g15.0<16,16,1>W g37.0<16,16,2>UB {align1}; add (16) g38.0<1>W g8.0<16,16,1>W g38.0<16,16,2>UB {align1}; add (16) g39.0<1>W g16.0<16,16,1>W g39.0<16,16,2>UB {align1}; add (16) g40.0<1>W g9.0<16,16,1>W g40.0<16,16,2>UB {align1}; add (16) g41.0<1>W g17.0<16,16,1>W g41.0<16,16,2>UB {align1}; add (16) g42.0<1>W g10.0<16,16,1>W g42.0<16,16,2>UB {align1}; add (16) g43.0<1>W g18.0<16,16,1>W g43.0<16,16,2>UB {align1}; write_back: mov (1) g1.8<1>UD 0x00F000FUD {align1}; mov.sat (16) g28.0<2>UB g28.0<16,16,1>W {align1}; mov.sat (16) g29.0<2>UB g29.0<16,16,1>W {align1}; mov.sat (16) g30.0<2>UB g30.0<16,16,1>W {align1}; mov.sat (16) g31.0<2>UB g31.0<16,16,1>W {align1}; mov.sat (16) g32.0<2>UB g32.0<16,16,1>W {align1}; mov.sat (16) g33.0<2>UB g33.0<16,16,1>W {align1}; mov.sat (16) g34.0<2>UB g34.0<16,16,1>W {align1}; mov.sat (16) g35.0<2>UB g35.0<16,16,1>W {align1}; mov.sat (16) g36.0<2>UB g36.0<16,16,1>W {align1}; mov.sat (16) g37.0<2>UB g37.0<16,16,1>W {align1}; mov.sat (16) g38.0<2>UB g38.0<16,16,1>W {align1}; mov.sat (16) g39.0<2>UB g39.0<16,16,1>W {align1}; mov.sat (16) g40.0<2>UB g40.0<16,16,1>W {align1}; mov.sat (16) g41.0<2>UB g41.0<16,16,1>W {align1}; mov.sat (16) g42.0<2>UB g42.0<16,16,1>W {align1}; mov.sat (16) g43.0<2>UB g43.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g28.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g29.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g30.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g31.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g32.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g33.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g34.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g35.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g36.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g37.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g38.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g39.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g40.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g41.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g42.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g43.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g1.8<1>UD 0x0070007UD { align1 }; shr (2) g1.0<1>UD g1.0<2,2,1>UD 1D {align1}; add (16) g44.0<1>UW g19.0<16,16,1>W g44.0<16,16,1>UW {align1}; add (16) g45.0<1>UW g20.0<16,16,1>W g45.0<16,16,1>UW {align1}; add (16) g46.0<1>UW g21.0<16,16,1>W g46.0<16,16,1>UW {align1}; add (16) g47.0<1>UW g22.0<16,16,1>W g47.0<16,16,1>UW {align1}; mov.sat (16) g44.0<2>UB g44.0<16,16,1>UW {align1}; mov.sat (16) g45.0<2>UB g45.0<16,16,1>UW {align1}; mov.sat (16) g46.0<2>UB g46.0<16,16,1>UW {align1}; mov.sat (16) g47.0<2>UB g47.0<16,16,1>UW {align1}; mov (16) m1.0<1>UB g44.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g45.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g46.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g47.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V add (16) g48.0<1>UW g23.0<16,16,1>W g48.0<16,16,1>UW {align1}; add (16) g49.0<1>UW g24.0<16,16,1>W g49.0<16,16,1>UW {align1}; add (16) g50.0<1>UW g25.0<16,16,1>W g50.0<16,16,1>UW {align1}; add (16) g51.0<1>UW g26.0<16,16,1>W g51.0<16,16,1>UW {align1}; mov.sat (16) g48.0<2>UB g48.0<16,16,1>UW {align1}; mov.sat (16) g49.0<2>UB g49.0<16,16,1>UW {align1}; mov.sat (16) g50.0<2>UB g50.0<16,16,1>UW {align1}; mov.sat (16) g51.0<2>UB g51.0<16,16,1>UW {align1}; mov (16) m1.0<1>UB g48.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g49.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g50.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g51.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/addidct_igd.g4i000066400000000000000000000130031267532330400257360ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g84~g107:IDCT data */ //mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; //restore x and y mov (2) g31.0<1>UD g82.0<2,2,1>UD {align1}; //restore x and y and.nz (1) null g82.30<1,1,1>UB 0x1UW {align1}; //dct_type (f0) jmpi field_dct; add.sat (32) g58.0<2>UB g84.0<16,16,1>W g58.0<16,16,2>UB {align1 compr}; add.sat (32) g60.0<2>UB g86.0<16,16,1>W g60.0<16,16,2>UB {align1 compr}; add.sat (32) g62.0<2>UB g88.0<16,16,1>W g62.0<16,16,2>UB {align1 compr}; add.sat (32) g64.0<2>UB g90.0<16,16,1>W g64.0<16,16,2>UB {align1 compr}; add.sat (32) g66.0<2>UB g92.0<16,16,1>W g66.0<16,16,2>UB {align1 compr}; add.sat (32) g68.0<2>UB g94.0<16,16,1>W g68.0<16,16,2>UB {align1 compr}; add.sat (32) g70.0<2>UB g96.0<16,16,1>W g70.0<16,16,2>UB {align1 compr}; add.sat (32) g72.0<2>UB g98.0<16,16,1>W g72.0<16,16,2>UB {align1 compr}; add.sat (32) g74.0<2>UB g100.0<16,16,1>W g74.0<16,16,2>UB {align1 compr}; add.sat (32) g76.0<2>UB g102.0<16,16,1>W g76.0<16,16,2>UB {align1 compr}; add.sat (32) g78.0<2>UB g104.0<16,16,1>W g78.0<16,16,2>UB {align1 compr}; add.sat (32) g80.0<2>UB g106.0<16,16,1>W g80.0<16,16,2>UB {align1 compr}; jmpi write_back; field_dct: add.sat (16) g58.0<2>UB g84.0<16,16,1>W g58.0<16,16,2>UB {align1}; add.sat (16) g59.0<2>UB g92.0<16,16,1>W g59.0<16,16,2>UB {align1}; add.sat (16) g60.0<2>UB g85.0<16,16,1>W g60.0<16,16,2>UB {align1}; add.sat (16) g61.0<2>UB g93.0<16,16,1>W g61.0<16,16,2>UB {align1}; add.sat (16) g62.0<2>UB g86.0<16,16,1>W g62.0<16,16,2>UB {align1}; add.sat (16) g63.0<2>UB g94.0<16,16,1>W g63.0<16,16,2>UB {align1}; add.sat (16) g64.0<2>UB g87.0<16,16,1>W g64.0<16,16,2>UB {align1}; add.sat (16) g65.0<2>UB g95.0<16,16,1>W g65.0<16,16,2>UB {align1}; add.sat (16) g66.0<2>UB g88.0<16,16,1>W g66.0<16,16,2>UB {align1}; add.sat (16) g67.0<2>UB g96.0<16,16,1>W g67.0<16,16,2>UB {align1}; add.sat (16) g68.0<2>UB g89.0<16,16,1>W g68.0<16,16,2>UB {align1}; add.sat (16) g69.0<2>UB g97.0<16,16,1>W g69.0<16,16,2>UB {align1}; add.sat (16) g70.0<2>UB g90.0<16,16,1>W g70.0<16,16,2>UB {align1}; add.sat (16) g71.0<2>UB g98.0<16,16,1>W g71.0<16,16,2>UB {align1}; add.sat (16) g72.0<2>UB g91.0<16,16,1>W g72.0<16,16,2>UB {align1}; add.sat (16) g73.0<2>UB g99.0<16,16,1>W g73.0<16,16,2>UB {align1}; /* add.sat (16) g74.0<2>UB g100.0<16,16,1>W g74.0<16,16,2>UB {align1}; add.sat (16) g75.0<2>UB g101.0<16,16,1>W g75.0<16,16,2>UB {align1}; add.sat (16) g76.0<2>UB g102.0<16,16,1>W g76.0<16,16,2>UB {align1}; add.sat (16) g77.0<2>UB g103.0<16,16,1>W g77.0<16,16,2>UB {align1}; add.sat (16) g78.0<2>UB g104.0<16,16,1>W g78.0<16,16,2>UB {align1}; add.sat (16) g79.0<2>UB g105.0<16,16,1>W g79.0<16,16,2>UB {align1}; add.sat (16) g80.0<2>UB g106.0<16,16,1>W g80.0<16,16,2>UB {align1}; add.sat (16) g81.0<2>UB g107.0<16,16,1>W g81.0<16,16,2>UB {align1}; */ add (16) g100.0<1>W g100.0<16,16,1>W g74.0<16,16,2>UB {align1}; add (16) g101.0<1>W g101.0<16,16,1>W g75.0<16,16,2>UB {align1}; add (16) g102.0<1>W g102.0<16,16,1>W g76.0<16,16,2>UB {align1}; add (16) g103.0<1>W g103.0<16,16,1>W g77.0<16,16,2>UB {align1}; add (16) g104.0<1>W g104.0<16,16,1>W g78.0<16,16,2>UB {align1}; add (16) g105.0<1>W g105.0<16,16,1>W g79.0<16,16,2>UB {align1}; add (16) g106.0<1>W g106.0<16,16,1>W g80.0<16,16,2>UB {align1}; add (16) g107.0<1>W g107.0<16,16,1>W g81.0<16,16,2>UB {align1}; mov.sat (16) g74.0<2>UB g100.0<16,16,1>W {align1}; mov.sat (16) g75.0<2>UB g101.0<16,16,1>W {align1}; mov.sat (16) g76.0<2>UB g102.0<16,16,1>W {align1}; mov.sat (16) g77.0<2>UB g103.0<16,16,1>W {align1}; mov.sat (16) g78.0<2>UB g104.0<16,16,1>W {align1}; mov.sat (16) g79.0<2>UB g105.0<16,16,1>W {align1}; mov.sat (16) g80.0<2>UB g106.0<16,16,1>W {align1}; mov.sat (16) g81.0<2>UB g107.0<16,16,1>W {align1}; write_back: mov (1) g31.8<1>UD 0x00F000FUD {align1}; mov (16) m1.0<1>UB g58.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g59.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g60.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g61.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g62.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g63.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g64.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g65.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g66.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g67.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g68.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g69.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g70.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g71.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g72.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g73.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g31.8<1>UD 0x0070007UD { align1 }; shr (2) g31.0<1>UD g31.0<2,2,1>UD 1D {align1}; mov (16) m1.0<1>UB g74.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g75.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g76.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g77.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V mov (16) m1.0<1>UB g78.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g79.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g80.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g81.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/block_clear.g4i000066400000000000000000000140651267532330400257700ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * */ and.nz (1) null g2.0<1,1,1>UD 0x1UD{align1}; (f0) jmpi direct_idct; add (1) g2.8<1>UD g76.8<1,1,1>UD 0UD{align1}; send (16) 0 g3.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g4.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g5.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g6.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g7.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g8.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g9.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g10.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g11.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g12.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g13.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g14.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g15.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g16.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g17.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g18.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g19.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g20.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g21.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g22.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g23<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g24.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g25.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g26.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; direct_idct: and.nz (1) null g76.12<1,1,1>UW 0x20UW {align1}; (f0) jmpi next_block; mov (8) g3.0<1>UW 0UW {align1}; mov (8) g4.0<1>UW 0UW {align1}; mov (8) g5.0<1>UW 0UW {align1}; mov (8) g6.0<1>UW 0UW {align1}; mov (8) g7.0<1>UW 0UW {align1}; mov (8) g8.0<1>UW 0UW {align1}; mov (8) g9.0<1>UW 0UW {align1}; mov (8) g10.0<1>UW 0UW {align1}; next_block: and.nz (1) null g1.12<1,1,1>UW 0x10UW {align1}; (f0) jmpi next_field; mov (8) g3.16<1>UW 0UW {align1}; mov (8) g4.16<1>UW 0UW {align1}; mov (8) g5.16<1>UW 0UW {align1}; mov (8) g6.16<1>UW 0UW {align1}; mov (8) g7.16<1>UW 0UW {align1}; mov (8) g8.16<1>UW 0UW {align1}; mov (8) g9.16<1>UW 0UW {align1}; mov (8) g10.16<1>UW 0UW {align1}; next_field: and.nz (1) null g1.12<1,1,1>UW 0x8UW {align1}; (f0) jmpi next_field; mov (8) g11.0<1>UW 0UW {align1}; mov (8) g12.0<1>UW 0UW {align1}; mov (8) g13.0<1>UW 0UW {align1}; mov (8) g14.0<1>UW 0UW {align1}; mov (8) g15.0<1>UW 0UW {align1}; mov (8) g16.0<1>UW 0UW {align1}; mov (8) g17.0<1>UW 0UW {align1}; mov (8) g18.0<1>UW 0UW {align1}; next_field: and.nz (1) null g1.12<1,1,1>UW 0x4UW {align1}; (f0) jmpi next_field; mov (8) g11.16<1>UW 0UW {align1}; mov (8) g12.16<1>UW 0UW {align1}; mov (8) g13.16<1>UW 0UW {align1}; mov (8) g14.16<1>UW 0UW {align1}; mov (8) g15.16<1>UW 0UW {align1}; mov (8) g16.16<1>UW 0UW {align1}; mov (8) g17.16<1>UW 0UW {align1}; mov (8) g18.16<1>UW 0UW {align1}; next_field: and.nz (1) null g1.12<1,1,1>UW 0x2UW {align1}; (f0) jmpi next_field; mov (16) g19.0<1>UW 0UW {align1}; mov (16) g20.0<1>UW 0UW {align1}; mov (16) g21.0<1>UW 0UW {align1}; mov (16) g22.0<1>UW 0UW {align1}; next_field: and.nz (1) null g1.12<1,1,1>UW 0x1UW {align1}; (f0) jmpi next_field; mov (16) g23.0<1>UW 0UW {align1}; mov (16) g24.0<1>UW 0UW {align1}; mov (16) g25.0<1>UW 0UW {align1}; mov (16) g26.0<1>UW 0UW {align1}; next_field: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime.g4a000066400000000000000000000226721267532330400256440ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (8) g116.0<1>UD g1.0<8,8,1>UD {align1}; /* forward---Y---first vector*/ mov(1) g115.8<1>UD 0x007001fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_y.g4i') mov (8) g52.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g54.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g56.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g58.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---Y---second vector*/ asr (2) g115.14<1>W g1.22<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x4UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.22') define(`mv2',`g1.24') include(`motion_field_y.g4i') mov (8) g53.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g55.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g57.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g59.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---UV---first vector*/ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`5') define(`surface_v',`6') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_uv.g4i') mov (8) g68.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g85.0<8,8,1>UW {align1}; /*forward---UV---second vector */ asr (2) g115.14<1>W g1.22<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.24') define(`mv2',`g1.26') include(`motion_field_uv.g4i') mov (8) g68.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g85.0<8,8,1>UW {align1}; /*backward---Y---first vector */ mov(8) g1.0<1>UD g116.0<8,8,1>UD {align1}; mov(1) g115.8<1>UD 0x007001fUD { align1 }; mov(1) g1.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_y.g4i') mov (8) g28.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g30.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g32.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g34.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g36.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g38.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g40.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g42.0<1>UD g103.0<8,8,1>UD {align1}; /*backward---Y---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g2.20<1,1,1>UD 0x8UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_y.g4i') avg.sat (16) g28.0<1>UW g52.0<16,16,1>UW g28.0<16,16,1>UW {align1}; avg.sat (16) g29.0<1>UW g53.0<16,16,1>UW g96.0<16,16,1>UW {align1}; avg.sat (16) g30.0<1>UW g54.0<16,16,1>UW g30.0<16,16,1>UW {align1}; avg.sat (16) g31.0<1>UW g55.0<16,16,1>UW g97.0<16,16,1>UW {align1}; avg.sat (16) g32.0<1>UW g56.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg.sat (16) g33.0<1>UW g57.0<16,16,1>UW g98.0<16,16,1>UW {align1}; avg.sat (16) g34.0<1>UW g58.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg.sat (16) g35.0<1>UW g59.0<16,16,1>UW g99.0<16,16,1>UW {align1}; avg.sat (16) g36.0<1>UW g60.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg.sat (16) g37.0<1>UW g61.0<16,16,1>UW g100.0<16,16,1>UW {align1}; avg.sat (16) g38.0<1>UW g62.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg.sat (16) g39.0<1>UW g63.0<16,16,1>UW g101.0<16,16,1>UW {align1}; avg.sat (16) g40.0<1>UW g64.0<16,16,1>UW g40.0<16,16,1>UW {align1}; avg.sat (16) g41.0<1>UW g65.0<16,16,1>UW g102.0<16,16,1>UW {align1}; avg.sat (16) g42.0<1>UW g66.0<16,16,1>UW g42.0<16,16,1>UW {align1}; avg.sat (16) g43.0<1>UW g67.0<16,16,1>UW g103.0<16,16,1>UW {align1}; /*backward---UV---first vector */ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`8') define(`surface_v',`9') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_uv.g4i') mov (8) g44.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.0<1>UW g85.0<8,8,1>UW {align1}; /*backward---UV---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_uv.g4i') mov (8) g44.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.16<1>UW g85.0<8,8,1>UW {align1}; avg.sat (16) g44.0<1>UW g68.0<16,16,1>UW g44.0<16,16,1>UW {align1}; avg.sat (16) g45.0<1>UW g69.0<16,16,1>UW g45.0<16,16,1>UW {align1}; avg.sat (16) g46.0<1>UW g70.0<16,16,1>UW g46.0<16,16,1>UW {align1}; avg.sat (16) g47.0<1>UW g71.0<16,16,1>UW g47.0<16,16,1>UW {align1}; avg.sat (16) g48.0<1>UW g72.0<16,16,1>UW g48.0<16,16,1>UW {align1}; avg.sat (16) g49.0<1>UW g73.0<16,16,1>UW g49.0<16,16,1>UW {align1}; avg.sat (16) g50.0<1>UW g74.0<16,16,1>UW g50.0<16,16,1>UW {align1}; avg.sat (16) g51.0<1>UW g75.0<16,16,1>UW g51.0<16,16,1>UW {align1}; include(`addidct.g4i') //send (16) 0 acc0<1>UW g0<8,8,1>UW // thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime.g4b000066400000000000000000004130321267532330400256370ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime.g4b.gen5000066400000000000000000004130321267532330400264740ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime_igd.g4a000066400000000000000000000227321267532330400264640ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (8) g116.0<1>UD g1.0<8,8,1>UD {align1}; /* forward---Y---first vector*/ mov(1) g115.8<1>UD 0x007001fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_y_igd.g4i') mov (8) g52.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g54.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g56.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g58.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---Y---second vector*/ asr (2) g115.14<1>W g1.22<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x4UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.22') define(`mv2',`g1.24') include(`motion_field_y_igd.g4i') mov (8) g53.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g55.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g57.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g59.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---UV---first vector*/ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`5') define(`surface_v',`6') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_uv_igd.g4i') mov (8) g68.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g85.0<8,8,1>UW {align1}; /*forward---UV---second vector */ asr (2) g115.14<1>W g1.22<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.24') define(`mv2',`g1.26') include(`motion_field_uv_igd.g4i') mov (8) g68.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g85.0<8,8,1>UW {align1}; /*backward---Y---first vector */ mov(8) g1.0<1>UD g116.0<8,8,1>UD {align1}; mov(1) g115.8<1>UD 0x007001fUD { align1 }; mov(1) g1.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_y_igd.g4i') mov (8) g28.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g30.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g32.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g34.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g36.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g38.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g40.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g42.0<1>UD g103.0<8,8,1>UD {align1}; /*backward---Y---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g2.20<1,1,1>UD 0x8UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_y_igd.g4i') avg.sat (16) g28.0<1>UW g52.0<16,16,1>UW g28.0<16,16,1>UW {align1}; avg.sat (16) g29.0<1>UW g53.0<16,16,1>UW g96.0<16,16,1>UW {align1}; avg.sat (16) g30.0<1>UW g54.0<16,16,1>UW g30.0<16,16,1>UW {align1}; avg.sat (16) g31.0<1>UW g55.0<16,16,1>UW g97.0<16,16,1>UW {align1}; avg.sat (16) g32.0<1>UW g56.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg.sat (16) g33.0<1>UW g57.0<16,16,1>UW g98.0<16,16,1>UW {align1}; avg.sat (16) g34.0<1>UW g58.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg.sat (16) g35.0<1>UW g59.0<16,16,1>UW g99.0<16,16,1>UW {align1}; avg.sat (16) g36.0<1>UW g60.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg.sat (16) g37.0<1>UW g61.0<16,16,1>UW g100.0<16,16,1>UW {align1}; avg.sat (16) g38.0<1>UW g62.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg.sat (16) g39.0<1>UW g63.0<16,16,1>UW g101.0<16,16,1>UW {align1}; avg.sat (16) g40.0<1>UW g64.0<16,16,1>UW g40.0<16,16,1>UW {align1}; avg.sat (16) g41.0<1>UW g65.0<16,16,1>UW g102.0<16,16,1>UW {align1}; avg.sat (16) g42.0<1>UW g66.0<16,16,1>UW g42.0<16,16,1>UW {align1}; avg.sat (16) g43.0<1>UW g67.0<16,16,1>UW g103.0<16,16,1>UW {align1}; /*backward---UV---first vector */ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`8') define(`surface_v',`9') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_uv_igd.g4i') mov (8) g44.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.0<1>UW g85.0<8,8,1>UW {align1}; /*backward---UV---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_uv_igd.g4i') mov (8) g44.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.16<1>UW g85.0<8,8,1>UW {align1}; avg.sat (16) g44.0<1>UW g68.0<16,16,1>UW g44.0<16,16,1>UW {align1}; avg.sat (16) g45.0<1>UW g69.0<16,16,1>UW g45.0<16,16,1>UW {align1}; avg.sat (16) g46.0<1>UW g70.0<16,16,1>UW g46.0<16,16,1>UW {align1}; avg.sat (16) g47.0<1>UW g71.0<16,16,1>UW g47.0<16,16,1>UW {align1}; avg.sat (16) g48.0<1>UW g72.0<16,16,1>UW g48.0<16,16,1>UW {align1}; avg.sat (16) g49.0<1>UW g73.0<16,16,1>UW g49.0<16,16,1>UW {align1}; avg.sat (16) g50.0<1>UW g74.0<16,16,1>UW g50.0<16,16,1>UW {align1}; avg.sat (16) g51.0<1>UW g75.0<16,16,1>UW g51.0<16,16,1>UW {align1}; include(`addidct.g4i') //send (16) 0 acc0<1>UW g0<8,8,1>UW // thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime_igd.g4b000066400000000000000000002044361267532330400264700ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000039 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000039 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000039 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000039 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/dual_prime_igd.g4b.gen5000066400000000000000000002044361267532330400273250ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000072 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000050 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000072 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000050 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000072 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000050 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000072 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000050 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward.g4a000066400000000000000000000115601267532330400264360ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (8) g116.0<1>UD g1.0<8,8,1>UD {align1}; /*Y buffer*/ mov(1) g115.8<1>UD 0x007001fUD { align1 }; mov(1) g1.8<1>UD 0x007000fUD { align1 }; /*first vector*/ asr (2) g115.14<1>W g1.18<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_y.g4i') mov (8) g28.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g30.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g32.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g34.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g36.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g38.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g40.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g42.0<1>UD g103.0<8,8,1>UD {align1}; /*second vector*/ asr (2) g115.14<1>W g1.26<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_y.g4i') mov (8) g29.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g31.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g33.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g35.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g37.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g39.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g41.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g43.0<1>UD g103.0<8,8,1>UD {align1}; /*U buffer, V buffer*/ mov(1) g115.8<1>UD 0x007000fUD { align1 }; /*first vector*/ asr (2) g115.14<1>W g1.18<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`8') define(`surface_v',`9') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_uv.g4i') mov (8) g44.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.0<1>UW g85.0<8,8,1>UW {align1}; /*second vector*/ asr (2) g115.14<1>W g1.26<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_uv.g4i') mov (8) g44.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.16<1>UW g85.0<8,8,1>UW {align1}; include(`addidct.g4i') //send (16) 0 acc0<1>UW g0<8,8,1>UW // thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward.g4b000066400000000000000000002200331267532330400264340ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward.g4b.gen5000066400000000000000000002200331267532330400272710ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward_igd.g4a000066400000000000000000000072661267532330400272710ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g84~g107:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IQ and IDCT /*field 0 of Y*/ asr (2) g31.14<1>W g82.18<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x2UW {align1}; //motion vertical field select (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) g115.16<1>UW 1UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 of Y*/ asr (2) g31.14<1>W g82.26<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A5AUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.18<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.0<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.0<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.0<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.0<1>UW g38.0<8,8,1>UW {align1 compr}; /*field 1 of UV*/ asr (2) g31.14<1>W g82.26<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A5AUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.16<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.16<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.16<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.16<1>UW g38.0<8,8,1>UW {align1 compr}; add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward_igd.g4b000066400000000000000000000065221267532330400272640ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_backward_igd.g4b.gen5000066400000000000000000000065221267532330400301210ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b.g4a000066400000000000000000000226721267532330400254140ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (8) g116.0<1>UD g1.0<8,8,1>UD {align1}; /* forward---Y---first vector*/ mov(1) g115.8<1>UD 0x007001fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_y.g4i') mov (8) g52.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g54.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g56.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g58.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---Y---second vector*/ asr (2) g115.14<1>W g1.22<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x4UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`4') define(`mv1',`g1.22') define(`mv2',`g1.24') include(`motion_field_y.g4i') mov (8) g53.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g55.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g57.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g59.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g103.0<8,8,1>UD {align1}; /*forward---UV---first vector*/ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`5') define(`surface_v',`6') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_uv.g4i') mov (8) g68.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g85.0<8,8,1>UW {align1}; /*forward---UV---second vector */ asr (2) g115.14<1>W g1.22<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.24') define(`mv2',`g1.26') include(`motion_field_uv.g4i') mov (8) g68.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g69.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g70.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g71.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g72.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g73.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g74.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g85.0<8,8,1>UW {align1}; /*backward---Y---first vector */ mov(8) g1.0<1>UD g116.0<8,8,1>UD {align1}; mov(1) g115.8<1>UD 0x007001fUD { align1 }; mov(1) g1.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_y.g4i') mov (8) g28.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g30.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g32.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g34.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g36.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g38.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g40.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g42.0<1>UD g103.0<8,8,1>UD {align1}; /*backward---Y---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 1W {align1}; add (2) g115.0<1>D g116.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov(1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g2.20<1,1,1>UD 0x8UD {align1}; (f0) add (1) g115.4<1>D g115.4<1,1,1>D 1D {align1}; define(`surface',`7') define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_y.g4i') avg.sat (16) g28.0<1>UW g52.0<16,16,1>UW g28.0<16,16,1>UW {align1}; avg.sat (16) g29.0<1>UW g53.0<16,16,1>UW g96.0<16,16,1>UW {align1}; avg.sat (16) g30.0<1>UW g54.0<16,16,1>UW g30.0<16,16,1>UW {align1}; avg.sat (16) g31.0<1>UW g55.0<16,16,1>UW g97.0<16,16,1>UW {align1}; avg.sat (16) g32.0<1>UW g56.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg.sat (16) g33.0<1>UW g57.0<16,16,1>UW g98.0<16,16,1>UW {align1}; avg.sat (16) g34.0<1>UW g58.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg.sat (16) g35.0<1>UW g59.0<16,16,1>UW g99.0<16,16,1>UW {align1}; avg.sat (16) g36.0<1>UW g60.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg.sat (16) g37.0<1>UW g61.0<16,16,1>UW g100.0<16,16,1>UW {align1}; avg.sat (16) g38.0<1>UW g62.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg.sat (16) g39.0<1>UW g63.0<16,16,1>UW g101.0<16,16,1>UW {align1}; avg.sat (16) g40.0<1>UW g64.0<16,16,1>UW g40.0<16,16,1>UW {align1}; avg.sat (16) g41.0<1>UW g65.0<16,16,1>UW g102.0<16,16,1>UW {align1}; avg.sat (16) g42.0<1>UW g66.0<16,16,1>UW g42.0<16,16,1>UW {align1}; avg.sat (16) g43.0<1>UW g67.0<16,16,1>UW g103.0<16,16,1>UW {align1}; /*backward---UV---first vector */ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.18<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`8') define(`surface_v',`9') define(`mv1',`g1.18') define(`mv2',`g1.20') include(`motion_field_uv.g4i') mov (8) g44.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.0<1>UW g85.0<8,8,1>UW {align1}; /*backward---UV---second vector */ asr (2) g115.14<1>W g1.26<2,2,1>W 2W {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.26') define(`mv2',`g1.28') include(`motion_field_uv.g4i') mov (8) g44.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.16<1>UW g85.0<8,8,1>UW {align1}; avg.sat (16) g44.0<1>UW g68.0<16,16,1>UW g44.0<16,16,1>UW {align1}; avg.sat (16) g45.0<1>UW g69.0<16,16,1>UW g45.0<16,16,1>UW {align1}; avg.sat (16) g46.0<1>UW g70.0<16,16,1>UW g46.0<16,16,1>UW {align1}; avg.sat (16) g47.0<1>UW g71.0<16,16,1>UW g47.0<16,16,1>UW {align1}; avg.sat (16) g48.0<1>UW g72.0<16,16,1>UW g48.0<16,16,1>UW {align1}; avg.sat (16) g49.0<1>UW g73.0<16,16,1>UW g49.0<16,16,1>UW {align1}; avg.sat (16) g50.0<1>UW g74.0<16,16,1>UW g50.0<16,16,1>UW {align1}; avg.sat (16) g51.0<1>UW g75.0<16,16,1>UW g51.0<16,16,1>UW {align1}; include(`addidct.g4i') //send (16) 0 acc0<1>UW g0<8,8,1>UW // thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b.g4b000066400000000000000000004130321267532330400254070ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a008 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b.g4b.gen5000066400000000000000000004130321267532330400262440ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000e3c, 0x0021003f, 0x00000004 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x26a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x26e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x27200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x28900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x28b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x28d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x28f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x29100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x29300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0e80, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00010001 }, { 0x00200040, 0x2e6034a5, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20000c3c, 0x00210054, 0x00000008 }, { 0x00010040, 0x2e641ca5, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10680, 0x00b10380 }, { 0x80800042, 0x23a02529, 0x00b106a0, 0x00b10c00 }, { 0x80800042, 0x23c02529, 0x00b106c0, 0x00b103c0 }, { 0x80800042, 0x23e02529, 0x00b106e0, 0x00b10c20 }, { 0x80800042, 0x24002529, 0x00b10700, 0x00b10400 }, { 0x80800042, 0x24202529, 0x00b10720, 0x00b10c40 }, { 0x80800042, 0x24402529, 0x00b10740, 0x00b10440 }, { 0x80800042, 0x24602529, 0x00b10760, 0x00b10c60 }, { 0x80800042, 0x24802529, 0x00b10780, 0x00b10480 }, { 0x80800042, 0x24a02529, 0x00b107a0, 0x00b10c80 }, { 0x80800042, 0x24c02529, 0x00b107c0, 0x00b104c0 }, { 0x80800042, 0x24e02529, 0x00b107e0, 0x00b10ca0 }, { 0x80800042, 0x25002529, 0x00b10800, 0x00b10500 }, { 0x80800042, 0x25202529, 0x00b10820, 0x00b10cc0 }, { 0x80800042, 0x25402529, 0x00b10840, 0x00b10540 }, { 0x80800042, 0x25602529, 0x00b10860, 0x00b10ce0 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e3dad, 0x00450032, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210032, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210034, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e3dad, 0x0045003a, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021003a, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x0021003c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a008 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a009 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x80800042, 0x25802529, 0x00b10880, 0x00b10580 }, { 0x80800042, 0x25a02529, 0x00b108a0, 0x00b105a0 }, { 0x80800042, 0x25c02529, 0x00b108c0, 0x00b105c0 }, { 0x80800042, 0x25e02529, 0x00b108e0, 0x00b105e0 }, { 0x80800042, 0x26002529, 0x00b10900, 0x00b10600 }, { 0x80800042, 0x26202529, 0x00b10920, 0x00b10620 }, { 0x80800042, 0x26402529, 0x00b10940, 0x00b10640 }, { 0x80800042, 0x26602529, 0x00b10960, 0x00b10660 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b_igd.g4a000066400000000000000000000165251267532330400262370ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g84~g107:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IQ and IDCT /*field 0 forward prediction of Y*/ asr (2) g31.14<1>W g82.14<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) g115.16<1>UW 0UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 forward prediction of Y*/ asr (2) g31.14<1>W g82.22<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A56UD {align1}; //g82.22,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 forward prediction of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.14<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.0<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.0<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.0<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.0<1>UW g38.0<8,8,1>UW {align1 compr}; /*field 1 forward prediction of UV*/ asr (2) g31.14<1>W g82.22<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A56UD {align1}; //g82.22,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.16<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.16<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.16<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.16<1>UW g38.0<8,8,1>UW {align1 compr}; /*field 0 backward prediction of Y*/ mov(2) g31.0<1>UD g82.0<2,2,1>UD {align1}; asr (2) g31.14<1>W g82.18<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) g115.16<1>UW 1UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data avg (16) g58.0<1>UW g58.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg (16) g60.0<1>UW g60.0<16,16,1>UW g33.0<16,16,1>UW {align1}; avg (16) g62.0<1>UW g62.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg (16) g64.0<1>UW g64.0<16,16,1>UW g35.0<16,16,1>UW {align1}; avg (16) g66.0<1>UW g66.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg (16) g68.0<1>UW g68.0<16,16,1>UW g37.0<16,16,1>UW {align1}; avg (16) g70.0<1>UW g70.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg (16) g72.0<1>UW g72.0<16,16,1>UW g39.0<16,16,1>UW {align1}; /*field 1 backward prediction of Y*/ asr (2) g31.14<1>W g82.26<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A5AUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data avg (16) g59.0<1>UW g59.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg (16) g61.0<1>UW g61.0<16,16,1>UW g33.0<16,16,1>UW {align1}; avg (16) g63.0<1>UW g63.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg (16) g65.0<1>UW g65.0<16,16,1>UW g35.0<16,16,1>UW {align1}; avg (16) g67.0<1>UW g67.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg (16) g69.0<1>UW g69.0<16,16,1>UW g37.0<16,16,1>UW {align1}; avg (16) g71.0<1>UW g71.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg (16) g73.0<1>UW g73.0<16,16,1>UW g39.0<16,16,1>UW {align1}; /*field 0 backward prediction of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.18<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x2UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data avg (16) g74.0<1>UW g74.0<8,8,1>UW g32.0<8,8,1>UW {align1 compr}; avg (16) g76.0<1>UW g76.0<8,8,1>UW g34.0<8,8,1>UW {align1 compr}; avg (16) g78.0<1>UW g78.0<8,8,1>UW g36.0<8,8,1>UW {align1 compr}; avg (16) g80.0<1>UW g80.0<8,8,1>UW g38.0<8,8,1>UW {align1 compr}; /*field 1 backward prediction of UV*/ asr (2) g31.14<1>W g82.26<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x8UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A5AUD {align1}; //g82.26,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data avg (16) g74.16<1>UW g74.16<8,8,1>UW g32.0<8,8,1>UW {align1 compr}; avg (16) g76.16<1>UW g76.16<8,8,1>UW g34.0<8,8,1>UW {align1 compr}; avg (16) g78.16<1>UW g78.16<8,8,1>UW g36.0<8,8,1>UW {align1 compr}; avg (16) g80.16<1>UW g80.16<8,8,1>UW g38.0<8,8,1>UW {align1 compr}; add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b_igd.g4b000066400000000000000000000147771267532330400262470ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00200001, 0x23e00021, 0x00450a40, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00800042, 0x27402529, 0x00b10740, 0x00b10400 }, { 0x00800042, 0x27802529, 0x00b10780, 0x00b10420 }, { 0x00800042, 0x27c02529, 0x00b107c0, 0x00b10440 }, { 0x00800042, 0x28002529, 0x00b10800, 0x00b10460 }, { 0x00800042, 0x28402529, 0x00b10840, 0x00b10480 }, { 0x00800042, 0x28802529, 0x00b10880, 0x00b104a0 }, { 0x00800042, 0x28c02529, 0x00b108c0, 0x00b104c0 }, { 0x00800042, 0x29002529, 0x00b10900, 0x00b104e0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00800042, 0x27602529, 0x00b10760, 0x00b10400 }, { 0x00800042, 0x27a02529, 0x00b107a0, 0x00b10420 }, { 0x00800042, 0x27e02529, 0x00b107e0, 0x00b10440 }, { 0x00800042, 0x28202529, 0x00b10820, 0x00b10460 }, { 0x00800042, 0x28602529, 0x00b10860, 0x00b10480 }, { 0x00800042, 0x28a02529, 0x00b108a0, 0x00b104a0 }, { 0x00800042, 0x28e02529, 0x00b108e0, 0x00b104c0 }, { 0x00800042, 0x29202529, 0x00b10920, 0x00b104e0 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802042, 0x29402529, 0x008d0940, 0x008d0400 }, { 0x00802042, 0x29802529, 0x008d0980, 0x008d0440 }, { 0x00802042, 0x29c02529, 0x008d09c0, 0x008d0480 }, { 0x00802042, 0x2a002529, 0x008d0a00, 0x008d04c0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802042, 0x29502529, 0x008d0950, 0x008d0400 }, { 0x00802042, 0x29902529, 0x008d0990, 0x008d0440 }, { 0x00802042, 0x29d02529, 0x008d09d0, 0x008d0480 }, { 0x00802042, 0x2a102529, 0x008d0a10, 0x008d04c0 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_f_b_igd.g4b.gen5000066400000000000000000000147771267532330400271040ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00200001, 0x23e00021, 0x00450a40, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00800042, 0x27402529, 0x00b10740, 0x00b10400 }, { 0x00800042, 0x27802529, 0x00b10780, 0x00b10420 }, { 0x00800042, 0x27c02529, 0x00b107c0, 0x00b10440 }, { 0x00800042, 0x28002529, 0x00b10800, 0x00b10460 }, { 0x00800042, 0x28402529, 0x00b10840, 0x00b10480 }, { 0x00800042, 0x28802529, 0x00b10880, 0x00b104a0 }, { 0x00800042, 0x28c02529, 0x00b108c0, 0x00b104c0 }, { 0x00800042, 0x29002529, 0x00b10900, 0x00b104e0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00800042, 0x27602529, 0x00b10760, 0x00b10400 }, { 0x00800042, 0x27a02529, 0x00b107a0, 0x00b10420 }, { 0x00800042, 0x27e02529, 0x00b107e0, 0x00b10440 }, { 0x00800042, 0x28202529, 0x00b10820, 0x00b10460 }, { 0x00800042, 0x28602529, 0x00b10860, 0x00b10480 }, { 0x00800042, 0x28a02529, 0x00b108a0, 0x00b104a0 }, { 0x00800042, 0x28e02529, 0x00b108e0, 0x00b104c0 }, { 0x00800042, 0x29202529, 0x00b10920, 0x00b104e0 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00020002 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802042, 0x29402529, 0x008d0940, 0x008d0400 }, { 0x00802042, 0x29802529, 0x008d0980, 0x008d0440 }, { 0x00802042, 0x29c02529, 0x008d09c0, 0x008d0480 }, { 0x00802042, 0x2a002529, 0x008d0a00, 0x008d04c0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5a, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00080008 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a5a }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802042, 0x29502529, 0x008d0950, 0x008d0400 }, { 0x00802042, 0x29902529, 0x008d0990, 0x008d0440 }, { 0x00802042, 0x29d02529, 0x008d09d0, 0x008d0480 }, { 0x00802042, 0x2a102529, 0x008d0a10, 0x008d04c0 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward.g4a000066400000000000000000000115371267532330400263300ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (8) g116.0<1>UD g1.0<8,8,1>UD {align1}; /*Y buffer*/ mov(1) g1.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 1UW {align1}; add (2) g115.0<1>UD g116.0<2,2,1>UD g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov (1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. /*first vector*/ and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_y.g4i') mov (8) g28.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g30.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g32.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g34.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g36.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g38.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g40.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g42.0<1>UD g103.0<8,8,1>UD {align1}; /*second vector*/ asr (2) g115.14<1>W g1.22<2,2,1>W 1UW {align1}; add (2) g115.0<1>UD g116.0<2,2,1>UD g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; mov (1) g115.8<1>UD 0x1fUD { align1 }; //read 1 line, 32 columns. and.nz (1) null g1.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g1.22') define(`mv2',`g1.24') include(`motion_field_y.g4i') mov (8) g29.0<1>UD g96.0<8,8,1>UD {align1}; mov (8) g31.0<1>UD g97.0<8,8,1>UD {align1}; mov (8) g33.0<1>UD g98.0<8,8,1>UD {align1}; mov (8) g35.0<1>UD g99.0<8,8,1>UD {align1}; mov (8) g37.0<1>UD g100.0<8,8,1>UD {align1}; mov (8) g39.0<1>UD g101.0<8,8,1>UD {align1}; mov (8) g41.0<1>UD g102.0<8,8,1>UD {align1}; mov (8) g43.0<1>UD g103.0<8,8,1>UD {align1}; /*U buffer, V buffer*/ /*first vector*/ mov(1) g115.8<1>UD 0x007000fUD { align1 }; asr (2) g115.14<1>W g1.14<2,2,1>W 2UW {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u',`5') define(`surface_v',`6') define(`mv1',`g1.14') define(`mv2',`g1.16') include(`motion_field_uv.g4i') mov (8) g44.0<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.0<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.0<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.0<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.0<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.0<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.0<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.0<1>UW g85.0<8,8,1>UW {align1}; /*second vector*/ asr (2) g115.14<1>W g1.22<2,2,1>W 2UW {align1}; asr (2) g115.0<1>D g116.0<2,2,1>D 1D {align1}; add (2) g115.0<1>D g115.0<2,2,1>D g115.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g1.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g1.22') define(`mv2',`g1.24') include(`motion_field_uv.g4i') mov (8) g44.16<1>UW g78.0<8,8,1>UW {align1}; mov (8) g45.16<1>UW g79.0<8,8,1>UW {align1}; mov (8) g46.16<1>UW g80.0<8,8,1>UW {align1}; mov (8) g47.16<1>UW g81.0<8,8,1>UW {align1}; mov (8) g48.16<1>UW g82.0<8,8,1>UW {align1}; mov (8) g49.16<1>UW g83.0<8,8,1>UW {align1}; mov (8) g50.16<1>UW g84.0<8,8,1>UW {align1}; mov (8) g51.16<1>UW g85.0<8,8,1>UW {align1}; include(`addidct.g4i') //send (16) 0 acc0<1>UW g0<8,8,1>UW // thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward.g4b000066400000000000000000002177441267532330400263410ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e2dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e2dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e603421, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000b1 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000007d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000068 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x008d0e60, 0x0411a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x008d0e60, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e2dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e2dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000076 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x00ad0e60, 0x0411a005 }, { 0x00800031, 0x2be01d29, 0x00ad0e60, 0x0411a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x2b601d29, 0x00ad0e60, 0x0414a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward.g4b.gen5000066400000000000000000002177441267532330400271760ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00600001, 0x2e800021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e2dad, 0x0045002e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23800021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23c00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24000021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24400021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24800021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24c00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25000021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25400021, 0x008d0ce0, 0x00000000 }, { 0x0020000c, 0x2e6e2dad, 0x00450036, 0x00010001 }, { 0x00200040, 0x2e603421, 0x00450e80, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000162 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000fa }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x00800040, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x00800040, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x00800040, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x00800040, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x00800040, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x00800040, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x00800040, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c1 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a01 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a41 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a81 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac1 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b01 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b41 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b81 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a01 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a41 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a81 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac1 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b01 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b41 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b81 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x00800040, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x00800040, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x00800040, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x00800040, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x00800040, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x00800040, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x00800040, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c2 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a02 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a42 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a82 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac2 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b02 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b42 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b82 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a02 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a42 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a82 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac2 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b02 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b42 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b82 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x00800040, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x00800040, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x00800040, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x00800040, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x00800040, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x00800040, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x00800040, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c3 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a03 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a43 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a83 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac3 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b03 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b43 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b83 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a03 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a43 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a83 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac3 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b03 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b43 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b83 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x00800040, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x00800040, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x00800040, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x00800040, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x00800040, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x00800040, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x00800040, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b109c4 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a04 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a44 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10a84 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10ac4 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b04 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b44 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10b84 }, { 0x00800040, 0x2c004529, 0x00b10c00, 0x00b10a04 }, { 0x00800040, 0x2c204529, 0x00b10c20, 0x00b10a44 }, { 0x00800040, 0x2c404529, 0x00b10c40, 0x00b10a84 }, { 0x00800040, 0x2c604529, 0x00b10c60, 0x00b10ac4 }, { 0x00800040, 0x2c804529, 0x00b10c80, 0x00b10b04 }, { 0x00800040, 0x2ca04529, 0x00b10ca0, 0x00b10b44 }, { 0x00800040, 0x2cc04529, 0x00b10cc0, 0x00b10b84 }, { 0x00800040, 0x2ce04529, 0x00b10ce0, 0x00b10bc4 }, { 0x00800008, 0x2c002d29, 0x00b10c00, 0x00020002 }, { 0x00800008, 0x2c202d29, 0x00b10c20, 0x00020002 }, { 0x00800008, 0x2c402d29, 0x00b10c40, 0x00020002 }, { 0x00800008, 0x2c602d29, 0x00b10c60, 0x00020002 }, { 0x00800008, 0x2c802d29, 0x00b10c80, 0x00020002 }, { 0x00800008, 0x2ca02d29, 0x00b10ca0, 0x00020002 }, { 0x00800008, 0x2cc02d29, 0x00b10cc0, 0x00020002 }, { 0x00800008, 0x2ce02d29, 0x00b10ce0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b109c1 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a01 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a41 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10a81 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10ac1 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b01 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b41 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10b81 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b109c2 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a02 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a42 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10a82 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10ac2 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b02 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b42 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10b82 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b109c3 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a03 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a43 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10a83 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10ac3 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b03 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b43 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10b83 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b109c4 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a04 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a44 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10a84 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10ac4 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b04 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b44 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10b84 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000d0 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2bc01d29, 0x408d0e60, 0x0218a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x2c004629, 0x00b109c0, 0x00b10a00 }, { 0x80800042, 0x2c204629, 0x00b10a00, 0x00b10a40 }, { 0x80800042, 0x2c404629, 0x00b10a40, 0x00b10a80 }, { 0x80800042, 0x2c604629, 0x00b10a80, 0x00b10ac0 }, { 0x80800042, 0x2c804629, 0x00b10ac0, 0x00b10b00 }, { 0x80800042, 0x2ca04629, 0x00b10b00, 0x00b10b40 }, { 0x80800042, 0x2cc04629, 0x00b10b40, 0x00b10b80 }, { 0x80800042, 0x2ce04629, 0x00b10b80, 0x00b10bc0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x2c004629, 0x00b109c1, 0x00b10a01 }, { 0x80800042, 0x2c204629, 0x00b10a01, 0x00b10a41 }, { 0x80800042, 0x2c404629, 0x00b10a41, 0x00b10a81 }, { 0x80800042, 0x2c604629, 0x00b10a81, 0x00b10ac1 }, { 0x80800042, 0x2c804629, 0x00b10ac1, 0x00b10b01 }, { 0x80800042, 0x2ca04629, 0x00b10b01, 0x00b10b41 }, { 0x80800042, 0x2cc04629, 0x00b10b41, 0x00b10b81 }, { 0x80800042, 0x2ce04629, 0x00b10b81, 0x00b10bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x2c004629, 0x00b109c2, 0x00b10a02 }, { 0x80800042, 0x2c204629, 0x00b10a02, 0x00b10a42 }, { 0x80800042, 0x2c404629, 0x00b10a42, 0x00b10a82 }, { 0x80800042, 0x2c604629, 0x00b10a82, 0x00b10ac2 }, { 0x80800042, 0x2c804629, 0x00b10ac2, 0x00b10b02 }, { 0x80800042, 0x2ca04629, 0x00b10b02, 0x00b10b42 }, { 0x80800042, 0x2cc04629, 0x00b10b42, 0x00b10b82 }, { 0x80800042, 0x2ce04629, 0x00b10b82, 0x00b10bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x2c004629, 0x00b109c3, 0x00b10a03 }, { 0x80800042, 0x2c204629, 0x00b10a03, 0x00b10a43 }, { 0x80800042, 0x2c404629, 0x00b10a43, 0x00b10a83 }, { 0x80800042, 0x2c604629, 0x00b10a83, 0x00b10ac3 }, { 0x80800042, 0x2c804629, 0x00b10ac3, 0x00b10b03 }, { 0x80800042, 0x2ca04629, 0x00b10b03, 0x00b10b43 }, { 0x80800042, 0x2cc04629, 0x00b10b43, 0x00b10b83 }, { 0x80800042, 0x2ce04629, 0x00b10b83, 0x00b10bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x29c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x2a801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2ac01d29, 0x408d0e60, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x2c000229, 0x00b109c0, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a00, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a40, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a80, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac0, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b00, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b40, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b80, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x2c000229, 0x00b109c1, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a01, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a41, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a81, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac1, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b01, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b41, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b81, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x2c000229, 0x00b109c2, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a02, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a42, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a82, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac2, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b02, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b42, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b82, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x2c000229, 0x00b109c3, 0x00000000 }, { 0x00800001, 0x2c200229, 0x00b10a03, 0x00000000 }, { 0x00800001, 0x2c400229, 0x00b10a43, 0x00000000 }, { 0x00800001, 0x2c600229, 0x00b10a83, 0x00000000 }, { 0x00800001, 0x2c800229, 0x00b10ac3, 0x00000000 }, { 0x00800001, 0x2ca00229, 0x00b10b03, 0x00000000 }, { 0x00800001, 0x2cc00229, 0x00b10b43, 0x00000000 }, { 0x00800001, 0x2ce00229, 0x00b10b83, 0x00000000 }, { 0x00600001, 0x23a00021, 0x008d0c00, 0x00000000 }, { 0x00600001, 0x23e00021, 0x008d0c20, 0x00000000 }, { 0x00600001, 0x24200021, 0x008d0c40, 0x00000000 }, { 0x00600001, 0x24600021, 0x008d0c60, 0x00000000 }, { 0x00600001, 0x24a00021, 0x008d0c80, 0x00000000 }, { 0x00600001, 0x24e00021, 0x008d0ca0, 0x00000000 }, { 0x00600001, 0x25200021, 0x008d0cc0, 0x00000000 }, { 0x00600001, 0x25600021, 0x008d0ce0, 0x00000000 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x0020000c, 0x2e6e2dad, 0x0045002e, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x0021002e, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210030, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25800129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25a00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25c00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25e00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26000129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26200129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26400129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26600129, 0x008d0aa0, 0x00000000 }, { 0x0020000c, 0x2e6e2dad, 0x00450036, 0x00020002 }, { 0x0020000c, 0x2e601ca5, 0x00450e80, 0x00000001 }, { 0x00200040, 0x2e6034a5, 0x00450e60, 0x00450e6e }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x0021003f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002d3c, 0x00210036, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000144 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ec }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x00800040, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x00800040, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x00800040, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae1 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b01 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b21 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae1 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b01 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b21 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b41 }, { 0x00800040, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x00800040, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x00800040, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x00800040, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b61 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b81 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b81 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba1 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc1 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00800040, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x00800040, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x00800040, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x00800040, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae2 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b02 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b22 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae2 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b02 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b22 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b42 }, { 0x00800040, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x00800040, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x00800040, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x00800040, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b62 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b82 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b82 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba2 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc2 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00800040, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x00800040, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x00800040, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x00800040, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae3 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b03 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b23 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae3 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b03 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b23 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b43 }, { 0x00800040, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x00800040, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x00800040, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x00800040, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b63 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b83 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b83 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba3 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc3 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x29c04629, 0x00ad0ac3, 0x00ad0ae3 }, { 0x00800040, 0x29e04629, 0x00ad0ae3, 0x00ad0b03 }, { 0x00800040, 0x2a004629, 0x00ad0b03, 0x00ad0b23 }, { 0x00800040, 0x2a204629, 0x00ad0b23, 0x00ad0b43 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ac4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0ae4 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b04 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b24 }, { 0x00800040, 0x29c04529, 0x00ad09c0, 0x00ad0ae4 }, { 0x00800040, 0x29e04529, 0x00ad09e0, 0x00ad0b04 }, { 0x00800040, 0x2a004529, 0x00ad0a00, 0x00ad0b24 }, { 0x00800040, 0x2a204529, 0x00ad0a20, 0x00ad0b44 }, { 0x00800040, 0x2a404629, 0x00ad0b63, 0x00ad0b83 }, { 0x00800040, 0x2a604629, 0x00ad0b83, 0x00ad0ba3 }, { 0x00800040, 0x2a804629, 0x00ad0ba3, 0x00ad0bc3 }, { 0x00800040, 0x2aa04629, 0x00ad0bc3, 0x00ad0be3 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b64 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0b84 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0ba4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0bc4 }, { 0x00800040, 0x2a404529, 0x00ad0a40, 0x00ad0b84 }, { 0x00800040, 0x2a604529, 0x00ad0a60, 0x00ad0ba4 }, { 0x00800040, 0x2a804529, 0x00ad0a80, 0x00ad0bc4 }, { 0x00800040, 0x2aa04529, 0x00ad0aa0, 0x00ad0be4 }, { 0x80800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x80800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x80800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x80800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x80800008, 0x2a402d29, 0x00b10a40, 0x00020002 }, { 0x80800008, 0x2a602d29, 0x00b10a60, 0x00020002 }, { 0x80800008, 0x2a802d29, 0x00b10a80, 0x00020002 }, { 0x80800008, 0x2aa02d29, 0x00b10aa0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000104 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ac1 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0ae1 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b01 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b21 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b61 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0b81 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0ba1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0bc1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ac2 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0ae2 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b02 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b22 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b62 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0b82 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0ba2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0bc2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac4 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae4 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b04 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b24 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b64 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b84 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba4 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc4 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000b0 }, { 0x01000005, 0x20002d3c, 0x00210038, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00800031, 0x2b401d29, 0x40ad0e60, 0x0218a005 }, { 0x00800031, 0x2be01d29, 0x40ad0e60, 0x0218a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x29c04629, 0x00ad0ac0, 0x00ad0ae0 }, { 0x80800042, 0x29e04629, 0x00ad0ae0, 0x00ad0b00 }, { 0x80800042, 0x2a004629, 0x00ad0b00, 0x00ad0b20 }, { 0x80800042, 0x2a204629, 0x00ad0b20, 0x00ad0b40 }, { 0x80800042, 0x2a404629, 0x00ad0b60, 0x00ad0b80 }, { 0x80800042, 0x2a604629, 0x00ad0b80, 0x00ad0ba0 }, { 0x80800042, 0x2a804629, 0x00ad0ba0, 0x00ad0bc0 }, { 0x80800042, 0x2aa04629, 0x00ad0bc0, 0x00ad0be0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x80800042, 0x29c04629, 0x00ad0ac1, 0x00ad0ae1 }, { 0x80800042, 0x29e04629, 0x00ad0ae1, 0x00ad0b01 }, { 0x80800042, 0x2a004629, 0x00ad0b01, 0x00ad0b21 }, { 0x80800042, 0x2a204629, 0x00ad0b21, 0x00ad0b41 }, { 0x80800042, 0x2a404629, 0x00ad0b61, 0x00ad0b81 }, { 0x80800042, 0x2a604629, 0x00ad0b81, 0x00ad0ba1 }, { 0x80800042, 0x2a804629, 0x00ad0ba1, 0x00ad0bc1 }, { 0x80800042, 0x2aa04629, 0x00ad0bc1, 0x00ad0be1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x80800042, 0x29c04629, 0x00ad0ac2, 0x00ad0ae2 }, { 0x80800042, 0x29e04629, 0x00ad0ae2, 0x00ad0b02 }, { 0x80800042, 0x2a004629, 0x00ad0b02, 0x00ad0b22 }, { 0x80800042, 0x2a204629, 0x00ad0b22, 0x00ad0b42 }, { 0x80800042, 0x2a404629, 0x00ad0b62, 0x00ad0b82 }, { 0x80800042, 0x2a604629, 0x00ad0b82, 0x00ad0ba2 }, { 0x80800042, 0x2a804629, 0x00ad0ba2, 0x00ad0bc2 }, { 0x80800042, 0x2aa04629, 0x00ad0bc2, 0x00ad0be2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x29c04629, 0x00ad0ac3, 0x00ad0ac3 }, { 0x80800042, 0x29e04629, 0x00ad0ae3, 0x00ad0ae3 }, { 0x80800042, 0x2a004629, 0x00ad0b03, 0x00ad0b03 }, { 0x80800042, 0x2a204629, 0x00ad0b23, 0x00ad0b23 }, { 0x80800042, 0x2a404629, 0x00ad0b63, 0x00ad0b63 }, { 0x80800042, 0x2a604629, 0x00ad0b83, 0x00ad0b83 }, { 0x80800042, 0x2a804629, 0x00ad0ba3, 0x00ad0ba3 }, { 0x80800042, 0x2aa04629, 0x00ad0bc3, 0x00ad0bc3 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x2ac01d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x2b601d29, 0x40ad0e60, 0x0248a006 }, { 0x00000005, 0x20580c21, 0x00210e60, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x29c00229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba0, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x29c00229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba1, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x29c00229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba2, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x29c00229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x2a400229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x2a600229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x2a800229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2aa00229, 0x00ad0bc3, 0x00000000 }, { 0x00600001, 0x25900129, 0x008d09c0, 0x00000000 }, { 0x00600001, 0x25b00129, 0x008d09e0, 0x00000000 }, { 0x00600001, 0x25d00129, 0x008d0a00, 0x00000000 }, { 0x00600001, 0x25f00129, 0x008d0a20, 0x00000000 }, { 0x00600001, 0x26100129, 0x008d0a40, 0x00000000 }, { 0x00600001, 0x26300129, 0x008d0a60, 0x00000000 }, { 0x00600001, 0x26500129, 0x008d0a80, 0x00000000 }, { 0x00600001, 0x26700129, 0x008d0aa0, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward_igd.g4a000066400000000000000000000072721267532330400271540ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g84~g107:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IDCT /*field 0 of Y*/ asr (2) g31.14<1>W g82.14<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x1UW {align1}; //motion vertical field select (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) g115.16<1>UW 0UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 of Y*/ asr (2) g31.14<1>W g82.22<2,2,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A56UD {align1}; //g82.22,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x20UD {align1}; //jump to the lib to read reference data mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.14<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x1UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.0<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.0<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.0<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.0<1>UW g38.0<8,8,1>UW {align1 compr}; /*field 1 of UV*/ asr (2) g31.14<1>W g82.22<2,2,1>W 2W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.31<1,1,1>UB 0x4UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; mov (1) a0.0<1>UD 0x0A56UD {align1}; //g82.22,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x30UD {align1}; //jump to the lib to read reference data mov (16) g74.16<1>UW g32.0<8,8,1>UW {align1 compr}; mov (16) g76.16<1>UW g34.0<8,8,1>UW {align1 compr}; mov (16) g78.16<1>UW g36.0<8,8,1>UW {align1 compr}; mov (16) g80.16<1>UW g38.0<8,8,1>UW {align1 compr}; add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward_igd.g4b000066400000000000000000000065221267532330400271520ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/field_forward_igd.g4b.gen5000066400000000000000000000065221267532330400300070ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x2e700169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000020 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00010001 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a56, 0x00020002 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002e3c, 0x00210a5f, 0x00040004 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a56 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000030 }, { 0x00802001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00802001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00802001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00802001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward.g4a000066400000000000000000000051131267532330400264420ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ /* shader for backward predict mc */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (2) g1.14<1>UW g1.18<2,2,1>UW {align1}; /* save payload */ mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; /* 8x8 media read/write payload */ mov (1) g1.8<1>UD 0x0070007UD {align1}; /* save payload, again */ define(`dest', `g118') define(`input_surface', `7') define(`mv1', `g115.14') define(`mv2', `g115.16') /* Y */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g115.0<2,2,1>UD g1.14<2,2,1>W {align1}; include(`motion_frame_y.g4i') /* motion_vector = motion_vector >> 1 */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ shr (2) g1.0<1>UD g115.0<2,2,1>UD 1UD {align1}; asr (2) g115.14<1>W g115.14<2,2,1>W 1W {align1}; asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g1.0<2,2,1>UD g1.14<2,2,1>W {align1}; /* U */ define(`input_surface1', `8') define(`input_surface2', `9') mov (1) g2.8<1>UD 0x007000fUD {align1}; include(`motion_frame_uv.g4i') /* V */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward.g4b000066400000000000000000001147241267532330400264540ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00200001, 0x202e0129, 0x00450032, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000012b }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000de }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000092 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000e5 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x008d0040, 0x0414a008 }, { 0x00800031, 0x2b401d29, 0x008d0040, 0x0414a009 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward.g4b.gen5000066400000000000000000001147241267532330400273110ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00200001, 0x202e0129, 0x00450032, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000256 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000001bc }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000124 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001ca }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x408d0040, 0x0248a008 }, { 0x00800031, 0x2b401d29, 0x408d0040, 0x0248a009 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward_igd.g4a000066400000000000000000000042751267532330400272750ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ /* mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; define(`UV_red',`0xffffffffUD') define(`UV_white',`0x7f7f7f7fUD') define(`UV_green',`0x00000000UD') mov(1) g31.8<1>UD 0x000f000fUD { align1 }; mov(16) m1<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m3<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m5<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m7<1>UD 0xFFFFFFFFUD {align1 compr}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(0, 0, 2, 0) mlen 9 rlen 0 { align1 }; shr (2) g31.0<1>UD g82.0<2,2,1>UD 1UW {align1}; mov(1) g31.8<1>UD 0x00070007UD { align1 }; mov (16) m1<1>UD UV_green {align1 compr}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IDCT //Y, (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) asr (2) g31.14<1>W g82.18<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 1UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x0UD {align1}; //jump to the lib to read reference data //UV, (x', y') = (x >> 1, y >> 1) + (motion_vector.x >> 2, motion_vector.y >> 2) shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.18<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x10UD {align1}; //jump to the lib to read reference data add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward_igd.g4b000066400000000000000000000014711267532330400272710ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_backward_igd.g4b.gen5000066400000000000000000000014711267532330400301260ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b.g4a000066400000000000000000000130011267532330400254050ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ /* shader for forward and backward predict mc */ /* (x', y') = (x, y) + (motion_vector1.x >> 1, motion_vector1.y >> 1) /* (x'', y'') = (x, y) + (motion_vector2.x >> 1, motion_vector2.y >> 1) /* f(x, y) = (motion_forward(x`, y`) + motion_backward(x'', y'') + 1) / 2 */ //Save payload mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (1) g1.8<1>UD 0x0070007UD {align1}; mov (8) g2.0<1>UD g1.0<8,8,1>UD {align1}; /* Y */ //Forward asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g115.0<2,2,1>UD g1.14<2,2,1>W {align1}; define(`input_surface', `4') define(`mv1', `g115.14') define(`mv2', `g115.16') include(`motion_frame_y.g4i') mov (16) g52.0<1>UD g28.0<16,16,1>UD {align1 compr}; mov (16) g54.0<1>UD g30.0<16,16,1>UD {align1 compr}; mov (16) g56.0<1>UD g32.0<16,16,1>UD {align1 compr}; mov (16) g58.0<1>UD g34.0<16,16,1>UD {align1 compr}; mov (16) g60.0<1>UD g36.0<16,16,1>UD {align1 compr}; mov (16) g62.0<1>UD g38.0<16,16,1>UD {align1 compr}; mov (16) g64.0<1>UD g40.0<16,16,1>UD {align1 compr}; mov (16) g66.0<1>UD g42.0<16,16,1>UD {align1 compr}; //Backward asr (2) g1.14<1>W g115.18<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g115.0<2,2,1>UD g1.14<2,2,1>W {align1}; define(`input_surface', `7') define(`mv1', `g115.18') define(`mv2', `g115.20') include(`motion_frame_y.g4i') //Average avg.sat (16) g28.0<1>UW g28.0<16,16,1>UW g52.0<16,16,1>UW {align1}; avg.sat (16) g29.0<1>UW g29.0<16,16,1>UW g53.0<16,16,1>UW {align1}; avg.sat (16) g30.0<1>UW g30.0<16,16,1>UW g54.0<16,16,1>UW {align1}; avg.sat (16) g31.0<1>UW g31.0<16,16,1>UW g55.0<16,16,1>UW {align1}; avg.sat (16) g32.0<1>UW g32.0<16,16,1>UW g56.0<16,16,1>UW {align1}; avg.sat (16) g33.0<1>UW g33.0<16,16,1>UW g57.0<16,16,1>UW {align1}; avg.sat (16) g34.0<1>UW g34.0<16,16,1>UW g58.0<16,16,1>UW {align1}; avg.sat (16) g35.0<1>UW g35.0<16,16,1>UW g59.0<16,16,1>UW {align1}; avg.sat (16) g36.0<1>UW g36.0<16,16,1>UW g60.0<16,16,1>UW {align1}; avg.sat (16) g37.0<1>UW g37.0<16,16,1>UW g61.0<16,16,1>UW {align1}; avg.sat (16) g38.0<1>UW g38.0<16,16,1>UW g62.0<16,16,1>UW {align1}; avg.sat (16) g39.0<1>UW g39.0<16,16,1>UW g63.0<16,16,1>UW {align1}; avg.sat (16) g40.0<1>UW g40.0<16,16,1>UW g64.0<16,16,1>UW {align1}; avg.sat (16) g41.0<1>UW g41.0<16,16,1>UW g65.0<16,16,1>UW {align1}; avg.sat (16) g42.0<1>UW g42.0<16,16,1>UW g66.0<16,16,1>UW {align1}; avg.sat (16) g43.0<1>UW g43.0<16,16,1>UW g67.0<16,16,1>UW {align1}; /* UV */ //Forward shr (2) g1.0<1>UD g115.0<2,2,1>UD 1UD {align1}; asr (2) g115.14<1>W g115.14<2,2,1>W 1W {align1}; asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g1.0<2,2,1>UD g1.14<2,2,1>W {align1}; define(`input_surface1', `5') define(`input_surface2', `6') define(`mv1', `g115.14') define(`mv2', `g115.16') mov (1) g2.8<1>UD 0x007000fUD {align1}; include(`motion_frame_uv.g4i') mov (16) g122.0<1>UB g44.0<16,16,2>UB {align1}; mov (16) g122.16<1>UB g45.0<16,16,2>UB {align1}; mov (16) g123.0<1>UB g46.0<16,16,2>UB {align1}; mov (16) g123.16<1>UB g47.0<16,16,2>UB {align1}; mov (16) g124.0<1>UB g48.0<16,16,2>UB {align1}; mov (16) g124.16<1>UB g49.0<16,16,2>UB {align1}; mov (16) g125.0<1>UB g50.0<16,16,2>UB {align1}; mov (16) g125.16<1>UB g51.0<16,16,2>UB {align1}; //Backward asr (2) g115.18<1>W g115.18<2,2,1>W 1W {align1}; asr (2) g1.14<1>W g115.18<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g1.0<2,2,1>UD g1.14<2,2,1>W {align1}; define(`input_surface1', `8') define(`input_surface2', `9') define(`mv1', `g115.18') define(`mv2', `g115.20') mov (1) g2.8<1>UD 0x007000fUD {align1}; include(`motion_frame_uv.g4i') //Average avg.sat (16) g44.0<1>UW g44.0<16,16,1>UW g122.0<16,16,1>UB {align1}; avg.sat (16) g45.0<1>UW g45.0<16,16,1>UW g122.16<16,16,1>UB {align1}; avg.sat (16) g46.0<1>UW g46.0<16,16,1>UW g123.0<16,16,1>UB {align1}; avg.sat (16) g47.0<1>UW g47.0<16,16,1>UW g123.16<16,16,1>UB {align1}; avg.sat (16) g48.0<1>UW g48.0<16,16,1>UW g124.0<16,16,1>UB {align1}; avg.sat (16) g49.0<1>UW g49.0<16,16,1>UW g124.16<16,16,1>UB {align1}; avg.sat (16) g50.0<1>UW g50.0<16,16,1>UW g125.0<16,16,1>UB {align1}; avg.sat (16) g51.0<1>UW g51.0<16,16,1>UW g125.16<16,16,1>UB {align1}; include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b.g4b000066400000000000000000002070171267532330400254220ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00600001, 0x20400021, 0x008d0020, 0x00000000 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000012b }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000de }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000092 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000e5 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00802001, 0x26800021, 0x00b10380, 0x00000000 }, { 0x00802001, 0x26c00021, 0x00b103c0, 0x00000000 }, { 0x00802001, 0x27000021, 0x00b10400, 0x00000000 }, { 0x00802001, 0x27400021, 0x00b10440, 0x00000000 }, { 0x00802001, 0x27800021, 0x00b10480, 0x00000000 }, { 0x00802001, 0x27c00021, 0x00b104c0, 0x00000000 }, { 0x00802001, 0x28000021, 0x00b10500, 0x00000000 }, { 0x00802001, 0x28400021, 0x00b10540, 0x00000000 }, { 0x0020000c, 0x202e3dad, 0x00450e72, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e72, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000012b }, { 0x01000005, 0x20000d3c, 0x00210e74, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000de }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000092 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000e5 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x01000005, 0x20000d3c, 0x00210e74, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10380, 0x00b10680 }, { 0x80800042, 0x23a02529, 0x00b103a0, 0x00b106a0 }, { 0x80800042, 0x23c02529, 0x00b103c0, 0x00b106c0 }, { 0x80800042, 0x23e02529, 0x00b103e0, 0x00b106e0 }, { 0x80800042, 0x24002529, 0x00b10400, 0x00b10700 }, { 0x80800042, 0x24202529, 0x00b10420, 0x00b10720 }, { 0x80800042, 0x24402529, 0x00b10440, 0x00b10740 }, { 0x80800042, 0x24602529, 0x00b10460, 0x00b10760 }, { 0x80800042, 0x24802529, 0x00b10480, 0x00b10780 }, { 0x80800042, 0x24a02529, 0x00b104a0, 0x00b107a0 }, { 0x80800042, 0x24c02529, 0x00b104c0, 0x00b107c0 }, { 0x80800042, 0x24e02529, 0x00b104e0, 0x00b107e0 }, { 0x80800042, 0x25002529, 0x00b10500, 0x00b10800 }, { 0x80800042, 0x25202529, 0x00b10520, 0x00b10820 }, { 0x80800042, 0x25402529, 0x00b10540, 0x00b10840 }, { 0x80800042, 0x25602529, 0x00b10560, 0x00b10860 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x008d0040, 0x0414a005 }, { 0x00800031, 0x2b401d29, 0x008d0040, 0x0414a006 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2f400231, 0x00b20580, 0x00000000 }, { 0x00800001, 0x2f500231, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x2f600231, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x2f700231, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x2f800231, 0x00b20600, 0x00000000 }, { 0x00800001, 0x2f900231, 0x00b20620, 0x00000000 }, { 0x00800001, 0x2fa00231, 0x00b20640, 0x00000000 }, { 0x00800001, 0x2fb00231, 0x00b20660, 0x00000000 }, { 0x0020000c, 0x2e723dad, 0x00450e72, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e72, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x008d0040, 0x0414a008 }, { 0x00800031, 0x2b401d29, 0x008d0040, 0x0414a009 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x80800042, 0x25804529, 0x00b10580, 0x00b10f40 }, { 0x80800042, 0x25a04529, 0x00b105a0, 0x00b10f50 }, { 0x80800042, 0x25c04529, 0x00b105c0, 0x00b10f60 }, { 0x80800042, 0x25e04529, 0x00b105e0, 0x00b10f70 }, { 0x80800042, 0x26004529, 0x00b10600, 0x00b10f80 }, { 0x80800042, 0x26204529, 0x00b10620, 0x00b10f90 }, { 0x80800042, 0x26404529, 0x00b10640, 0x00b10fa0 }, { 0x80800042, 0x26604529, 0x00b10660, 0x00b10fb0 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b.g4b.gen5000066400000000000000000002070171267532330400262570ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00600001, 0x20400021, 0x008d0020, 0x00000000 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000256 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000001bc }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000124 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001ca }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00802001, 0x26800021, 0x00b10380, 0x00000000 }, { 0x00802001, 0x26c00021, 0x00b103c0, 0x00000000 }, { 0x00802001, 0x27000021, 0x00b10400, 0x00000000 }, { 0x00802001, 0x27400021, 0x00b10440, 0x00000000 }, { 0x00802001, 0x27800021, 0x00b10480, 0x00000000 }, { 0x00802001, 0x27c00021, 0x00b104c0, 0x00000000 }, { 0x00802001, 0x28000021, 0x00b10500, 0x00000000 }, { 0x00802001, 0x28400021, 0x00b10540, 0x00000000 }, { 0x0020000c, 0x202e3dad, 0x00450e72, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e72, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000256 }, { 0x01000005, 0x20000d3c, 0x00210e74, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000001bc }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000124 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001ca }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x01000005, 0x20000d3c, 0x00210e74, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a007 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a007 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a007 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x80800042, 0x23802529, 0x00b10380, 0x00b10680 }, { 0x80800042, 0x23a02529, 0x00b103a0, 0x00b106a0 }, { 0x80800042, 0x23c02529, 0x00b103c0, 0x00b106c0 }, { 0x80800042, 0x23e02529, 0x00b103e0, 0x00b106e0 }, { 0x80800042, 0x24002529, 0x00b10400, 0x00b10700 }, { 0x80800042, 0x24202529, 0x00b10420, 0x00b10720 }, { 0x80800042, 0x24402529, 0x00b10440, 0x00b10740 }, { 0x80800042, 0x24602529, 0x00b10460, 0x00b10760 }, { 0x80800042, 0x24802529, 0x00b10480, 0x00b10780 }, { 0x80800042, 0x24a02529, 0x00b104a0, 0x00b107a0 }, { 0x80800042, 0x24c02529, 0x00b104c0, 0x00b107c0 }, { 0x80800042, 0x24e02529, 0x00b104e0, 0x00b107e0 }, { 0x80800042, 0x25002529, 0x00b10500, 0x00b10800 }, { 0x80800042, 0x25202529, 0x00b10520, 0x00b10820 }, { 0x80800042, 0x25402529, 0x00b10540, 0x00b10840 }, { 0x80800042, 0x25602529, 0x00b10560, 0x00b10860 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x408d0040, 0x0248a005 }, { 0x00800031, 0x2b401d29, 0x408d0040, 0x0248a006 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00800001, 0x2f400231, 0x00b20580, 0x00000000 }, { 0x00800001, 0x2f500231, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x2f600231, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x2f700231, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x2f800231, 0x00b20600, 0x00000000 }, { 0x00800001, 0x2f900231, 0x00b20620, 0x00000000 }, { 0x00800001, 0x2fa00231, 0x00b20640, 0x00000000 }, { 0x00800001, 0x2fb00231, 0x00b20660, 0x00000000 }, { 0x0020000c, 0x2e723dad, 0x00450e72, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e72, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x408d0040, 0x0248a008 }, { 0x00800031, 0x2b401d29, 0x408d0040, 0x0248a009 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x80800042, 0x25804529, 0x00b10580, 0x00b10f40 }, { 0x80800042, 0x25a04529, 0x00b105a0, 0x00b10f50 }, { 0x80800042, 0x25c04529, 0x00b105c0, 0x00b10f60 }, { 0x80800042, 0x25e04529, 0x00b105e0, 0x00b10f70 }, { 0x80800042, 0x26004529, 0x00b10600, 0x00b10f80 }, { 0x80800042, 0x26204529, 0x00b10620, 0x00b10f90 }, { 0x80800042, 0x26404529, 0x00b10640, 0x00b10fa0 }, { 0x80800042, 0x26604529, 0x00b10660, 0x00b10fb0 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b_igd.g4a000066400000000000000000000106011267532330400262330ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ /* mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; define(`UV_red',`0xffffffffUD') define(`UV_white',`0x7f7f7f7fUD') define(`UV_green',`0x00000000UD') mov(1) g31.8<1>UD 0x000f000fUD { align1 }; mov(16) m1<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m3<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m5<1>UD 0xFFFFFFFFUD {align1 compr}; mov(16) m7<1>UD 0xFFFFFFFFUD {align1 compr}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(0, 0, 2, 0) mlen 9 rlen 0 { align1 }; shr (2) g31.0<1>UD g82.0<2,2,1>UD 1UW {align1}; mov(1) g31.8<1>UD 0x00070007UD { align1 }; mov (16) m1<1>UD UV_green {align1 compr}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IDCT //Y, Forward asr (2) g31.14<1>W g82.14<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 0UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x0UD {align1}; //jump to the lib to read reference data //Save Forward mov (16) g108.0<1>UD g58.0<16,16,1>UD {align1 compr}; mov (16) g110.0<1>UD g60.0<16,16,1>UD {align1 compr}; mov (16) g112.0<1>UD g62.0<16,16,1>UD {align1 compr}; mov (16) g114.0<1>UD g64.0<16,16,1>UD {align1 compr}; mov (16) g116.0<1>UD g66.0<16,16,1>UD {align1 compr}; mov (16) g118.0<1>UD g68.0<16,16,1>UD {align1 compr}; mov (16) g120.0<1>UD g70.0<16,16,1>UD {align1 compr}; mov (16) g122.0<1>UD g72.0<16,16,1>UD {align1 compr}; //Y, Backward asr (2) g31.14<1>W g82.18<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 1UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A52UD {align1}; //g82.18,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x0UD {align1}; //jump to the lib to read reference data //Average Forward and Backward avg (32) g58.0<1>UW g58.0<16,16,1>UW g108.0<16,16,1>UW {align1 compr}; avg (32) g60.0<1>UW g60.0<16,16,1>UW g110.0<16,16,1>UW {align1 compr}; avg (32) g62.0<1>UW g62.0<16,16,1>UW g112.0<16,16,1>UW {align1 compr}; avg (32) g64.0<1>UW g64.0<16,16,1>UW g114.0<16,16,1>UW {align1 compr}; avg (32) g66.0<1>UW g66.0<16,16,1>UW g116.0<16,16,1>UW {align1 compr}; avg (32) g68.0<1>UW g68.0<16,16,1>UW g118.0<16,16,1>UW {align1 compr}; avg (32) g70.0<1>UW g70.0<16,16,1>UW g120.0<16,16,1>UW {align1 compr}; avg (32) g72.0<1>UW g72.0<16,16,1>UW g122.0<16,16,1>UW {align1 compr}; //UV, Forward shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.14<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 0UW {align1}; //0:forward 1:backward mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x10UD {align1}; //jump to the lib to read reference data //Save UV Forward mov (32) g108.0<1>UW g74.0<16,16,1>UW {align1 compr}; mov (32) g110.0<1>UW g76.0<16,16,1>UW {align1 compr}; mov (32) g112.0<1>UW g78.0<16,16,1>UW {align1 compr}; mov (32) g114.0<1>UW g80.0<16,16,1>UW {align1 compr}; //UV, Backward asr (2) g31.14<1>W g82.18<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 1UW {align1}; //0:forward 1:backward mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x10UD {align1}; //jump to the lib to read reference data //Average Forward and Backward avg (32) g74.0<1>UW g74.0<16,16,1>UW g108.0<16,16,1>UW {align1 compr}; avg (32) g76.0<1>UW g76.0<16,16,1>UW g110.0<16,16,1>UW {align1 compr}; avg (32) g78.0<1>UW g78.0<16,16,1>UW g112.0<16,16,1>UW {align1 compr}; avg (32) g80.0<1>UW g80.0<16,16,1>UW g114.0<16,16,1>UW {align1 compr}; add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b_igd.g4b000066400000000000000000000053651267532330400262470ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00802001, 0x2d800021, 0x00b10740, 0x00000000 }, { 0x00802001, 0x2dc00021, 0x00b10780, 0x00000000 }, { 0x00802001, 0x2e000021, 0x00b107c0, 0x00000000 }, { 0x00802001, 0x2e400021, 0x00b10800, 0x00000000 }, { 0x00802001, 0x2e800021, 0x00b10840, 0x00000000 }, { 0x00802001, 0x2ec00021, 0x00b10880, 0x00000000 }, { 0x00802001, 0x2f000021, 0x00b108c0, 0x00000000 }, { 0x00802001, 0x2f400021, 0x00b10900, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00a02042, 0x27402529, 0x00b10740, 0x00b10d80 }, { 0x00a02042, 0x27802529, 0x00b10780, 0x00b10dc0 }, { 0x00a02042, 0x27c02529, 0x00b107c0, 0x00b10e00 }, { 0x00a02042, 0x28002529, 0x00b10800, 0x00b10e40 }, { 0x00a02042, 0x28402529, 0x00b10840, 0x00b10e80 }, { 0x00a02042, 0x28802529, 0x00b10880, 0x00b10ec0 }, { 0x00a02042, 0x28c02529, 0x00b108c0, 0x00b10f00 }, { 0x00a02042, 0x29002529, 0x00b10900, 0x00b10f40 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00a02001, 0x2d800129, 0x00b10940, 0x00000000 }, { 0x00a02001, 0x2dc00129, 0x00b10980, 0x00000000 }, { 0x00a02001, 0x2e000129, 0x00b109c0, 0x00000000 }, { 0x00a02001, 0x2e400129, 0x00b10a00, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00a02042, 0x29402529, 0x00b10940, 0x00b10d80 }, { 0x00a02042, 0x29802529, 0x00b10980, 0x00b10dc0 }, { 0x00a02042, 0x29c02529, 0x00b109c0, 0x00b10e00 }, { 0x00a02042, 0x2a002529, 0x00b10a00, 0x00b10e40 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_f_b_igd.g4b.gen5000066400000000000000000000053651267532330400271040ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00802001, 0x2d800021, 0x00b10740, 0x00000000 }, { 0x00802001, 0x2dc00021, 0x00b10780, 0x00000000 }, { 0x00802001, 0x2e000021, 0x00b107c0, 0x00000000 }, { 0x00802001, 0x2e400021, 0x00b10800, 0x00000000 }, { 0x00802001, 0x2e800021, 0x00b10840, 0x00000000 }, { 0x00802001, 0x2ec00021, 0x00b10880, 0x00000000 }, { 0x00802001, 0x2f000021, 0x00b108c0, 0x00000000 }, { 0x00802001, 0x2f400021, 0x00b10900, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a52 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00a02042, 0x27402529, 0x00b10740, 0x00b10d80 }, { 0x00a02042, 0x27802529, 0x00b10780, 0x00b10dc0 }, { 0x00a02042, 0x27c02529, 0x00b107c0, 0x00b10e00 }, { 0x00a02042, 0x28002529, 0x00b10800, 0x00b10e40 }, { 0x00a02042, 0x28402529, 0x00b10840, 0x00b10e80 }, { 0x00a02042, 0x28802529, 0x00b10880, 0x00b10ec0 }, { 0x00a02042, 0x28c02529, 0x00b108c0, 0x00b10f00 }, { 0x00a02042, 0x29002529, 0x00b10900, 0x00b10f40 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00a02001, 0x2d800129, 0x00b10940, 0x00000000 }, { 0x00a02001, 0x2dc00129, 0x00b10980, 0x00000000 }, { 0x00a02001, 0x2e000129, 0x00b109c0, 0x00000000 }, { 0x00a02001, 0x2e400129, 0x00b10a00, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a52, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00010001 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00a02042, 0x29402529, 0x00b10940, 0x00b10d80 }, { 0x00a02042, 0x29802529, 0x00b10980, 0x00b10dc0 }, { 0x00a02042, 0x29c02529, 0x00b109c0, 0x00b10e00 }, { 0x00a02042, 0x2a002529, 0x00b10a00, 0x00b10e40 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward.g4a000066400000000000000000000047131267532330400263350ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ /* shader for backward predict mc */ /* save payload */ mov (8) g76.0<1>UD g1.0<8,8,1>UD {align1}; //mov (8) g77.0<1>UD g2.0<8,8,1>UD {align1}; include(`block_clear.g4i') mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; mov (1) g1.8<1>UD 0x0070007UD {align1}; define(`input_surface', `4') define(`mv1', `g115.14') define(`mv2', `g115.16') /* Y */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g115.0<2,2,1>UD g1.14<2,2,1>W {align1}; include(`motion_frame_y.g4i') /* motion_vector = motion_vector >> 1 */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ /* U */ shr (2) g1.0<1>UD g115.0<2,2,1>UD 1UD {align1}; asr (2) g115.14<1>W g115.14<2,2,1>W 1W {align1}; asr (2) g1.14<1>W g115.14<2,2,1>W 1W {align1}; add (2) g2.0<1>UD g1.0<2,2,1>UD g1.14<2,2,1>W {align1}; define(`input_surface1', `5') define(`input_surface2', `6') mov (1) g2.8<1>UD 0x007000fUD {align1}; include(`motion_frame_uv.g4i') /* V */ /* (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) */ include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward.g4b000066400000000000000000001146351267532330400263430ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000012b }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000de }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000092 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000e5 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009a }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x008d0040, 0x0411a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x008d0040, 0x0418a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x008d0040, 0x0418a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x008d0040, 0x0414a005 }, { 0x00800031, 0x2b401d29, 0x008d0040, 0x0414a006 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward.g4b.gen5000066400000000000000000001146351267532330400272000ustar00rootroot00000000000000 { 0x00600001, 0x29800021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210988, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x02000005, 0x20002d3c, 0x0021098c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x20700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x20f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21a00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21c00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21e00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22400169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x21700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21b00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21d00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x21f00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x22500169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22a00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x22c00169, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x0021002c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x22e00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x23400169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450e60, 0x0045002e }, { 0x01000005, 0x20000d3c, 0x00210e6e, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000256 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000001bc }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000031 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800040, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x00800040, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x00800040, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x00800040, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x00800040, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x00800040, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x00800040, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x00800040, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x00800040, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x00800040, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x00800040, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x00800040, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x00800040, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x00800040, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x00800040, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x00800040, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c60 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c80 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca0 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc0 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce0 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d00 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d20 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d40 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d60 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d80 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da0 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc0 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de0 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e00 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e20 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f00 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000124 }, { 0x00800040, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x00800040, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x00800040, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x00800040, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x00800040, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x00800040, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x00800040, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x00800040, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x00800040, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x00800040, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x00800040, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x00800040, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x00800040, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x00800040, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x00800040, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x00800040, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c61 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c81 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca1 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce1 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d01 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d21 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d41 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d61 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d81 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc1 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de1 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e01 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e21 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f01 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00800040, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x00800040, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x00800040, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x00800040, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x00800040, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x00800040, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x00800040, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x00800040, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x00800040, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x00800040, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x00800040, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x00800040, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x00800040, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x00800040, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x00800040, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x00800040, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c62 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c82 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca2 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc2 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce2 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d02 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d22 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d42 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d62 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d82 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da2 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc2 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de2 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e02 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e22 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f02 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00800040, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x00800040, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x00800040, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x00800040, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x00800040, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x00800040, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x00800040, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x00800040, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x00800040, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x00800040, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x00800040, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x00800040, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x00800040, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x00800040, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x00800040, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x00800040, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c63 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c83 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca3 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc3 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce3 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d03 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d23 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d43 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d63 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d83 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da3 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc3 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de3 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e03 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e23 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f03 }, { 0x00800040, 0x23804529, 0x00b10380, 0x00b10c64 }, { 0x00800040, 0x23a04529, 0x00b103a0, 0x00b10c84 }, { 0x00800040, 0x23c04529, 0x00b103c0, 0x00b10ca4 }, { 0x00800040, 0x23e04529, 0x00b103e0, 0x00b10cc4 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10ce4 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10d04 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10d24 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10d44 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10d64 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10d84 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10da4 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10dc4 }, { 0x00800040, 0x25004529, 0x00b10500, 0x00b10de4 }, { 0x00800040, 0x25204529, 0x00b10520, 0x00b10e04 }, { 0x00800040, 0x25404529, 0x00b10540, 0x00b10e24 }, { 0x00800040, 0x25604529, 0x00b10560, 0x00b10f04 }, { 0x80800008, 0x23802d29, 0x00b10380, 0x00020002 }, { 0x80800008, 0x23a02d29, 0x00b103a0, 0x00020002 }, { 0x80800008, 0x23c02d29, 0x00b103c0, 0x00020002 }, { 0x80800008, 0x23e02d29, 0x00b103e0, 0x00020002 }, { 0x80800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x80800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x80800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x80800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x80800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x80800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x80800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x80800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x80800008, 0x25002d29, 0x00b10500, 0x00020002 }, { 0x80800008, 0x25202d29, 0x00b10520, 0x00020002 }, { 0x80800008, 0x25402d29, 0x00b10540, 0x00020002 }, { 0x80800008, 0x25602d29, 0x00b10560, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001ca }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20581c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c41 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c61 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10c81 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10ca1 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10cc1 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10ce1 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d01 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d21 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d41 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d61 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10d81 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10da1 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10dc1 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10de1 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e01 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10e21 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c42 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c62 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10c82 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10ca2 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10cc2 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10ce2 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d02 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d22 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d42 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d62 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10d82 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10da2 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10dc2 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10de2 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e02 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10e22 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c43 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c63 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10c83 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10ca3 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10cc3 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10ce3 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d03 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d23 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d43 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d63 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10d83 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10da3 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10dc3 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10de3 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e03 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10e23 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c44 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c64 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10c84 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10ca4 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10cc4 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10ce4 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d04 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d24 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d44 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d64 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10d84 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10da4 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10dc4 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10de4 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e04 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10e24 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000134 }, { 0x01000005, 0x20000d3c, 0x00210e70, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00000001, 0x20480061, 0x00000000, 0x0000001f }, { 0x00800031, 0x2f001d29, 0x408d0040, 0x0218a004 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x80800042, 0x23804629, 0x00b10c40, 0x00b10c60 }, { 0x80800042, 0x23a04629, 0x00b10c60, 0x00b10c80 }, { 0x80800042, 0x23c04629, 0x00b10c80, 0x00b10ca0 }, { 0x80800042, 0x23e04629, 0x00b10ca0, 0x00b10cc0 }, { 0x80800042, 0x24004629, 0x00b10cc0, 0x00b10ce0 }, { 0x80800042, 0x24204629, 0x00b10ce0, 0x00b10d00 }, { 0x80800042, 0x24404629, 0x00b10d00, 0x00b10d20 }, { 0x80800042, 0x24604629, 0x00b10d20, 0x00b10d40 }, { 0x80800042, 0x24804629, 0x00b10d40, 0x00b10d60 }, { 0x80800042, 0x24a04629, 0x00b10d60, 0x00b10d80 }, { 0x80800042, 0x24c04629, 0x00b10d80, 0x00b10da0 }, { 0x80800042, 0x24e04629, 0x00b10da0, 0x00b10dc0 }, { 0x80800042, 0x25004629, 0x00b10dc0, 0x00b10de0 }, { 0x80800042, 0x25204629, 0x00b10de0, 0x00b10e00 }, { 0x80800042, 0x25404629, 0x00b10e00, 0x00b10e20 }, { 0x80800042, 0x25604629, 0x00b10e20, 0x00b10f00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x80800042, 0x23804629, 0x00b10c41, 0x00b10c61 }, { 0x80800042, 0x23a04629, 0x00b10c61, 0x00b10c81 }, { 0x80800042, 0x23c04629, 0x00b10c81, 0x00b10ca1 }, { 0x80800042, 0x23e04629, 0x00b10ca1, 0x00b10cc1 }, { 0x80800042, 0x24004629, 0x00b10cc1, 0x00b10ce1 }, { 0x80800042, 0x24204629, 0x00b10ce1, 0x00b10d01 }, { 0x80800042, 0x24404629, 0x00b10d01, 0x00b10d21 }, { 0x80800042, 0x24604629, 0x00b10d21, 0x00b10d41 }, { 0x80800042, 0x24804629, 0x00b10d41, 0x00b10d61 }, { 0x80800042, 0x24a04629, 0x00b10d61, 0x00b10d81 }, { 0x80800042, 0x24c04629, 0x00b10d81, 0x00b10da1 }, { 0x80800042, 0x24e04629, 0x00b10da1, 0x00b10dc1 }, { 0x80800042, 0x25004629, 0x00b10dc1, 0x00b10de1 }, { 0x80800042, 0x25204629, 0x00b10de1, 0x00b10e01 }, { 0x80800042, 0x25404629, 0x00b10e01, 0x00b10e21 }, { 0x80800042, 0x25604629, 0x00b10e21, 0x00b10f01 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x80800042, 0x23804629, 0x00b10c42, 0x00b10c62 }, { 0x80800042, 0x23a04629, 0x00b10c62, 0x00b10c82 }, { 0x80800042, 0x23c04629, 0x00b10c82, 0x00b10ca2 }, { 0x80800042, 0x23e04629, 0x00b10ca2, 0x00b10cc2 }, { 0x80800042, 0x24004629, 0x00b10cc2, 0x00b10ce2 }, { 0x80800042, 0x24204629, 0x00b10ce2, 0x00b10d02 }, { 0x80800042, 0x24404629, 0x00b10d02, 0x00b10d22 }, { 0x80800042, 0x24604629, 0x00b10d22, 0x00b10d42 }, { 0x80800042, 0x24804629, 0x00b10d42, 0x00b10d62 }, { 0x80800042, 0x24a04629, 0x00b10d62, 0x00b10d82 }, { 0x80800042, 0x24c04629, 0x00b10d82, 0x00b10da2 }, { 0x80800042, 0x24e04629, 0x00b10da2, 0x00b10dc2 }, { 0x80800042, 0x25004629, 0x00b10dc2, 0x00b10de2 }, { 0x80800042, 0x25204629, 0x00b10de2, 0x00b10e02 }, { 0x80800042, 0x25404629, 0x00b10e02, 0x00b10e22 }, { 0x80800042, 0x25604629, 0x00b10e22, 0x00b10f02 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800042, 0x23804629, 0x00b10c43, 0x00b10c63 }, { 0x80800042, 0x23a04629, 0x00b10c63, 0x00b10c83 }, { 0x80800042, 0x23c04629, 0x00b10c83, 0x00b10ca3 }, { 0x80800042, 0x23e04629, 0x00b10ca3, 0x00b10cc3 }, { 0x80800042, 0x24004629, 0x00b10cc3, 0x00b10ce3 }, { 0x80800042, 0x24204629, 0x00b10ce3, 0x00b10d03 }, { 0x80800042, 0x24404629, 0x00b10d03, 0x00b10d23 }, { 0x80800042, 0x24604629, 0x00b10d23, 0x00b10d43 }, { 0x80800042, 0x24804629, 0x00b10d43, 0x00b10d63 }, { 0x80800042, 0x24a04629, 0x00b10d63, 0x00b10d83 }, { 0x80800042, 0x24c04629, 0x00b10d83, 0x00b10da3 }, { 0x80800042, 0x24e04629, 0x00b10da3, 0x00b10dc3 }, { 0x80800042, 0x25004629, 0x00b10dc3, 0x00b10de3 }, { 0x80800042, 0x25204629, 0x00b10de3, 0x00b10e03 }, { 0x80800042, 0x25404629, 0x00b10e03, 0x00b10e23 }, { 0x80800042, 0x25604629, 0x00b10e23, 0x00b10f03 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000094 }, { 0x00000001, 0x20480061, 0x00000000, 0x0007001f }, { 0x00800031, 0x2c401d29, 0x408d0040, 0x0288a004 }, { 0x00000040, 0x20440c21, 0x00210044, 0x00000008 }, { 0x00800031, 0x2d401d29, 0x408d0040, 0x0288a004 }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000011 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x23800229, 0x00b10c40, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c60, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c80, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca0, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce0, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d00, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d20, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d60, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d80, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da0, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc0, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de0, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e00, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e20, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x00800001, 0x23800229, 0x00b10c41, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c61, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c81, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca1, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc1, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce1, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d01, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d21, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d41, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d61, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d81, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da1, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc1, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de1, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e01, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e21, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x00800001, 0x23800229, 0x00b10c42, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c62, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c82, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca2, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc2, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce2, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d02, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d22, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d42, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d62, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d82, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da2, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc2, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de2, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e02, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e22, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x23800229, 0x00b10c43, 0x00000000 }, { 0x00800001, 0x23a00229, 0x00b10c63, 0x00000000 }, { 0x00800001, 0x23c00229, 0x00b10c83, 0x00000000 }, { 0x00800001, 0x23e00229, 0x00b10ca3, 0x00000000 }, { 0x00800001, 0x24000229, 0x00b10cc3, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10ce3, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10d03, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b10d23, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10d43, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10d63, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10d83, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b10da3, 0x00000000 }, { 0x00800001, 0x25000229, 0x00b10dc3, 0x00000000 }, { 0x00800001, 0x25200229, 0x00b10de3, 0x00000000 }, { 0x00800001, 0x25400229, 0x00b10e03, 0x00000000 }, { 0x00800001, 0x25600229, 0x00b10e23, 0x00000000 }, { 0x00200008, 0x20200c21, 0x00450e60, 0x00000001 }, { 0x0020000c, 0x2e6e3dad, 0x00450e6e, 0x00010001 }, { 0x0020000c, 0x202e3dad, 0x00450e6e, 0x00010001 }, { 0x00200040, 0x20403421, 0x00450020, 0x0045002e }, { 0x00000001, 0x20480061, 0x00000000, 0x0007000f }, { 0x00000005, 0x20580c21, 0x00210040, 0x00000003 }, { 0x00800031, 0x2ac01d29, 0x408d0040, 0x0248a005 }, { 0x00800031, 0x2b401d29, 0x408d0040, 0x0248a006 }, { 0x00000041, 0x20580c21, 0x00210058, 0x00000009 }, { 0x00000020, 0x34001400, 0x00001400, 0x00210058 }, { 0x00800001, 0x25800229, 0x00ad0ac0, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae0, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b00, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b20, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b40, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b60, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b80, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba0, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00800001, 0x25800229, 0x00ad0ac1, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae1, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b01, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b21, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b41, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b61, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b81, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba1, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x25800229, 0x00ad0ac2, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae2, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b02, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b22, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b42, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b62, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b82, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba2, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x25800229, 0x00ad0ac3, 0x00000000 }, { 0x00800001, 0x25a00229, 0x00ad0ae3, 0x00000000 }, { 0x00800001, 0x25c00229, 0x00ad0b03, 0x00000000 }, { 0x00800001, 0x25e00229, 0x00ad0b23, 0x00000000 }, { 0x00800001, 0x26000229, 0x00ad0b43, 0x00000000 }, { 0x00800001, 0x26200229, 0x00ad0b63, 0x00000000 }, { 0x00800001, 0x26400229, 0x00ad0b83, 0x00000000 }, { 0x00800001, 0x26600229, 0x00ad0ba3, 0x00000000 }, { 0x00600001, 0x20200021, 0x008d0980, 0x00000000 }, { 0x00800001, 0x458101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45a101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45c101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x45e101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x460101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x462101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x464101f1, 0x00000000, 0x00000000 }, { 0x00800001, 0x466101f1, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10080, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b100a0, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b100c0, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100e0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b10100, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b10120, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b10140, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b10160, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b10180, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b101a0, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b101c0, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b101e0, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10200, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10220, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x238045ad, 0x00b10060, 0x00b20380 }, { 0x00800040, 0x23a045ad, 0x00b10160, 0x00b203a0 }, { 0x00800040, 0x23c045ad, 0x00b10080, 0x00b203c0 }, { 0x00800040, 0x23e045ad, 0x00b10180, 0x00b203e0 }, { 0x00800040, 0x240045ad, 0x00b100a0, 0x00b20400 }, { 0x00800040, 0x242045ad, 0x00b101a0, 0x00b20420 }, { 0x00800040, 0x244045ad, 0x00b100c0, 0x00b20440 }, { 0x00800040, 0x246045ad, 0x00b101c0, 0x00b20460 }, { 0x00800040, 0x248045ad, 0x00b100e0, 0x00b20480 }, { 0x00800040, 0x24a045ad, 0x00b101e0, 0x00b204a0 }, { 0x00800040, 0x24c045ad, 0x00b10100, 0x00b204c0 }, { 0x00800040, 0x24e045ad, 0x00b10200, 0x00b204e0 }, { 0x00800040, 0x250045ad, 0x00b10120, 0x00b20500 }, { 0x00800040, 0x252045ad, 0x00b10220, 0x00b20520 }, { 0x00800040, 0x254045ad, 0x00b10140, 0x00b20540 }, { 0x00800040, 0x256045ad, 0x00b10240, 0x00b20560 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x438001b1, 0x00b10380, 0x00000000 }, { 0x80800001, 0x43a001b1, 0x00b103a0, 0x00000000 }, { 0x80800001, 0x43c001b1, 0x00b103c0, 0x00000000 }, { 0x80800001, 0x43e001b1, 0x00b103e0, 0x00000000 }, { 0x80800001, 0x440001b1, 0x00b10400, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20380, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b203a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b203c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b203e0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20400, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20560, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450020, 0x00000001 }, { 0x00800040, 0x258025a9, 0x00b10260, 0x00b10580 }, { 0x00800040, 0x25a025a9, 0x00b10280, 0x00b105a0 }, { 0x00800040, 0x25c025a9, 0x00b102a0, 0x00b105c0 }, { 0x00800040, 0x25e025a9, 0x00b102c0, 0x00b105e0 }, { 0x80800001, 0x45800131, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a00131, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c00131, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e00131, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b205e0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800040, 0x260025a9, 0x00b102e0, 0x00b10600 }, { 0x00800040, 0x262025a9, 0x00b10300, 0x00b10620 }, { 0x00800040, 0x264025a9, 0x00b10320, 0x00b10640 }, { 0x00800040, 0x266025a9, 0x00b10340, 0x00b10660 }, { 0x80800001, 0x46000131, 0x00b10600, 0x00000000 }, { 0x80800001, 0x46200131, 0x00b10620, 0x00000000 }, { 0x80800001, 0x46400131, 0x00b10640, 0x00000000 }, { 0x80800001, 0x46600131, 0x00b10660, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20600, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20660, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward_igd.g4a000066400000000000000000000025651267532330400271630ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x50UD {align1}; //jump to the lib to do IDCT //Y, (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) asr (2) g31.14<1>W g82.14<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g32.16<1>UW 0UW {align1}; //0:forward 1:backward mov (1) a0.0<1>UD 0x0A4EUD {align1}; //g82.14,motion vector mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x00UD {align1}; //jump to the lib to read reference data //UV, (x', y') = (x >> 1, y >> 1) + (motion_vector.x >> 2, motion_vector.y >> 2) shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.14<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; mov (1) g126.8<1>UD ip {align1}; add (1) ip g21.0<1,1,1>UD 0x10UD {align1}; //jump to the lib to read reference data add (1) ip g21.0<1,1,1>UD 0x40UD {align1}; //jump to the lib to add the reference and idct data xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward_igd.g4b000066400000000000000000000014711267532330400271570ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/frame_forward_igd.g4b.gen5000066400000000000000000000014711267532330400300140ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000050 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24100169, 0x00000000, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x00000a4e }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a4e, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000010 }, { 0x00000040, 0x34000c20, 0x002102a0, 0x00000040 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture.g4a000066400000000000000000000176501267532330400253470ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (8) g115.0<1>UD g1.0<8,8,1>UD {align1}; and.nz (1) null g2.0<1,1,1>UD 0x1UD{align1}; (f0) jmpi direct_idct; add (1) g2.8<1>UD g115.8<1,1,1>UD 0UD{align1}; send (16) 0 g3.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g4.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g5.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g6.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g7.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g8.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g9.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g10.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g11.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g12.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g13.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g14.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g15.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g16.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g17.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g18.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g19.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g20.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g21.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g22.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g23<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g24.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g25.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; add (1) g2.8<1>UD g2.8<1,1,1>UD 32UD {align1}; send (16) 0 g26.0<1>UD g2<16,16,1>UD read(3, 0, 2, 0) mlen 1 rlen 1 { align1 }; direct_idct: mov (1) g1.8<1>UD 0x00F000FUD {align1}; mov.sat (16) g3.0<2>UB g3.0<16,16,1>W {align1}; mov.sat (16) g4.0<2>UB g4.0<16,16,1>W {align1}; mov.sat (16) g5.0<2>UB g5.0<16,16,1>W {align1}; mov.sat (16) g6.0<2>UB g6.0<16,16,1>W {align1}; mov.sat (16) g7.0<2>UB g7.0<16,16,1>W {align1}; mov.sat (16) g8.0<2>UB g8.0<16,16,1>W {align1}; mov.sat (16) g9.0<2>UB g9.0<16,16,1>W {align1}; mov.sat (16) g10.0<2>UB g10.0<16,16,1>W {align1}; mov.sat (16) g11.0<2>UB g11.0<16,16,1>W {align1}; mov.sat (16) g12.0<2>UB g12.0<16,16,1>W {align1}; mov.sat (16) g13.0<2>UB g13.0<16,16,1>W {align1}; mov.sat (16) g14.0<2>UB g14.0<16,16,1>W {align1}; mov.sat (16) g15.0<2>UB g15.0<16,16,1>W {align1}; mov.sat (16) g16.0<2>UB g16.0<16,16,1>W {align1}; mov.sat (16) g17.0<2>UB g17.0<16,16,1>W {align1}; mov.sat (16) g18.0<2>UB g18.0<16,16,1>W {align1}; and.nz (1) null g1.30<1,1,1>UB 0x1UW{align1}; (f0) jmpi field_dct; //Frame IDCT mov (16) m1.0<1>UB g3.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g4.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g5.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g6.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g7.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g8.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g9.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g10.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g11.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g12.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g13.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g14.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g15.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g16.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g17.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g18.0<16,16,2>UB {align1}; jmpi write_back; field_dct: //Field IDCT mov (16) m1.0<1>UB g3.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g11.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g4.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g12.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g5.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g13.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g6.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g14.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g7.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g15.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g8.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g16.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g9.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g17.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g10.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g18.0<16,16,2>UB {align1}; write_back: send (16) 0 acc0<1>UW g1<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g1.8<1>UD 0x0070007UD { align1 }; shr (2) g1.0<1>UD g115.0<2,2,1>UD 1D {align1}; mov.sat (16) g19.0<2>UB g19.0<16,16,1>W {align1}; mov.sat (16) g20.0<2>UB g20.0<16,16,1>W {align1}; mov.sat (16) g21.0<2>UB g21.0<16,16,1>W {align1}; mov.sat (16) g22.0<2>UB g22.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g19.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g20.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g21.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g22.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V mov.sat (16) g23.0<2>UB g23.0<16,16,1>W {align1}; mov.sat (16) g24.0<2>UB g24.0<16,16,1>W {align1}; mov.sat (16) g25.0<2>UB g25.0<16,16,1>W {align1}; mov.sat (16) g26.0<2>UB g26.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g23.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g24.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g25.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g26.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture.g4b000066400000000000000000000153331267532330400253440ustar00rootroot00000000000000 { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000040, 0x20480c21, 0x00210e68, 0x00000000 }, { 0x00800031, 0x20601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x00b10040, 0x04110203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x00b10040, 0x04110203 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x406001b1, 0x00b10060, 0x00000000 }, { 0x80800001, 0x408001b1, 0x00b10080, 0x00000000 }, { 0x80800001, 0x40a001b1, 0x00b100a0, 0x00000000 }, { 0x80800001, 0x40c001b1, 0x00b100c0, 0x00000000 }, { 0x80800001, 0x40e001b1, 0x00b100e0, 0x00000000 }, { 0x80800001, 0x410001b1, 0x00b10100, 0x00000000 }, { 0x80800001, 0x412001b1, 0x00b10120, 0x00000000 }, { 0x80800001, 0x414001b1, 0x00b10140, 0x00000000 }, { 0x80800001, 0x416001b1, 0x00b10160, 0x00000000 }, { 0x80800001, 0x418001b1, 0x00b10180, 0x00000000 }, { 0x80800001, 0x41a001b1, 0x00b101a0, 0x00000000 }, { 0x80800001, 0x41c001b1, 0x00b101c0, 0x00000000 }, { 0x80800001, 0x41e001b1, 0x00b101e0, 0x00000000 }, { 0x80800001, 0x420001b1, 0x00b10200, 0x00000000 }, { 0x80800001, 0x422001b1, 0x00b10220, 0x00000000 }, { 0x80800001, 0x424001b1, 0x00b10240, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x20200232, 0x00b20060, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20080, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b200a0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b200c0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b200e0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20100, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20120, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20140, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20160, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20180, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b201a0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b201c0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b201e0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20200, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20220, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20240, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x20200232, 0x00b20060, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20160, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20080, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20180, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b200a0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b201a0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b200c0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b201c0, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b200e0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b201e0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20100, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20200, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20120, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20220, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20140, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20240, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05902000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450e60, 0x00000001 }, { 0x80800001, 0x426001b1, 0x00b10260, 0x00000000 }, { 0x80800001, 0x428001b1, 0x00b10280, 0x00000000 }, { 0x80800001, 0x42a001b1, 0x00b102a0, 0x00000000 }, { 0x80800001, 0x42c001b1, 0x00b102c0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20260, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20280, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b202a0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b202c0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x80800001, 0x42e001b1, 0x00b102e0, 0x00000000 }, { 0x80800001, 0x430001b1, 0x00b10300, 0x00000000 }, { 0x80800001, 0x432001b1, 0x00b10320, 0x00000000 }, { 0x80800001, 0x434001b1, 0x00b10340, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b202e0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20300, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20320, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20340, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture.g4b.gen5000066400000000000000000000153331267532330400262010ustar00rootroot00000000000000 { 0x00600001, 0x2e600021, 0x008d0020, 0x00000000 }, { 0x02000005, 0x20000c3c, 0x00210040, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000060 }, { 0x00000040, 0x20480c21, 0x00210e68, 0x00000000 }, { 0x00800031, 0x20601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x20e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x21e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22401c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22601c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22801c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22a01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22c01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x22e01c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23001c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23201c21, 0x40b10040, 0x02180203 }, { 0x00000040, 0x20480c21, 0x00210048, 0x00000020 }, { 0x00800031, 0x23401c21, 0x40b10040, 0x02180203 }, { 0x00000001, 0x20280061, 0x00000000, 0x000f000f }, { 0x80800001, 0x406001b1, 0x00b10060, 0x00000000 }, { 0x80800001, 0x408001b1, 0x00b10080, 0x00000000 }, { 0x80800001, 0x40a001b1, 0x00b100a0, 0x00000000 }, { 0x80800001, 0x40c001b1, 0x00b100c0, 0x00000000 }, { 0x80800001, 0x40e001b1, 0x00b100e0, 0x00000000 }, { 0x80800001, 0x410001b1, 0x00b10100, 0x00000000 }, { 0x80800001, 0x412001b1, 0x00b10120, 0x00000000 }, { 0x80800001, 0x414001b1, 0x00b10140, 0x00000000 }, { 0x80800001, 0x416001b1, 0x00b10160, 0x00000000 }, { 0x80800001, 0x418001b1, 0x00b10180, 0x00000000 }, { 0x80800001, 0x41a001b1, 0x00b101a0, 0x00000000 }, { 0x80800001, 0x41c001b1, 0x00b101c0, 0x00000000 }, { 0x80800001, 0x41e001b1, 0x00b101e0, 0x00000000 }, { 0x80800001, 0x420001b1, 0x00b10200, 0x00000000 }, { 0x80800001, 0x422001b1, 0x00b10220, 0x00000000 }, { 0x80800001, 0x424001b1, 0x00b10240, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x0021003e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x20200232, 0x00b20060, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20080, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b200a0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b200c0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b200e0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20100, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20120, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20140, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20160, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20180, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b201a0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b201c0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b201e0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20200, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20220, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20240, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x20200232, 0x00b20060, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20160, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20080, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20180, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b200a0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b201a0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b200c0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b201c0, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b200e0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b201e0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20100, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20200, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20120, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20220, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20140, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20240, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x12082000 }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00200008, 0x20201c21, 0x00450e60, 0x00000001 }, { 0x80800001, 0x426001b1, 0x00b10260, 0x00000000 }, { 0x80800001, 0x428001b1, 0x00b10280, 0x00000000 }, { 0x80800001, 0x42a001b1, 0x00b102a0, 0x00000000 }, { 0x80800001, 0x42c001b1, 0x00b102c0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20260, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20280, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b202a0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b202c0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x80800001, 0x42e001b1, 0x00b102e0, 0x00000000 }, { 0x80800001, 0x430001b1, 0x00b10300, 0x00000000 }, { 0x80800001, 0x432001b1, 0x00b10320, 0x00000000 }, { 0x80800001, 0x434001b1, 0x00b10340, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b202e0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20300, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20320, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20340, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture_igd.g4a000066400000000000000000000076561267532330400261770ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT tab g31: read and write message descriptor g32~g55:DCT data g58~g81:reference data g82: thread payload g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov.sat (16) g33.0<2>UB g33.0<16,16,1>W {align1}; mov.sat (16) g34.0<2>UB g34.0<16,16,1>W {align1}; mov.sat (16) g35.0<2>UB g35.0<16,16,1>W {align1}; mov.sat (16) g36.0<2>UB g36.0<16,16,1>W {align1}; mov.sat (16) g37.0<2>UB g37.0<16,16,1>W {align1}; mov.sat (16) g38.0<2>UB g38.0<16,16,1>W {align1}; mov.sat (16) g39.0<2>UB g39.0<16,16,1>W {align1}; mov.sat (16) g40.0<2>UB g40.0<16,16,1>W {align1}; mov.sat (16) g41.0<2>UB g41.0<16,16,1>W {align1}; mov.sat (16) g42.0<2>UB g42.0<16,16,1>W {align1}; mov.sat (16) g43.0<2>UB g43.0<16,16,1>W {align1}; mov.sat (16) g44.0<2>UB g44.0<16,16,1>W {align1}; mov.sat (16) g45.0<2>UB g45.0<16,16,1>W {align1}; mov.sat (16) g46.0<2>UB g46.0<16,16,1>W {align1}; mov.sat (16) g47.0<2>UB g47.0<16,16,1>W {align1}; mov.sat (16) g48.0<2>UB g48.0<16,16,1>W {align1}; mov.sat (16) g49.0<2>UB g49.0<16,16,1>W {align1}; mov.sat (16) g50.0<2>UB g50.0<16,16,1>W {align1}; mov.sat (16) g51.0<2>UB g51.0<16,16,1>W {align1}; mov.sat (16) g52.0<2>UB g52.0<16,16,1>W {align1}; mov.sat (16) g53.0<2>UB g53.0<16,16,1>W {align1}; mov.sat (16) g54.0<2>UB g54.0<16,16,1>W {align1}; mov.sat (16) g55.0<2>UB g55.0<16,16,1>W {align1}; mov.sat (16) g56.0<2>UB g56.0<16,16,1>W {align1}; mov (1) g31.8<1>UD 0x00F000FUD {align1}; and.nz (1) null g82.30<1,1,1>UB 0x1UW{align1}; (f0) jmpi field_dct_y; mov (16) m1.0<1>UB g33.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g34.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g35.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g36.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g37.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g38.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g39.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g40.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g41.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g42.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g43.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g44.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g45.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g46.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g47.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g48.0<16,16,2>UB {align1}; jmpi write_back_y; field_dct_y: mov (16) m1.0<1>UB g33.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g41.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g34.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g42.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g35.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g43.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g36.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g44.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g37.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g45.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g38.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g46.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g39.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g47.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g40.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g48.0<16,16,2>UB {align1}; write_back_y: send (16) 0 acc0<1>UW g31<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g31.8<1>UD 0x0070007UD { align1 }; shr (2) g31.0<1>UD g82.0<2,2,1>UD 1D {align1}; mov (16) m1.0<1>UB g49.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g50.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g51.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g52.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V mov (16) m1.0<1>UB g53.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g54.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g55.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g56.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; OUT: send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture_igd.g4b000066400000000000000000000100351267532330400261610ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x80800001, 0x458001b1, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a001b1, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c001b1, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e001b1, 0x00b105e0, 0x00000000 }, { 0x80800001, 0x460001b1, 0x00b10600, 0x00000000 }, { 0x80800001, 0x462001b1, 0x00b10620, 0x00000000 }, { 0x80800001, 0x464001b1, 0x00b10640, 0x00000000 }, { 0x80800001, 0x466001b1, 0x00b10660, 0x00000000 }, { 0x80800001, 0x468001b1, 0x00b10680, 0x00000000 }, { 0x80800001, 0x46a001b1, 0x00b106a0, 0x00000000 }, { 0x80800001, 0x46c001b1, 0x00b106c0, 0x00000000 }, { 0x80800001, 0x46e001b1, 0x00b106e0, 0x00000000 }, { 0x80800001, 0x470001b1, 0x00b10700, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x02000005, 0x20002e3c, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x20200232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20560, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20600, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x20200232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20560, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20600, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x00450a40, 0x00000001 }, { 0x00800001, 0x20200232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20660, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20680, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800001, 0x20200232, 0x00b206a0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b206c0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b206e0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20700, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/ipicture_igd.g4b.gen5000066400000000000000000000100351267532330400270160ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x80800001, 0x442001b1, 0x00b10420, 0x00000000 }, { 0x80800001, 0x444001b1, 0x00b10440, 0x00000000 }, { 0x80800001, 0x446001b1, 0x00b10460, 0x00000000 }, { 0x80800001, 0x448001b1, 0x00b10480, 0x00000000 }, { 0x80800001, 0x44a001b1, 0x00b104a0, 0x00000000 }, { 0x80800001, 0x44c001b1, 0x00b104c0, 0x00000000 }, { 0x80800001, 0x44e001b1, 0x00b104e0, 0x00000000 }, { 0x80800001, 0x450001b1, 0x00b10500, 0x00000000 }, { 0x80800001, 0x452001b1, 0x00b10520, 0x00000000 }, { 0x80800001, 0x454001b1, 0x00b10540, 0x00000000 }, { 0x80800001, 0x456001b1, 0x00b10560, 0x00000000 }, { 0x80800001, 0x458001b1, 0x00b10580, 0x00000000 }, { 0x80800001, 0x45a001b1, 0x00b105a0, 0x00000000 }, { 0x80800001, 0x45c001b1, 0x00b105c0, 0x00000000 }, { 0x80800001, 0x45e001b1, 0x00b105e0, 0x00000000 }, { 0x80800001, 0x460001b1, 0x00b10600, 0x00000000 }, { 0x80800001, 0x462001b1, 0x00b10620, 0x00000000 }, { 0x80800001, 0x464001b1, 0x00b10640, 0x00000000 }, { 0x80800001, 0x466001b1, 0x00b10660, 0x00000000 }, { 0x80800001, 0x468001b1, 0x00b10680, 0x00000000 }, { 0x80800001, 0x46a001b1, 0x00b106a0, 0x00000000 }, { 0x80800001, 0x46c001b1, 0x00b106c0, 0x00000000 }, { 0x80800001, 0x46e001b1, 0x00b106e0, 0x00000000 }, { 0x80800001, 0x470001b1, 0x00b10700, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x02000005, 0x20002e3c, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x20200232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20560, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20600, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x20200232, 0x00b20420, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20520, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20440, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20540, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20460, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20560, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20480, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20580, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b204a0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b205a0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b204c0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b205c0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b204e0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b205e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20500, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20600, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x00450a40, 0x00000001 }, { 0x00800001, 0x20200232, 0x00b20620, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20640, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20660, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20680, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800001, 0x20200232, 0x00b206a0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b206c0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b206e0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20700, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/lib_igd.g4a000066400000000000000000000074461267532330400251160ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix in UB format g3~g4:non intra IQ matrix in UB format g5~g20:IDCT table g32~g55:DCT data before IQ g56~g79:DCT data after IQ g84~g107: IDCT data after idct g82: thread payload backup g126.8: ip before jump to the lib */ jmpi MOTION_FRAME_Y; jmpi MOTION_FRAME_UV; jmpi MOTION_FIELD_Y; jmpi MOTION_FIELD_UV; jmpi ADD_IDCT; mov (16) g84.0<1>W g33.0<16,16,1>W {align1}; mov (16) g85.0<1>W g34.0<16,16,1>W {align1}; mov (16) g86.0<1>W g35.0<16,16,1>W {align1}; mov (16) g87.0<1>W g36.0<16,16,1>W {align1}; mov (16) g88.0<1>W g37.0<16,16,1>W {align1}; mov (16) g89.0<1>W g38.0<16,16,1>W {align1}; mov (16) g90.0<1>W g39.0<16,16,1>W {align1}; mov (16) g91.0<1>W g40.0<16,16,1>W {align1}; mov (16) g92.0<1>W g41.0<16,16,1>W {align1}; mov (16) g93.0<1>W g42.0<16,16,1>W {align1}; mov (16) g94.0<1>W g43.0<16,16,1>W {align1}; mov (16) g95.0<1>W g44.0<16,16,1>W {align1}; mov (16) g96.0<1>W g45.0<16,16,1>W {align1}; mov (16) g97.0<1>W g46.0<16,16,1>W {align1}; mov (16) g98.0<1>W g47.0<16,16,1>W {align1}; mov (16) g99.0<1>W g48.0<16,16,1>W {align1}; mov (16) g100.0<1>W g49.0<16,16,1>W {align1}; mov (16) g101.0<1>W g50.0<16,16,1>W {align1}; mov (16) g102.0<1>W g51.0<16,16,1>W {align1}; mov (16) g103.0<1>W g52.0<16,16,1>W {align1}; mov (16) g104.0<1>W g53.0<16,16,1>W {align1}; mov (16) g105.0<1>W g54.0<16,16,1>W {align1}; mov (16) g106.0<1>W g55.0<16,16,1>W {align1}; mov (16) g107.0<1>W g56.0<16,16,1>W {align1}; //Y0 and.nz (1) null g82.12<1,1,1>UW 0x20UW {align1}; (f0) jmpi block_y1; mov (8) g84.0<1>W 0W {align1}; mov (8) g85.0<1>W 0W {align1}; mov (8) g86.0<1>W 0W {align1}; mov (8) g87.0<1>W 0W {align1}; mov (8) g88.0<1>W 0W {align1}; mov (8) g89.0<1>W 0W {align1}; mov (8) g90.0<1>W 0W {align1}; mov (8) g91.0<1>W 0W {align1}; //Y1 block_y1: and.nz (1) null g82.12<1,1,1>UW 0x10UW {align1}; (f0) jmpi block_y2; mov (8) g84.16<1>W 0W {align1}; mov (8) g85.16<1>W 0W {align1}; mov (8) g86.16<1>W 0W {align1}; mov (8) g87.16<1>W 0W {align1}; mov (8) g88.16<1>W 0W {align1}; mov (8) g89.16<1>W 0W {align1}; mov (8) g90.16<1>W 0W {align1}; mov (8) g91.16<1>W 0W {align1}; //Y2 block_y2: and.nz (1) null g82.12<1,1,1>UW 0x08UW {align1}; (f0) jmpi block_y3; mov (8) g92.0<1>W 0W {align1}; mov (8) g93.0<1>W 0W {align1}; mov (8) g94.0<1>W 0W {align1}; mov (8) g95.0<1>W 0W {align1}; mov (8) g96.0<1>W 0W {align1}; mov (8) g97.0<1>W 0W {align1}; mov (8) g98.0<1>W 0W {align1}; mov (8) g99.0<1>W 0W {align1}; //Y3 block_y3: and.nz (1) null g82.12<1,1,1>UW 0x04UW {align1}; (f0) jmpi block_u; mov (8) g92.16<1>W 0W {align1}; mov (8) g93.16<1>W 0W {align1}; mov (8) g94.16<1>W 0W {align1}; mov (8) g95.16<1>W 0W {align1}; mov (8) g96.16<1>W 0W {align1}; mov (8) g97.16<1>W 0W {align1}; mov (8) g98.16<1>W 0W {align1}; mov (8) g99.16<1>W 0W {align1}; //U block_u: and.nz (1) null g82.12<1,1,1>UW 0x02UW {align1}; (f0) jmpi block_v; mov (16) g100.0<1>W 0W {align1}; mov (16) g101.0<1>W 0W {align1}; mov (16) g102.0<1>W 0W {align1}; mov (16) g103.0<1>W 0W {align1}; //V block_v: and.nz (1) null g82.12<1,1,1>UW 0x01UW {align1}; (f0) jmpi out; mov (16) g104.0<1>W 0W {align1}; mov (16) g105.0<1>W 0W {align1}; mov (16) g106.0<1>W 0W {align1}; mov (16) g107.0<1>W 0W {align1}; out: add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back MOTION_FRAME_Y: include(`motion_frame_y_igd.g4i') add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back MOTION_FRAME_UV: include(`motion_frame_uv_igd.g4i') add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back MOTION_FIELD_Y: include(`motion_field_y_igd.g4i') add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back MOTION_FIELD_UV: include(`motion_field_uv_igd.g4i') add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back ADD_IDCT: include(`addidct_igd.g4i') xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/lib_igd.g4b000066400000000000000000000737421267532330400251210ustar00rootroot00000000000000 { 0x00000020, 0x34001c00, 0x00001400, 0x00000051 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000f0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000fc }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000016f }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001da }, { 0x00800001, 0x2a8001ad, 0x00b10420, 0x00000000 }, { 0x00800001, 0x2aa001ad, 0x00b10440, 0x00000000 }, { 0x00800001, 0x2ac001ad, 0x00b10460, 0x00000000 }, { 0x00800001, 0x2ae001ad, 0x00b10480, 0x00000000 }, { 0x00800001, 0x2b0001ad, 0x00b104a0, 0x00000000 }, { 0x00800001, 0x2b2001ad, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x2b4001ad, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x2b6001ad, 0x00b10500, 0x00000000 }, { 0x00800001, 0x2b8001ad, 0x00b10520, 0x00000000 }, { 0x00800001, 0x2ba001ad, 0x00b10540, 0x00000000 }, { 0x00800001, 0x2bc001ad, 0x00b10560, 0x00000000 }, { 0x00800001, 0x2be001ad, 0x00b10580, 0x00000000 }, { 0x00800001, 0x2c0001ad, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x2c2001ad, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x2c4001ad, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x2c6001ad, 0x00b10600, 0x00000000 }, { 0x00800001, 0x2c8001ad, 0x00b10620, 0x00000000 }, { 0x00800001, 0x2ca001ad, 0x00b10640, 0x00000000 }, { 0x00800001, 0x2cc001ad, 0x00b10660, 0x00000000 }, { 0x00800001, 0x2ce001ad, 0x00b10680, 0x00000000 }, { 0x00800001, 0x2d0001ad, 0x00b106a0, 0x00000000 }, { 0x00800001, 0x2d2001ad, 0x00b106c0, 0x00000000 }, { 0x00800001, 0x2d4001ad, 0x00b106e0, 0x00000000 }, { 0x00800001, 0x2d6001ad, 0x00b10700, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x2a8001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2aa001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ac001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ae001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b0001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b2001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b4001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b6001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x2a9001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ab001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ad001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2af001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b1001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b3001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b5001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b7001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x2b8001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ba001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bc001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2be001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c0001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c2001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c4001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c6001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00600001, 0x2b9001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bb001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bd001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bf001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c1001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c3001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c5001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c7001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x2c8001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ca001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2cc001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ce001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800001, 0x2d0001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d2001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d4001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d6001ed, 0x00000000, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000067 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000049 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x00a02008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x00a02008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x00a02008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x00a02008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x00a02008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x00a02008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x00a02008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x00a02008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000051 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000036 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000021 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x00800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x00800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x00800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x00800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x00800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x00800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x00800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x00800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x00800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x00800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x00800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x00800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x00800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x00800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x00800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x00800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00a02001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00a02001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00a02001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00a02001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00a02001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00a02001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00a02001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00a02001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a009 }, { 0x00a02001, 0x29400229, 0x00ad0440, 0x00000000 }, { 0x00a02001, 0x29800229, 0x00ad0480, 0x00000000 }, { 0x00a02001, 0x29c00229, 0x00ad0580, 0x00000000 }, { 0x00a02001, 0x2a000229, 0x00ad05c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000041 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002d }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000039 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000019 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000007 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000003 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0414a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00200001, 0x23e00021, 0x00450a40, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000d }, { 0x80a02040, 0x474045b1, 0x00b10a80, 0x00b20740 }, { 0x80a02040, 0x478045b1, 0x00b10ac0, 0x00b20780 }, { 0x80a02040, 0x47c045b1, 0x00b10b00, 0x00b207c0 }, { 0x80a02040, 0x480045b1, 0x00b10b40, 0x00b20800 }, { 0x80a02040, 0x484045b1, 0x00b10b80, 0x00b20840 }, { 0x80a02040, 0x488045b1, 0x00b10bc0, 0x00b20880 }, { 0x80a02040, 0x48c045b1, 0x00b10c00, 0x00b208c0 }, { 0x80a02040, 0x490045b1, 0x00b10c40, 0x00b20900 }, { 0x80a02040, 0x494045b1, 0x00b10c80, 0x00b20940 }, { 0x80a02040, 0x498045b1, 0x00b10cc0, 0x00b20980 }, { 0x80a02040, 0x49c045b1, 0x00b10d00, 0x00b209c0 }, { 0x80a02040, 0x4a0045b1, 0x00b10d40, 0x00b20a00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x80800040, 0x474045b1, 0x00b10a80, 0x00b20740 }, { 0x80800040, 0x476045b1, 0x00b10b80, 0x00b20760 }, { 0x80800040, 0x478045b1, 0x00b10aa0, 0x00b20780 }, { 0x80800040, 0x47a045b1, 0x00b10ba0, 0x00b207a0 }, { 0x80800040, 0x47c045b1, 0x00b10ac0, 0x00b207c0 }, { 0x80800040, 0x47e045b1, 0x00b10bc0, 0x00b207e0 }, { 0x80800040, 0x480045b1, 0x00b10ae0, 0x00b20800 }, { 0x80800040, 0x482045b1, 0x00b10be0, 0x00b20820 }, { 0x80800040, 0x484045b1, 0x00b10b00, 0x00b20840 }, { 0x80800040, 0x486045b1, 0x00b10c00, 0x00b20860 }, { 0x80800040, 0x488045b1, 0x00b10b20, 0x00b20880 }, { 0x80800040, 0x48a045b1, 0x00b10c20, 0x00b208a0 }, { 0x80800040, 0x48c045b1, 0x00b10b40, 0x00b208c0 }, { 0x80800040, 0x48e045b1, 0x00b10c40, 0x00b208e0 }, { 0x80800040, 0x490045b1, 0x00b10b60, 0x00b20900 }, { 0x80800040, 0x492045b1, 0x00b10c60, 0x00b20920 }, { 0x00800040, 0x2c8045ad, 0x00b10c80, 0x00b20940 }, { 0x00800040, 0x2ca045ad, 0x00b10ca0, 0x00b20960 }, { 0x00800040, 0x2cc045ad, 0x00b10cc0, 0x00b20980 }, { 0x00800040, 0x2ce045ad, 0x00b10ce0, 0x00b209a0 }, { 0x00800040, 0x2d0045ad, 0x00b10d00, 0x00b209c0 }, { 0x00800040, 0x2d2045ad, 0x00b10d20, 0x00b209e0 }, { 0x00800040, 0x2d4045ad, 0x00b10d40, 0x00b20a00 }, { 0x00800040, 0x2d6045ad, 0x00b10d60, 0x00b20a20 }, { 0x80800001, 0x494001b1, 0x00b10c80, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10ca0, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10cc0, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b10ce0, 0x00000000 }, { 0x80800001, 0x49c001b1, 0x00b10d00, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b10d20, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10d40, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10d60, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/lib_igd.g4b.gen5000066400000000000000000000737421267532330400257560ustar00rootroot00000000000000 { 0x00000020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001e0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000001f8 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000002de }, { 0x00000020, 0x34001c00, 0x00001400, 0x000003b4 }, { 0x00800001, 0x2a8001ad, 0x00b10420, 0x00000000 }, { 0x00800001, 0x2aa001ad, 0x00b10440, 0x00000000 }, { 0x00800001, 0x2ac001ad, 0x00b10460, 0x00000000 }, { 0x00800001, 0x2ae001ad, 0x00b10480, 0x00000000 }, { 0x00800001, 0x2b0001ad, 0x00b104a0, 0x00000000 }, { 0x00800001, 0x2b2001ad, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x2b4001ad, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x2b6001ad, 0x00b10500, 0x00000000 }, { 0x00800001, 0x2b8001ad, 0x00b10520, 0x00000000 }, { 0x00800001, 0x2ba001ad, 0x00b10540, 0x00000000 }, { 0x00800001, 0x2bc001ad, 0x00b10560, 0x00000000 }, { 0x00800001, 0x2be001ad, 0x00b10580, 0x00000000 }, { 0x00800001, 0x2c0001ad, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x2c2001ad, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x2c4001ad, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x2c6001ad, 0x00b10600, 0x00000000 }, { 0x00800001, 0x2c8001ad, 0x00b10620, 0x00000000 }, { 0x00800001, 0x2ca001ad, 0x00b10640, 0x00000000 }, { 0x00800001, 0x2cc001ad, 0x00b10660, 0x00000000 }, { 0x00800001, 0x2ce001ad, 0x00b10680, 0x00000000 }, { 0x00800001, 0x2d0001ad, 0x00b106a0, 0x00000000 }, { 0x00800001, 0x2d2001ad, 0x00b106c0, 0x00000000 }, { 0x00800001, 0x2d4001ad, 0x00b106e0, 0x00000000 }, { 0x00800001, 0x2d6001ad, 0x00b10700, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x2a8001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2aa001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ac001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ae001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b0001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b2001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b4001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b6001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00100010 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x2a9001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ab001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ad001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2af001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b1001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b3001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b5001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b7001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00080008 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x2b8001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ba001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bc001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2be001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c0001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c2001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c4001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c6001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00040004 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00600001, 0x2b9001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bb001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bd001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bf001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c1001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c3001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c5001ed, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c7001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2c8001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ca001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2cc001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ce001ed, 0x00000000, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a4c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800001, 0x2d0001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d2001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d4001ed, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d6001ed, 0x00000000, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000ce }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000092 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x00a02008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x00a02008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x00a02008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x00a02008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x00a02008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x00a02008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x00a02008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x00a02008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000a2 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000006c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20000d3c, 0x00218000, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000042 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x00800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x00800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x00800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x00800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x00800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x00800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x00800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x00800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x00800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x00800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x00800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x00800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x00800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x00800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x00800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x00800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00a02001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00a02001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00a02001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00a02001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00a02001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00a02001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00a02001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00a02001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210410, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a009 }, { 0x00a02001, 0x29400229, 0x00ad0440, 0x00000000 }, { 0x00a02001, 0x29800229, 0x00ad0480, 0x00000000 }, { 0x00a02001, 0x29c00229, 0x00ad0580, 0x00000000 }, { 0x00a02001, 0x2a000229, 0x00ad05c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000082 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005a }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600040, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600040, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600040, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600040, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0501 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0521 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0541 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0561 }, { 0x00600040, 0x24004529, 0x008d0400, 0x008d0521 }, { 0x00600040, 0x24204529, 0x008d0420, 0x008d0541 }, { 0x00600040, 0x24404529, 0x008d0440, 0x008d0561 }, { 0x00600040, 0x24604529, 0x008d0460, 0x008d0581 }, { 0x00600040, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600040, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600040, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600040, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05a1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05c1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d05e1 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0601 }, { 0x00600040, 0x24804529, 0x008d0480, 0x008d05c1 }, { 0x00600040, 0x24a04529, 0x008d04a0, 0x008d05e1 }, { 0x00600040, 0x24c04529, 0x008d04c0, 0x008d0601 }, { 0x00600040, 0x24e04529, 0x008d04e0, 0x008d0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000072 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0501 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0521 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0541 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0561 }, { 0x00600042, 0x24804629, 0x008d0580, 0x008d0581 }, { 0x00600042, 0x24a04629, 0x008d05a0, 0x008d05a1 }, { 0x00600042, 0x24c04629, 0x008d05c0, 0x008d05c1 }, { 0x00600042, 0x24e04629, 0x008d05e0, 0x008d05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000050 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00000002 }, { 0x01000005, 0x20002d3c, 0x00218000, 0x00020002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000e }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00600042, 0x24004629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x24204629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x24404629, 0x008d0540, 0x008d0560 }, { 0x00600042, 0x24604629, 0x008d0560, 0x008d0580 }, { 0x00600042, 0x24804629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x24a04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x24c04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x24e04629, 0x008d0600, 0x008d0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x02000005, 0x20002d3c, 0x00210e70, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a006 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000004 }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0248a009 }, { 0x00802001, 0x24000229, 0x008d0500, 0x00000000 }, { 0x00802001, 0x24400229, 0x008d0540, 0x00000000 }, { 0x00802001, 0x24800229, 0x008d0600, 0x00000000 }, { 0x00802001, 0x24c00229, 0x008d0640, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00200001, 0x23e00021, 0x00450a40, 0x00000000 }, { 0x02000005, 0x20002e3c, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x80a02040, 0x474045b1, 0x00b10a80, 0x00b20740 }, { 0x80a02040, 0x478045b1, 0x00b10ac0, 0x00b20780 }, { 0x80a02040, 0x47c045b1, 0x00b10b00, 0x00b207c0 }, { 0x80a02040, 0x480045b1, 0x00b10b40, 0x00b20800 }, { 0x80a02040, 0x484045b1, 0x00b10b80, 0x00b20840 }, { 0x80a02040, 0x488045b1, 0x00b10bc0, 0x00b20880 }, { 0x80a02040, 0x48c045b1, 0x00b10c00, 0x00b208c0 }, { 0x80a02040, 0x490045b1, 0x00b10c40, 0x00b20900 }, { 0x80a02040, 0x494045b1, 0x00b10c80, 0x00b20940 }, { 0x80a02040, 0x498045b1, 0x00b10cc0, 0x00b20980 }, { 0x80a02040, 0x49c045b1, 0x00b10d00, 0x00b209c0 }, { 0x80a02040, 0x4a0045b1, 0x00b10d40, 0x00b20a00 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x80800040, 0x474045b1, 0x00b10a80, 0x00b20740 }, { 0x80800040, 0x476045b1, 0x00b10b80, 0x00b20760 }, { 0x80800040, 0x478045b1, 0x00b10aa0, 0x00b20780 }, { 0x80800040, 0x47a045b1, 0x00b10ba0, 0x00b207a0 }, { 0x80800040, 0x47c045b1, 0x00b10ac0, 0x00b207c0 }, { 0x80800040, 0x47e045b1, 0x00b10bc0, 0x00b207e0 }, { 0x80800040, 0x480045b1, 0x00b10ae0, 0x00b20800 }, { 0x80800040, 0x482045b1, 0x00b10be0, 0x00b20820 }, { 0x80800040, 0x484045b1, 0x00b10b00, 0x00b20840 }, { 0x80800040, 0x486045b1, 0x00b10c00, 0x00b20860 }, { 0x80800040, 0x488045b1, 0x00b10b20, 0x00b20880 }, { 0x80800040, 0x48a045b1, 0x00b10c20, 0x00b208a0 }, { 0x80800040, 0x48c045b1, 0x00b10b40, 0x00b208c0 }, { 0x80800040, 0x48e045b1, 0x00b10c40, 0x00b208e0 }, { 0x80800040, 0x490045b1, 0x00b10b60, 0x00b20900 }, { 0x80800040, 0x492045b1, 0x00b10c60, 0x00b20920 }, { 0x00800040, 0x2c8045ad, 0x00b10c80, 0x00b20940 }, { 0x00800040, 0x2ca045ad, 0x00b10ca0, 0x00b20960 }, { 0x00800040, 0x2cc045ad, 0x00b10cc0, 0x00b20980 }, { 0x00800040, 0x2ce045ad, 0x00b10ce0, 0x00b209a0 }, { 0x00800040, 0x2d0045ad, 0x00b10d00, 0x00b209c0 }, { 0x00800040, 0x2d2045ad, 0x00b10d20, 0x00b209e0 }, { 0x00800040, 0x2d4045ad, 0x00b10d40, 0x00b20a00 }, { 0x00800040, 0x2d6045ad, 0x00b10d60, 0x00b20a20 }, { 0x80800001, 0x494001b1, 0x00b10c80, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10ca0, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10cc0, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b10ce0, 0x00000000 }, { 0x80800001, 0x49c001b1, 0x00b10d00, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b10d20, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10d40, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10d60, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_field_uv.g4i000066400000000000000000000033501267532330400267050ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and.z (1) null mv1<1,1,1>UW 2UW {align1}; (f0) jmpi L1; and.z (1) null mv2<1,1,1>UW 2UW {align1}; (f0) jmpi L2; include(`read_field_x1y1_uv.g4i') jmpi L5; L2: include(`read_field_x1y0_uv.g4i') jmpi L5; L1: and.z (1) null mv2<1,1,1>UW 2UW {align1}; (f0) jmpi L4; include(`read_field_x0y1_uv.g4i') jmpi L5; L4: include(`read_field_x0y0_uv.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_field_uv_igd.g4i000066400000000000000000000035561267532330400275400ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng */ and.z (1) null g[a0.0]<1,1,1>UW 2UW {align1}; (f0) jmpi L1; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 2UW {align1}; (f0) jmpi L2; include(`read_field_x1y1_uv_igd.g4i') jmpi L5; L2: include(`read_field_x1y0_uv_igd.g4i') jmpi L5; L1: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 2UW {align1}; (f0) jmpi L4; include(`read_field_x0y1_uv_igd.g4i') jmpi L5; L4: include(`read_field_x0y0_uv_igd.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_field_y.g4i000066400000000000000000000032031267532330400265200ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and.z (1) null mv1<1,1,1>UW 1UW {align1}; (f0) jmpi L1; and.z (1) null mv2<1,1,1>UW 1UW {align1}; (f0) jmpi L2; include(`read_field_x1y1_y.g4i') jmpi L5; L2: include(`read_field_x1y0_y.g4i') jmpi L5; L1: and.z (1) null mv2<1,1,1>UW 1UW {align1}; (f0) jmpi L4; include(`read_field_x0y1_y.g4i') jmpi L5; L4: include(`read_field_x0y0_y.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_field_y_igd.g4i000066400000000000000000000033731267532330400273530ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng */ and.z (1) null g[a0.0]<1,1,1>UW 1UW {align1}; (f0) jmpi L1; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 1UW {align1}; (f0) jmpi L2; include(`read_field_x1y1_y_igd.g4i') jmpi L5; L2: include(`read_field_x1y0_y_igd.g4i') jmpi L5; L1: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 1UW {align1}; (f0) jmpi L4; include(`read_field_x0y1_y_igd.g4i') jmpi L5; L4: include(`read_field_x0y0_y_igd.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_frame_uv.g4i000066400000000000000000000024771267532330400267250ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng */ include(`read_frame_x0y0_uv.g4i') xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_frame_uv_igd.g4i000066400000000000000000000025051267532330400275400ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng */ include(`read_frame_x0y0_uv_igd.g4i') xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_frame_y.g4i000066400000000000000000000034141267532330400265330ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai */ /* if (motion_vect.x & 1) { * if (motion_vect.y & 1) * half_pixel in x and y; * else * half_pixel in x; * } else { * if (motion_vect.y & 1) * half_pixel y; * else * full_pixel_read; * } */ and.z (1) null mv1<1,1,1>UW 1UD {align1}; (f0) jmpi LL1; and.z (1) null mv2<1,1,1>UW 1UD {align1}; (f0) jmpi LL2; include(`read_frame_x1y1_y.g4i') jmpi LL5; LL2: include(`read_frame_x1y0_y.g4i') jmpi LL5; LL1: and.z (1) null mv2<1,1,1>UW 1UD {align1}; (f0) jmpi LL4; include(`read_frame_x0y1_y.g4i') jmpi LL5; LL4: include(`read_frame_x0y0_y.g4i') LL5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/motion_frame_y_igd.g4i000066400000000000000000000036111267532330400273550ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai */ /* if (motion_vect.x & 1) { * if (motion_vect.y & 1) * half_pixel in x and y; * else * half_pixel in x; * } else { * if (motion_vect.y & 1) * half_pixel y; * else * full_pixel_read; * } */ and.z (1) null g[a0.0]<1,1,1>UW 1UD {align1}; (f0) jmpi LL1; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 1UD {align1}; (f0) jmpi LL2; include(`read_frame_x1y1_y_igd.g4i') jmpi LL5; LL2: include(`read_frame_x1y0_y_igd.g4i') jmpi LL5; LL1: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x2UD {align1}; and.z (1) null g[a0.0]<1,1,1>UW 1UD {align1}; (f0) jmpi LL4; include(`read_frame_x0y1_y_igd.g4i') jmpi LL5; LL4: include(`read_frame_x0y0_y_igd.g4i') LL5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/null.g4a000066400000000000000000000045331267532330400244710ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * */ mov (8) g3.0<1>UD g1.0<8,8,1>UD {align1}; mov (16) g8.0<1>UD 0xFFFFFFFFUD {align1 compr}; mov(1) g1.8<1>UD 0x0070007UD { align1 }; mov (16) m1<1>UD g8.0<8,8,1>UD {align1 compr}; /*Write 8x8 block to (x,y)*/ send (16) 0 acc0<1>UW g1<8,8,1>UW write(0, 0, 2, 0) mlen 3 rlen 0 { align1 }; add (1) g1.0<1>UD g3.0<1,1,1>UD 0x8UD {align1}; /*Write 8x8 block to (x+8,y)*/ send (16) 0 acc0<1>UW g1<8,8,1>UW write(0, 0, 2, 0) mlen 3 rlen 0 { align1 }; add (1) g1.4<1>UD g3.4<1,1,1>UD 0x8UD {align1}; /*Write 8x8 block to (x+8,y+8)*/ send (16) 0 acc0<1>UW g1<8,8,1>UW write(0, 0, 2, 0) mlen 3 rlen 0 { align1 }; mov (1) g1.0<1>UD g3.0<1,1,1>UD {align1}; /*Write 8x8 block to (x,y+8)*/ send (16) 0 acc0<1>UW g1<8,8,1>UW write(0, 0, 2, 0) mlen 3 rlen 0 { align1 }; /*Fill U buffer & V buffer with 0x7F*/ mov (16) m1<1>UD 0x7f7f7f7fUD {align1 compr}; shr (1) g1.0<1>UD g3.0<1,1,1>UD 1D {align1}; shr (1) g1.4<1>UD g3.4<1,1,1>UD 1D {align1}; send (16) 0 acc0<1>UW g1<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g1<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/null.g4b000066400000000000000000000016471267532330400244750ustar00rootroot00000000000000 { 0x00600001, 0x20600021, 0x008d0020, 0x00000000 }, { 0x00802001, 0x21000061, 0x00000000, 0xffffffff }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00802001, 0x20200022, 0x008d0100, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302000 }, { 0x00000040, 0x20200c21, 0x00210060, 0x00000008 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302000 }, { 0x00000040, 0x20240c21, 0x00210064, 0x00000008 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302000 }, { 0x00000001, 0x20200021, 0x00210060, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302000 }, { 0x00802001, 0x20200062, 0x00000000, 0x7f7f7f7f }, { 0x00000008, 0x20201c21, 0x00210060, 0x00000001 }, { 0x00000008, 0x20241c21, 0x00210064, 0x00000001 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0020, 0x05302001 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/null.g4b.gen5000066400000000000000000000016471267532330400253320ustar00rootroot00000000000000 { 0x00600001, 0x20600021, 0x008d0020, 0x00000000 }, { 0x00802001, 0x21000061, 0x00000000, 0xffffffff }, { 0x00000001, 0x20280061, 0x00000000, 0x00070007 }, { 0x00802001, 0x20200022, 0x008d0100, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082000 }, { 0x00000040, 0x20200c21, 0x00210060, 0x00000008 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082000 }, { 0x00000040, 0x20240c21, 0x00210064, 0x00000008 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082000 }, { 0x00000001, 0x20200021, 0x00210060, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082000 }, { 0x00802001, 0x20200062, 0x00000000, 0x7f7f7f7f }, { 0x00000008, 0x20201c21, 0x00210060, 0x00000001 }, { 0x00000008, 0x20241c21, 0x00210064, 0x00000001 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082002 }, { 0x00800031, 0x24001d28, 0x508d0020, 0x06082001 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y0_uv.g4i000066400000000000000000000061411267532330400271740ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x7000FUD {align1}; // 8*16/32=4 send (16) 0 g86.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g91.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; mov (16) g78.0<1>UW g86.0<16,8,1>UB {align1}; mov (16) g79.0<1>UW g87.0<16,8,1>UB {align1}; mov (16) g80.0<1>UW g88.0<16,8,1>UB {align1}; mov (16) g81.0<1>UW g89.0<16,8,1>UB {align1}; mov (16) g82.0<1>UW g91.0<16,8,1>UB {align1}; mov (16) g83.0<1>UW g92.0<16,8,1>UB {align1}; mov (16) g84.0<1>UW g93.0<16,8,1>UB {align1}; mov (16) g85.0<1>UW g94.0<16,8,1>UB {align1}; jmpi out; mov (16) g78.0<1>UW g86.1<16,8,1>UB {align1}; mov (16) g79.0<1>UW g87.1<16,8,1>UB {align1}; mov (16) g80.0<1>UW g88.1<16,8,1>UB {align1}; mov (16) g81.0<1>UW g89.1<16,8,1>UB {align1}; mov (16) g82.0<1>UW g91.1<16,8,1>UB {align1}; mov (16) g83.0<1>UW g92.1<16,8,1>UB {align1}; mov (16) g84.0<1>UW g93.1<16,8,1>UB {align1}; mov (16) g85.0<1>UW g94.1<16,8,1>UB {align1}; jmpi out; mov (16) g78.0<1>UW g86.2<16,8,1>UB {align1}; mov (16) g79.0<1>UW g87.2<16,8,1>UB {align1}; mov (16) g80.0<1>UW g88.2<16,8,1>UB {align1}; mov (16) g81.0<1>UW g89.2<16,8,1>UB {align1}; mov (16) g82.0<1>UW g91.2<16,8,1>UB {align1}; mov (16) g83.0<1>UW g92.2<16,8,1>UB {align1}; mov (16) g84.0<1>UW g93.2<16,8,1>UB {align1}; mov (16) g85.0<1>UW g94.2<16,8,1>UB {align1}; jmpi out; mov (16) g78.0<1>UW g86.3<16,8,1>UB {align1}; mov (16) g79.0<1>UW g87.3<16,8,1>UB {align1}; mov (16) g80.0<1>UW g88.3<16,8,1>UB {align1}; mov (16) g81.0<1>UW g89.3<16,8,1>UB {align1}; mov (16) g82.0<1>UW g91.3<16,8,1>UB {align1}; mov (16) g83.0<1>UW g92.3<16,8,1>UB {align1}; mov (16) g84.0<1>UW g93.3<16,8,1>UB {align1}; mov (16) g85.0<1>UW g94.3<16,8,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y0_uv_igd.g4i000066400000000000000000000017221267532330400300170ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(5,2,0,2) mlen 1 rlen 4 {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(6,2,0,2) mlen 1 rlen 4 {align1}; jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(8,2,0,2) mlen 1 rlen 4 {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(9,2,0,2) mlen 1 rlen 4 {align1}; put_data: mov (16) g32.0<1>UW g40.0<8,8,1>UB {align1 compr}; mov (16) g34.0<1>UW g42.0<8,8,1>UB {align1 compr}; mov (16) g36.0<1>UW g48.0<8,8,1>UB {align1 compr}; mov (16) g38.0<1>UW g50.0<8,8,1>UB {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y0_y.g4i000066400000000000000000000071251267532330400270150ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g78.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g80.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g82.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g84.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g86.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; mov (16) g96.0<1>UW g78.0<16,16,1>UB {align1}; mov (16) g97.0<1>UW g80.0<16,16,1>UB {align1}; mov (16) g98.0<1>UW g82.0<16,16,1>UB {align1}; mov (16) g99.0<1>UW g84.0<16,16,1>UB {align1}; mov (16) g100.0<1>UW g86.0<16,16,1>UB {align1}; mov (16) g101.0<1>UW g88.0<16,16,1>UB {align1}; mov (16) g102.0<1>UW g90.0<16,16,1>UB {align1}; mov (16) g103.0<1>UW g92.0<16,16,1>UB {align1}; jmpi out; mov (16) g96.0<1>UW g78.1<16,16,1>UB {align1}; mov (16) g97.0<1>UW g80.1<16,16,1>UB {align1}; mov (16) g98.0<1>UW g82.1<16,16,1>UB {align1}; mov (16) g99.0<1>UW g84.1<16,16,1>UB {align1}; mov (16) g100.0<1>UW g86.1<16,16,1>UB {align1}; mov (16) g101.0<1>UW g88.1<16,16,1>UB {align1}; mov (16) g102.0<1>UW g90.1<16,16,1>UB {align1}; mov (16) g103.0<1>UW g92.1<16,16,1>UB {align1}; jmpi out; mov (16) g96.0<1>UW g78.2<16,16,1>UB {align1}; mov (16) g97.0<1>UW g80.2<16,16,1>UB {align1}; mov (16) g98.0<1>UW g82.2<16,16,1>UB {align1}; mov (16) g99.0<1>UW g84.2<16,16,1>UB {align1}; mov (16) g100.0<1>UW g86.2<16,16,1>UB {align1}; mov (16) g101.0<1>UW g88.2<16,16,1>UB {align1}; mov (16) g102.0<1>UW g90.2<16,16,1>UB {align1}; mov (16) g103.0<1>UW g92.2<16,16,1>UB {align1}; jmpi out; mov (16) g96.0<1>UW g78.3<16,16,1>UB {align1}; mov (16) g97.0<1>UW g80.3<16,16,1>UB {align1}; mov (16) g98.0<1>UW g82.3<16,16,1>UB {align1}; mov (16) g99.0<1>UW g84.3<16,16,1>UB {align1}; mov (16) g100.0<1>UW g86.3<16,16,1>UB {align1}; mov (16) g101.0<1>UW g88.3<16,16,1>UB {align1}; mov (16) g102.0<1>UW g90.3<16,16,1>UB {align1}; mov (16) g103.0<1>UW g92.3<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y0_y_igd.g4i000066400000000000000000000023411267532330400276330ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g84~g107:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07001FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; put_data: mov (16) g32.0<1>UW g40.0<16,16,1>UB {align1}; mov (16) g33.0<1>UW g42.0<16,16,1>UB {align1}; mov (16) g34.0<1>UW g44.0<16,16,1>UB {align1}; mov (16) g35.0<1>UW g46.0<16,16,1>UB {align1}; mov (16) g36.0<1>UW g48.0<16,16,1>UB {align1}; mov (16) g37.0<1>UW g50.0<16,16,1>UB {align1}; mov (16) g38.0<1>UW g52.0<16,16,1>UB {align1}; mov (16) g39.0<1>UW g54.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y1_uv.g4i000066400000000000000000000076651267532330400272110ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x07000FUD {align1}; // 8*16/32=4 send (16) 0 g86.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g91.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; send (16) 0 g90.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g95.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 1 {align1}; and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g78.0<1>UW g86.0<16,8,1>UB g87.0<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.0<16,8,1>UB g88.0<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.0<16,8,1>UB g89.0<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.0<16,8,1>UB g90.0<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.0<16,8,1>UB g92.0<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.0<16,8,1>UB g93.0<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.0<16,8,1>UB g94.0<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.1<16,8,1>UB g87.1<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.1<16,8,1>UB g88.1<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.1<16,8,1>UB g89.1<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.1<16,8,1>UB g90.1<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.1<16,8,1>UB g92.1<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.1<16,8,1>UB g93.1<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.1<16,8,1>UB g94.1<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.1<16,8,1>UB g95.1<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.2<16,8,1>UB g87.2<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.2<16,8,1>UB g88.2<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.2<16,8,1>UB g89.2<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.2<16,8,1>UB g90.2<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.2<16,8,1>UB g92.2<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.2<16,8,1>UB g93.2<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.2<16,8,1>UB g94.2<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.2<16,8,1>UB g95.2<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.3<16,8,1>UB g86.3<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.3<16,8,1>UB g87.3<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.3<16,8,1>UB g88.3<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.3<16,8,1>UB g89.3<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.3<16,8,1>UB g91.3<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.3<16,8,1>UB g92.3<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.3<16,8,1>UB g93.3<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.3<16,8,1>UB g94.3<16,8,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y1_uv_igd.g4i000066400000000000000000000033471267532330400300250ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 1 {align1};//V jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 1 {align1};//V put_data: avg (8) g32.0<1>UW g40.0<8,8,1>UB g41.0<8,8,1>UB {align1}; avg (8) g33.0<1>UW g41.0<8,8,1>UB g42.0<8,8,1>UB {align1}; avg (8) g34.0<1>UW g42.0<8,8,1>UB g43.0<8,8,1>UB {align1}; avg (8) g35.0<1>UW g43.0<8,8,1>UB g44.0<8,8,1>UB {align1}; avg (8) g36.0<1>UW g45.0<8,8,1>UB g46.0<8,8,1>UB {align1}; avg (8) g37.0<1>UW g46.0<8,8,1>UB g47.0<8,8,1>UB {align1}; avg (8) g38.0<1>UW g47.0<8,8,1>UB g48.0<8,8,1>UB {align1}; avg (8) g39.0<1>UW g48.0<8,8,1>UB g49.0<8,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y1_y.g4i000066400000000000000000000106351267532330400270160ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g78.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g80.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g82.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g84.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g86.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g94.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g96.0<1>UW g78.0<16,16,1>UB g80.0<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.0<16,16,1>UB g82.0<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.0<16,16,1>UB g84.0<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.0<16,16,1>UB g86.0<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.0<16,16,1>UB g88.0<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.0<16,16,1>UB g90.0<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.0<16,16,1>UB g92.0<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.0<16,16,1>UB g94.0<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.1<16,16,1>UB g80.1<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.1<16,16,1>UB g82.1<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.1<16,16,1>UB g84.1<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.1<16,16,1>UB g86.1<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.1<16,16,1>UB g88.1<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.1<16,16,1>UB g90.1<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.1<16,16,1>UB g92.1<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.1<16,16,1>UB g94.1<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.2<16,16,1>UB g80.2<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.2<16,16,1>UB g82.2<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.2<16,16,1>UB g84.2<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.2<16,16,1>UB g86.2<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.2<16,16,1>UB g88.2<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.2<16,16,1>UB g90.2<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.2<16,16,1>UB g92.2<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.2<16,16,1>UB g94.2<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.3<16,16,1>UB g80.3<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.3<16,16,1>UB g82.3<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.3<16,16,1>UB g84.3<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.3<16,16,1>UB g86.3<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.3<16,16,1>UB g88.3<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.3<16,16,1>UB g90.3<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.3<16,16,1>UB g92.3<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.3<16,16,1>UB g94.3<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x0y1_y_igd.g4i000066400000000000000000000032561267532330400276420ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07001FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 1 {align1}; jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 1 {align1}; put_data: avg (16) g32.0<1>UW g40.0<16,16,1>UB g42.0<16,16,1>UB {align1}; avg (16) g33.0<1>UW g42.0<16,16,1>UB g44.0<16,16,1>UB {align1}; avg (16) g34.0<1>UW g44.0<16,16,1>UB g46.0<16,16,1>UB {align1}; avg (16) g35.0<1>UW g46.0<16,16,1>UB g48.0<16,16,1>UB {align1}; avg (16) g36.0<1>UW g48.0<16,16,1>UB g50.0<16,16,1>UB {align1}; avg (16) g37.0<1>UW g50.0<16,16,1>UB g52.0<16,16,1>UB {align1}; avg (16) g38.0<1>UW g52.0<16,16,1>UB g54.0<16,16,1>UB {align1}; avg (16) g39.0<1>UW g54.0<16,16,1>UB g56.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y0_uv.g4i000066400000000000000000000073431267532330400272020ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x07000FUD {align1}; // 8*16/32=4 send (16) 0 g86.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g91.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g78.0<1>UW g86.0<16,8,1>UB g86.1<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.0<16,8,1>UB g87.1<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.0<16,8,1>UB g88.1<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.0<16,8,1>UB g89.1<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.0<16,8,1>UB g91.1<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.0<16,8,1>UB g92.1<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.0<16,8,1>UB g93.1<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.0<16,8,1>UB g94.1<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.1<16,8,1>UB g86.2<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.1<16,8,1>UB g87.2<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.1<16,8,1>UB g88.2<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.1<16,8,1>UB g89.2<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.1<16,8,1>UB g91.2<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.1<16,8,1>UB g92.2<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.1<16,8,1>UB g93.2<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.1<16,8,1>UB g94.2<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.2<16,8,1>UB g86.3<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.2<16,8,1>UB g87.3<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.2<16,8,1>UB g88.3<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.2<16,8,1>UB g89.3<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.2<16,8,1>UB g91.3<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.2<16,8,1>UB g92.3<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.2<16,8,1>UB g93.3<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.2<16,8,1>UB g94.3<16,8,1>UB {align1}; jmpi out; avg.sat (16) g78.0<1>UW g86.3<16,8,1>UB g86.4<16,8,1>UB {align1}; avg.sat (16) g79.0<1>UW g87.3<16,8,1>UB g87.4<16,8,1>UB {align1}; avg.sat (16) g80.0<1>UW g88.3<16,8,1>UB g88.4<16,8,1>UB {align1}; avg.sat (16) g81.0<1>UW g89.3<16,8,1>UB g89.4<16,8,1>UB {align1}; avg.sat (16) g82.0<1>UW g91.3<16,8,1>UB g91.4<16,8,1>UB {align1}; avg.sat (16) g83.0<1>UW g92.3<16,8,1>UB g92.4<16,8,1>UB {align1}; avg.sat (16) g84.0<1>UW g93.3<16,8,1>UB g93.4<16,8,1>UB {align1}; avg.sat (16) g85.0<1>UW g94.3<16,8,1>UB g94.4<16,8,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y0_uv_igd.g4i000066400000000000000000000024021267532330400300140ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; // 8*16/32=4 and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g44.0<1>UW g115<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 4 {align1};//V jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g44.0<1>UW g115<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 4 {align1};//V put_data: avg (8) g32.0<1>UW g40.0<8,8,1>UB g40.1<8,8,1>UB {align1}; avg (8) g33.0<1>UW g41.0<8,8,1>UB g41.1<8,8,1>UB {align1}; avg (8) g34.0<1>UW g42.0<8,8,1>UB g42.1<8,8,1>UB {align1}; avg (8) g35.0<1>UW g43.0<8,8,1>UB g43.1<8,8,1>UB {align1}; avg (8) g36.0<1>UW g44.0<8,8,1>UB g44.1<8,8,1>UB {align1}; avg (8) g37.0<1>UW g45.0<8,8,1>UB g45.1<8,8,1>UB {align1}; avg (8) g38.0<1>UW g46.0<8,8,1>UB g46.1<8,8,1>UB {align1}; avg (8) g39.0<1>UW g47.0<8,8,1>UB g47.1<8,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y0_y.g4i000066400000000000000000000103651267532330400270160ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g78.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g80.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g82.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g84.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g86.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g96.0<1>UW g78.0<16,16,1>UB g78.1<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.0<16,16,1>UB g80.1<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.0<16,16,1>UB g82.1<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.0<16,16,1>UB g84.1<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.0<16,16,1>UB g86.1<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.0<16,16,1>UB g88.1<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.0<16,16,1>UB g90.1<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.0<16,16,1>UB g92.1<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.1<16,16,1>UB g78.2<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.1<16,16,1>UB g80.2<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.1<16,16,1>UB g82.2<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.1<16,16,1>UB g84.2<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.1<16,16,1>UB g86.2<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.1<16,16,1>UB g88.2<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.1<16,16,1>UB g90.2<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.1<16,16,1>UB g92.2<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.2<16,16,1>UB g78.3<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.2<16,16,1>UB g80.3<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.2<16,16,1>UB g82.3<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.2<16,16,1>UB g84.3<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.2<16,16,1>UB g86.3<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.2<16,16,1>UB g88.3<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.2<16,16,1>UB g90.3<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.2<16,16,1>UB g92.3<16,16,1>UB {align1}; jmpi out; avg.sat (16) g96.0<1>UW g78.3<16,16,1>UB g78.4<16,16,1>UB {align1}; avg.sat (16) g97.0<1>UW g80.3<16,16,1>UB g80.4<16,16,1>UB {align1}; avg.sat (16) g98.0<1>UW g82.3<16,16,1>UB g82.4<16,16,1>UB {align1}; avg.sat (16) g99.0<1>UW g84.3<16,16,1>UB g84.4<16,16,1>UB {align1}; avg.sat (16) g100.0<1>UW g86.3<16,16,1>UB g86.4<16,16,1>UB {align1}; avg.sat (16) g101.0<1>UW g88.3<16,16,1>UB g88.4<16,16,1>UB {align1}; avg.sat (16) g102.0<1>UW g90.3<16,16,1>UB g90.4<16,16,1>UB {align1}; avg.sat (16) g103.0<1>UW g92.3<16,16,1>UB g92.4<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y0_y_igd.g4i000066400000000000000000000025511267532330400276370ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07001FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; put_data: avg (16) g32.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; avg (16) g33.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; avg (16) g34.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; avg (16) g35.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; avg (16) g36.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; avg (16) g37.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; avg (16) g38.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; avg (16) g39.0<1>UW g54.0<16,16,1>UB g54.1<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y1_uv.g4i000066400000000000000000000203051267532330400271740ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x07000FUD {align1}; send (16) 0 g86.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g91.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 25UD {align1}; mov (1) g115.8<1>UD 0x01000FUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g90.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g95.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 1 {align1}; jmpi g2.24<1,1,1>D; //U add (16) g78.0<1>UW g86.0<16,8,1>UB g87.0<16,8,1>UB {align1}; add (16) g79.0<1>UW g87.0<16,8,1>UB g88.0<16,8,1>UB {align1}; add (16) g80.0<1>UW g88.0<16,8,1>UB g89.0<16,8,1>UB {align1}; add (16) g81.0<1>UW g89.0<16,8,1>UB g90.0<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g86.1<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g87.1<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g88.1<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g89.1<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g87.1<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g88.1<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g89.1<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g90.1<16,8,1>UB {align1}; //V add (16) g82.0<1>UW g91.0<16,8,1>UB g92.0<16,8,1>UB {align1}; add (16) g83.0<1>UW g92.0<16,8,1>UB g93.0<16,8,1>UB {align1}; add (16) g84.0<1>UW g93.0<16,8,1>UB g94.0<16,8,1>UB {align1}; add (16) g85.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g91.1<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g92.1<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g93.1<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g94.1<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g92.1<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g93.1<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g94.1<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g95.1<16,8,1>UB {align1}; jmpi out; //U add (16) g78.0<1>UW g86.1<16,8,1>UB g87.1<16,8,1>UB {align1}; add (16) g79.0<1>UW g87.1<16,8,1>UB g88.1<16,8,1>UB {align1}; add (16) g80.0<1>UW g88.1<16,8,1>UB g89.1<16,8,1>UB {align1}; add (16) g81.0<1>UW g89.1<16,8,1>UB g90.1<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g86.2<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g87.2<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g88.2<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g89.2<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g87.2<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g88.2<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g89.2<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g90.2<16,8,1>UB {align1}; //V add (16) g82.0<1>UW g91.1<16,8,1>UB g92.1<16,8,1>UB {align1}; add (16) g83.0<1>UW g92.1<16,8,1>UB g93.1<16,8,1>UB {align1}; add (16) g84.0<1>UW g93.1<16,8,1>UB g94.1<16,8,1>UB {align1}; add (16) g85.0<1>UW g94.1<16,8,1>UB g95.1<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g91.2<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g92.2<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g93.2<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g94.2<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g92.2<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g93.2<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g94.2<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g95.2<16,8,1>UB {align1}; jmpi out; //U add (16) g78.0<1>UW g86.2<16,8,1>UB g87.2<16,8,1>UB {align1}; add (16) g79.0<1>UW g87.2<16,8,1>UB g88.2<16,8,1>UB {align1}; add (16) g80.0<1>UW g88.2<16,8,1>UB g89.2<16,8,1>UB {align1}; add (16) g81.0<1>UW g89.2<16,8,1>UB g90.2<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g86.3<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g87.3<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g88.3<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g89.3<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g87.3<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g88.3<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g89.3<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g90.3<16,8,1>UB {align1}; //V add (16) g82.0<1>UW g91.2<16,8,1>UB g92.2<16,8,1>UB {align1}; add (16) g83.0<1>UW g92.2<16,8,1>UB g93.2<16,8,1>UB {align1}; add (16) g84.0<1>UW g93.2<16,8,1>UB g94.2<16,8,1>UB {align1}; add (16) g85.0<1>UW g94.2<16,8,1>UB g95.2<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g91.3<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g92.3<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g93.3<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g94.3<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g92.3<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g93.3<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g94.3<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g95.3<16,8,1>UB {align1}; jmpi out; //U add (16) g78.0<1>UW g86.3<16,8,1>UB g87.3<16,8,1>UB {align1}; add (16) g79.0<1>UW g87.3<16,8,1>UB g88.3<16,8,1>UB {align1}; add (16) g80.0<1>UW g88.3<16,8,1>UB g89.3<16,8,1>UB {align1}; add (16) g81.0<1>UW g89.3<16,8,1>UB g90.3<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g86.4<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g87.4<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g88.4<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g89.4<16,8,1>UB {align1}; add (16) g78.0<1>UW g78.0<16,8,1>UW g87.4<16,8,1>UB {align1}; add (16) g79.0<1>UW g79.0<16,8,1>UW g88.4<16,8,1>UB {align1}; add (16) g80.0<1>UW g80.0<16,8,1>UW g89.4<16,8,1>UB {align1}; add (16) g81.0<1>UW g81.0<16,8,1>UW g90.4<16,8,1>UB {align1}; //V add (16) g82.0<1>UW g91.3<16,8,1>UB g92.3<16,8,1>UB {align1}; add (16) g83.0<1>UW g92.3<16,8,1>UB g93.3<16,8,1>UB {align1}; add (16) g84.0<1>UW g93.3<16,8,1>UB g94.3<16,8,1>UB {align1}; add (16) g85.0<1>UW g94.3<16,8,1>UB g95.3<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g91.4<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g92.4<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g93.4<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g94.4<16,8,1>UB {align1}; add (16) g82.0<1>UW g82.0<16,8,1>UW g92.4<16,8,1>UB {align1}; add (16) g83.0<1>UW g83.0<16,8,1>UW g93.4<16,8,1>UB {align1}; add (16) g84.0<1>UW g84.0<16,8,1>UW g94.4<16,8,1>UB {align1}; add (16) g85.0<1>UW g85.0<16,8,1>UW g95.4<16,8,1>UB {align1}; out: shr.sat (16) g78.0<1>UW g78.0<16,16,1>UW 2UW {align1}; shr.sat (16) g79.0<1>UW g79.0<16,16,1>UW 2UW {align1}; shr.sat (16) g80.0<1>UW g80.0<16,16,1>UW 2UW {align1}; shr.sat (16) g81.0<1>UW g81.0<16,16,1>UW 2UW {align1}; shr.sat (16) g82.0<1>UW g82.0<16,16,1>UW 2UW {align1}; shr.sat (16) g83.0<1>UW g83.0<16,16,1>UW 2UW {align1}; shr.sat (16) g84.0<1>UW g84.0<16,16,1>UW 2UW {align1}; shr.sat (16) g85.0<1>UW g85.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y1_uv_igd.g4i000066400000000000000000000056041267532330400300240ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 1 {align1};//V jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 1 {align1};//V put_data: //U add (8) g32.0<1>UW g40.0<8,8,1>UB g41.0<8,8,1>UB {align1}; add (8) g33.0<1>UW g41.0<8,8,1>UB g42.0<8,8,1>UB {align1}; add (8) g34.0<1>UW g42.0<8,8,1>UB g43.0<8,8,1>UB {align1}; add (8) g35.0<1>UW g43.0<8,8,1>UB g44.0<8,8,1>UB {align1}; add (8) g32.0<1>UW g32.0<8,8,1>UW g40.1<8,8,1>UB {align1}; add (8) g33.0<1>UW g33.0<8,8,1>UW g41.1<8,8,1>UB {align1}; add (8) g34.0<1>UW g34.0<8,8,1>UW g42.1<8,8,1>UB {align1}; add (8) g35.0<1>UW g35.0<8,8,1>UW g43.1<8,8,1>UB {align1}; add (8) g32.0<1>UW g32.0<8,8,1>UW g41.1<8,8,1>UB {align1}; add (8) g33.0<1>UW g33.0<8,8,1>UW g42.1<8,8,1>UB {align1}; add (8) g34.0<1>UW g34.0<8,8,1>UW g43.1<8,8,1>UB {align1}; add (8) g35.0<1>UW g35.0<8,8,1>UW g44.1<8,8,1>UB {align1}; //V add (8) g36.0<1>UW g45.0<8,8,1>UB g46.0<8,8,1>UB {align1}; add (8) g37.0<1>UW g46.0<8,8,1>UB g47.0<8,8,1>UB {align1}; add (8) g38.0<1>UW g47.0<8,8,1>UB g48.0<8,8,1>UB {align1}; add (8) g39.0<1>UW g48.0<8,8,1>UB g49.0<8,8,1>UB {align1}; add (8) g36.0<1>UW g36.0<8,8,1>UW g45.1<8,8,1>UB {align1}; add (8) g37.0<1>UW g37.0<8,8,1>UW g46.1<8,8,1>UB {align1}; add (8) g38.0<1>UW g38.0<8,8,1>UW g47.1<8,8,1>UB {align1}; add (8) g39.0<1>UW g39.0<8,8,1>UW g48.1<8,8,1>UB {align1}; add (8) g36.0<1>UW g36.0<8,8,1>UW g46.1<8,8,1>UB {align1}; add (8) g37.0<1>UW g37.0<8,8,1>UW g47.1<8,8,1>UB {align1}; add (8) g38.0<1>UW g38.0<8,8,1>UW g48.1<8,8,1>UB {align1}; add (8) g39.0<1>UW g39.0<8,8,1>UW g49.1<8,8,1>UB {align1}; shr (32) g32.0<1>UW g32.0<16,16,1>UW 2UW {align1 compr}; shr (32) g34.0<1>UW g34.0<16,16,1>UW 2UW {align1 compr}; shr (32) g36.0<1>UW g36.0<16,16,1>UW 2UW {align1 compr}; shr (32) g38.0<1>UW g38.0<16,16,1>UW 2UW {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y1_y.g4i000066400000000000000000000214061267532330400270150ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g78.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g80.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g82.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g84.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g86.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g94.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; and (1) g2.24<1>UD g115.0<1,1,1>UD 3UD {align1}; mul (1) g2.24<1>UD g2.24<1,1,1>UD 25UD {align1}; jmpi g2.24<1,1,1>D; add (16) g96.0<1>UW g78.0<16,16,1>UB g80.0<16,16,1>UB {align1}; add (16) g97.0<1>UW g80.0<16,16,1>UB g82.0<16,16,1>UB {align1}; add (16) g98.0<1>UW g82.0<16,16,1>UB g84.0<16,16,1>UB {align1}; add (16) g99.0<1>UW g84.0<16,16,1>UB g86.0<16,16,1>UB {align1}; add (16) g100.0<1>UW g86.0<16,16,1>UB g88.0<16,16,1>UB {align1}; add (16) g101.0<1>UW g88.0<16,16,1>UB g90.0<16,16,1>UB {align1}; add (16) g102.0<1>UW g90.0<16,16,1>UB g92.0<16,16,1>UB {align1}; add (16) g103.0<1>UW g92.0<16,16,1>UB g94.0<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g78.1<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g80.1<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g82.1<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g84.1<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g86.1<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g88.1<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g90.1<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g92.1<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g80.1<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g82.1<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g84.1<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g86.1<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g88.1<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g90.1<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g92.1<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g94.1<16,16,1>UB {align1}; jmpi out; add (16) g96.0<1>UW g78.1<16,16,1>UB g80.1<16,16,1>UB {align1}; add (16) g97.0<1>UW g80.1<16,16,1>UB g82.1<16,16,1>UB {align1}; add (16) g98.0<1>UW g82.1<16,16,1>UB g84.1<16,16,1>UB {align1}; add (16) g99.0<1>UW g84.1<16,16,1>UB g86.1<16,16,1>UB {align1}; add (16) g100.0<1>UW g86.1<16,16,1>UB g88.1<16,16,1>UB {align1}; add (16) g101.0<1>UW g88.1<16,16,1>UB g90.1<16,16,1>UB {align1}; add (16) g102.0<1>UW g90.1<16,16,1>UB g92.1<16,16,1>UB {align1}; add (16) g103.0<1>UW g92.1<16,16,1>UB g94.1<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g78.2<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g80.2<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g82.2<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g84.2<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g86.2<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g88.2<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g90.2<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g92.2<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g80.2<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g82.2<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g84.2<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g86.2<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g88.2<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g90.2<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g92.2<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g94.2<16,16,1>UB {align1}; jmpi out; add (16) g96.0<1>UW g78.2<16,16,1>UB g80.2<16,16,1>UB {align1}; add (16) g97.0<1>UW g80.2<16,16,1>UB g82.2<16,16,1>UB {align1}; add (16) g98.0<1>UW g82.2<16,16,1>UB g84.2<16,16,1>UB {align1}; add (16) g99.0<1>UW g84.2<16,16,1>UB g86.2<16,16,1>UB {align1}; add (16) g100.0<1>UW g86.2<16,16,1>UB g88.2<16,16,1>UB {align1}; add (16) g101.0<1>UW g88.2<16,16,1>UB g90.2<16,16,1>UB {align1}; add (16) g102.0<1>UW g90.2<16,16,1>UB g92.2<16,16,1>UB {align1}; add (16) g103.0<1>UW g92.2<16,16,1>UB g94.2<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g78.3<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g80.3<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g82.3<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g84.3<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g86.3<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g88.3<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g90.3<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g92.3<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g80.3<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g82.3<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g84.3<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g86.3<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g88.3<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g90.3<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g92.3<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g94.3<16,16,1>UB {align1}; jmpi out; add (16) g96.0<1>UW g78.3<16,16,1>UB g80.3<16,16,1>UB {align1}; add (16) g97.0<1>UW g80.3<16,16,1>UB g82.3<16,16,1>UB {align1}; add (16) g98.0<1>UW g82.3<16,16,1>UB g84.3<16,16,1>UB {align1}; add (16) g99.0<1>UW g84.3<16,16,1>UB g86.3<16,16,1>UB {align1}; add (16) g100.0<1>UW g86.3<16,16,1>UB g88.3<16,16,1>UB {align1}; add (16) g101.0<1>UW g88.3<16,16,1>UB g90.3<16,16,1>UB {align1}; add (16) g102.0<1>UW g90.3<16,16,1>UB g92.3<16,16,1>UB {align1}; add (16) g103.0<1>UW g92.3<16,16,1>UB g94.3<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g78.4<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g80.4<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g82.4<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g84.4<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g86.4<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g88.4<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g90.4<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g92.4<16,16,1>UB {align1}; add (16) g96.0<1>UW g96.0<16,16,1>UW g80.4<16,16,1>UB {align1}; add (16) g97.0<1>UW g97.0<16,16,1>UW g82.4<16,16,1>UB {align1}; add (16) g98.0<1>UW g98.0<16,16,1>UW g84.4<16,16,1>UB {align1}; add (16) g99.0<1>UW g99.0<16,16,1>UW g86.4<16,16,1>UB {align1}; add (16) g100.0<1>UW g100.0<16,16,1>UW g88.4<16,16,1>UB {align1}; add (16) g101.0<1>UW g101.0<16,16,1>UW g90.4<16,16,1>UB {align1}; add (16) g102.0<1>UW g102.0<16,16,1>UW g92.4<16,16,1>UB {align1}; add (16) g103.0<1>UW g103.0<16,16,1>UW g94.4<16,16,1>UB {align1}; out: shr (16) g96.0<1>UW g96.0<16,16,1>UW 2UW {align1}; shr (16) g97.0<1>UW g97.0<16,16,1>UW 2UW {align1}; shr (16) g98.0<1>UW g98.0<16,16,1>UW 2UW {align1}; shr (16) g99.0<1>UW g99.0<16,16,1>UW 2UW {align1}; shr (16) g100.0<1>UW g100.0<16,16,1>UW 2UW {align1}; shr (16) g101.0<1>UW g101.0<16,16,1>UW 2UW {align1}; shr (16) g102.0<1>UW g102.0<16,16,1>UW 2UW {align1}; shr (16) g103.0<1>UW g103.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_field_x1y1_y_igd.g4i000066400000000000000000000056241267532330400276440ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07001FUD {align1}; and.nz (1) null g115.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(4,2,0,2) mlen 1 rlen 1 {align1}; jmpi put_data; read_backward: send (16) 0 g40.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(7,2,0,2) mlen 1 rlen 1 {align1}; put_data: add (16) g32.0<1>UW g40.0<16,16,1>UB g42.0<16,16,1>UB {align1}; add (16) g33.0<1>UW g42.0<16,16,1>UB g44.0<16,16,1>UB {align1}; add (16) g34.0<1>UW g44.0<16,16,1>UB g46.0<16,16,1>UB {align1}; add (16) g35.0<1>UW g46.0<16,16,1>UB g48.0<16,16,1>UB {align1}; add (16) g36.0<1>UW g48.0<16,16,1>UB g50.0<16,16,1>UB {align1}; add (16) g37.0<1>UW g50.0<16,16,1>UB g52.0<16,16,1>UB {align1}; add (16) g38.0<1>UW g52.0<16,16,1>UB g54.0<16,16,1>UB {align1}; add (16) g39.0<1>UW g54.0<16,16,1>UB g56.0<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g40.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g54.1<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g54.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g56.1<16,16,1>UB {align1}; shr (32) g32.0<1>UW g32.0<16,16,1>UW 2UW {align1 compr}; shr (32) g34.0<1>UW g34.0<16,16,1>UW 2UW {align1 compr}; shr (32) g36.0<1>UW g36.0<16,16,1>UW 2UW {align1 compr}; shr (32) g38.0<1>UW g38.0<16,16,1>UW 2UW {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y0_uv.g4i000066400000000000000000000060531267532330400272050ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and (1) g2.24<1>UD g2.0<1,1,1>UD 0x3UD {align1}; send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 0x9UD {align1}; jmpi g2.24<1,1,1>D; mov (16) g44.0<1>UW g86.0<16,8,1>UB {align1}; mov (16) g45.0<1>UW g87.0<16,8,1>UB {align1}; mov (16) g46.0<1>UW g88.0<16,8,1>UB {align1}; mov (16) g47.0<1>UW g89.0<16,8,1>UB {align1}; mov (16) g48.0<1>UW g90.0<16,8,1>UB {align1}; mov (16) g49.0<1>UW g91.0<16,8,1>UB {align1}; mov (16) g50.0<1>UW g92.0<16,8,1>UB {align1}; mov (16) g51.0<1>UW g93.0<16,8,1>UB {align1}; jmpi out; mov (16) g44.0<1>UW g86.1<16,8,1>UB {align1}; mov (16) g45.0<1>UW g87.1<16,8,1>UB {align1}; mov (16) g46.0<1>UW g88.1<16,8,1>UB {align1}; mov (16) g47.0<1>UW g89.1<16,8,1>UB {align1}; mov (16) g48.0<1>UW g90.1<16,8,1>UB {align1}; mov (16) g49.0<1>UW g91.1<16,8,1>UB {align1}; mov (16) g50.0<1>UW g92.1<16,8,1>UB {align1}; mov (16) g51.0<1>UW g93.1<16,8,1>UB {align1}; jmpi out; mov (16) g44.0<1>UW g86.2<16,8,1>UB {align1}; mov (16) g45.0<1>UW g87.2<16,8,1>UB {align1}; mov (16) g46.0<1>UW g88.2<16,8,1>UB {align1}; mov (16) g47.0<1>UW g89.2<16,8,1>UB {align1}; mov (16) g48.0<1>UW g90.2<16,8,1>UB {align1}; mov (16) g49.0<1>UW g91.2<16,8,1>UB {align1}; mov (16) g50.0<1>UW g92.2<16,8,1>UB {align1}; mov (16) g51.0<1>UW g93.2<16,8,1>UB {align1}; jmpi out; mov (16) g44.0<1>UW g86.3<16,8,1>UB {align1}; mov (16) g45.0<1>UW g87.3<16,8,1>UB {align1}; mov (16) g46.0<1>UW g88.3<16,8,1>UB {align1}; mov (16) g47.0<1>UW g89.3<16,8,1>UB {align1}; mov (16) g48.0<1>UW g90.3<16,8,1>UB {align1}; mov (16) g49.0<1>UW g91.3<16,8,1>UB {align1}; mov (16) g50.0<1>UW g92.3<16,8,1>UB {align1}; mov (16) g51.0<1>UW g93.3<16,8,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y0_uv_igd.g4i000066400000000000000000000017631267532330400300330ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007000fUD {align1}; and.nz (1) null g32.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g34.0<1>UW g32<8,8,1>UW read(5, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g44.0<1>UW g32<8,8,1>UW read(6, 2, 0, 2) mlen 1 rlen 4 {align1}; jmpi put_data; read_backward: send (16) 0 g34.0<1>UW g32<8,8,1>UW read(8, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g44.0<1>UW g32<8,8,1>UW read(9, 2, 0, 2) mlen 1 rlen 4 {align1}; put_data: mov (32) g74.0<1>UW g34.0<16,8,1>UB {align1 compr}; mov (32) g76.0<1>UW g36.0<16,8,1>UB {align1 compr}; mov (32) g78.0<1>UW g44.0<16,8,1>UB {align1 compr}; mov (32) g80.0<1>UW g46.0<16,8,1>UB {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y0_y.g4i000066400000000000000000000112671267532330400270260ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007001FUD {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g106.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g2.0<1,1,1>UD 3UD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 17UD {align1}; jmpi g2.24<1,1,1>D; mov (16) g28.0<1>UW g98.0<16,16,1>UB {align1}; mov (16) g29.0<1>UW g99.0<16,16,1>UB {align1}; mov (16) g30.0<1>UW g100.0<16,16,1>UB {align1}; mov (16) g31.0<1>UW g101.0<16,16,1>UB {align1}; mov (16) g32.0<1>UW g102.0<16,16,1>UB {align1}; mov (16) g33.0<1>UW g103.0<16,16,1>UB {align1}; mov (16) g34.0<1>UW g104.0<16,16,1>UB {align1}; mov (16) g35.0<1>UW g105.0<16,16,1>UB {align1}; mov (16) g36.0<1>UW g106.0<16,16,1>UB {align1}; mov (16) g37.0<1>UW g107.0<16,16,1>UB {align1}; mov (16) g38.0<1>UW g108.0<16,16,1>UB {align1}; mov (16) g39.0<1>UW g109.0<16,16,1>UB {align1}; mov (16) g40.0<1>UW g110.0<16,16,1>UB {align1}; mov (16) g41.0<1>UW g111.0<16,16,1>UB {align1}; mov (16) g42.0<1>UW g112.0<16,16,1>UB {align1}; mov (16) g43.0<1>UW g113.0<16,16,1>UB {align1}; jmpi out; mov (16) g28.0<1>UW g98.1<16,16,1>UB {align1}; mov (16) g29.0<1>UW g99.1<16,16,1>UB {align1}; mov (16) g30.0<1>UW g100.1<16,16,1>UB {align1}; mov (16) g31.0<1>UW g101.1<16,16,1>UB {align1}; mov (16) g32.0<1>UW g102.1<16,16,1>UB {align1}; mov (16) g33.0<1>UW g103.1<16,16,1>UB {align1}; mov (16) g34.0<1>UW g104.1<16,16,1>UB {align1}; mov (16) g35.0<1>UW g105.1<16,16,1>UB {align1}; mov (16) g36.0<1>UW g106.1<16,16,1>UB {align1}; mov (16) g37.0<1>UW g107.1<16,16,1>UB {align1}; mov (16) g38.0<1>UW g108.1<16,16,1>UB {align1}; mov (16) g39.0<1>UW g109.1<16,16,1>UB {align1}; mov (16) g40.0<1>UW g110.1<16,16,1>UB {align1}; mov (16) g41.0<1>UW g111.1<16,16,1>UB {align1}; mov (16) g42.0<1>UW g112.1<16,16,1>UB {align1}; mov (16) g43.0<1>UW g113.1<16,16,1>UB {align1}; jmpi out; mov (16) g28.0<1>UW g98.2<16,16,1>UB {align1}; mov (16) g29.0<1>UW g99.2<16,16,1>UB {align1}; mov (16) g30.0<1>UW g100.2<16,16,1>UB {align1}; mov (16) g31.0<1>UW g101.2<16,16,1>UB {align1}; mov (16) g32.0<1>UW g102.2<16,16,1>UB {align1}; mov (16) g33.0<1>UW g103.2<16,16,1>UB {align1}; mov (16) g34.0<1>UW g104.2<16,16,1>UB {align1}; mov (16) g35.0<1>UW g105.2<16,16,1>UB {align1}; mov (16) g36.0<1>UW g106.2<16,16,1>UB {align1}; mov (16) g37.0<1>UW g107.2<16,16,1>UB {align1}; mov (16) g38.0<1>UW g108.2<16,16,1>UB {align1}; mov (16) g39.0<1>UW g109.2<16,16,1>UB {align1}; mov (16) g40.0<1>UW g110.2<16,16,1>UB {align1}; mov (16) g41.0<1>UW g111.2<16,16,1>UB {align1}; mov (16) g42.0<1>UW g112.2<16,16,1>UB {align1}; mov (16) g43.0<1>UW g113.2<16,16,1>UB {align1}; jmpi out; mov (16) g28.0<1>UW g98.3<16,16,1>UB {align1}; mov (16) g29.0<1>UW g99.3<16,16,1>UB {align1}; mov (16) g30.0<1>UW g100.3<16,16,1>UB {align1}; mov (16) g31.0<1>UW g101.3<16,16,1>UB {align1}; mov (16) g32.0<1>UW g102.3<16,16,1>UB {align1}; mov (16) g33.0<1>UW g103.3<16,16,1>UB {align1}; mov (16) g34.0<1>UW g104.3<16,16,1>UB {align1}; mov (16) g35.0<1>UW g105.3<16,16,1>UB {align1}; mov (16) g36.0<1>UW g106.3<16,16,1>UB {align1}; mov (16) g37.0<1>UW g107.3<16,16,1>UB {align1}; mov (16) g38.0<1>UW g108.3<16,16,1>UB {align1}; mov (16) g39.0<1>UW g109.3<16,16,1>UB {align1}; mov (16) g40.0<1>UW g110.3<16,16,1>UB {align1}; mov (16) g41.0<1>UW g111.3<16,16,1>UB {align1}; mov (16) g42.0<1>UW g112.3<16,16,1>UB {align1}; mov (16) g43.0<1>UW g113.3<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y0_y_igd.g4i000066400000000000000000000024541267532330400276470ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; and.nz (1) null g32.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; jmpi put_data; read_backward: send (16) 0 g38.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; put_data: mov (32) g58.0<1>UW g38.0<16,16,1>UB {align1 compr}; mov (32) g60.0<1>UW g40.0<16,16,1>UB {align1 compr}; mov (32) g62.0<1>UW g42.0<16,16,1>UB {align1 compr}; mov (32) g64.0<1>UW g44.0<16,16,1>UB {align1 compr}; mov (32) g66.0<1>UW g46.0<16,16,1>UB {align1 compr}; mov (32) g68.0<1>UW g48.0<16,16,1>UB {align1 compr}; mov (32) g70.0<1>UW g50.0<16,16,1>UB {align1 compr}; mov (32) g72.0<1>UW g52.0<16,16,1>UB {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y1_uv.g4i000066400000000000000000000076741267532330400272200ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDINg BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINgEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIgHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAgES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISINg FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINgS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and (1) g2.24<1>UD g2.0<1,1,1>UD 0x3UD {align1}; send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g94.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mov (1) g2.8<1>UD 0x01001FUD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; mov (1) g2.8<1>UD 0x007000fUD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 0x9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g44.0<1>UW g86.0<16,8,1>UB g87.0<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.0<16,8,1>UB g88.0<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.0<16,8,1>UB g89.0<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.0<16,8,1>UB g90.0<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g95.0<16,8,1>UB g96.0<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g96.0<16,8,1>UB g97.0<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g97.0<16,8,1>UB g98.0<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.1<16,8,1>UB g87.1<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.1<16,8,1>UB g88.1<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.1<16,8,1>UB g89.1<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.1<16,8,1>UB g90.1<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g94.1<16,8,1>UB g95.1<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g95.1<16,8,1>UB g96.1<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g96.1<16,8,1>UB g97.1<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g97.1<16,8,1>UB g98.1<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.2<16,8,1>UB g87.2<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.2<16,8,1>UB g88.2<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.2<16,8,1>UB g89.2<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.2<16,8,1>UB g90.2<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g94.2<16,8,1>UB g95.2<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g95.2<16,8,1>UB g96.2<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g96.2<16,8,1>UB g97.2<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g97.2<16,8,1>UB g98.2<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.3<16,8,1>UB g87.3<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.3<16,8,1>UB g88.3<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.3<16,8,1>UB g89.3<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.3<16,8,1>UB g90.3<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g94.3<16,8,1>UB g95.3<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g95.3<16,8,1>UB g96.3<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g96.3<16,8,1>UB g97.3<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g97.3<16,8,1>UB g98.3<16,8,1>UB{align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y1_uv_igd.g4i000066400000000000000000000044071267532330400300320ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDINg BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINgEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIgHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAgES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISINg FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINgS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g94.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mov (1) g2.8<1>UD 0x01001FUD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; mov (1) g2.8<1>UD 0x007000fUD {align1}; avg.sat (16) g44.0<1>UW g86.0<16,8,1>UB g87.0<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.0<16,8,1>UB g88.0<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.0<16,8,1>UB g89.0<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.0<16,8,1>UB g90.0<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g95.0<16,8,1>UB g96.0<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g96.0<16,8,1>UB g97.0<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g97.0<16,8,1>UB g98.0<16,8,1>UB{align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y1_y.g4i000066400000000000000000000143361267532330400270270ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007001FUD {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g2.0<1,1,1>UD 3UD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 17UD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g106.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; mov (1) g2.8<1>UD 0x1FUD {align1}; send (16) 0 g120.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 1 {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g28.0<1>UW g98.0<16,16,1>UB g99.0<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.0<16,16,1>UB g100.0<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.0<16,16,1>UB g101.0<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.0<16,16,1>UB g102.0<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.0<16,16,1>UB g103.0<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.0<16,16,1>UB g104.0<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.0<16,16,1>UB g105.0<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.0<16,16,1>UB g106.0<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.0<16,16,1>UB g107.0<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.0<16,16,1>UB g108.0<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.0<16,16,1>UB g109.0<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.0<16,16,1>UB g110.0<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.0<16,16,1>UB g111.0<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.0<16,16,1>UB g112.0<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.0<16,16,1>UB g113.0<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.0<16,16,1>UB g120.0<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.1<16,16,1>UB g99.1<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.1<16,16,1>UB g100.1<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.1<16,16,1>UB g101.1<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.1<16,16,1>UB g102.1<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.1<16,16,1>UB g103.1<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.1<16,16,1>UB g104.1<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.1<16,16,1>UB g105.1<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.1<16,16,1>UB g106.1<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.1<16,16,1>UB g107.1<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.1<16,16,1>UB g108.1<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.1<16,16,1>UB g109.1<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.1<16,16,1>UB g110.1<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.1<16,16,1>UB g111.1<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.1<16,16,1>UB g112.1<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.1<16,16,1>UB g113.1<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.1<16,16,1>UB g120.1<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.2<16,16,1>UB g99.2<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.2<16,16,1>UB g100.2<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.2<16,16,1>UB g101.2<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.2<16,16,1>UB g102.2<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.2<16,16,1>UB g103.2<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.2<16,16,1>UB g104.2<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.2<16,16,1>UB g105.2<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.2<16,16,1>UB g106.2<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.2<16,16,1>UB g107.2<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.2<16,16,1>UB g108.2<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.2<16,16,1>UB g109.2<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.2<16,16,1>UB g110.2<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.2<16,16,1>UB g111.2<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.2<16,16,1>UB g112.2<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.2<16,16,1>UB g113.2<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.2<16,16,1>UB g120.2<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.3<16,16,1>UB g99.3<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.3<16,16,1>UB g100.3<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.3<16,16,1>UB g101.3<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.3<16,16,1>UB g102.3<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.3<16,16,1>UB g103.3<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.3<16,16,1>UB g104.3<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.3<16,16,1>UB g105.3<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.3<16,16,1>UB g106.3<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.3<16,16,1>UB g107.3<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.3<16,16,1>UB g108.3<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.3<16,16,1>UB g109.3<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.3<16,16,1>UB g110.3<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.3<16,16,1>UB g111.3<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.3<16,16,1>UB g112.3<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.3<16,16,1>UB g113.3<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.3<16,16,1>UB g120.3<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x0y1_y_igd.g4i000066400000000000000000000043061267532330400276460ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; and.nz (1) null g32.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 1 {align1}; jmpi put_data; read_backward: send (16) 0 g38.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 1 {align1}; put_data: avg (16) g58.0<1>UW g38.0<16,16,1>UB g39.0<16,16,1>UB {align1}; avg (16) g59.0<1>UW g39.0<16,16,1>UB g40.0<16,16,1>UB {align1}; avg (16) g60.0<1>UW g40.0<16,16,1>UB g41.0<16,16,1>UB {align1}; avg (16) g61.0<1>UW g41.0<16,16,1>UB g42.0<16,16,1>UB {align1}; avg (16) g62.0<1>UW g42.0<16,16,1>UB g43.0<16,16,1>UB {align1}; avg (16) g63.0<1>UW g43.0<16,16,1>UB g44.0<16,16,1>UB {align1}; avg (16) g64.0<1>UW g44.0<16,16,1>UB g45.0<16,16,1>UB {align1}; avg (16) g65.0<1>UW g45.0<16,16,1>UB g46.0<16,16,1>UB {align1}; avg (16) g66.0<1>UW g46.0<16,16,1>UB g47.0<16,16,1>UB {align1}; avg (16) g67.0<1>UW g47.0<16,16,1>UB g48.0<16,16,1>UB {align1}; avg (16) g68.0<1>UW g48.0<16,16,1>UB g49.0<16,16,1>UB {align1}; avg (16) g69.0<1>UW g49.0<16,16,1>UB g50.0<16,16,1>UB {align1}; avg (16) g70.0<1>UW g50.0<16,16,1>UB g51.0<16,16,1>UB {align1}; avg (16) g71.0<1>UW g51.0<16,16,1>UB g52.0<16,16,1>UB {align1}; avg (16) g72.0<1>UW g52.0<16,16,1>UB g53.0<16,16,1>UB {align1}; avg (16) g73.0<1>UW g53.0<16,16,1>UB g54.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y0_uv.g4i000066400000000000000000000072641267532330400272130ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007000FUD {align1}; and (1) g2.24<1>UD g2.0<1,1,1>UD 0x3UD {align1}; send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 0x9UD {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g44.0<1>UW g86.0<16,8,1>UB g86.1<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.0<16,8,1>UB g87.1<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.0<16,8,1>UB g88.1<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.0<16,8,1>UB g89.1<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g90.0<16,8,1>UB g90.1<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g91.0<16,8,1>UB g91.1<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g92.0<16,8,1>UB g92.1<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g93.0<16,8,1>UB g93.1<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.1<16,8,1>UB g86.2<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.1<16,8,1>UB g87.2<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.1<16,8,1>UB g88.2<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.1<16,8,1>UB g89.2<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g90.1<16,8,1>UB g90.2<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g91.1<16,8,1>UB g91.2<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g92.1<16,8,1>UB g92.2<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g93.1<16,8,1>UB g93.2<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.2<16,8,1>UB g86.3<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.2<16,8,1>UB g87.3<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.2<16,8,1>UB g88.3<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.2<16,8,1>UB g89.3<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g90.2<16,8,1>UB g90.3<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g91.2<16,8,1>UB g91.3<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g92.2<16,8,1>UB g92.3<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g93.2<16,8,1>UB g93.3<16,8,1>UB{align1}; jmpi out; avg.sat (16) g44.0<1>UW g86.3<16,8,1>UB g86.4<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.3<16,8,1>UB g87.4<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.3<16,8,1>UB g88.4<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.3<16,8,1>UB g89.4<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g90.3<16,8,1>UB g90.4<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g91.3<16,8,1>UB g91.4<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g92.3<16,8,1>UB g92.4<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g93.3<16,8,1>UB g93.4<16,8,1>UB{align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y0_uv_igd.g4i000066400000000000000000000040001267532330400300170ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007000FUD {align1}; send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; avg.sat (16) g44.0<1>UW g86.0<16,8,1>UB g86.1<16,8,1>UB{align1}; avg.sat (16) g45.0<1>UW g87.0<16,8,1>UB g87.1<16,8,1>UB{align1}; avg.sat (16) g46.0<1>UW g88.0<16,8,1>UB g88.1<16,8,1>UB{align1}; avg.sat (16) g47.0<1>UW g89.0<16,8,1>UB g89.1<16,8,1>UB{align1}; avg.sat (16) g48.0<1>UW g90.0<16,8,1>UB g90.1<16,8,1>UB{align1}; avg.sat (16) g49.0<1>UW g91.0<16,8,1>UB g91.1<16,8,1>UB{align1}; avg.sat (16) g50.0<1>UW g92.0<16,8,1>UB g92.1<16,8,1>UB{align1}; avg.sat (16) g51.0<1>UW g93.0<16,8,1>UB g93.1<16,8,1>UB{align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y0_y.g4i000066400000000000000000000140571267532330400270270ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007001FUD {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g2.0<1,1,1>UD 3UD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 17D {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g106.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; jmpi g2.24<1,1,1>D; avg.sat (16) g28.0<1>UW g98.0<16,16,1>UB g98.1<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.0<16,16,1>UB g99.1<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.0<16,16,1>UB g100.1<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.0<16,16,1>UB g101.1<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.0<16,16,1>UB g102.1<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.0<16,16,1>UB g103.1<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.0<16,16,1>UB g104.1<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.0<16,16,1>UB g105.1<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.0<16,16,1>UB g106.1<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.0<16,16,1>UB g107.1<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.0<16,16,1>UB g108.1<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.0<16,16,1>UB g109.1<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.0<16,16,1>UB g110.1<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.0<16,16,1>UB g111.1<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.0<16,16,1>UB g112.1<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.0<16,16,1>UB g113.1<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.1<16,16,1>UB g98.2<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.1<16,16,1>UB g99.2<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.1<16,16,1>UB g100.2<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.1<16,16,1>UB g101.2<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.1<16,16,1>UB g102.2<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.1<16,16,1>UB g103.2<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.1<16,16,1>UB g104.2<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.1<16,16,1>UB g105.2<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.1<16,16,1>UB g106.2<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.1<16,16,1>UB g107.2<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.1<16,16,1>UB g108.2<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.1<16,16,1>UB g109.2<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.1<16,16,1>UB g110.2<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.1<16,16,1>UB g111.2<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.1<16,16,1>UB g112.2<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.1<16,16,1>UB g113.2<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.2<16,16,1>UB g98.3<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.2<16,16,1>UB g99.3<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.2<16,16,1>UB g100.3<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.2<16,16,1>UB g101.3<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.2<16,16,1>UB g102.3<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.2<16,16,1>UB g103.3<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.2<16,16,1>UB g104.3<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.2<16,16,1>UB g105.3<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.2<16,16,1>UB g106.3<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.2<16,16,1>UB g107.3<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.2<16,16,1>UB g108.3<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.2<16,16,1>UB g109.3<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.2<16,16,1>UB g110.3<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.2<16,16,1>UB g111.3<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.2<16,16,1>UB g112.3<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.2<16,16,1>UB g113.3<16,16,1>UB {align1}; jmpi out; avg.sat (16) g28.0<1>UW g98.3<16,16,1>UB g98.4<16,16,1>UB {align1}; avg.sat (16) g29.0<1>UW g99.3<16,16,1>UB g99.4<16,16,1>UB {align1}; avg.sat (16) g30.0<1>UW g100.3<16,16,1>UB g100.4<16,16,1>UB {align1}; avg.sat (16) g31.0<1>UW g101.3<16,16,1>UB g101.4<16,16,1>UB {align1}; avg.sat (16) g32.0<1>UW g102.3<16,16,1>UB g102.4<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g103.3<16,16,1>UB g103.4<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g104.3<16,16,1>UB g104.4<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g105.3<16,16,1>UB g105.4<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g106.3<16,16,1>UB g106.4<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g107.3<16,16,1>UB g107.4<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g108.3<16,16,1>UB g108.4<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g109.3<16,16,1>UB g109.4<16,16,1>UB {align1}; avg.sat (16) g40.0<1>UW g110.3<16,16,1>UB g110.4<16,16,1>UB {align1}; avg.sat (16) g41.0<1>UW g111.3<16,16,1>UB g111.4<16,16,1>UB {align1}; avg.sat (16) g42.0<1>UW g112.3<16,16,1>UB g112.4<16,16,1>UB {align1}; avg.sat (16) g43.0<1>UW g113.3<16,16,1>UB g113.4<16,16,1>UB {align1}; out: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y0_y_igd.g4i000066400000000000000000000036041267532330400276460ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; and.nz (1) null g32.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; jmpi put_data; read_backward: send (16) 0 g38.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; put_data: avg (16) g58.0<1>UW g38.0<16,16,1>UB g38.1<16,16,1>UB {align1}; avg (16) g59.0<1>UW g39.0<16,16,1>UB g39.1<16,16,1>UB {align1}; avg (16) g60.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; avg (16) g61.0<1>UW g41.0<16,16,1>UB g41.1<16,16,1>UB {align1}; avg (16) g62.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; avg (16) g63.0<1>UW g43.0<16,16,1>UB g43.1<16,16,1>UB {align1}; avg (16) g64.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; avg (16) g65.0<1>UW g45.0<16,16,1>UB g45.1<16,16,1>UB {align1}; avg (16) g66.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; avg (16) g67.0<1>UW g47.0<16,16,1>UB g47.1<16,16,1>UB {align1}; avg (16) g68.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; avg (16) g69.0<1>UW g49.0<16,16,1>UB g49.1<16,16,1>UB {align1}; avg (16) g70.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; avg (16) g71.0<1>UW g51.0<16,16,1>UB g51.1<16,16,1>UB {align1}; avg (16) g72.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; avg (16) g73.0<1>UW g53.0<16,16,1>UB g53.1<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y1_uv.g4i000066400000000000000000000201721267532330400272050ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and (1) g2.24<1>UD g2.0<1,1,1>UD 0x3UD {align1}; send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g94.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mov (1) g2.8<1>UD 0x01001FUD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8D {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; mov (1) g2.8<1>UD 0x007000fUD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 25UD {align1}; jmpi g2.24<1,1,1>D; add (16) g44.0<1>UW g86.0<16,8,1>UB g86.1<16,8,1>UB{align1}; add (16) g45.0<1>UW g87.0<16,8,1>UB g87.1<16,8,1>UB{align1}; add (16) g46.0<1>UW g88.0<16,8,1>UB g88.1<16,8,1>UB{align1}; add (16) g47.0<1>UW g89.0<16,8,1>UB g89.1<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.0<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.0<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.0<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.0<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.1<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.1<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.1<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.1<16,8,1>UB{align1}; add (16) g48.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB{align1}; add (16) g49.0<1>UW g95.0<16,8,1>UB g96.0<16,8,1>UB{align1}; add (16) g50.0<1>UW g96.0<16,8,1>UB g97.0<16,8,1>UB{align1}; add (16) g51.0<1>UW g97.0<16,8,1>UB g98.0<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g94.1<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g95.1<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g96.1<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g97.1<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g95.1<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g96.1<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g97.1<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g98.1<16,8,1>UB{align1}; jmpi out; add (16) g44.0<1>UW g86.1<16,8,1>UB g86.2<16,8,1>UB{align1}; add (16) g45.0<1>UW g87.1<16,8,1>UB g87.2<16,8,1>UB{align1}; add (16) g46.0<1>UW g88.1<16,8,1>UB g88.2<16,8,1>UB{align1}; add (16) g47.0<1>UW g89.1<16,8,1>UB g89.2<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.1<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.1<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.1<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.1<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.2<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.2<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.2<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.2<16,8,1>UB{align1}; add (16) g48.0<1>UW g94.1<16,8,1>UB g95.1<16,8,1>UB{align1}; add (16) g49.0<1>UW g95.1<16,8,1>UB g96.1<16,8,1>UB{align1}; add (16) g50.0<1>UW g96.1<16,8,1>UB g97.1<16,8,1>UB{align1}; add (16) g51.0<1>UW g97.1<16,8,1>UB g98.1<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g94.2<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g95.2<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g96.2<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g97.2<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g95.2<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g96.2<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g97.2<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g98.2<16,8,1>UB{align1}; jmpi out; add (16) g44.0<1>UW g86.2<16,8,1>UB g86.3<16,8,1>UB{align1}; add (16) g45.0<1>UW g87.2<16,8,1>UB g87.3<16,8,1>UB{align1}; add (16) g46.0<1>UW g88.2<16,8,1>UB g88.3<16,8,1>UB{align1}; add (16) g47.0<1>UW g89.2<16,8,1>UB g89.3<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.2<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.2<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.2<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.2<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.3<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.3<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.3<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.3<16,8,1>UB{align1}; add (16) g48.0<1>UW g94.2<16,8,1>UB g95.2<16,8,1>UB{align1}; add (16) g49.0<1>UW g95.2<16,8,1>UB g96.2<16,8,1>UB{align1}; add (16) g50.0<1>UW g96.2<16,8,1>UB g97.2<16,8,1>UB{align1}; add (16) g51.0<1>UW g97.2<16,8,1>UB g98.2<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g94.3<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g95.3<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g96.3<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g97.3<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g95.3<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g96.3<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g97.3<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g98.3<16,8,1>UB{align1}; jmpi out; add (16) g44.0<1>UW g86.3<16,8,1>UB g86.4<16,8,1>UB{align1}; add (16) g45.0<1>UW g87.3<16,8,1>UB g87.4<16,8,1>UB{align1}; add (16) g46.0<1>UW g88.3<16,8,1>UB g88.4<16,8,1>UB{align1}; add (16) g47.0<1>UW g89.3<16,8,1>UB g89.4<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.3<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.3<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.3<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.3<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.4<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.4<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.4<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.4<16,8,1>UB{align1}; add (16) g48.0<1>UW g94.3<16,8,1>UB g95.3<16,8,1>UB{align1}; add (16) g49.0<1>UW g95.3<16,8,1>UB g96.3<16,8,1>UB{align1}; add (16) g50.0<1>UW g96.3<16,8,1>UB g97.3<16,8,1>UB{align1}; add (16) g51.0<1>UW g97.3<16,8,1>UB g98.3<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g94.4<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g95.4<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g96.4<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g97.4<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g95.4<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g96.4<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g97.4<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g98.4<16,8,1>UB{align1}; out: shr.sat (16) g44.0<1>UW g44.0<16,16,1>UW 2UW {align1}; shr.sat (16) g45.0<1>UW g45.0<16,16,1>UW 2UW {align1}; shr.sat (16) g46.0<1>UW g46.0<16,16,1>UW 2UW {align1}; shr.sat (16) g47.0<1>UW g47.0<16,16,1>UW 2UW {align1}; shr.sat (16) g48.0<1>UW g48.0<16,16,1>UW 2UW {align1}; shr.sat (16) g49.0<1>UW g49.0<16,16,1>UW 2UW {align1}; shr.sat (16) g50.0<1>UW g50.0<16,16,1>UW 2UW {align1}; shr.sat (16) g51.0<1>UW g51.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y1_uv_igd.g4i000066400000000000000000000072011267532330400300260ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ send (16) 0 g86.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g94.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mov (1) g2.8<1>UD 0x01001FUD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8D {align1}; send (16) 0 g90.0<1>UW g2<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; mov (1) g2.8<1>UD 0x007000fUD {align1}; add (16) g44.0<1>UW g86.0<16,8,1>UB g86.1<16,8,1>UB{align1}; add (16) g45.0<1>UW g87.0<16,8,1>UB g87.1<16,8,1>UB{align1}; add (16) g46.0<1>UW g88.0<16,8,1>UB g88.1<16,8,1>UB{align1}; add (16) g47.0<1>UW g89.0<16,8,1>UB g89.1<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.0<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.0<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.0<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.0<16,8,1>UB{align1}; add (16) g44.0<1>UW g44.0<16,16,1>UW g87.1<16,8,1>UB{align1}; add (16) g45.0<1>UW g45.0<16,16,1>UW g88.1<16,8,1>UB{align1}; add (16) g46.0<1>UW g46.0<16,16,1>UW g89.1<16,8,1>UB{align1}; add (16) g47.0<1>UW g47.0<16,16,1>UW g90.1<16,8,1>UB{align1}; add (16) g48.0<1>UW g94.0<16,8,1>UB g95.0<16,8,1>UB{align1}; add (16) g49.0<1>UW g95.0<16,8,1>UB g96.0<16,8,1>UB{align1}; add (16) g50.0<1>UW g96.0<16,8,1>UB g97.0<16,8,1>UB{align1}; add (16) g51.0<1>UW g97.0<16,8,1>UB g98.0<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g94.1<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g95.1<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g96.1<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g97.1<16,8,1>UB{align1}; add (16) g48.0<1>UW g48.0<16,16,1>UW g95.1<16,8,1>UB{align1}; add (16) g49.0<1>UW g49.0<16,16,1>UW g96.1<16,8,1>UB{align1}; add (16) g50.0<1>UW g50.0<16,16,1>UW g97.1<16,8,1>UB{align1}; add (16) g51.0<1>UW g51.0<16,16,1>UW g98.1<16,8,1>UB{align1}; shr.sat (16) g44.0<1>UW g44.0<16,16,1>UW 2UW {align1}; shr.sat (16) g45.0<1>UW g45.0<16,16,1>UW 2UW {align1}; shr.sat (16) g46.0<1>UW g46.0<16,16,1>UW 2UW {align1}; shr.sat (16) g47.0<1>UW g47.0<16,16,1>UW 2UW {align1}; shr.sat (16) g48.0<1>UW g48.0<16,16,1>UW 2UW {align1}; shr.sat (16) g49.0<1>UW g49.0<16,16,1>UW 2UW {align1}; shr.sat (16) g50.0<1>UW g50.0<16,16,1>UW 2UW {align1}; shr.sat (16) g51.0<1>UW g51.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y1_y.g4i000066400000000000000000000357111267532330400270300ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g2.8<1>UD 0x007001FUD {align1}; send (16) 0 g98.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; and (1) g2.24<1>UD g2.0<1,1,1>UD 3UD {align1}; mul(1) g2.24<1>UD g2.24<1,1,1>UD 49UD {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; send (16) 0 g106.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g2.4<1>UD g2.4<1,1,1>UD 8UD {align1}; mov (1) g2.8<1>UD 0x1FUD {align1}; send (16) 0 g120.0<1>UW g2<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 1 {align1}; jmpi g2.24<1,1,1>D; add (16) g28.0<1>UW g98.0<16,16,1>UB g98.1<16,16,1>UB {align1}; add (16) g29.0<1>UW g99.0<16,16,1>UB g99.1<16,16,1>UB {align1}; add (16) g30.0<1>UW g100.0<16,16,1>UB g100.1<16,16,1>UB {align1}; add (16) g31.0<1>UW g101.0<16,16,1>UB g101.1<16,16,1>UB {align1}; add (16) g32.0<1>UW g102.0<16,16,1>UB g102.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g103.0<16,16,1>UB g103.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g104.0<16,16,1>UB g104.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g105.0<16,16,1>UB g105.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g106.0<16,16,1>UB g106.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g107.0<16,16,1>UB g107.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g108.0<16,16,1>UB g108.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g109.0<16,16,1>UB g109.1<16,16,1>UB {align1}; add (16) g40.0<1>UW g110.0<16,16,1>UB g110.1<16,16,1>UB {align1}; add (16) g41.0<1>UW g111.0<16,16,1>UB g111.1<16,16,1>UB {align1}; add (16) g42.0<1>UW g112.0<16,16,1>UB g112.1<16,16,1>UB {align1}; add (16) g43.0<1>UW g113.0<16,16,1>UB g113.1<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.0<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.0<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.0<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.0<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.0<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.0<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.0<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.0<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.0<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.0<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.0<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.0<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.0<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.0<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.0<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.0<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.1<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.1<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.1<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.1<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.1<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.1<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.1<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.1<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.1<16,16,1>UB {align1}; jmpi out; add (16) g28.0<1>UW g98.1<16,16,1>UB g98.2<16,16,1>UB {align1}; add (16) g29.0<1>UW g99.1<16,16,1>UB g99.2<16,16,1>UB {align1}; add (16) g30.0<1>UW g100.1<16,16,1>UB g100.2<16,16,1>UB {align1}; add (16) g31.0<1>UW g101.1<16,16,1>UB g101.2<16,16,1>UB {align1}; add (16) g32.0<1>UW g102.1<16,16,1>UB g102.2<16,16,1>UB {align1}; add (16) g33.0<1>UW g103.1<16,16,1>UB g103.2<16,16,1>UB {align1}; add (16) g34.0<1>UW g104.1<16,16,1>UB g104.2<16,16,1>UB {align1}; add (16) g35.0<1>UW g105.1<16,16,1>UB g105.2<16,16,1>UB {align1}; add (16) g36.0<1>UW g106.1<16,16,1>UB g106.2<16,16,1>UB {align1}; add (16) g37.0<1>UW g107.1<16,16,1>UB g107.2<16,16,1>UB {align1}; add (16) g38.0<1>UW g108.1<16,16,1>UB g108.2<16,16,1>UB {align1}; add (16) g39.0<1>UW g109.1<16,16,1>UB g109.2<16,16,1>UB {align1}; add (16) g40.0<1>UW g110.1<16,16,1>UB g110.2<16,16,1>UB {align1}; add (16) g41.0<1>UW g111.1<16,16,1>UB g111.2<16,16,1>UB {align1}; add (16) g42.0<1>UW g112.1<16,16,1>UB g112.2<16,16,1>UB {align1}; add (16) g43.0<1>UW g113.1<16,16,1>UB g113.2<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.1<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.1<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.1<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.1<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.1<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.1<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.1<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.1<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.1<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.2<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.2<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.2<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.2<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.2<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.2<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.2<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.2<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.2<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.2<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.2<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.2<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.2<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.2<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.2<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.2<16,16,1>UB {align1}; jmpi out; add (16) g28.0<1>UW g98.2<16,16,1>UB g98.3<16,16,1>UB {align1}; add (16) g29.0<1>UW g99.2<16,16,1>UB g99.3<16,16,1>UB {align1}; add (16) g30.0<1>UW g100.2<16,16,1>UB g100.3<16,16,1>UB {align1}; add (16) g31.0<1>UW g101.2<16,16,1>UB g101.3<16,16,1>UB {align1}; add (16) g32.0<1>UW g102.2<16,16,1>UB g102.3<16,16,1>UB {align1}; add (16) g33.0<1>UW g103.2<16,16,1>UB g103.3<16,16,1>UB {align1}; add (16) g34.0<1>UW g104.2<16,16,1>UB g104.3<16,16,1>UB {align1}; add (16) g35.0<1>UW g105.2<16,16,1>UB g105.3<16,16,1>UB {align1}; add (16) g36.0<1>UW g106.2<16,16,1>UB g106.3<16,16,1>UB {align1}; add (16) g37.0<1>UW g107.2<16,16,1>UB g107.3<16,16,1>UB {align1}; add (16) g38.0<1>UW g108.2<16,16,1>UB g108.3<16,16,1>UB {align1}; add (16) g39.0<1>UW g109.2<16,16,1>UB g109.3<16,16,1>UB {align1}; add (16) g40.0<1>UW g110.2<16,16,1>UB g110.3<16,16,1>UB {align1}; add (16) g41.0<1>UW g111.2<16,16,1>UB g111.3<16,16,1>UB {align1}; add (16) g42.0<1>UW g112.2<16,16,1>UB g112.3<16,16,1>UB {align1}; add (16) g43.0<1>UW g113.2<16,16,1>UB g113.3<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.2<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.2<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.2<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.2<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.2<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.2<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.2<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.2<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.2<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.2<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.2<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.2<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.2<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.2<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.2<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.2<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.3<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.3<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.3<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.3<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.3<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.3<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.3<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.3<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.3<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.3<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.3<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.3<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.3<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.3<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.3<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.3<16,16,1>UB {align1}; jmpi out; add (16) g28.0<1>UW g98.3<16,16,1>UB g98.4<16,16,1>UB {align1}; add (16) g29.0<1>UW g99.3<16,16,1>UB g99.4<16,16,1>UB {align1}; add (16) g30.0<1>UW g100.3<16,16,1>UB g100.4<16,16,1>UB {align1}; add (16) g31.0<1>UW g101.3<16,16,1>UB g101.4<16,16,1>UB {align1}; add (16) g32.0<1>UW g102.3<16,16,1>UB g102.4<16,16,1>UB {align1}; add (16) g33.0<1>UW g103.3<16,16,1>UB g103.4<16,16,1>UB {align1}; add (16) g34.0<1>UW g104.3<16,16,1>UB g104.4<16,16,1>UB {align1}; add (16) g35.0<1>UW g105.3<16,16,1>UB g105.4<16,16,1>UB {align1}; add (16) g36.0<1>UW g106.3<16,16,1>UB g106.4<16,16,1>UB {align1}; add (16) g37.0<1>UW g107.3<16,16,1>UB g107.4<16,16,1>UB {align1}; add (16) g38.0<1>UW g108.3<16,16,1>UB g108.4<16,16,1>UB {align1}; add (16) g39.0<1>UW g109.3<16,16,1>UB g109.4<16,16,1>UB {align1}; add (16) g40.0<1>UW g110.3<16,16,1>UB g110.4<16,16,1>UB {align1}; add (16) g41.0<1>UW g111.3<16,16,1>UB g111.4<16,16,1>UB {align1}; add (16) g42.0<1>UW g112.3<16,16,1>UB g112.4<16,16,1>UB {align1}; add (16) g43.0<1>UW g113.3<16,16,1>UB g113.4<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.3<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.3<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.3<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.3<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.3<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.3<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.3<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.3<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.3<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.3<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.3<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.3<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.3<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.3<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.3<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.3<16,16,1>UB {align1}; add (16) g28.0<1>UW g28.0<16,16,1>UW g99.4<16,16,1>UB {align1}; add (16) g29.0<1>UW g29.0<16,16,1>UW g100.4<16,16,1>UB {align1}; add (16) g30.0<1>UW g30.0<16,16,1>UW g101.4<16,16,1>UB {align1}; add (16) g31.0<1>UW g31.0<16,16,1>UW g102.4<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g103.4<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g104.4<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g105.4<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g106.4<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g107.4<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g108.4<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g109.4<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g110.4<16,16,1>UB {align1}; add (16) g40.0<1>UW g40.0<16,16,1>UW g111.4<16,16,1>UB {align1}; add (16) g41.0<1>UW g41.0<16,16,1>UW g112.4<16,16,1>UB {align1}; add (16) g42.0<1>UW g42.0<16,16,1>UW g113.4<16,16,1>UB {align1}; add (16) g43.0<1>UW g43.0<16,16,1>UW g120.4<16,16,1>UB {align1}; out: shr.sat (16) g28.0<1>UW g28.0<16,16,1>UW 2UW {align1}; shr.sat (16) g29.0<1>UW g29.0<16,16,1>UW 2UW {align1}; shr.sat (16) g30.0<1>UW g30.0<16,16,1>UW 2UW {align1}; shr.sat (16) g31.0<1>UW g31.0<16,16,1>UW 2UW {align1}; shr.sat (16) g32.0<1>UW g32.0<16,16,1>UW 2UW {align1}; shr.sat (16) g33.0<1>UW g33.0<16,16,1>UW 2UW {align1}; shr.sat (16) g34.0<1>UW g34.0<16,16,1>UW 2UW {align1}; shr.sat (16) g35.0<1>UW g35.0<16,16,1>UW 2UW {align1}; shr.sat (16) g36.0<1>UW g36.0<16,16,1>UW 2UW {align1}; shr.sat (16) g37.0<1>UW g37.0<16,16,1>UW 2UW {align1}; shr.sat (16) g38.0<1>UW g38.0<16,16,1>UW 2UW {align1}; shr.sat (16) g39.0<1>UW g39.0<16,16,1>UW 2UW {align1}; shr.sat (16) g40.0<1>UW g40.0<16,16,1>UW 2UW {align1}; shr.sat (16) g41.0<1>UW g41.0<16,16,1>UW 2UW {align1}; shr.sat (16) g42.0<1>UW g42.0<16,16,1>UW 2UW {align1}; shr.sat (16) g43.0<1>UW g43.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/mc/read_frame_x1y1_y_igd.g4i000066400000000000000000000112211267532330400276410ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; and.nz (1) null g32.16<1,1,1>UW 1UW {align1}; (f0) jmpi read_backward; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(4, 2, 0, 2) mlen 1 rlen 1 {align1}; jmpi put_data; read_backward: send (16) 0 g38.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(7, 2, 0, 2) mlen 1 rlen 1 {align1}; put_data: add (16) g58.0<1>UW g38.0<16,16,1>UB g38.1<16,16,1>UB {align1}; add (16) g59.0<1>UW g39.0<16,16,1>UB g39.1<16,16,1>UB {align1}; add (16) g60.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; add (16) g61.0<1>UW g41.0<16,16,1>UB g41.1<16,16,1>UB {align1}; add (16) g62.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; add (16) g63.0<1>UW g43.0<16,16,1>UB g43.1<16,16,1>UB {align1}; add (16) g64.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; add (16) g65.0<1>UW g45.0<16,16,1>UB g45.1<16,16,1>UB {align1}; add (16) g66.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; add (16) g67.0<1>UW g47.0<16,16,1>UB g47.1<16,16,1>UB {align1}; add (16) g68.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; add (16) g69.0<1>UW g49.0<16,16,1>UB g49.1<16,16,1>UB {align1}; add (16) g70.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; add (16) g71.0<1>UW g51.0<16,16,1>UB g51.1<16,16,1>UB {align1}; add (16) g72.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; add (16) g73.0<1>UW g53.0<16,16,1>UB g53.1<16,16,1>UB {align1}; add (16) g58.0<1>UW g58.0<16,16,1>UW g39.0<16,16,1>UB {align1}; add (16) g59.0<1>UW g59.0<16,16,1>UW g40.0<16,16,1>UB {align1}; add (16) g60.0<1>UW g60.0<16,16,1>UW g41.0<16,16,1>UB {align1}; add (16) g61.0<1>UW g61.0<16,16,1>UW g42.0<16,16,1>UB {align1}; add (16) g62.0<1>UW g62.0<16,16,1>UW g43.0<16,16,1>UB {align1}; add (16) g63.0<1>UW g63.0<16,16,1>UW g44.0<16,16,1>UB {align1}; add (16) g64.0<1>UW g64.0<16,16,1>UW g45.0<16,16,1>UB {align1}; add (16) g65.0<1>UW g65.0<16,16,1>UW g46.0<16,16,1>UB {align1}; add (16) g66.0<1>UW g66.0<16,16,1>UW g47.0<16,16,1>UB {align1}; add (16) g67.0<1>UW g67.0<16,16,1>UW g48.0<16,16,1>UB {align1}; add (16) g68.0<1>UW g68.0<16,16,1>UW g49.0<16,16,1>UB {align1}; add (16) g69.0<1>UW g69.0<16,16,1>UW g50.0<16,16,1>UB {align1}; add (16) g70.0<1>UW g70.0<16,16,1>UW g51.0<16,16,1>UB {align1}; add (16) g71.0<1>UW g71.0<16,16,1>UW g52.0<16,16,1>UB {align1}; add (16) g72.0<1>UW g72.0<16,16,1>UW g53.0<16,16,1>UB {align1}; add (16) g73.0<1>UW g73.0<16,16,1>UW g54.0<16,16,1>UB {align1}; add (16) g58.0<1>UW g58.0<16,16,1>UW g39.1<16,16,1>UB {align1}; add (16) g59.0<1>UW g59.0<16,16,1>UW g40.1<16,16,1>UB {align1}; add (16) g60.0<1>UW g60.0<16,16,1>UW g41.1<16,16,1>UB {align1}; add (16) g61.0<1>UW g61.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g62.0<1>UW g62.0<16,16,1>UW g43.1<16,16,1>UB {align1}; add (16) g63.0<1>UW g63.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g64.0<1>UW g64.0<16,16,1>UW g45.1<16,16,1>UB {align1}; add (16) g65.0<1>UW g65.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g66.0<1>UW g66.0<16,16,1>UW g47.1<16,16,1>UB {align1}; add (16) g67.0<1>UW g67.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g68.0<1>UW g68.0<16,16,1>UW g49.1<16,16,1>UB {align1}; add (16) g69.0<1>UW g69.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g70.0<1>UW g70.0<16,16,1>UW g51.1<16,16,1>UB {align1}; add (16) g71.0<1>UW g71.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g72.0<1>UW g72.0<16,16,1>UW g53.1<16,16,1>UB {align1}; add (16) g73.0<1>UW g73.0<16,16,1>UW g54.1<16,16,1>UB {align1}; shr (32) g58.0<1>UW g58.0<16,16,1>UW 2UW {align1 compr}; shr (32) g60.0<1>UW g60.0<16,16,1>UW 2UW {align1 compr}; shr (32) g62.0<1>UW g62.0<16,16,1>UW 2UW {align1 compr}; shr (32) g64.0<1>UW g64.0<16,16,1>UW 2UW {align1 compr}; shr (32) g66.0<1>UW g66.0<16,16,1>UW 2UW {align1 compr}; shr (32) g68.0<1>UW g68.0<16,16,1>UW 2UW {align1 compr}; shr (32) g70.0<1>UW g70.0<16,16,1>UW 2UW {align1 compr}; shr (32) g72.0<1>UW g72.0<16,16,1>UW 2UW {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/000077500000000000000000000000001267532330400233035ustar00rootroot00000000000000xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/Makefile.am000066400000000000000000000035361267532330400253460ustar00rootroot00000000000000 INTEL_G4I = addidct.g4i \ do_iq_intra.g4i \ do_iq_non_intra.g4i \ idct.g4i \ iq_intra.g4i \ iq_non_intra.g4i \ motion_field_uv.g4i \ motion_field_y.g4i \ motion_frame_uv.g4i \ motion_frame_y.g4i \ read_field_x0y0_uv.g4i \ read_field_x0y1_uv.g4i \ read_field_x1y0_uv.g4i \ read_field_x1y1_uv.g4i \ read_field_x0y0_y.g4i \ read_field_x0y1_y.g4i \ read_field_x1y0_y.g4i \ read_field_x1y1_y.g4i \ read_frame_x0y0_uv.g4i \ read_frame_x0y1_uv.g4i \ read_frame_x1y0_uv.g4i \ read_frame_x1y1_uv.g4i \ read_frame_x0y0_y.g4i \ read_frame_x0y1_y.g4i \ read_frame_x1y0_y.g4i \ read_frame_x1y1_y.g4i INTEL_G4A = ipicture.g4a \ lib.g4a \ frame_forward.g4a \ frame_backward.g4a \ frame_f_b.g4a \ field_forward.g4a \ field_backward.g4a \ field_f_b.g4a INTEL_G4B = ipicture.g4b \ lib.g4b \ frame_forward.g4b \ frame_backward.g4b \ frame_f_b.g4b \ field_forward.g4b \ field_backward.g4b \ field_f_b.g4b INTEL_G4B_GEN5 = ipicture.g4b.gen5 \ lib.g4b.gen5 \ frame_forward.g4b.gen5 \ frame_backward.g4b.gen5 \ frame_f_b.g4b.gen5 \ field_forward.g4b.gen5 \ field_backward.g4b.gen5 \ field_f_b.g4b.gen5 EXTRA_DIST = $(INTEL_G4I) \ $(INTEL_G4A) \ $(INTEL_G4B) \ $(INTEL_G4B_GEN5) if HAVE_GEN4ASM SUFFIXES = .g4a .g4b .g4a.g4b: $(AM_V_GEN)m4 $*.g4a > $*.g4m && @INTEL_GEN4ASM@ -o $@ $*.g4m && @INTEL_GEN4ASM@ -g 5 -o $@.gen5 $*.g4m && rm $*.g4m $(INTEL_G4B): $(INTEL_GEN4ASM) $(INTEL_G4I) BUILT_SOURCES= $(INTEL_G4B) clean-local: -rm -f $(INTEL_G4B) -rm -f $(INTEL_G4B_GEN5) endif xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/addidct.g4i000066400000000000000000000157111267532330400253110ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; //restore x and y and.nz (1) null g82.2<1,1,1>UW 0x20UW {align1}; //dct_type (f0) jmpi field_dct; add (16) g58.0<1>W g83.0<16,16,1>W g58.0<16,16,2>UB {align1}; add (16) g59.0<1>W g84.0<16,16,1>W g59.0<16,16,2>UB {align1}; add (16) g60.0<1>W g85.0<16,16,1>W g60.0<16,16,2>UB {align1}; add (16) g61.0<1>W g86.0<16,16,1>W g61.0<16,16,2>UB {align1}; add (16) g62.0<1>W g87.0<16,16,1>W g62.0<16,16,2>UB {align1}; add (16) g63.0<1>W g88.0<16,16,1>W g63.0<16,16,2>UB {align1}; add (16) g64.0<1>W g89.0<16,16,1>W g64.0<16,16,2>UB {align1}; add (16) g65.0<1>W g90.0<16,16,1>W g65.0<16,16,2>UB {align1}; add (16) g66.0<1>W g91.0<16,16,1>W g66.0<16,16,2>UB {align1}; add (16) g67.0<1>W g92.0<16,16,1>W g67.0<16,16,2>UB {align1}; add (16) g68.0<1>W g93.0<16,16,1>W g68.0<16,16,2>UB {align1}; add (16) g69.0<1>W g94.0<16,16,1>W g69.0<16,16,2>UB {align1}; add (16) g70.0<1>W g95.0<16,16,1>W g70.0<16,16,2>UB {align1}; add (16) g71.0<1>W g96.0<16,16,1>W g71.0<16,16,2>UB {align1}; add (16) g72.0<1>W g97.0<16,16,1>W g72.0<16,16,2>UB {align1}; add (16) g73.0<1>W g98.0<16,16,1>W g73.0<16,16,2>UB {align1}; jmpi write_back; field_dct: add (16) g58.0<1>W g83.0<16,16,1>W g58.0<16,16,2>UB {align1}; add (16) g59.0<1>W g91.0<16,16,1>W g59.0<16,16,2>UB {align1}; add (16) g60.0<1>W g84.0<16,16,1>W g60.0<16,16,2>UB {align1}; add (16) g61.0<1>W g92.0<16,16,1>W g61.0<16,16,2>UB {align1}; add (16) g62.0<1>W g85.0<16,16,1>W g62.0<16,16,2>UB {align1}; add (16) g63.0<1>W g93.0<16,16,1>W g63.0<16,16,2>UB {align1}; add (16) g64.0<1>W g86.0<16,16,1>W g64.0<16,16,2>UB {align1}; add (16) g65.0<1>W g94.0<16,16,1>W g65.0<16,16,2>UB {align1}; add (16) g66.0<1>W g87.0<16,16,1>W g66.0<16,16,2>UB {align1}; add (16) g67.0<1>W g95.0<16,16,1>W g67.0<16,16,2>UB {align1}; add (16) g68.0<1>W g88.0<16,16,1>W g68.0<16,16,2>UB {align1}; add (16) g69.0<1>W g96.0<16,16,1>W g69.0<16,16,2>UB {align1}; add (16) g70.0<1>W g89.0<16,16,1>W g70.0<16,16,2>UB {align1}; add (16) g71.0<1>W g97.0<16,16,1>W g71.0<16,16,2>UB {align1}; add (16) g72.0<1>W g90.0<16,16,1>W g72.0<16,16,2>UB {align1}; add (16) g73.0<1>W g98.0<16,16,1>W g73.0<16,16,2>UB {align1}; write_back: mov (1) g31.8<1>UD 0x00F000FUD {align1}; mov.sat (16) g58.0<2>UB g58.0<16,16,1>W {align1}; mov.sat (16) g59.0<2>UB g59.0<16,16,1>W {align1}; mov.sat (16) g60.0<2>UB g60.0<16,16,1>W {align1}; mov.sat (16) g61.0<2>UB g61.0<16,16,1>W {align1}; mov.sat (16) g62.0<2>UB g62.0<16,16,1>W {align1}; mov.sat (16) g63.0<2>UB g63.0<16,16,1>W {align1}; mov.sat (16) g64.0<2>UB g64.0<16,16,1>W {align1}; mov.sat (16) g65.0<2>UB g65.0<16,16,1>W {align1}; mov.sat (16) g66.0<2>UB g66.0<16,16,1>W {align1}; mov.sat (16) g67.0<2>UB g67.0<16,16,1>W {align1}; mov.sat (16) g68.0<2>UB g68.0<16,16,1>W {align1}; mov.sat (16) g69.0<2>UB g69.0<16,16,1>W {align1}; mov.sat (16) g70.0<2>UB g70.0<16,16,1>W {align1}; mov.sat (16) g71.0<2>UB g71.0<16,16,1>W {align1}; mov.sat (16) g72.0<2>UB g72.0<16,16,1>W {align1}; mov.sat (16) g73.0<2>UB g73.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g58.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g59.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g60.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g61.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g62.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g63.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g64.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g65.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g66.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g67.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g68.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g69.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g70.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g71.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g72.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g73.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g31.8<1>UD 0x0070007UD { align1 }; shr (2) g31.0<1>UD g31.0<2,2,1>UD 1D {align1}; add (16) g74.0<1>W g99.0<16,16,1>W g74.0<16,16,1>UW {align1}; add (16) g75.0<1>W g100.0<16,16,1>W g75.0<16,16,1>UW {align1}; add (16) g76.0<1>W g101.0<16,16,1>W g76.0<16,16,1>UW {align1}; add (16) g77.0<1>W g102.0<16,16,1>W g77.0<16,16,1>UW {align1}; mov.sat (16) g74.0<2>UB g74.0<16,16,1>W {align1}; mov.sat (16) g75.0<2>UB g75.0<16,16,1>W {align1}; mov.sat (16) g76.0<2>UB g76.0<16,16,1>W {align1}; mov.sat (16) g77.0<2>UB g77.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g74.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g75.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g76.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g77.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V add (16) g78.0<1>UW g103.0<16,16,1>W g78.0<16,16,1>UW {align1}; add (16) g79.0<1>UW g104.0<16,16,1>W g79.0<16,16,1>UW {align1}; add (16) g80.0<1>UW g105.0<16,16,1>W g80.0<16,16,1>UW {align1}; add (16) g81.0<1>UW g106.0<16,16,1>W g81.0<16,16,1>UW {align1}; mov.sat (16) g78.0<2>UB g78.0<16,16,1>W {align1}; mov.sat (16) g79.0<2>UB g79.0<16,16,1>W {align1}; mov.sat (16) g80.0<2>UB g80.0<16,16,1>W {align1}; mov.sat (16) g81.0<2>UB g81.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g78.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g79.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g80.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g81.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/do_iq_intra.g4i000066400000000000000000000055631267532330400262110ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g112~g115: intra IQ matrix in UW format (in order to use instruction compress), copys from g1~g2 g[a0.0]:DCT data of a block g125: ip before jump if(v==0 && u==0 && intra_mb) F''[v][u] = QF[v][u] * intra_dc_mult else F''[v][u] = (QF[v][u]*W[w][v][u]*quantiser_scale*2)/32 */ DO_IQ_INTRA: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mov (1) g111.0<1>W g[a0.0]<1,1,1>W {align1}; mul (16) g116.0<1>D g[a0.0]<8,8,1>W g112.0<8,8,1>UW {align1 compr}; mul (16) g116.0<1>D g116.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g116.0<1>D g116.0<8,8,1>D 4UW {align1 compr}; mul (1) g116.0<1>D g111<1,1,1>W g109.4<1,1,1>UW {align1}; //intra_dc_mult add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g118.0<1>D g[a0.0]<8,8,1>W g113.0<8,8,1>UW {align1 compr}; mul (16) g118.0<1>D g118.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g118.0<1>D g118.0<8,8,1>D 4UW {align1 compr}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g120.0<1>D g[a0.0]<8,8,1>W g114.0<8,8,1>UW {align1 compr}; mul (16) g120.0<1>D g120.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g120.0<1>D g120.0<8,8,1>D 4UW {align1 compr}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g122.0<1>D g[a0.0]<8,8,1>W g115.0<8,8,1>UW {align1 compr}; mul (16) g122.0<1>D g122.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g122.0<1>D g122.0<8,8,1>D 4UW {align1 compr}; add (1) ip g125.0<1,1,1>UD 0x20UD {align1}; //jump back xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/do_iq_non_intra.g4i000066400000000000000000000052771267532330400270650ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g112~g115: intra IQ matrix in UW format (in order to use instruction compress), copys from g1~g2 g[a0.0]:DCT data of a block g125: ip before jump F''[v][u]=(((QF[v][u]*2)+Sign(QF[v][u])) * W[w][v][u] * quantiser_scale)/32; */ DO_IQ_NON_INTRA: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g116.0<1>D g[a0.0]<8,8,1>W g112.0<8,8,1>UW {align1 compr}; mul (16) g116.0<1>D g116.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g116.0<1>D g116.0<8,8,1>D 4UW {align1 compr}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g118.0<1>D g[a0.0]<8,8,1>W g113.0<8,8,1>UW {align1 compr}; mul (16) g118.0<1>D g118.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g118.0<1>D g118.0<8,8,1>D 4UW {align1 compr}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g120.0<1>D g[a0.0]<8,8,1>W g114.0<8,8,1>UW {align1 compr}; mul (16) g120.0<1>D g120.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g120.0<1>D g120.0<8,8,1>D 4UW {align1 compr}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; mul (16) g122.0<1>D g[a0.0]<8,8,1>W g115.0<8,8,1>UW {align1 compr}; mul (16) g122.0<1>D g122.0<8,8,1>D g109.0<8,8,0>UW {align1 compr}; asr (16) g122.0<1>D g122.0<8,8,1>D 4UW {align1 compr}; add (1) ip g125.0<1,1,1>UD 0x20UD {align1}; //jump back xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_backward.g4a000066400000000000000000000116761267532330400266340ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov(2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; /*field 0 of Y*/ asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x2000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`7') define(`mv1',`g82.20') define(`mv2',`g82.22') include(`motion_field_y.g4i') mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 of Y*/ asr (2) g31.14<1>W g82.28<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x8000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`7') define(`mv1',`g82.28') define(`mv2',`g82.30') include(`motion_field_y.g4i') mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g82.20<1>W g82.20<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and.nz (1) null g82.2<1,1,1>UW 0x2000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u', `8') define(`surface_v', `9') define(`mv1',`g82.20') define(`mv2',`g82.22') include(`motion_field_uv.g4i') mov (8) g74.0<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.0<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.0<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.0<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.0<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.0<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.0<1>UW g39.0<8,8,1>UW {align1}; /*field 1 of UV*/ asr (2) g82.28<1>W g82.28<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.28<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and.nz (1) null g82.2<1,1,1>UW 0x8000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g82.28') define(`mv2',`g82.30') include(`motion_field_uv.g4i') mov (8) g74.16<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.16<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.16<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.16<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.16<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.16<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.16<1>UW g39.0<8,8,1>UW {align1}; include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_backward.g4b000066400000000000000000000733171267532330400266350ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a543dad, 0x00450a54, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a5c3dad, 0x00450a5c, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_backward.g4b.gen5000066400000000000000000000733171267532330400274720ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a543dad, 0x00450a54, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a5c3dad, 0x00450a5c, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_f_b.g4a000066400000000000000000000222351267532330400255750ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov(2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; /*field 0 forward prediction of Y*/ asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x1000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g82.16') define(`mv2',`g82.18') include(`motion_field_y.g4i') mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 forward prediction of Y*/ asr (2) g31.14<1>W g82.24<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x4000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g82.24') define(`mv2',`g82.26') include(`motion_field_y.g4i') mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 forward prediction of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g82.16<1>W g82.16<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x1000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u', `5') define(`surface_v', `6') define(`mv1',`g82.16') define(`mv2',`g82.18') include(`motion_field_uv.g4i') mov (8) g74.0<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.0<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.0<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.0<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.0<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.0<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.0<1>UW g39.0<8,8,1>UW {align1}; /*field 1 forward prediction of UV*/ asr (2) g82.24<1>W g82.24<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.24<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x4000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g82.24') define(`mv2',`g82.26') include(`motion_field_uv.g4i') mov (8) g74.16<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.16<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.16<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.16<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.16<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.16<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.16<1>UW g39.0<8,8,1>UW {align1}; /*field 0 backward prediction of Y*/ mov(2) g31.0<1>UD g82.12<2,2,1>UW {align1}; asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x2000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`7') define(`mv1',`g82.20') define(`mv2',`g82.22') include(`motion_field_y.g4i') avg.sat (16) g58.0<1>UW g58.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg.sat (16) g60.0<1>UW g60.0<16,16,1>UW g33.0<16,16,1>UW {align1}; avg.sat (16) g62.0<1>UW g62.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg.sat (16) g64.0<1>UW g64.0<16,16,1>UW g35.0<16,16,1>UW {align1}; avg.sat (16) g66.0<1>UW g66.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg.sat (16) g68.0<1>UW g68.0<16,16,1>UW g37.0<16,16,1>UW {align1}; avg.sat (16) g70.0<1>UW g70.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg.sat (16) g72.0<1>UW g72.0<16,16,1>UW g39.0<16,16,1>UW {align1}; /*field 1 backward prediction of Y*/ asr (2) g31.14<1>W g82.28<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x8000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`7') define(`mv1',`g82.28') define(`mv2',`g82.30') include(`motion_field_y.g4i') avg.sat (16) g59.0<1>UW g59.0<16,16,1>UW g32.0<16,16,1>UW {align1}; avg.sat (16) g61.0<1>UW g61.0<16,16,1>UW g33.0<16,16,1>UW {align1}; avg.sat (16) g63.0<1>UW g63.0<16,16,1>UW g34.0<16,16,1>UW {align1}; avg.sat (16) g65.0<1>UW g65.0<16,16,1>UW g35.0<16,16,1>UW {align1}; avg.sat (16) g67.0<1>UW g67.0<16,16,1>UW g36.0<16,16,1>UW {align1}; avg.sat (16) g69.0<1>UW g69.0<16,16,1>UW g37.0<16,16,1>UW {align1}; avg.sat (16) g71.0<1>UW g71.0<16,16,1>UW g38.0<16,16,1>UW {align1}; avg.sat (16) g73.0<1>UW g73.0<16,16,1>UW g39.0<16,16,1>UW {align1}; /*field 0 backward prediction of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g82.20<1>W g82.20<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x2000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u', `8') define(`surface_v', `9') define(`mv1',`g82.20') define(`mv2',`g82.22') include(`motion_field_uv.g4i') avg.sat (8) g74.0<1>UW g74.0<8,8,1>UW g32.0<8,8,1>UW {align1}; avg.sat (8) g75.0<1>UW g75.0<8,8,1>UW g33.0<8,8,1>UW {align1}; avg.sat (8) g76.0<1>UW g76.0<8,8,1>UW g34.0<8,8,1>UW {align1}; avg.sat (8) g77.0<1>UW g77.0<8,8,1>UW g35.0<8,8,1>UW {align1}; avg.sat (8) g78.0<1>UW g78.0<8,8,1>UW g36.0<8,8,1>UW {align1}; avg.sat (8) g79.0<1>UW g79.0<8,8,1>UW g37.0<8,8,1>UW {align1}; avg.sat (8) g80.0<1>UW g80.0<8,8,1>UW g38.0<8,8,1>UW {align1}; avg.sat (8) g81.0<1>UW g81.0<8,8,1>UW g39.0<8,8,1>UW {align1}; /*field 1 backward prediction of UV*/ asr (2) g82.28<1>W g82.28<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.28<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x8000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`mv1',`g82.28') define(`mv2',`g82.30') include(`motion_field_uv.g4i') avg.sat (8) g74.16<1>UW g74.16<8,8,1>UW g32.0<8,8,1>UW {align1}; avg.sat (8) g75.16<1>UW g75.16<8,8,1>UW g33.0<8,8,1>UW {align1}; avg.sat (8) g76.16<1>UW g76.16<8,8,1>UW g34.0<8,8,1>UW {align1}; avg.sat (8) g77.16<1>UW g77.16<8,8,1>UW g35.0<8,8,1>UW {align1}; avg.sat (8) g78.16<1>UW g78.16<8,8,1>UW g36.0<8,8,1>UW {align1}; avg.sat (8) g79.16<1>UW g79.16<8,8,1>UW g37.0<8,8,1>UW {align1}; avg.sat (8) g80.16<1>UW g80.16<8,8,1>UW g38.0<8,8,1>UW {align1}; avg.sat (8) g81.16<1>UW g81.16<8,8,1>UW g39.0<8,8,1>UW {align1}; include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_f_b.g4b000066400000000000000000001541311267532330400255770ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a503dad, 0x00450a50, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a583dad, 0x00450a58, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x27402529, 0x00b10740, 0x00b10400 }, { 0x80800042, 0x27802529, 0x00b10780, 0x00b10420 }, { 0x80800042, 0x27c02529, 0x00b107c0, 0x00b10440 }, { 0x80800042, 0x28002529, 0x00b10800, 0x00b10460 }, { 0x80800042, 0x28402529, 0x00b10840, 0x00b10480 }, { 0x80800042, 0x28802529, 0x00b10880, 0x00b104a0 }, { 0x80800042, 0x28c02529, 0x00b108c0, 0x00b104c0 }, { 0x80800042, 0x29002529, 0x00b10900, 0x00b104e0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x27602529, 0x00b10760, 0x00b10400 }, { 0x80800042, 0x27a02529, 0x00b107a0, 0x00b10420 }, { 0x80800042, 0x27e02529, 0x00b107e0, 0x00b10440 }, { 0x80800042, 0x28202529, 0x00b10820, 0x00b10460 }, { 0x80800042, 0x28602529, 0x00b10860, 0x00b10480 }, { 0x80800042, 0x28a02529, 0x00b108a0, 0x00b104a0 }, { 0x80800042, 0x28e02529, 0x00b108e0, 0x00b104c0 }, { 0x80800042, 0x29202529, 0x00b10920, 0x00b104e0 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a543dad, 0x00450a54, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x80600042, 0x29402529, 0x008d0940, 0x008d0400 }, { 0x80600042, 0x29602529, 0x008d0960, 0x008d0420 }, { 0x80600042, 0x29802529, 0x008d0980, 0x008d0440 }, { 0x80600042, 0x29a02529, 0x008d09a0, 0x008d0460 }, { 0x80600042, 0x29c02529, 0x008d09c0, 0x008d0480 }, { 0x80600042, 0x29e02529, 0x008d09e0, 0x008d04a0 }, { 0x80600042, 0x2a002529, 0x008d0a00, 0x008d04c0 }, { 0x80600042, 0x2a202529, 0x008d0a20, 0x008d04e0 }, { 0x0020000c, 0x2a5c3dad, 0x00450a5c, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a008 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a008 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x80600042, 0x29502529, 0x008d0950, 0x008d0400 }, { 0x80600042, 0x29702529, 0x008d0970, 0x008d0420 }, { 0x80600042, 0x29902529, 0x008d0990, 0x008d0440 }, { 0x80600042, 0x29b02529, 0x008d09b0, 0x008d0460 }, { 0x80600042, 0x29d02529, 0x008d09d0, 0x008d0480 }, { 0x80600042, 0x29f02529, 0x008d09f0, 0x008d04a0 }, { 0x80600042, 0x2a102529, 0x008d0a10, 0x008d04c0 }, { 0x80600042, 0x2a302529, 0x008d0a30, 0x008d04e0 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_f_b.g4b.gen5000066400000000000000000001541311267532330400264340ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a503dad, 0x00450a50, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a583dad, 0x00450a58, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x27402529, 0x00b10740, 0x00b10400 }, { 0x80800042, 0x27802529, 0x00b10780, 0x00b10420 }, { 0x80800042, 0x27c02529, 0x00b107c0, 0x00b10440 }, { 0x80800042, 0x28002529, 0x00b10800, 0x00b10460 }, { 0x80800042, 0x28402529, 0x00b10840, 0x00b10480 }, { 0x80800042, 0x28802529, 0x00b10880, 0x00b104a0 }, { 0x80800042, 0x28c02529, 0x00b108c0, 0x00b104c0 }, { 0x80800042, 0x29002529, 0x00b10900, 0x00b104e0 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a007 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a007 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a007 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x80800042, 0x27602529, 0x00b10760, 0x00b10400 }, { 0x80800042, 0x27a02529, 0x00b107a0, 0x00b10420 }, { 0x80800042, 0x27e02529, 0x00b107e0, 0x00b10440 }, { 0x80800042, 0x28202529, 0x00b10820, 0x00b10460 }, { 0x80800042, 0x28602529, 0x00b10860, 0x00b10480 }, { 0x80800042, 0x28a02529, 0x00b108a0, 0x00b104a0 }, { 0x80800042, 0x28e02529, 0x00b108e0, 0x00b104c0 }, { 0x80800042, 0x29202529, 0x00b10920, 0x00b104e0 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a543dad, 0x00450a54, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x20002000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a54, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a56, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x80600042, 0x29402529, 0x008d0940, 0x008d0400 }, { 0x80600042, 0x29602529, 0x008d0960, 0x008d0420 }, { 0x80600042, 0x29802529, 0x008d0980, 0x008d0440 }, { 0x80600042, 0x29a02529, 0x008d09a0, 0x008d0460 }, { 0x80600042, 0x29c02529, 0x008d09c0, 0x008d0480 }, { 0x80600042, 0x29e02529, 0x008d09e0, 0x008d04a0 }, { 0x80600042, 0x2a002529, 0x008d0a00, 0x008d04c0 }, { 0x80600042, 0x2a202529, 0x008d0a20, 0x008d04e0 }, { 0x0020000c, 0x2a5c3dad, 0x00450a5c, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a5c, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x80008000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a5c, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a5e, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a009 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a008 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a009 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a008 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a009 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x80600042, 0x29502529, 0x008d0950, 0x008d0400 }, { 0x80600042, 0x29702529, 0x008d0970, 0x008d0420 }, { 0x80600042, 0x29902529, 0x008d0990, 0x008d0440 }, { 0x80600042, 0x29b02529, 0x008d09b0, 0x008d0460 }, { 0x80600042, 0x29d02529, 0x008d09d0, 0x008d0480 }, { 0x80600042, 0x29f02529, 0x008d09f0, 0x008d04a0 }, { 0x80600042, 0x2a102529, 0x008d0a10, 0x008d04c0 }, { 0x80600042, 0x2a302529, 0x008d0a30, 0x008d04e0 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_forward.g4a000066400000000000000000000122221267532330400265060ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; /*field 0 of Y*/ asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x1000UW {align1}; //motion vertical field select (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g82.16') define(`mv2',`g82.18') include(`motion_field_y.g4i') mov (8) g58.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g60.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g62.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g64.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g66.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g68.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g70.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g72.0<1>UD g39.0<8,8,1>UD {align1}; /*field 1 of Y*/ asr (2) g31.14<1>W g82.24<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x4000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface',`4') define(`mv1',`g82.24') define(`mv2',`g82.26') include(`motion_field_y.g4i') mov (8) g59.0<1>UD g32.0<8,8,1>UD {align1}; mov (8) g61.0<1>UD g33.0<8,8,1>UD {align1}; mov (8) g63.0<1>UD g34.0<8,8,1>UD {align1}; mov (8) g65.0<1>UD g35.0<8,8,1>UD {align1}; mov (8) g67.0<1>UD g36.0<8,8,1>UD {align1}; mov (8) g69.0<1>UD g37.0<8,8,1>UD {align1}; mov (8) g71.0<1>UD g38.0<8,8,1>UD {align1}; mov (8) g73.0<1>UD g39.0<8,8,1>UD {align1}; /*field 0 of UV*/ shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g82.16<1>W g82.16<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x1000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u', `5') define(`surface_v', `6') define(`mv1',`g82.16') define(`mv2',`g82.18') include(`motion_field_uv.g4i') mov (8) g74.0<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.0<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.0<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.0<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.0<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.0<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.0<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.0<1>UW g39.0<8,8,1>UW {align1}; /*field 1 of UV*/ asr (2) g82.24<1>W g82.24<2,2,1>W 1W {align1}; asr (2) g31.14<1>W g82.24<2,2,1>W 1W {align1}; shl (1) g31.16<1>W g31.16<1,1,1>W 1W {align1}; add (2) g115.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; and (1) g115.4<1>UD g115.4<1,1,1>UD 0xFFFFFFFEUD {align1}; and.nz (1) null g82.2<1,1,1>UW 0x4000UW {align1}; (f0) add (1) g115.4<1>UD g115.4<1,1,1>UD 1UD {align1}; define(`surface_u', `5') define(`surface_v', `6') define(`mv1',`g82.24') define(`mv2',`g82.26') include(`motion_field_uv.g4i') mov (8) g74.16<1>UW g32.0<8,8,1>UW {align1}; mov (8) g75.16<1>UW g33.0<8,8,1>UW {align1}; mov (8) g76.16<1>UW g34.0<8,8,1>UW {align1}; mov (8) g77.16<1>UW g35.0<8,8,1>UW {align1}; mov (8) g78.16<1>UW g36.0<8,8,1>UW {align1}; mov (8) g79.16<1>UW g37.0<8,8,1>UW {align1}; mov (8) g80.16<1>UW g38.0<8,8,1>UW {align1}; mov (8) g81.16<1>UW g39.0<8,8,1>UW {align1}; include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_forward.g4b000066400000000000000000000734751267532330400265300ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000045 }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002f }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000017 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x008d0e60, 0x0411a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000013 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x008d0e60, 0x0411a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x008d0e60, 0x0418a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a503dad, 0x00450a50, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a583dad, 0x00450a58, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000032 }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000029 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0414a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001d }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x008d0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x008d0e60, 0x0414a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x008d0e60, 0x0411a005 }, { 0x00800031, 0x26201d29, 0x008d0e60, 0x0411a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x00ad0e60, 0x0414a005 }, { 0x00800031, 0x25a01d29, 0x00ad0e60, 0x0414a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/field_forward.g4b.gen5000066400000000000000000000734751267532330400273650ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27400021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27800021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27c00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28000021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28400021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28800021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28c00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29000021, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20002dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000008a }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x00800040, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x00800040, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x00800040, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x00800040, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x00800040, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x00800040, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x00800040, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x00800040, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10501 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10541 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b10581 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b105c1 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10601 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10641 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b10681 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b106c1 }, { 0x00800040, 0x24004529, 0x00b10400, 0x00b10541 }, { 0x00800040, 0x24204529, 0x00b10420, 0x00b10581 }, { 0x00800040, 0x24404529, 0x00b10440, 0x00b105c1 }, { 0x00800040, 0x24604529, 0x00b10460, 0x00b10601 }, { 0x00800040, 0x24804529, 0x00b10480, 0x00b10641 }, { 0x00800040, 0x24a04529, 0x00b104a0, 0x00b10681 }, { 0x00800040, 0x24c04529, 0x00b104c0, 0x00b106c1 }, { 0x00800040, 0x24e04529, 0x00b104e0, 0x00b10701 }, { 0x00800008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00800008, 0x24202d29, 0x00b10420, 0x00020002 }, { 0x00800008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00800008, 0x24602d29, 0x00b10460, 0x00020002 }, { 0x00800008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00800008, 0x24a02d29, 0x00b104a0, 0x00020002 }, { 0x00800008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00800008, 0x24e02d29, 0x00b104e0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b106c1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000058 }, { 0x01000005, 0x20002dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x27001d29, 0x408d0e60, 0x0218a004 }, { 0x80800042, 0x24004629, 0x00b10500, 0x00b10540 }, { 0x80800042, 0x24204629, 0x00b10540, 0x00b10580 }, { 0x80800042, 0x24404629, 0x00b10580, 0x00b105c0 }, { 0x80800042, 0x24604629, 0x00b105c0, 0x00b10600 }, { 0x80800042, 0x24804629, 0x00b10600, 0x00b10640 }, { 0x80800042, 0x24a04629, 0x00b10640, 0x00b10680 }, { 0x80800042, 0x24c04629, 0x00b10680, 0x00b106c0 }, { 0x80800042, 0x24e04629, 0x00b106c0, 0x00b10700 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000026 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25401d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00800031, 0x25c01d29, 0x408d0e60, 0x0218a004 }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000002 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007001f }, { 0x00800031, 0x26001d29, 0x408d0e60, 0x0288a004 }, { 0x00800001, 0x24000229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x24400229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x24600229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x24800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00b106c0, 0x00000000 }, { 0x00600001, 0x27600021, 0x008d0400, 0x00000000 }, { 0x00600001, 0x27a00021, 0x008d0420, 0x00000000 }, { 0x00600001, 0x27e00021, 0x008d0440, 0x00000000 }, { 0x00600001, 0x28200021, 0x008d0460, 0x00000000 }, { 0x00600001, 0x28600021, 0x008d0480, 0x00000000 }, { 0x00600001, 0x28a00021, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x28e00021, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x29200021, 0x008d04e0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x2a503dad, 0x00450a50, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x10001000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a50, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a52, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29400129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29600129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29800129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29a00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29c00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29e00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a000129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a200129, 0x008d04e0, 0x00000000 }, { 0x0020000c, 0x2a583dad, 0x00450a58, 0x00010001 }, { 0x0020000c, 0x23ee3dad, 0x00450a58, 0x00010001 }, { 0x00000009, 0x23f03dad, 0x002103f0, 0x00010001 }, { 0x00200040, 0x2e603421, 0x004503e0, 0x004503ee }, { 0x00000005, 0x2e640c21, 0x00210e64, 0xfffffffe }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x40004000 }, { 0x00010040, 0x2e640c21, 0x00210e64, 0x00000001 }, { 0x01000005, 0x20003dbc, 0x00210a58, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000064 }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0001000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800040, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800040, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800040, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800040, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0501 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0521 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0541 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0561 }, { 0x00800040, 0x24004529, 0x00ad0400, 0x00ad0521 }, { 0x00800040, 0x24204529, 0x00ad0420, 0x00ad0541 }, { 0x00800040, 0x24404529, 0x00ad0440, 0x00ad0561 }, { 0x00800040, 0x24604529, 0x00ad0460, 0x00ad0581 }, { 0x00800040, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800040, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800040, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800040, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05a1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05c1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad05e1 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0601 }, { 0x00800040, 0x24804529, 0x00ad0480, 0x00ad05c1 }, { 0x00800040, 0x24a04529, 0x00ad04a0, 0x00ad05e1 }, { 0x00800040, 0x24c04529, 0x00ad04c0, 0x00ad0601 }, { 0x00800040, 0x24e04529, 0x00ad04e0, 0x00ad0621 }, { 0x00a02008, 0x24002d29, 0x00b10400, 0x00020002 }, { 0x00a02008, 0x24402d29, 0x00b10440, 0x00020002 }, { 0x00a02008, 0x24802d29, 0x00b10480, 0x00020002 }, { 0x00a02008, 0x24c02d29, 0x00b104c0, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000052 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0248a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0501 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0521 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0541 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0561 }, { 0x00800042, 0x24804629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x24a04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x24c04629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x24e04629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000003a }, { 0x01000005, 0x20003dbc, 0x00210a5a, 0x00010001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x408d0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x408d0e60, 0x0248a006 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0000000f }, { 0x00000040, 0x2e640c21, 0x00210e64, 0x00000008 }, { 0x00800031, 0x25801d29, 0x408d0e60, 0x0218a005 }, { 0x00800031, 0x26201d29, 0x408d0e60, 0x0218a006 }, { 0x00800042, 0x24004629, 0x00ad0500, 0x00ad0520 }, { 0x00800042, 0x24204629, 0x00ad0520, 0x00ad0540 }, { 0x00800042, 0x24404629, 0x00ad0540, 0x00ad0560 }, { 0x00800042, 0x24604629, 0x00ad0560, 0x00ad0580 }, { 0x00800042, 0x24804629, 0x00ad05a0, 0x00ad05c0 }, { 0x00800042, 0x24a04629, 0x00ad05c0, 0x00ad05e0 }, { 0x00800042, 0x24c04629, 0x00ad05e0, 0x00ad0600 }, { 0x00800042, 0x24e04629, 0x00ad0600, 0x00ad0620 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x2e680061, 0x00000000, 0x0007000f }, { 0x00800031, 0x25001d29, 0x40ad0e60, 0x0248a005 }, { 0x00800031, 0x25a01d29, 0x40ad0e60, 0x0248a006 }, { 0x00800001, 0x24000229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x24200229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x24400229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x24600229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x24800229, 0x00ad05a0, 0x00000000 }, { 0x00800001, 0x24a00229, 0x00ad05c0, 0x00000000 }, { 0x00800001, 0x24c00229, 0x00ad05e0, 0x00000000 }, { 0x00800001, 0x24e00229, 0x00ad0600, 0x00000000 }, { 0x00600001, 0x29500129, 0x008d0400, 0x00000000 }, { 0x00600001, 0x29700129, 0x008d0420, 0x00000000 }, { 0x00600001, 0x29900129, 0x008d0440, 0x00000000 }, { 0x00600001, 0x29b00129, 0x008d0460, 0x00000000 }, { 0x00600001, 0x29d00129, 0x008d0480, 0x00000000 }, { 0x00600001, 0x29f00129, 0x008d04a0, 0x00000000 }, { 0x00600001, 0x2a100129, 0x008d04c0, 0x00000000 }, { 0x00600001, 0x2a300129, 0x008d04e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_backward.g4a000066400000000000000000000047121267532330400266340ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov(2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; //Y, (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface', `7') define(`mv1', `g82.20') define(`mv2', `g82.22') include(`motion_frame_y.g4i') //UV, (x', y') = (x >> 1, y >> 1) + (motion_vector.x >> 2, motion_vector.y >> 2) shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.20<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface1', `8') define(`input_surface2', `9') include(`motion_frame_uv.g4i') include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_backward.g4b000066400000000000000000000475071267532330400266460ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005f }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a008 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a009 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a009 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000025 }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a008 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a009 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x008d0400, 0x0414a008 }, { 0x00800031, 0x25001d29, 0x008d0400, 0x0414a009 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_backward.g4b.gen5000066400000000000000000000475071267532330400275030ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000be }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000090 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a008 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a009 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a009 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a008 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a009 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x408d0400, 0x0248a008 }, { 0x00800031, 0x25001d29, 0x408d0400, 0x0248a009 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_f_b.g4a000066400000000000000000000125551267532330400256100ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; //Y, Forward mov (1) g31.8<1>UD 0x0070007UD {align1}; define(`input_surface', `4') define(`mv1', `g82.16') define(`mv2', `g82.18') asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; include(`motion_frame_y.g4i') //Save Forward mov (16) g108.0<1>UD g58.0<16,16,1>UD {align1 compr}; mov (16) g110.0<1>UD g60.0<16,16,1>UD {align1 compr}; mov (16) g112.0<1>UD g62.0<16,16,1>UD {align1 compr}; mov (16) g114.0<1>UD g64.0<16,16,1>UD {align1 compr}; mov (16) g116.0<1>UD g66.0<16,16,1>UD {align1 compr}; mov (16) g118.0<1>UD g68.0<16,16,1>UD {align1 compr}; mov (16) g120.0<1>UD g70.0<16,16,1>UD {align1 compr}; mov (16) g122.0<1>UD g72.0<16,16,1>UD {align1 compr}; //Y, Backward define(`input_surface', `7') define(`mv1', `g82.20') define(`mv2', `g82.22') asr (2) g31.14<1>W g82.20<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; include(`motion_frame_y.g4i') //Average Forward and Backward avg.sat (16) g58.0<1>UW g58.0<16,16,1>UW g108.0<16,16,1>UW {align1}; avg.sat (16) g59.0<1>UW g59.0<16,16,1>UW g109.0<16,16,1>UW {align1}; avg.sat (16) g60.0<1>UW g60.0<16,16,1>UW g110.0<16,16,1>UW {align1}; avg.sat (16) g61.0<1>UW g61.0<16,16,1>UW g111.0<16,16,1>UW {align1}; avg.sat (16) g62.0<1>UW g62.0<16,16,1>UW g112.0<16,16,1>UW {align1}; avg.sat (16) g63.0<1>UW g63.0<16,16,1>UW g113.0<16,16,1>UW {align1}; avg.sat (16) g64.0<1>UW g64.0<16,16,1>UW g114.0<16,16,1>UW {align1}; avg.sat (16) g65.0<1>UW g65.0<16,16,1>UW g115.0<16,16,1>UW {align1}; avg.sat (16) g66.0<1>UW g66.0<16,16,1>UW g116.0<16,16,1>UW {align1}; avg.sat (16) g67.0<1>UW g67.0<16,16,1>UW g117.0<16,16,1>UW {align1}; avg.sat (16) g68.0<1>UW g68.0<16,16,1>UW g118.0<16,16,1>UW {align1}; avg.sat (16) g69.0<1>UW g69.0<16,16,1>UW g119.0<16,16,1>UW {align1}; avg.sat (16) g70.0<1>UW g70.0<16,16,1>UW g120.0<16,16,1>UW {align1}; avg.sat (16) g71.0<1>UW g71.0<16,16,1>UW g121.0<16,16,1>UW {align1}; avg.sat (16) g72.0<1>UW g72.0<16,16,1>UW g122.0<16,16,1>UW {align1}; avg.sat (16) g73.0<1>UW g73.0<16,16,1>UW g123.0<16,16,1>UW {align1}; //UV, Forward shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.16<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface1', `5') define(`input_surface2', `6') mov (1) g32.8<1>UD 0x007000fUD {align1}; include(`motion_frame_uv.g4i') //Save UV Forward mov (16) g108.0<1>UB g74.0<16,16,2>UB {align1}; mov (16) g108.16<1>UB g75.0<16,16,2>UB {align1}; mov (16) g109.0<1>UB g76.0<16,16,2>UB {align1}; mov (16) g109.16<1>UB g77.0<16,16,2>UB {align1}; mov (16) g110.0<1>UB g78.0<16,16,2>UB {align1}; mov (16) g110.16<1>UB g79.0<16,16,2>UB {align1}; mov (16) g111.0<1>UB g80.0<16,16,2>UB {align1}; mov (16) g111.16<1>UB g81.0<16,16,2>UB {align1}; //UV, Backward asr (2) g31.14<1>W g82.20<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface1', `8') define(`input_surface2', `9') include(`motion_frame_uv.g4i') //Average Forward and Backward avg.sat (16) g74.0<1>UW g74.0<16,16,1>UW g108.0<16,16,1>UB {align1}; avg.sat (16) g75.0<1>UW g75.0<16,16,1>UW g108.16<16,16,1>UB {align1}; avg.sat (16) g76.0<1>UW g76.0<16,16,1>UW g109.0<16,16,1>UB {align1}; avg.sat (16) g77.0<1>UW g77.0<16,16,1>UW g109.16<16,16,1>UB {align1}; avg.sat (16) g78.0<1>UW g78.0<16,16,1>UW g110.0<16,16,1>UB {align1}; avg.sat (16) g79.0<1>UW g79.0<16,16,1>UW g110.16<16,16,1>UB {align1}; avg.sat (16) g80.0<1>UW g80.0<16,16,1>UW g111.0<16,16,1>UB {align1}; avg.sat (16) g81.0<1>UW g81.0<16,16,1>UW g111.16<16,16,1>UB {align1}; include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_f_b.g4b000066400000000000000000001104051267532330400256020ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005f }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00802001, 0x2d800021, 0x00b10740, 0x00000000 }, { 0x00802001, 0x2dc00021, 0x00b10780, 0x00000000 }, { 0x00802001, 0x2e000021, 0x00b107c0, 0x00000000 }, { 0x00802001, 0x2e400021, 0x00b10800, 0x00000000 }, { 0x00802001, 0x2e800021, 0x00b10840, 0x00000000 }, { 0x00802001, 0x2ec00021, 0x00b10880, 0x00000000 }, { 0x00802001, 0x2f000021, 0x00b108c0, 0x00000000 }, { 0x00802001, 0x2f400021, 0x00b10900, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005f }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a007 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x80800042, 0x27402529, 0x00b10740, 0x00b10d80 }, { 0x80800042, 0x27602529, 0x00b10760, 0x00b10da0 }, { 0x80800042, 0x27802529, 0x00b10780, 0x00b10dc0 }, { 0x80800042, 0x27a02529, 0x00b107a0, 0x00b10de0 }, { 0x80800042, 0x27c02529, 0x00b107c0, 0x00b10e00 }, { 0x80800042, 0x27e02529, 0x00b107e0, 0x00b10e20 }, { 0x80800042, 0x28002529, 0x00b10800, 0x00b10e40 }, { 0x80800042, 0x28202529, 0x00b10820, 0x00b10e60 }, { 0x80800042, 0x28402529, 0x00b10840, 0x00b10e80 }, { 0x80800042, 0x28602529, 0x00b10860, 0x00b10ea0 }, { 0x80800042, 0x28802529, 0x00b10880, 0x00b10ec0 }, { 0x80800042, 0x28a02529, 0x00b108a0, 0x00b10ee0 }, { 0x80800042, 0x28c02529, 0x00b108c0, 0x00b10f00 }, { 0x80800042, 0x28e02529, 0x00b108e0, 0x00b10f20 }, { 0x80800042, 0x29002529, 0x00b10900, 0x00b10f40 }, { 0x80800042, 0x29202529, 0x00b10920, 0x00b10f60 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a005 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a006 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a006 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000025 }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a005 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a006 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x008d0400, 0x0414a005 }, { 0x00800031, 0x25001d29, 0x008d0400, 0x0414a006 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x2d800231, 0x00b20940, 0x00000000 }, { 0x00800001, 0x2d900231, 0x00b20960, 0x00000000 }, { 0x00800001, 0x2da00231, 0x00b20980, 0x00000000 }, { 0x00800001, 0x2db00231, 0x00b209a0, 0x00000000 }, { 0x00800001, 0x2dc00231, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x2dd00231, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x2de00231, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x2df00231, 0x00b20a20, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a008 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a009 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a009 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000025 }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a008 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a008 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a009 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x008d0400, 0x0414a008 }, { 0x00800031, 0x25001d29, 0x008d0400, 0x0414a009 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x80800042, 0x29404529, 0x00b10940, 0x00b10d80 }, { 0x80800042, 0x29604529, 0x00b10960, 0x00b10d90 }, { 0x80800042, 0x29804529, 0x00b10980, 0x00b10da0 }, { 0x80800042, 0x29a04529, 0x00b109a0, 0x00b10db0 }, { 0x80800042, 0x29c04529, 0x00b109c0, 0x00b10dc0 }, { 0x80800042, 0x29e04529, 0x00b109e0, 0x00b10dd0 }, { 0x80800042, 0x2a004529, 0x00b10a00, 0x00b10de0 }, { 0x80800042, 0x2a204529, 0x00b10a20, 0x00b10df0 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_f_b.g4b.gen5000066400000000000000000001104051267532330400264370ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000be }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000090 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00802001, 0x2d800021, 0x00b10740, 0x00000000 }, { 0x00802001, 0x2dc00021, 0x00b10780, 0x00000000 }, { 0x00802001, 0x2e000021, 0x00b107c0, 0x00000000 }, { 0x00802001, 0x2e400021, 0x00b10800, 0x00000000 }, { 0x00802001, 0x2e800021, 0x00b10840, 0x00000000 }, { 0x00802001, 0x2ec00021, 0x00b10880, 0x00000000 }, { 0x00802001, 0x2f000021, 0x00b108c0, 0x00000000 }, { 0x00802001, 0x2f400021, 0x00b10900, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000be }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000090 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a007 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a007 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a007 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x80800042, 0x27402529, 0x00b10740, 0x00b10d80 }, { 0x80800042, 0x27602529, 0x00b10760, 0x00b10da0 }, { 0x80800042, 0x27802529, 0x00b10780, 0x00b10dc0 }, { 0x80800042, 0x27a02529, 0x00b107a0, 0x00b10de0 }, { 0x80800042, 0x27c02529, 0x00b107c0, 0x00b10e00 }, { 0x80800042, 0x27e02529, 0x00b107e0, 0x00b10e20 }, { 0x80800042, 0x28002529, 0x00b10800, 0x00b10e40 }, { 0x80800042, 0x28202529, 0x00b10820, 0x00b10e60 }, { 0x80800042, 0x28402529, 0x00b10840, 0x00b10e80 }, { 0x80800042, 0x28602529, 0x00b10860, 0x00b10ea0 }, { 0x80800042, 0x28802529, 0x00b10880, 0x00b10ec0 }, { 0x80800042, 0x28a02529, 0x00b108a0, 0x00b10ee0 }, { 0x80800042, 0x28c02529, 0x00b108c0, 0x00b10f00 }, { 0x80800042, 0x28e02529, 0x00b108e0, 0x00b10f20 }, { 0x80800042, 0x29002529, 0x00b10900, 0x00b10f40 }, { 0x80800042, 0x29202529, 0x00b10920, 0x00b10f60 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a005 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a006 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a006 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a005 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a006 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x408d0400, 0x0248a005 }, { 0x00800031, 0x25001d29, 0x408d0400, 0x0248a006 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00800001, 0x2d800231, 0x00b20940, 0x00000000 }, { 0x00800001, 0x2d900231, 0x00b20960, 0x00000000 }, { 0x00800001, 0x2da00231, 0x00b20980, 0x00000000 }, { 0x00800001, 0x2db00231, 0x00b209a0, 0x00000000 }, { 0x00800001, 0x2dc00231, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x2dd00231, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x2de00231, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x2df00231, 0x00b20a20, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a54, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a54, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a008 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a009 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a009 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x01000005, 0x20000d3c, 0x00210a56, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a008 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a009 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a008 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a009 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x408d0400, 0x0248a008 }, { 0x00800031, 0x25001d29, 0x408d0400, 0x0248a009 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x80800042, 0x29404529, 0x00b10940, 0x00b10d80 }, { 0x80800042, 0x29604529, 0x00b10960, 0x00b10d90 }, { 0x80800042, 0x29804529, 0x00b10980, 0x00b10da0 }, { 0x80800042, 0x29a04529, 0x00b109a0, 0x00b10db0 }, { 0x80800042, 0x29c04529, 0x00b109c0, 0x00b10dc0 }, { 0x80800042, 0x29e04529, 0x00b109e0, 0x00b10dd0 }, { 0x80800042, 0x2a004529, 0x00b10a00, 0x00b10de0 }, { 0x80800042, 0x2a204529, 0x00b10a20, 0x00b10df0 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_forward.g4a000066400000000000000000000047131267532330400265230ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; mov (1) g126.8<1>UD ip {align1}; mov (1) ip g21.0<1,1,1>UD {align1}; //Y, (x', y') = (x, y) + (motion_vector.x >> 1, motion_vector.y >> 1) asr (2) g31.14<1>W g82.16<2,2,1>W 1W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface', `4') define(`mv1', `g82.16') define(`mv2', `g82.18') include(`motion_frame_y.g4i') //UV, (x', y') = (x >> 1, y >> 1) + (motion_vector.x >> 2, motion_vector.y >> 2) shr (2) g31.0<1>UD g31.0<2,2,1>UD 1UD {align1}; asr (2) g31.14<1>W g82.16<2,2,1>W 2W {align1}; add (2) g32.0<1>UD g31.0<2,2,1>UD g31.14<2,2,1>W {align1}; define(`input_surface1', `5') define(`input_surface2', `6') include(`motion_frame_uv.g4i') include(`addidct.g4i') send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_forward.g4b000066400000000000000000000475071267532330400265340ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000005f }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000048 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000043 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002e }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x008d0400, 0x0411a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x008d0400, 0x0418a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x008d0400, 0x0418a004 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000004e }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000040 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a005 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a006 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000031 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0414a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0414a006 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000025 }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000018 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x008d0400, 0x0418a005 }, { 0x00800031, 0x25801d29, 0x008d0400, 0x0418a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x008d0400, 0x0411a005 }, { 0x00800031, 0x26801d29, 0x008d0400, 0x0411a006 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000b }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x008d0400, 0x0414a005 }, { 0x00800031, 0x25001d29, 0x008d0400, 0x0414a006 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/frame_forward.g4b.gen5000066400000000000000000000475071267532330400273710ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000001, 0x2fc80001, 0x00001400, 0x00000000 }, { 0x00000001, 0x34000020, 0x002102a0, 0x00000000 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00010001 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x000000be }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000090 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x00800040, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x00800040, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x00800040, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x00800040, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x00800040, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x00800040, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x00800040, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x00800040, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x00800040, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x00800040, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x00800040, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x00800040, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x00800040, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x00800040, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x00800040, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x00800040, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e0 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10500 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10520 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10540 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10560 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10580 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a0 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c0 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e0 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10600 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10620 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10640 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10660 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10680 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a0 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c0 }, { 0x00800040, 0x27404529, 0x00b10740, 0x00b104e1 }, { 0x00800040, 0x27604529, 0x00b10760, 0x00b10501 }, { 0x00800040, 0x27804529, 0x00b10780, 0x00b10521 }, { 0x00800040, 0x27a04529, 0x00b107a0, 0x00b10541 }, { 0x00800040, 0x27c04529, 0x00b107c0, 0x00b10561 }, { 0x00800040, 0x27e04529, 0x00b107e0, 0x00b10581 }, { 0x00800040, 0x28004529, 0x00b10800, 0x00b105a1 }, { 0x00800040, 0x28204529, 0x00b10820, 0x00b105c1 }, { 0x00800040, 0x28404529, 0x00b10840, 0x00b105e1 }, { 0x00800040, 0x28604529, 0x00b10860, 0x00b10601 }, { 0x00800040, 0x28804529, 0x00b10880, 0x00b10621 }, { 0x00800040, 0x28a04529, 0x00b108a0, 0x00b10641 }, { 0x00800040, 0x28c04529, 0x00b108c0, 0x00b10661 }, { 0x00800040, 0x28e04529, 0x00b108e0, 0x00b10681 }, { 0x00800040, 0x29004529, 0x00b10900, 0x00b106a1 }, { 0x00800040, 0x29204529, 0x00b10920, 0x00b106c1 }, { 0x80800008, 0x27402d29, 0x00b10740, 0x00020002 }, { 0x80800008, 0x27602d29, 0x00b10760, 0x00020002 }, { 0x80800008, 0x27802d29, 0x00b10780, 0x00020002 }, { 0x80800008, 0x27a02d29, 0x00b107a0, 0x00020002 }, { 0x80800008, 0x27c02d29, 0x00b107c0, 0x00020002 }, { 0x80800008, 0x27e02d29, 0x00b107e0, 0x00020002 }, { 0x80800008, 0x28002d29, 0x00b10800, 0x00020002 }, { 0x80800008, 0x28202d29, 0x00b10820, 0x00020002 }, { 0x80800008, 0x28402d29, 0x00b10840, 0x00020002 }, { 0x80800008, 0x28602d29, 0x00b10860, 0x00020002 }, { 0x80800008, 0x28802d29, 0x00b10880, 0x00020002 }, { 0x80800008, 0x28a02d29, 0x00b108a0, 0x00020002 }, { 0x80800008, 0x28c02d29, 0x00b108c0, 0x00020002 }, { 0x80800008, 0x28e02d29, 0x00b108e0, 0x00020002 }, { 0x80800008, 0x29002d29, 0x00b10900, 0x00020002 }, { 0x80800008, 0x29202d29, 0x00b10920, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000086 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104c1 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b104e1 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10501 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10521 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10541 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10561 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b10581 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105a1 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105c1 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b105e1 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10601 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10621 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10641 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10661 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b10681 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106a1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000005c }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000001 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x26c01d29, 0x408d0400, 0x0218a004 }, { 0x80800042, 0x27404629, 0x00b104c0, 0x00b104e0 }, { 0x80800042, 0x27604629, 0x00b104e0, 0x00b10500 }, { 0x80800042, 0x27804629, 0x00b10500, 0x00b10520 }, { 0x80800042, 0x27a04629, 0x00b10520, 0x00b10540 }, { 0x80800042, 0x27c04629, 0x00b10540, 0x00b10560 }, { 0x80800042, 0x27e04629, 0x00b10560, 0x00b10580 }, { 0x80800042, 0x28004629, 0x00b10580, 0x00b105a0 }, { 0x80800042, 0x28204629, 0x00b105a0, 0x00b105c0 }, { 0x80800042, 0x28404629, 0x00b105c0, 0x00b105e0 }, { 0x80800042, 0x28604629, 0x00b105e0, 0x00b10600 }, { 0x80800042, 0x28804629, 0x00b10600, 0x00b10620 }, { 0x80800042, 0x28a04629, 0x00b10620, 0x00b10640 }, { 0x80800042, 0x28c04629, 0x00b10640, 0x00b10660 }, { 0x80800042, 0x28e04629, 0x00b10660, 0x00b10680 }, { 0x80800042, 0x29004629, 0x00b10680, 0x00b106a0 }, { 0x80800042, 0x29204629, 0x00b106a0, 0x00b106c0 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000028 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24c01d29, 0x408d0400, 0x0288a004 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00800031, 0x25c01d29, 0x408d0400, 0x0288a004 }, { 0x00800001, 0x27400229, 0x00b104c0, 0x00000000 }, { 0x00800001, 0x27600229, 0x00b104e0, 0x00000000 }, { 0x00800001, 0x27800229, 0x00b10500, 0x00000000 }, { 0x00800001, 0x27a00229, 0x00b10520, 0x00000000 }, { 0x00800001, 0x27c00229, 0x00b10540, 0x00000000 }, { 0x00800001, 0x27e00229, 0x00b10560, 0x00000000 }, { 0x00800001, 0x28000229, 0x00b10580, 0x00000000 }, { 0x00800001, 0x28200229, 0x00b105a0, 0x00000000 }, { 0x00800001, 0x28400229, 0x00b105c0, 0x00000000 }, { 0x00800001, 0x28600229, 0x00b105e0, 0x00000000 }, { 0x00800001, 0x28800229, 0x00b10600, 0x00000000 }, { 0x00800001, 0x28a00229, 0x00b10620, 0x00000000 }, { 0x00800001, 0x28c00229, 0x00b10640, 0x00000000 }, { 0x00800001, 0x28e00229, 0x00b10660, 0x00000000 }, { 0x00800001, 0x29000229, 0x00b10680, 0x00000000 }, { 0x00800001, 0x29200229, 0x00b106a0, 0x00000000 }, { 0x00200008, 0x23e00c21, 0x004503e0, 0x00000001 }, { 0x0020000c, 0x23ee3dad, 0x00450a50, 0x00020002 }, { 0x00200040, 0x24003421, 0x004503e0, 0x004503ee }, { 0x01000005, 0x20000d3c, 0x00210a50, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000009c }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000080 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a005 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a006 }, { 0x00600040, 0x29404629, 0x008d0440, 0x008d0441 }, { 0x00600040, 0x29504629, 0x008d0460, 0x008d0461 }, { 0x00600040, 0x29604629, 0x008d0480, 0x008d0481 }, { 0x00600040, 0x29704629, 0x008d04a0, 0x008d04a1 }, { 0x00600040, 0x29804629, 0x008d04c0, 0x008d04c1 }, { 0x00600040, 0x29904629, 0x008d04e0, 0x008d04e1 }, { 0x00600040, 0x29a04629, 0x008d0500, 0x008d0501 }, { 0x00600040, 0x29b04629, 0x008d0520, 0x008d0521 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0460 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0480 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a0 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c0 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e0 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0500 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0520 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0540 }, { 0x00600040, 0x29404529, 0x008d0940, 0x008d0461 }, { 0x00600040, 0x29504529, 0x008d0950, 0x008d0481 }, { 0x00600040, 0x29604529, 0x008d0960, 0x008d04a1 }, { 0x00600040, 0x29704529, 0x008d0970, 0x008d04c1 }, { 0x00600040, 0x29804529, 0x008d0980, 0x008d04e1 }, { 0x00600040, 0x29904529, 0x008d0990, 0x008d0501 }, { 0x00600040, 0x29a04529, 0x008d09a0, 0x008d0521 }, { 0x00600040, 0x29b04529, 0x008d09b0, 0x008d0541 }, { 0x00600040, 0x29c04629, 0x008d0580, 0x008d0581 }, { 0x00600040, 0x29d04629, 0x008d05a0, 0x008d05a1 }, { 0x00600040, 0x29e04629, 0x008d05c0, 0x008d05c1 }, { 0x00600040, 0x29f04629, 0x008d05e0, 0x008d05e1 }, { 0x00600040, 0x2a004629, 0x008d0600, 0x008d0601 }, { 0x00600040, 0x2a104629, 0x008d0620, 0x008d0621 }, { 0x00600040, 0x2a204629, 0x008d0640, 0x008d0641 }, { 0x00600040, 0x2a304629, 0x008d0660, 0x008d0661 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a0 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c0 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e0 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0600 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0620 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0640 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0660 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0680 }, { 0x00600040, 0x29c04529, 0x008d09c0, 0x008d05a1 }, { 0x00600040, 0x29d04529, 0x008d09d0, 0x008d05c1 }, { 0x00600040, 0x29e04529, 0x008d09e0, 0x008d05e1 }, { 0x00600040, 0x29f04529, 0x008d09f0, 0x008d0601 }, { 0x00600040, 0x2a004529, 0x008d0a00, 0x008d0621 }, { 0x00600040, 0x2a104529, 0x008d0a10, 0x008d0641 }, { 0x00600040, 0x2a204529, 0x008d0a20, 0x008d0661 }, { 0x00600040, 0x2a304529, 0x008d0a30, 0x008d0681 }, { 0x00800008, 0x29402d29, 0x00b10940, 0x00020002 }, { 0x00800008, 0x29602d29, 0x00b10960, 0x00020002 }, { 0x00800008, 0x29802d29, 0x00b10980, 0x00020002 }, { 0x00800008, 0x29a02d29, 0x00b109a0, 0x00020002 }, { 0x00800008, 0x29c02d29, 0x00b109c0, 0x00020002 }, { 0x00800008, 0x29e02d29, 0x00b109e0, 0x00020002 }, { 0x00800008, 0x2a002d29, 0x00b10a00, 0x00020002 }, { 0x00800008, 0x2a202d29, 0x00b10a20, 0x00020002 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000062 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0248a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0248a006 }, { 0x00800042, 0x29404629, 0x00ad0440, 0x00ad0441 }, { 0x00800042, 0x29604629, 0x00ad0460, 0x00ad0461 }, { 0x00800042, 0x29804629, 0x00ad0480, 0x00ad0481 }, { 0x00800042, 0x29a04629, 0x00ad04a0, 0x00ad04a1 }, { 0x00800042, 0x29c04629, 0x00ad0580, 0x00ad0581 }, { 0x00800042, 0x29e04629, 0x00ad05a0, 0x00ad05a1 }, { 0x00800042, 0x2a004629, 0x00ad05c0, 0x00ad05c1 }, { 0x00800042, 0x2a204629, 0x00ad05e0, 0x00ad05e1 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004a }, { 0x01000005, 0x20000d3c, 0x00210a52, 0x00000002 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000030 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007001f }, { 0x00800031, 0x24401d29, 0x408d0400, 0x0288a005 }, { 0x00800031, 0x25801d29, 0x408d0400, 0x0288a006 }, { 0x00000040, 0x24040c21, 0x00210404, 0x00000008 }, { 0x00000001, 0x24080061, 0x00000000, 0x0000001f }, { 0x00800031, 0x25401d29, 0x408d0400, 0x0218a005 }, { 0x00800031, 0x26801d29, 0x408d0400, 0x0218a006 }, { 0x00600042, 0x29404629, 0x008d0440, 0x008d0460 }, { 0x00600042, 0x29504629, 0x008d0460, 0x008d0480 }, { 0x00600042, 0x29604629, 0x008d0480, 0x008d04a0 }, { 0x00600042, 0x29704629, 0x008d04a0, 0x008d04c0 }, { 0x00600042, 0x29804629, 0x008d04c0, 0x008d04e0 }, { 0x00600042, 0x29904629, 0x008d04e0, 0x008d0500 }, { 0x00600042, 0x29a04629, 0x008d0500, 0x008d0520 }, { 0x00600042, 0x29b04629, 0x008d0520, 0x008d0540 }, { 0x00600042, 0x29c04629, 0x008d0580, 0x008d05a0 }, { 0x00600042, 0x29d04629, 0x008d05a0, 0x008d05c0 }, { 0x00600042, 0x29e04629, 0x008d05c0, 0x008d05e0 }, { 0x00600042, 0x29f04629, 0x008d05e0, 0x008d0600 }, { 0x00600042, 0x2a004629, 0x008d0600, 0x008d0620 }, { 0x00600042, 0x2a104629, 0x008d0620, 0x008d0640 }, { 0x00600042, 0x2a204629, 0x008d0640, 0x008d0660 }, { 0x00600042, 0x2a304629, 0x008d0660, 0x008d0680 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00000001, 0x24080061, 0x00000000, 0x0007000f }, { 0x00800031, 0x24801d29, 0x408d0400, 0x0248a005 }, { 0x00800031, 0x25001d29, 0x408d0400, 0x0248a006 }, { 0x00800001, 0x29400229, 0x00ad0480, 0x00000000 }, { 0x00800001, 0x29600229, 0x00ad04a0, 0x00000000 }, { 0x00800001, 0x29800229, 0x00ad04c0, 0x00000000 }, { 0x00800001, 0x29a00229, 0x00ad04e0, 0x00000000 }, { 0x00800001, 0x29c00229, 0x00ad0500, 0x00000000 }, { 0x00800001, 0x29e00229, 0x00ad0520, 0x00000000 }, { 0x00800001, 0x2a000229, 0x00ad0540, 0x00000000 }, { 0x00800001, 0x2a200229, 0x00ad0560, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10a80, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10aa0, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10ac0, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10ae0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10b00, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10b20, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10b40, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10b60, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10b80, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10ba0, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10bc0, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10be0, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c00, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10c20, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800040, 0x274045ad, 0x00b10a60, 0x00b20740 }, { 0x00800040, 0x276045ad, 0x00b10b60, 0x00b20760 }, { 0x00800040, 0x278045ad, 0x00b10a80, 0x00b20780 }, { 0x00800040, 0x27a045ad, 0x00b10b80, 0x00b207a0 }, { 0x00800040, 0x27c045ad, 0x00b10aa0, 0x00b207c0 }, { 0x00800040, 0x27e045ad, 0x00b10ba0, 0x00b207e0 }, { 0x00800040, 0x280045ad, 0x00b10ac0, 0x00b20800 }, { 0x00800040, 0x282045ad, 0x00b10bc0, 0x00b20820 }, { 0x00800040, 0x284045ad, 0x00b10ae0, 0x00b20840 }, { 0x00800040, 0x286045ad, 0x00b10be0, 0x00b20860 }, { 0x00800040, 0x288045ad, 0x00b10b00, 0x00b20880 }, { 0x00800040, 0x28a045ad, 0x00b10c00, 0x00b208a0 }, { 0x00800040, 0x28c045ad, 0x00b10b20, 0x00b208c0 }, { 0x00800040, 0x28e045ad, 0x00b10c20, 0x00b208e0 }, { 0x00800040, 0x290045ad, 0x00b10b40, 0x00b20900 }, { 0x00800040, 0x292045ad, 0x00b10c40, 0x00b20920 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x474001b1, 0x00b10740, 0x00000000 }, { 0x80800001, 0x476001b1, 0x00b10760, 0x00000000 }, { 0x80800001, 0x478001b1, 0x00b10780, 0x00000000 }, { 0x80800001, 0x47a001b1, 0x00b107a0, 0x00000000 }, { 0x80800001, 0x47c001b1, 0x00b107c0, 0x00000000 }, { 0x80800001, 0x47e001b1, 0x00b107e0, 0x00000000 }, { 0x80800001, 0x480001b1, 0x00b10800, 0x00000000 }, { 0x80800001, 0x482001b1, 0x00b10820, 0x00000000 }, { 0x80800001, 0x484001b1, 0x00b10840, 0x00000000 }, { 0x80800001, 0x486001b1, 0x00b10860, 0x00000000 }, { 0x80800001, 0x488001b1, 0x00b10880, 0x00000000 }, { 0x80800001, 0x48a001b1, 0x00b108a0, 0x00000000 }, { 0x80800001, 0x48c001b1, 0x00b108c0, 0x00000000 }, { 0x80800001, 0x48e001b1, 0x00b108e0, 0x00000000 }, { 0x80800001, 0x490001b1, 0x00b10900, 0x00000000 }, { 0x80800001, 0x492001b1, 0x00b10920, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20740, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20760, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20780, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b207a0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b207c0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b207e0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20800, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20820, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20840, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20860, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20880, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b208a0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b208c0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b208e0, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20900, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20920, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01c21, 0x004503e0, 0x00000001 }, { 0x00800040, 0x294025ad, 0x00b10c60, 0x00b10940 }, { 0x00800040, 0x296025ad, 0x00b10c80, 0x00b10960 }, { 0x00800040, 0x298025ad, 0x00b10ca0, 0x00b10980 }, { 0x00800040, 0x29a025ad, 0x00b10cc0, 0x00b109a0 }, { 0x80800001, 0x494001b1, 0x00b10940, 0x00000000 }, { 0x80800001, 0x496001b1, 0x00b10960, 0x00000000 }, { 0x80800001, 0x498001b1, 0x00b10980, 0x00000000 }, { 0x80800001, 0x49a001b1, 0x00b109a0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20940, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20960, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20980, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b209a0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x00800040, 0x29c025a9, 0x00b10ce0, 0x00b109c0 }, { 0x00800040, 0x29e025a9, 0x00b10d00, 0x00b109e0 }, { 0x00800040, 0x2a0025a9, 0x00b10d20, 0x00b10a00 }, { 0x00800040, 0x2a2025a9, 0x00b10d40, 0x00b10a20 }, { 0x80800001, 0x49c001b1, 0x00b109c0, 0x00000000 }, { 0x80800001, 0x49e001b1, 0x00b109e0, 0x00000000 }, { 0x80800001, 0x4a0001b1, 0x00b10a00, 0x00000000 }, { 0x80800001, 0x4a2001b1, 0x00b10a20, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b209c0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b209e0, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a00, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20a20, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/idct.g4i000066400000000000000000000155541267532330400246450ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix in UB format g3~g4:non intra IQ matrix in UB format g5~g20:IDCT table g56~g79:DCT data after IQ before idct g83~g106: IDCT data after idct g82: thread payload backup g125: ip before idct */ IDCT_START: mov (1) g126.0<1>UD ip {align1}; jmpi DO_IDCT; add (16) g32<1>D g32<8,8,1>D ROW_ADD {compr}; add (16) g34<1>D g34<8,8,1>D ROW_ADD {compr}; add (16) g36<1>D g36<8,8,1>D ROW_ADD {compr}; add (16) g38<1>D g38<8,8,1>D ROW_ADD {compr}; shr (16) g32<1>D g32<8,8,1>D ROW_SHIFT {compr}; shr (16) g34<1>D g34<8,8,1>D ROW_SHIFT {compr}; shr (16) g36<1>D g36<8,8,1>D ROW_SHIFT {compr}; shr (16) g38<1>D g38<8,8,1>D ROW_SHIFT {compr}; mov (16) g110.0<1>W g32<16,8,2>W {align1}; mov (16) g111.0<1>W g34<16,8,2>W {align1}; mov (16) g112.0<1>W g36<16,8,2>W {align1}; mov (16) g113.0<1>W g38<16,8,2>W {align1}; mov (1) g80.0<1>UD a0.0<1,1,1>UD {align1}; //save a0 mov (1) a0.0<1>UD 0x0DB00DA0UD {align1}; //begin at g110.0, the output of idct_row.g4i mov (1) g126.0<1>UD ip {align1}; jmpi DO_IDCT; add (16) g32<1>D g32<8,8,1>D COL_ADD {compr}; add (16) g34<1>D g34<8,8,1>D COL_ADD {compr}; add (16) g36<1>D g36<8,8,1>D COL_ADD {compr}; add (16) g38<1>D g38<8,8,1>D COL_ADD {compr}; shr (16) g32<1>D g32<8,8,1>D COL_SHIFT {compr}; shr (16) g34<1>D g34<8,8,1>D COL_SHIFT {compr}; shr (16) g36<1>D g36<8,8,1>D COL_SHIFT {compr}; shr (16) g38<1>D g38<8,8,1>D COL_SHIFT {compr}; mov (1) a0.0<1>UD g80.0<1,1,1>UD {align1}; //restore a0 add (1) ip g125.0<1,1,1>UD 0x20UD {align1}; //jump back DO_IDCT: add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; //increase the address dp4 (16) g40<1>D g[a0.0]<8,8,1>W g5<8,8,1>D {align1 compr}; dp4 (16) g42<1>D g[a0.0]<8,8,1>W g7<8,8,1>D {align1 compr}; dp4 (16) g44<1>D g[a0.0]<8,8,1>W g9<8,8,1>D {align1 compr}; dp4 (16) g46<1>D g[a0.0]<8,8,1>W g11<8,8,1>D {align1 compr}; dp4 (16) g48<1>D g[a0.0]<8,8,1>W g13<8,8,1>D {align1 compr}; dp4 (16) g50<1>D g[a0.0]<8,8,1>W g15<8,8,1>D {align1 compr}; dp4 (16) g52<1>D g[a0.0]<8,8,1>W g17<8,8,1>D {align1 compr}; dp4 (16) g54<1>D g[a0.0]<8,8,1>W g19<8,8,1>D {align1 compr}; add (2) g32.0<1>D g40.0<8,1,8>D g40.16<8,1,8>D {align1}; add (2) g33.0<1>D g42.0<8,1,8>D g42.16<8,1,8>D {align1}; add (2) g34.0<1>D g44.0<8,1,8>D g44.16<8,1,8>D {align1}; add (2) g35.0<1>D g46.0<8,1,8>D g46.16<8,1,8>D {align1}; add (2) g36.0<1>D g48.0<8,1,8>D g48.16<8,1,8>D {align1}; add (2) g37.0<1>D g50.0<8,1,8>D g50.16<8,1,8>D {align1}; add (2) g38.0<1>D g52.0<8,1,8>D g52.16<8,1,8>D {align1}; add (2) g39.0<1>D g54.0<8,1,8>D g54.16<8,1,8>D {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; dp4 (16) g40<1>D g[a0.0]<8,8,1>W g5<8,8,1>D {align1 compr}; dp4 (16) g42<1>D g[a0.0]<8,8,1>W g7<8,8,1>D {align1 compr}; dp4 (16) g44<1>D g[a0.0]<8,8,1>W g9<8,8,1>D {align1 compr}; dp4 (16) g46<1>D g[a0.0]<8,8,1>W g11<8,8,1>D {align1 compr}; dp4 (16) g48<1>D g[a0.0]<8,8,1>W g13<8,8,1>D {align1 compr}; dp4 (16) g50<1>D g[a0.0]<8,8,1>W g15<8,8,1>D {align1 compr}; dp4 (16) g52<1>D g[a0.0]<8,8,1>W g17<8,8,1>D {align1 compr}; dp4 (16) g54<1>D g[a0.0]<8,8,1>W g19<8,8,1>D {align1 compr}; add (2) g32.8<1>D g40.0<8,1,8>D g40.16<8,1,8>D {align1}; add (2) g33.8<1>D g42.0<8,1,8>D g42.16<8,1,8>D {align1}; add (2) g34.8<1>D g44.0<8,1,8>D g44.16<8,1,8>D {align1}; add (2) g35.8<1>D g46.0<8,1,8>D g46.16<8,1,8>D {align1}; add (2) g36.8<1>D g48.0<8,1,8>D g48.16<8,1,8>D {align1}; add (2) g37.8<1>D g50.0<8,1,8>D g50.16<8,1,8>D {align1}; add (2) g38.8<1>D g52.0<8,1,8>D g52.16<8,1,8>D {align1}; add (2) g39.8<1>D g54.0<8,1,8>D g54.16<8,1,8>D {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; dp4 (16) g40<1>D g[a0.0]<8,8,1>W g5<8,8,1>D {align1 compr}; dp4 (16) g42<1>D g[a0.0]<8,8,1>W g7<8,8,1>D {align1 compr}; dp4 (16) g44<1>D g[a0.0]<8,8,1>W g9<8,8,1>D {align1 compr}; dp4 (16) g46<1>D g[a0.0]<8,8,1>W g11<8,8,1>D {align1 compr}; dp4 (16) g48<1>D g[a0.0]<8,8,1>W g13<8,8,1>D {align1 compr}; dp4 (16) g50<1>D g[a0.0]<8,8,1>W g15<8,8,1>D {align1 compr}; dp4 (16) g52<1>D g[a0.0]<8,8,1>W g17<8,8,1>D {align1 compr}; dp4 (16) g54<1>D g[a0.0]<8,8,1>W g19<8,8,1>D {align1 compr}; add (2) g32.16<1>D g40.0<8,1,8>D g40.16<8,1,8>D {align1}; add (2) g33.16<1>D g42.0<8,1,8>D g42.16<8,1,8>D {align1}; add (2) g34.16<1>D g44.0<8,1,8>D g44.16<8,1,8>D {align1}; add (2) g35.16<1>D g46.0<8,1,8>D g46.16<8,1,8>D {align1}; add (2) g36.16<1>D g48.0<8,1,8>D g48.16<8,1,8>D {align1}; add (2) g37.16<1>D g50.0<8,1,8>D g50.16<8,1,8>D {align1}; add (2) g38.16<1>D g52.0<8,1,8>D g52.16<8,1,8>D {align1}; add (2) g39.16<1>D g54.0<8,1,8>D g54.16<8,1,8>D {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00200020UD {align1}; dp4 (16) g40<1>D g[a0.0]<8,8,1>W g5<8,8,1>D {align1 compr}; dp4 (16) g42<1>D g[a0.0]<8,8,1>W g7<8,8,1>D {align1 compr}; dp4 (16) g44<1>D g[a0.0]<8,8,1>W g9<8,8,1>D {align1 compr}; dp4 (16) g46<1>D g[a0.0]<8,8,1>W g11<8,8,1>D {align1 compr}; dp4 (16) g48<1>D g[a0.0]<8,8,1>W g13<8,8,1>D {align1 compr}; dp4 (16) g50<1>D g[a0.0]<8,8,1>W g15<8,8,1>D {align1 compr}; dp4 (16) g52<1>D g[a0.0]<8,8,1>W g17<8,8,1>D {align1 compr}; dp4 (16) g54<1>D g[a0.0]<8,8,1>W g19<8,8,1>D {align1 compr}; add (2) g32.24<1>D g40.0<8,1,8>D g40.16<8,1,8>D {align1}; add (2) g33.24<1>D g42.0<8,1,8>D g42.16<8,1,8>D {align1}; add (2) g34.24<1>D g44.0<8,1,8>D g44.16<8,1,8>D {align1}; add (2) g35.24<1>D g46.0<8,1,8>D g46.16<8,1,8>D {align1}; add (2) g36.24<1>D g48.0<8,1,8>D g48.16<8,1,8>D {align1}; add (2) g37.24<1>D g50.0<8,1,8>D g50.16<8,1,8>D {align1}; add (2) g38.24<1>D g52.0<8,1,8>D g52.16<8,1,8>D {align1}; add (2) g39.24<1>D g54.0<8,1,8>D g54.16<8,1,8>D {align1}; add (1) ip g126.0<1,1,1>UD 0x20UD {align1}; //jump back xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/ipicture.g4a000066400000000000000000000176031267532330400255330ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT tab g31: read and write message descriptor g32~g55:DCT data g58~g81:reference data g82: thread payload g83~g106:IDCT data */ mov (8) g82.0<1>UD g31.0<8,8,1>UD {align1}; mov (2) g31.0<1>UD g82.12<2,2,1>UW {align1}; include(`iq_intra.g4i') //defined for idct define(`ROW_SHIFT', `11UD') define(`ROW_ADD', `0x400UD') define(`COL_SHIFT', `20UD') define(`COL_ADD', `0x80000UD') mov (1) a0.0<1>UD 0x06F006E0UD {align1}; //0x06F006E0UD+0x00200020UD=0x07100700UD (g56.0 and g56.16) //Y0 mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (8) g83.0<1>W g32.0<16,8,2>W 128UW {align1}; add (8) g84.0<1>W g33.0<16,8,2>W 128UW {align1}; add (8) g85.0<1>W g34.0<16,8,2>W 128UW {align1}; add (8) g86.0<1>W g35.0<16,8,2>W 128UW {align1}; add (8) g87.0<1>W g36.0<16,8,2>W 128UW {align1}; add (8) g88.0<1>W g37.0<16,8,2>W 128UW {align1}; add (8) g89.0<1>W g38.0<16,8,2>W 128UW {align1}; add (8) g90.0<1>W g39.0<16,8,2>W 128UW {align1}; //Y1 mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (8) g83.16<1>W g32.0<16,8,2>W 128UW {align1}; add (8) g84.16<1>W g33.0<16,8,2>W 128UW {align1}; add (8) g85.16<1>W g34.0<16,8,2>W 128UW {align1}; add (8) g86.16<1>W g35.0<16,8,2>W 128UW {align1}; add (8) g87.16<1>W g36.0<16,8,2>W 128UW {align1}; add (8) g88.16<1>W g37.0<16,8,2>W 128UW {align1}; add (8) g89.16<1>W g38.0<16,8,2>W 128UW {align1}; add (8) g90.16<1>W g39.0<16,8,2>W 128UW {align1}; //Y2 mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (8) g91.0<1>W g32.0<16,8,2>W 128UW {align1}; add (8) g92.0<1>W g33.0<16,8,2>W 128UW {align1}; add (8) g93.0<1>W g34.0<16,8,2>W 128UW {align1}; add (8) g94.0<1>W g35.0<16,8,2>W 128UW {align1}; add (8) g95.0<1>W g36.0<16,8,2>W 128UW {align1}; add (8) g96.0<1>W g37.0<16,8,2>W 128UW {align1}; add (8) g97.0<1>W g38.0<16,8,2>W 128UW {align1}; add (8) g98.0<1>W g39.0<16,8,2>W 128UW {align1}; //Y3 mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (8) g91.16<1>W g32.0<16,8,2>W 128UW {align1}; add (8) g92.16<1>W g33.0<16,8,2>W 128UW {align1}; add (8) g93.16<1>W g34.0<16,8,2>W 128UW {align1}; add (8) g94.16<1>W g35.0<16,8,2>W 128UW {align1}; add (8) g95.16<1>W g36.0<16,8,2>W 128UW {align1}; add (8) g96.16<1>W g37.0<16,8,2>W 128UW {align1}; add (8) g97.16<1>W g38.0<16,8,2>W 128UW {align1}; add (8) g98.16<1>W g39.0<16,8,2>W 128UW {align1}; //U mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (16) g99.0<1>W g32.0<16,8,2>W 128UW {align1}; add (16) g100.0<1>W g34.0<16,8,2>W 128UW {align1}; add (16) g101.0<1>W g36.0<16,8,2>W 128UW {align1}; add (16) g102.0<1>W g38.0<16,8,2>W 128UW {align1}; //V mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; add (16) g103.0<1>W g32.0<16,8,2>W 128UW {align1}; add (16) g104.0<1>W g34.0<16,8,2>W 128UW {align1}; add (16) g105.0<1>W g36.0<16,8,2>W 128UW {align1}; add (16) g106.0<1>W g38.0<16,8,2>W 128UW {align1}; /******************* MC ************************/ mov (1) g31.8<1>UD 0x00F000FUD {align1}; mov.sat (16) g83.0<2>UB g83.0<16,16,1>W {align1}; mov.sat (16) g84.0<2>UB g84.0<16,16,1>W {align1}; mov.sat (16) g85.0<2>UB g85.0<16,16,1>W {align1}; mov.sat (16) g86.0<2>UB g86.0<16,16,1>W {align1}; mov.sat (16) g87.0<2>UB g87.0<16,16,1>W {align1}; mov.sat (16) g88.0<2>UB g88.0<16,16,1>W {align1}; mov.sat (16) g89.0<2>UB g89.0<16,16,1>W {align1}; mov.sat (16) g90.0<2>UB g90.0<16,16,1>W {align1}; mov.sat (16) g91.0<2>UB g91.0<16,16,1>W {align1}; mov.sat (16) g92.0<2>UB g92.0<16,16,1>W {align1}; mov.sat (16) g93.0<2>UB g93.0<16,16,1>W {align1}; mov.sat (16) g94.0<2>UB g94.0<16,16,1>W {align1}; mov.sat (16) g95.0<2>UB g95.0<16,16,1>W {align1}; mov.sat (16) g96.0<2>UB g96.0<16,16,1>W {align1}; mov.sat (16) g97.0<2>UB g97.0<16,16,1>W {align1}; mov.sat (16) g98.0<2>UB g98.0<16,16,1>W {align1}; and.nz (1) null g82.2<1,1,1>UW 0x20UW{align1}; (f0) jmpi field_dct; mov (16) m1.0<1>UB g83.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g84.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g85.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g86.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g87.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g88.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g89.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g90.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g91.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g92.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g93.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g94.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g95.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g96.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g97.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g98.0<16,16,2>UB {align1}; jmpi write_back; field_dct: mov (16) m1.0<1>UB g83.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g91.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g84.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g92.0<16,16,2>UB {align1}; mov (16) m3.0<1>UB g85.0<16,16,2>UB {align1}; mov (16) m3.16<1>UB g93.0<16,16,2>UB {align1}; mov (16) m4.0<1>UB g86.0<16,16,2>UB {align1}; mov (16) m4.16<1>UB g94.0<16,16,2>UB {align1}; mov (16) m5.0<1>UB g87.0<16,16,2>UB {align1}; mov (16) m5.16<1>UB g95.0<16,16,2>UB {align1}; mov (16) m6.0<1>UB g88.0<16,16,2>UB {align1}; mov (16) m6.16<1>UB g96.0<16,16,2>UB {align1}; mov (16) m7.0<1>UB g89.0<16,16,2>UB {align1}; mov (16) m7.16<1>UB g97.0<16,16,2>UB {align1}; mov (16) m8.0<1>UB g90.0<16,16,2>UB {align1}; mov (16) m8.16<1>UB g98.0<16,16,2>UB {align1}; write_back: send (16) 0 acc0<1>UW g31<8,8,1>UW write(0,0,2,0) mlen 9 rlen 0 {align1}; //U mov (1) g31.8<1>UD 0x0070007UD { align1 }; shr (2) g31.0<1>UD g82.12<2,2,1>UW 1D {align1}; mov.sat (16) g99.0<2>UB g99.0<16,16,1>W {align1}; mov.sat (16) g100.0<2>UB g100.0<16,16,1>W {align1}; mov.sat (16) g101.0<2>UB g101.0<16,16,1>W {align1}; mov.sat (16) g102.0<2>UB g102.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g99.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g100.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g101.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g102.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(1, 0, 2, 0) mlen 3 rlen 0 { align1 }; //V mov.sat (16) g103.0<2>UB g103.0<16,16,1>W {align1}; mov.sat (16) g104.0<2>UB g104.0<16,16,1>W {align1}; mov.sat (16) g105.0<2>UB g105.0<16,16,1>W {align1}; mov.sat (16) g106.0<2>UB g106.0<16,16,1>W {align1}; mov (16) m1.0<1>UB g103.0<16,16,2>UB {align1}; mov (16) m1.16<1>UB g104.0<16,16,2>UB {align1}; mov (16) m2.0<1>UB g105.0<16,16,2>UB {align1}; mov (16) m2.16<1>UB g106.0<16,16,2>UB {align1}; send (16) 0 acc0<1>UW g31<8,8,1>UW write(2, 0, 2, 0) mlen 3 rlen 0 { align1 }; OUT: send (16) 0 acc0<1>UW g0<8,8,1>UW thread_spawner(0, 0, 0) mlen 1 rlen 0 { align1 EOT}; include(`do_iq_intra.g4i') include(`idct.g4i') xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/ipicture.g4b000066400000000000000000000414771267532330400255420ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000005, 0x2da02d29, 0x00210a48, 0x001f001f }, { 0x00000005, 0x2da42d29, 0x00210a48, 0x60006000 }, { 0x00000008, 0x2da42d29, 0x00210da4, 0x000d000d }, { 0x00000001, 0x2da60169, 0x00000000, 0x00080008 }, { 0x00000008, 0x2da42529, 0x00210da6, 0x00210da4 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00090009 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00110011 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00190019 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffe7ffe7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00030003 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x00400040 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000009 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xfff7fff7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00010001 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x000a000a }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000005 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffefffef }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00020002 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x001c001c }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000001 }, { 0x00000009, 0x2da00d29, 0x00210da0, 0x00000001 }, { 0x00000001, 0x2dc00129, 0x00210da0, 0x00000000 }, { 0x00800001, 0x2e000229, 0x00b10020, 0x00000000 }, { 0x00800001, 0x2e200229, 0x00b10030, 0x00000000 }, { 0x00800001, 0x2e400229, 0x00b10040, 0x00000000 }, { 0x00800001, 0x2e600229, 0x00b10050, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x03f003e0 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000a1 }, { 0x00800001, 0x270001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x272001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x274001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x276001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000009b }, { 0x00800001, 0x278001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x27a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x27c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x27e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000095 }, { 0x00800001, 0x280001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x282001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x284001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x286001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000008f }, { 0x00800001, 0x288001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x28a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x28c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x28e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000089 }, { 0x00800001, 0x290001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x292001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x294001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x296001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000083 }, { 0x00800001, 0x298001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x29a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x29c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x29e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x06f006e0 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000008f }, { 0x00600040, 0x2a602dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2a802dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2aa02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2ac02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2ae02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2b002dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2b202dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2b402dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000085 }, { 0x00600040, 0x2a702dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2a902dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2ab02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2ad02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2af02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2b102dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2b302dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2b502dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000007b }, { 0x00600040, 0x2b602dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2b802dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2ba02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2bc02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2be02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2c002dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2c202dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2c402dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000071 }, { 0x00600040, 0x2b702dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2b902dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2bb02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2bd02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2bf02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2c102dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2c302dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2c502dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000067 }, { 0x00800040, 0x2c602dad, 0x00ae0400, 0x00800080 }, { 0x00800040, 0x2c802dad, 0x00ae0440, 0x00800080 }, { 0x00800040, 0x2ca02dad, 0x00ae0480, 0x00800080 }, { 0x00800040, 0x2cc02dad, 0x00ae04c0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00800040, 0x2ce02dad, 0x00ae0400, 0x00800080 }, { 0x00800040, 0x2d002dad, 0x00ae0440, 0x00800080 }, { 0x00800040, 0x2d202dad, 0x00ae0480, 0x00800080 }, { 0x00800040, 0x2d402dad, 0x00ae04c0, 0x00800080 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x4a6001b1, 0x00b10a60, 0x00000000 }, { 0x80800001, 0x4a8001b1, 0x00b10a80, 0x00000000 }, { 0x80800001, 0x4aa001b1, 0x00b10aa0, 0x00000000 }, { 0x80800001, 0x4ac001b1, 0x00b10ac0, 0x00000000 }, { 0x80800001, 0x4ae001b1, 0x00b10ae0, 0x00000000 }, { 0x80800001, 0x4b0001b1, 0x00b10b00, 0x00000000 }, { 0x80800001, 0x4b2001b1, 0x00b10b20, 0x00000000 }, { 0x80800001, 0x4b4001b1, 0x00b10b40, 0x00000000 }, { 0x80800001, 0x4b6001b1, 0x00b10b60, 0x00000000 }, { 0x80800001, 0x4b8001b1, 0x00b10b80, 0x00000000 }, { 0x80800001, 0x4ba001b1, 0x00b10ba0, 0x00000000 }, { 0x80800001, 0x4bc001b1, 0x00b10bc0, 0x00000000 }, { 0x80800001, 0x4be001b1, 0x00b10be0, 0x00000000 }, { 0x80800001, 0x4c0001b1, 0x00b10c00, 0x00000000 }, { 0x80800001, 0x4c2001b1, 0x00b10c20, 0x00000000 }, { 0x80800001, 0x4c4001b1, 0x00b10c40, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x00800001, 0x20200232, 0x00b20a60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20a80, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20aa0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20ac0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20ae0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20b00, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20b20, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20b40, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20b60, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20b80, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20ba0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20bc0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20be0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20c00, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20c20, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20c40, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00800001, 0x20200232, 0x00b20a60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20b60, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a80, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20b80, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20aa0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20ba0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20ac0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20bc0, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20ae0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20be0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20b00, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20c00, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20b20, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20c20, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20b40, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20c40, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05902000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01d21, 0x00450a4c, 0x00000001 }, { 0x80800001, 0x4c6001b1, 0x00b10c60, 0x00000000 }, { 0x80800001, 0x4c8001b1, 0x00b10c80, 0x00000000 }, { 0x80800001, 0x4ca001b1, 0x00b10ca0, 0x00000000 }, { 0x80800001, 0x4cc001b1, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20c60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20c80, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20ca0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20cc0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302001 }, { 0x80800001, 0x4ce001b1, 0x00b10ce0, 0x00000000 }, { 0x80800001, 0x4d0001b1, 0x00b10d00, 0x00000000 }, { 0x80800001, 0x4d2001b1, 0x00b10d20, 0x00000000 }, { 0x80800001, 0x4d4001b1, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20ce0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20d00, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20d20, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20d40, 0x00000000 }, { 0x00800031, 0x24001d28, 0x008d03e0, 0x05302002 }, { 0x00800031, 0x24001d28, 0x008d0000, 0x87100000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00000001, 0x2de001ad, 0x00218000, 0x00000000 }, { 0x00802041, 0x2e8025a5, 0x008d8000, 0x008d0e00 }, { 0x00802041, 0x2e8024a5, 0x008d0e80, 0x008c0da0 }, { 0x0080200c, 0x2e802ca5, 0x008d0e80, 0x00040004 }, { 0x00000041, 0x2e8025a5, 0x00210de0, 0x00210da4 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2ec025a5, 0x008d8000, 0x008d0e20 }, { 0x00802041, 0x2ec024a5, 0x008d0ec0, 0x008c0da0 }, { 0x0080200c, 0x2ec02ca5, 0x008d0ec0, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f0025a5, 0x008d8000, 0x008d0e40 }, { 0x00802041, 0x2f0024a5, 0x008d0f00, 0x008c0da0 }, { 0x0080200c, 0x2f002ca5, 0x008d0f00, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f4025a5, 0x008d8000, 0x008d0e60 }, { 0x00802041, 0x2f4024a5, 0x008d0f40, 0x008c0da0 }, { 0x0080200c, 0x2f402ca5, 0x008d0f40, 0x00040004 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00000400 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00000400 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00000400 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00000400 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x0000000b }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x0000000b }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x0000000b }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x0000000b }, { 0x00800001, 0x2dc001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2de001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2e0001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2e2001ad, 0x00ae04c0, 0x00000000 }, { 0x00000001, 0x2a000001, 0x00210200, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x0db00da0 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00080000 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00080000 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00080000 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00080000 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x00000014 }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x00000014 }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x00000014 }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x00000014 }, { 0x00000001, 0x22000020, 0x00210a00, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x34000c20, 0x00210fc0, 0x00000020 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/ipicture.g4b.gen5000066400000000000000000000414771267532330400263770ustar00rootroot00000000000000 { 0x00600001, 0x2a400021, 0x008d03e0, 0x00000000 }, { 0x00200001, 0x23e00121, 0x00450a4c, 0x00000000 }, { 0x00000005, 0x2da02d29, 0x00210a48, 0x001f001f }, { 0x00000005, 0x2da42d29, 0x00210a48, 0x60006000 }, { 0x00000008, 0x2da42d29, 0x00210da4, 0x000d000d }, { 0x00000001, 0x2da60169, 0x00000000, 0x00080008 }, { 0x00000008, 0x2da42529, 0x00210da6, 0x00210da4 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00090009 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00110011 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00190019 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffe7ffe7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00030003 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x00400040 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xfff7fff7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00010001 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x000a000a }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffefffef }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00020002 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x001c001c }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00000009, 0x2da00d29, 0x00210da0, 0x00000001 }, { 0x00000001, 0x2dc00129, 0x00210da0, 0x00000000 }, { 0x00800001, 0x2e000229, 0x00b10020, 0x00000000 }, { 0x00800001, 0x2e200229, 0x00b10030, 0x00000000 }, { 0x00800001, 0x2e400229, 0x00b10040, 0x00000000 }, { 0x00800001, 0x2e600229, 0x00b10050, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x03f003e0 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000142 }, { 0x00800001, 0x270001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x272001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x274001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x276001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000136 }, { 0x00800001, 0x278001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x27a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x27c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x27e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000012a }, { 0x00800001, 0x280001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x282001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x284001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x286001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000011e }, { 0x00800001, 0x288001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x28a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x28c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x28e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000112 }, { 0x00800001, 0x290001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x292001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x294001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x296001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000106 }, { 0x00800001, 0x298001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x29a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x29c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x29e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x06f006e0 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000011e }, { 0x00600040, 0x2a602dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2a802dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2aa02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2ac02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2ae02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2b002dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2b202dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2b402dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000010a }, { 0x00600040, 0x2a702dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2a902dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2ab02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2ad02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2af02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2b102dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2b302dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2b502dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000f6 }, { 0x00600040, 0x2b602dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2b802dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2ba02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2bc02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2be02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2c002dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2c202dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2c402dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000e2 }, { 0x00600040, 0x2b702dad, 0x00ae0400, 0x00800080 }, { 0x00600040, 0x2b902dad, 0x00ae0420, 0x00800080 }, { 0x00600040, 0x2bb02dad, 0x00ae0440, 0x00800080 }, { 0x00600040, 0x2bd02dad, 0x00ae0460, 0x00800080 }, { 0x00600040, 0x2bf02dad, 0x00ae0480, 0x00800080 }, { 0x00600040, 0x2c102dad, 0x00ae04a0, 0x00800080 }, { 0x00600040, 0x2c302dad, 0x00ae04c0, 0x00800080 }, { 0x00600040, 0x2c502dad, 0x00ae04e0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000ce }, { 0x00800040, 0x2c602dad, 0x00ae0400, 0x00800080 }, { 0x00800040, 0x2c802dad, 0x00ae0440, 0x00800080 }, { 0x00800040, 0x2ca02dad, 0x00ae0480, 0x00800080 }, { 0x00800040, 0x2cc02dad, 0x00ae04c0, 0x00800080 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00800040, 0x2ce02dad, 0x00ae0400, 0x00800080 }, { 0x00800040, 0x2d002dad, 0x00ae0440, 0x00800080 }, { 0x00800040, 0x2d202dad, 0x00ae0480, 0x00800080 }, { 0x00800040, 0x2d402dad, 0x00ae04c0, 0x00800080 }, { 0x00000001, 0x23e80061, 0x00000000, 0x000f000f }, { 0x80800001, 0x4a6001b1, 0x00b10a60, 0x00000000 }, { 0x80800001, 0x4a8001b1, 0x00b10a80, 0x00000000 }, { 0x80800001, 0x4aa001b1, 0x00b10aa0, 0x00000000 }, { 0x80800001, 0x4ac001b1, 0x00b10ac0, 0x00000000 }, { 0x80800001, 0x4ae001b1, 0x00b10ae0, 0x00000000 }, { 0x80800001, 0x4b0001b1, 0x00b10b00, 0x00000000 }, { 0x80800001, 0x4b2001b1, 0x00b10b20, 0x00000000 }, { 0x80800001, 0x4b4001b1, 0x00b10b40, 0x00000000 }, { 0x80800001, 0x4b6001b1, 0x00b10b60, 0x00000000 }, { 0x80800001, 0x4b8001b1, 0x00b10b80, 0x00000000 }, { 0x80800001, 0x4ba001b1, 0x00b10ba0, 0x00000000 }, { 0x80800001, 0x4bc001b1, 0x00b10bc0, 0x00000000 }, { 0x80800001, 0x4be001b1, 0x00b10be0, 0x00000000 }, { 0x80800001, 0x4c0001b1, 0x00b10c00, 0x00000000 }, { 0x80800001, 0x4c2001b1, 0x00b10c20, 0x00000000 }, { 0x80800001, 0x4c4001b1, 0x00b10c40, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a42, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x00800001, 0x20200232, 0x00b20a60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20a80, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20aa0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20ac0, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20ae0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20b00, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20b20, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20b40, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20b60, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20b80, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20ba0, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20bc0, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20be0, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20c00, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20c20, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20c40, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000020 }, { 0x00800001, 0x20200232, 0x00b20a60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20b60, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20a80, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20b80, 0x00000000 }, { 0x00800001, 0x20600232, 0x00b20aa0, 0x00000000 }, { 0x00800001, 0x20700232, 0x00b20ba0, 0x00000000 }, { 0x00800001, 0x20800232, 0x00b20ac0, 0x00000000 }, { 0x00800001, 0x20900232, 0x00b20bc0, 0x00000000 }, { 0x00800001, 0x20a00232, 0x00b20ae0, 0x00000000 }, { 0x00800001, 0x20b00232, 0x00b20be0, 0x00000000 }, { 0x00800001, 0x20c00232, 0x00b20b00, 0x00000000 }, { 0x00800001, 0x20d00232, 0x00b20c00, 0x00000000 }, { 0x00800001, 0x20e00232, 0x00b20b20, 0x00000000 }, { 0x00800001, 0x20f00232, 0x00b20c20, 0x00000000 }, { 0x00800001, 0x21000232, 0x00b20b40, 0x00000000 }, { 0x00800001, 0x21100232, 0x00b20c40, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x12082000 }, { 0x00000001, 0x23e80061, 0x00000000, 0x00070007 }, { 0x00200008, 0x23e01d21, 0x00450a4c, 0x00000001 }, { 0x80800001, 0x4c6001b1, 0x00b10c60, 0x00000000 }, { 0x80800001, 0x4c8001b1, 0x00b10c80, 0x00000000 }, { 0x80800001, 0x4ca001b1, 0x00b10ca0, 0x00000000 }, { 0x80800001, 0x4cc001b1, 0x00b10cc0, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20c60, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20c80, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20ca0, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20cc0, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082001 }, { 0x80800001, 0x4ce001b1, 0x00b10ce0, 0x00000000 }, { 0x80800001, 0x4d0001b1, 0x00b10d00, 0x00000000 }, { 0x80800001, 0x4d2001b1, 0x00b10d20, 0x00000000 }, { 0x80800001, 0x4d4001b1, 0x00b10d40, 0x00000000 }, { 0x00800001, 0x20200232, 0x00b20ce0, 0x00000000 }, { 0x00800001, 0x20300232, 0x00b20d00, 0x00000000 }, { 0x00800001, 0x20400232, 0x00b20d20, 0x00000000 }, { 0x00800001, 0x20500232, 0x00b20d40, 0x00000000 }, { 0x00800031, 0x24001d28, 0x508d03e0, 0x06082002 }, { 0x00800031, 0x24001d28, 0x748d0000, 0x82000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00000001, 0x2de001ad, 0x00218000, 0x00000000 }, { 0x00802041, 0x2e8025a5, 0x008d8000, 0x008d0e00 }, { 0x00802041, 0x2e8024a5, 0x008d0e80, 0x008c0da0 }, { 0x0080200c, 0x2e802ca5, 0x008d0e80, 0x00040004 }, { 0x00000041, 0x2e8025a5, 0x00210de0, 0x00210da4 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2ec025a5, 0x008d8000, 0x008d0e20 }, { 0x00802041, 0x2ec024a5, 0x008d0ec0, 0x008c0da0 }, { 0x0080200c, 0x2ec02ca5, 0x008d0ec0, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f0025a5, 0x008d8000, 0x008d0e40 }, { 0x00802041, 0x2f0024a5, 0x008d0f00, 0x008c0da0 }, { 0x0080200c, 0x2f002ca5, 0x008d0f00, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f4025a5, 0x008d8000, 0x008d0e60 }, { 0x00802041, 0x2f4024a5, 0x008d0f40, 0x008c0da0 }, { 0x0080200c, 0x2f402ca5, 0x008d0f40, 0x00040004 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00000400 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00000400 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00000400 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00000400 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x0000000b }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x0000000b }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x0000000b }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x0000000b }, { 0x00800001, 0x2dc001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2de001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2e0001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2e2001ad, 0x00ae04c0, 0x00000000 }, { 0x00000001, 0x2a000001, 0x00210200, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x0db00da0 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00080000 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00080000 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00080000 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00080000 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x00000014 }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x00000014 }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x00000014 }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x00000014 }, { 0x00000001, 0x22000020, 0x00210a00, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x34000c20, 0x00210fc0, 0x00000020 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/iq_intra.g4i000066400000000000000000000112051267532330400255150ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix in UB format g3~g4:non intra IQ matrix in UB format g5~g20:IDCT table g32~g55:DCT data before IQ g56~g79:DCT data after IQ g82: thread payload backup g109: g109.0:q_scale_code, g109.4:intra_dc_mult, g110: q_scale_code g111: intra DC coefficient g112~g115: intra IQ matrix in UW format (in order to use instruction compress), copys from g1~g2 g125: ip before jump */ and (1) g109.0<1>UW g82.8<1,1,1>UW 0x1fUW {align1}; //q_scale_code and (1) g109.4<1>UW g82.8<1,1,1>UW 0x6000UW {align1}; //intra_dc_presion shr (1) g109.4<1>UW g109.4<1,1,1>UW 13UW {align1}; mov (1) g109.6<1>UW 0x8UW {align1}; shr (1) g109.4<1>UW g109.6<1,1,1>UW g109.4<1,1,1>UW {align1}; //intra_dc_mult and.z (1) null g82.8<1,1,1>UW 0x20UW {align1}; //if(q_scale_type==0) q_scale=q_scale_code*2; (f0) jmpi Q_SCALE_TYPE_0; cmp.l (1) null g109.0<1,1,1>UW 9UW {align1}; //if(q_scale_type!=0) calculate q_scale (f0) jmpi DO_IQ; cmp.l (1) null g109.0<1,1,1>UW 17UW {align1}; (f0) jmpi RANG_9_16; cmp.l (1) null g109.0<1,1,1>UW 25UW {align1}; (f0) jmpi RANG_17_24; RANG_25_31: add (1) g109.0<1>UW g109.0<1,1,1>UW -25W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 3UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 64UW {align1}; jmpi DO_IQ; RANG_9_16: add (1) g109.0<1>UW g109.0<1,1,1>UW -9W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 1UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 10UW {align1}; jmpi DO_IQ; RANG_17_24: add (1) g109.0<1>UW g109.0<1,1,1>UW -17W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 2UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 28UW {align1}; jmpi DO_IQ; Q_SCALE_TYPE_0: shl (1) g109.0<1>UW g109.0<1,1,1>UW 1UD {align1}; DO_IQ: mov (1) g110.0<1>UW g109.0<1,1,1>UW {align1}; mov (16) g112.0<1>UW g1.0<16,16,1>UB {align1}; mov (16) g113.0<1>UW g1.16<16,16,1>UB {align1}; mov (16) g114.0<1>UW g2.0<16,16,1>UB {align1}; mov (16) g115.0<1>UW g2.16<16,16,1>UB {align1}; mov (1) a0.0<1>UD 0x03F003E0UD {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g56.0<1>W g116.0<16,8,2>W {align1}; mov (16) g57.0<1>W g118.0<16,8,2>W {align1}; mov (16) g58.0<1>W g120.0<16,8,2>W {align1}; mov (16) g59.0<1>W g122.0<16,8,2>W {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g60.0<1>W g116.0<16,8,2>W {align1}; mov (16) g61.0<1>W g118.0<16,8,2>W {align1}; mov (16) g62.0<1>W g120.0<16,8,2>W {align1}; mov (16) g63.0<1>W g122.0<16,8,2>W {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g64.0<1>W g116.0<16,8,2>W {align1}; mov (16) g65.0<1>W g118.0<16,8,2>W {align1}; mov (16) g66.0<1>W g120.0<16,8,2>W {align1}; mov (16) g67.0<1>W g122.0<16,8,2>W {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g68.0<1>W g116.0<16,8,2>W {align1}; mov (16) g69.0<1>W g118.0<16,8,2>W {align1}; mov (16) g70.0<1>W g120.0<16,8,2>W {align1}; mov (16) g71.0<1>W g122.0<16,8,2>W {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g72.0<1>W g116.0<16,8,2>W {align1}; mov (16) g73.0<1>W g118.0<16,8,2>W {align1}; mov (16) g74.0<1>W g120.0<16,8,2>W {align1}; mov (16) g75.0<1>W g122.0<16,8,2>W {align1}; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_INTRA; mov (16) g76.0<1>W g116.0<16,8,2>W {align1}; mov (16) g77.0<1>W g118.0<16,8,2>W {align1}; mov (16) g78.0<1>W g120.0<16,8,2>W {align1}; mov (16) g79.0<1>W g122.0<16,8,2>W {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/iq_non_intra.g4i000066400000000000000000000116741267532330400264010ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix in UB format g3~g4:non intra IQ matrix in UB format g5~g20:IDCT table g32~g55:DCT data before IQ g56~g79:DCT data after IQ g82: thread payload backup g109: q_scale_code g110: q_scale_code g112~g115: non intra IQ matrix in UW format (in order to use instruction compress), copys from g3~g4 g125: ip before jump */ and (1) g109.0<1>UW g82.8<1,1,1>UW 0x1fUW {align1}; //q_scale_code and.z (1) null g82.8<1,1,1>UW 0x20UW {align1}; //if(q_scale_type==0) q_scale=q_scale_code*2; (f0) jmpi Q_SCALE_TYPE_0; cmp.l (1) null g109.0<1,1,1>UW 9UW {align1}; //if(q_scale_type!=0) calculate q_scale (f0) jmpi DO_IQ; cmp.l (1) null g109.0<1,1,1>UW 17UW {align1}; (f0) jmpi RANG_9_16; cmp.l (1) null g109.0<1,1,1>UW 25UW {align1}; (f0) jmpi RANG_17_24; RANG_25_31: add (1) g109.0<1>UW g109.0<1,1,1>UW -25W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 3UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 64UW {align1}; jmpi DO_IQ; RANG_9_16: add (1) g109.0<1>UW g109.0<1,1,1>UW -9W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 1UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 10UW {align1}; jmpi DO_IQ; RANG_17_24: add (1) g109.0<1>UW g109.0<1,1,1>UW -17W {align1}; shl (1) g109.0<1>UW g109.0<1,1,1>UW 2UW {align1}; add (1) g109.0<1>UW g109.0<1,1,1>UW 28UW {align1}; jmpi DO_IQ; Q_SCALE_TYPE_0: shl (1) g109.0<1>UW g109.0<1,1,1>UW 1UD {align1}; DO_IQ: mov (1) g110.0<1>UW g109.0<1,1,1>UW {align1}; mov (16) g112.0<1>UW g3.0<16,16,1>UB {align1}; mov (16) g113.0<1>UW g3.16<16,16,1>UB {align1}; mov (16) g114.0<1>UW g4.0<16,16,1>UB {align1}; mov (16) g115.0<1>UW g4.16<16,16,1>UB {align1}; mov (1) a0.0<1>UD 0x03F003E0UD {align1}; //Y0 iq_non_intra_y0: and.z (1) null g82.8<1,1,1>UW 0x800UW {align1}; (f0) jmpi iq_non_intra_y1; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g56.0<1>W g116.0<16,8,2>W {align1}; mov (16) g57.0<1>W g118.0<16,8,2>W {align1}; mov (16) g58.0<1>W g120.0<16,8,2>W {align1}; mov (16) g59.0<1>W g122.0<16,8,2>W {align1}; //Y1 iq_non_intra_y1: and.z (1) null g82.8<1,1,1>UW 0x400UW {align1}; (f0) jmpi iq_non_intra_y2; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g60.0<1>W g116.0<16,8,2>W {align1}; mov (16) g61.0<1>W g118.0<16,8,2>W {align1}; mov (16) g62.0<1>W g120.0<16,8,2>W {align1}; mov (16) g63.0<1>W g122.0<16,8,2>W {align1}; //Y2 iq_non_intra_y2: and.z (1) null g82.8<1,1,1>UW 0x200UW {align1}; (f0) jmpi iq_non_intra_y3; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g64.0<1>W g116.0<16,8,2>W {align1}; mov (16) g65.0<1>W g118.0<16,8,2>W {align1}; mov (16) g66.0<1>W g120.0<16,8,2>W {align1}; mov (16) g67.0<1>W g122.0<16,8,2>W {align1}; //Y3 iq_non_intra_y3: and.z (1) null g82.8<1,1,1>UW 0x100UW {align1}; (f0) jmpi iq_non_intra_u; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g68.0<1>W g116.0<16,8,2>W {align1}; mov (16) g69.0<1>W g118.0<16,8,2>W {align1}; mov (16) g70.0<1>W g120.0<16,8,2>W {align1}; mov (16) g71.0<1>W g122.0<16,8,2>W {align1}; //U iq_non_intra_u: and.z (1) null g82.8<1,1,1>UW 0x80UW {align1}; (f0) jmpi iq_non_intra_v; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g72.0<1>W g116.0<16,8,2>W {align1}; mov (16) g73.0<1>W g118.0<16,8,2>W {align1}; mov (16) g74.0<1>W g120.0<16,8,2>W {align1}; mov (16) g75.0<1>W g122.0<16,8,2>W {align1}; //V iq_non_intra_v: and.z (1) null g82.8<1,1,1>UW 0x40UW {align1}; (f0) jmpi iq_non_intra_end; mov (1) g125.0<1>UD ip {align1}; jmpi DO_IQ_NON_INTRA; mov (16) g76.0<1>W g116.0<16,8,2>W {align1}; mov (16) g77.0<1>W g118.0<16,8,2>W {align1}; mov (16) g78.0<1>W g120.0<16,8,2>W {align1}; mov (16) g79.0<1>W g122.0<16,8,2>W {align1}; iq_non_intra_end: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/lib.g4a000066400000000000000000000144371267532330400244570ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix in UB format g3~g4:non intra IQ matrix in UB format g5~g20:IDCT table g32~g55:DCT data before IQ g56~g79:DCT data after IQ g83~g106: IDCT data after idct g82: thread payload backup g125: ip before jump */ include(`iq_non_intra.g4i') define(`ROW_SHIFT', `11UD') //define for idct define(`ROW_ADD', `0x400UD') define(`COL_SHIFT', `20UD') define(`COL_ADD', `0x80000UD') mov (1) a0.0<1>UD 0x06F006E0UD {align1};//0x06F006E0UD+0x00200020UD=0x07100700UD (g56.0 and g56.16,the start of DCT data) //Y0 and.nz (1) null g82.8<1,1,1>UW 0x800UW {align1}; (f0) jmpi do_idct_y0; mov (8) g83.0<1>UW 0UW {align1}; mov (8) g84.0<1>UW 0UW {align1}; mov (8) g85.0<1>UW 0UW {align1}; mov (8) g86.0<1>UW 0UW {align1}; mov (8) g87.0<1>UW 0UW {align1}; mov (8) g88.0<1>UW 0UW {align1}; mov (8) g89.0<1>UW 0UW {align1}; mov (8) g90.0<1>UW 0UW {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00800080UD {align1}; jmpi block_y1; do_idct_y0: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (8) g83.0<1>W g32.0<16,8,2>W {align1}; mov (8) g84.0<1>W g33.0<16,8,2>W {align1}; mov (8) g85.0<1>W g34.0<16,8,2>W {align1}; mov (8) g86.0<1>W g35.0<16,8,2>W {align1}; mov (8) g87.0<1>W g36.0<16,8,2>W {align1}; mov (8) g88.0<1>W g37.0<16,8,2>W {align1}; mov (8) g89.0<1>W g38.0<16,8,2>W {align1}; mov (8) g90.0<1>W g39.0<16,8,2>W {align1}; //Y1 block_y1: and.nz (1) null g82.8<1,1,1>UW 0x400UW {align1}; (f0) jmpi do_idct_y1; mov (8) g83.16<1>UW 0UW {align1}; mov (8) g84.16<1>UW 0UW {align1}; mov (8) g85.16<1>UW 0UW {align1}; mov (8) g86.16<1>UW 0UW {align1}; mov (8) g87.16<1>UW 0UW {align1}; mov (8) g88.16<1>UW 0UW {align1}; mov (8) g89.16<1>UW 0UW {align1}; mov (8) g90.16<1>UW 0UW {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00800080UD {align1}; jmpi block_y2; do_idct_y1: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (8) g83.16<1>W g32.0<16,8,2>W {align1}; mov (8) g84.16<1>W g33.0<16,8,2>W {align1}; mov (8) g85.16<1>W g34.0<16,8,2>W {align1}; mov (8) g86.16<1>W g35.0<16,8,2>W {align1}; mov (8) g87.16<1>W g36.0<16,8,2>W {align1}; mov (8) g88.16<1>W g37.0<16,8,2>W {align1}; mov (8) g89.16<1>W g38.0<16,8,2>W {align1}; mov (8) g90.16<1>W g39.0<16,8,2>W {align1}; //Y2 block_y2: and.nz (1) null g82.8<1,1,1>UW 0x200UW {align1}; (f0) jmpi do_idct_y2; mov (8) g91.0<1>UW 0UW {align1}; mov (8) g92.0<1>UW 0UW {align1}; mov (8) g93.0<1>UW 0UW {align1}; mov (8) g94.0<1>UW 0UW {align1}; mov (8) g95.0<1>UW 0UW {align1}; mov (8) g96.0<1>UW 0UW {align1}; mov (8) g97.0<1>UW 0UW {align1}; mov (8) g98.0<1>UW 0UW {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00800080UD {align1}; jmpi block_y3; do_idct_y2: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (8) g91.0<1>W g32.0<16,8,2>W {align1}; mov (8) g92.0<1>W g33.0<16,8,2>W {align1}; mov (8) g93.0<1>W g34.0<16,8,2>W {align1}; mov (8) g94.0<1>W g35.0<16,8,2>W {align1}; mov (8) g95.0<1>W g36.0<16,8,2>W {align1}; mov (8) g96.0<1>W g37.0<16,8,2>W {align1}; mov (8) g97.0<1>W g38.0<16,8,2>W {align1}; mov (8) g98.0<1>W g39.0<16,8,2>W {align1}; //Y3 block_y3: and.nz (1) null g82.8<1,1,1>UW 0x100UW {align1}; (f0) jmpi do_idct_y3; mov (8) g91.16<1>UW 0UW {align1}; mov (8) g92.16<1>UW 0UW {align1}; mov (8) g93.16<1>UW 0UW {align1}; mov (8) g94.16<1>UW 0UW {align1}; mov (8) g95.16<1>UW 0UW {align1}; mov (8) g96.16<1>UW 0UW {align1}; mov (8) g97.16<1>UW 0UW {align1}; mov (8) g98.16<1>UW 0UW {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00800080UD {align1}; jmpi block_u; do_idct_y3: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (8) g91.16<1>W g32.0<16,8,2>W {align1}; mov (8) g92.16<1>W g33.0<16,8,2>W {align1}; mov (8) g93.16<1>W g34.0<16,8,2>W {align1}; mov (8) g94.16<1>W g35.0<16,8,2>W {align1}; mov (8) g95.16<1>W g36.0<16,8,2>W {align1}; mov (8) g96.16<1>W g37.0<16,8,2>W {align1}; mov (8) g97.16<1>W g38.0<16,8,2>W {align1}; mov (8) g98.16<1>W g39.0<16,8,2>W {align1}; //U block_u: and.nz (1) null g82.8<1,1,1>UW 0x80UW {align1}; (f0) jmpi do_idct_u; mov (16) g99.0<1>UW 0UW {align1}; mov (16) g100.0<1>UW 0UW {align1}; mov (16) g101.0<1>UW 0UW {align1}; mov (16) g102.0<1>UW 0UW {align1}; add (1) a0.0<1>UD a0.0<1,1,1>UD 0x00800080UD {align1}; jmpi block_v; do_idct_u: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (16) g99.0<1>W g32.0<16,8,2>W {align1}; mov (16) g100.0<1>W g34.0<16,8,2>W {align1}; mov (16) g101.0<1>W g36.0<16,8,2>W {align1}; mov (16) g102.0<1>W g38.0<16,8,2>W {align1}; //V block_v: and.nz (1) null g82.8<1,1,1>UW 0x40UW {align1}; (f0) jmpi do_idct_v; mov (16) g103.0<1>UW 0UW {align1}; mov (16) g104.0<1>UW 0UW {align1}; mov (16) g105.0<1>UW 0UW {align1}; mov (16) g106.0<1>UW 0UW {align1}; jmpi block_end; do_idct_v: mov (1) g125.0<1>UD ip {align1}; jmpi IDCT_START; mov (16) g103.0<1>W g32.0<16,8,2>W {align1}; mov (16) g104.0<1>W g34.0<16,8,2>W {align1}; mov (16) g105.0<1>W g36.0<16,8,2>W {align1}; mov (16) g106.0<1>W g38.0<16,8,2>W {align1}; block_end: add (1) ip g126.8<1,1,1>UD 0x20UD {align1}; //jump back include(`do_iq_non_intra.g4i') include(`idct.g4i') xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/lib.g4b000066400000000000000000000407651267532330400244630ustar00rootroot00000000000000 { 0x00000005, 0x2da02d29, 0x00210a48, 0x001f001f }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00090009 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000011 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00110011 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00190019 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000008 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffe7ffe7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00030003 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x00400040 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000009 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xfff7fff7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00010001 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x000a000a }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000005 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffefffef }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00020002 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x001c001c }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000001 }, { 0x00000009, 0x2da00d29, 0x00210da0, 0x00000001 }, { 0x00000001, 0x2dc00129, 0x00210da0, 0x00000000 }, { 0x00800001, 0x2e000229, 0x00b10060, 0x00000000 }, { 0x00800001, 0x2e200229, 0x00b10070, 0x00000000 }, { 0x00800001, 0x2e400229, 0x00b10080, 0x00000000 }, { 0x00800001, 0x2e600229, 0x00b10090, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x03f003e0 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x08000800 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000a1 }, { 0x00800001, 0x270001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x272001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x274001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x276001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x04000400 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000099 }, { 0x00800001, 0x278001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x27a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x27c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x27e001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x02000200 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000091 }, { 0x00800001, 0x280001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x282001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x284001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x286001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x01000100 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000089 }, { 0x00800001, 0x288001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x28a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x28c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x28e001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00800080 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000081 }, { 0x00800001, 0x290001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x292001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x294001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x296001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00400040 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000079 }, { 0x00800001, 0x298001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x29a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x29c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x29e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x06f006e0 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x08000800 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00600001, 0x2a600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2a800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2aa00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ac00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ae00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b400169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000077 }, { 0x00600001, 0x2a6001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2a8001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2aa001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2ac001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2ae001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2b0001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2b2001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2b4001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x04000400 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00600001, 0x2a700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2a900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ab00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ad00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2af00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b500169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000061 }, { 0x00600001, 0x2a7001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2a9001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2ab001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2ad001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2af001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2b1001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2b3001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2b5001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x02000200 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00600001, 0x2b600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ba00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bc00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2be00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c400169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000004b }, { 0x00600001, 0x2b6001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2b8001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2ba001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2bc001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2be001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2c0001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2c2001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2c4001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x01000100 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00600001, 0x2b700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bb00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bd00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bf00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c500169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000035 }, { 0x00600001, 0x2b7001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2b9001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2bb001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2bd001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2bf001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2c1001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2c3001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2c5001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x00800080 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00800001, 0x2c600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2c800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ca00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2cc00169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000023 }, { 0x00800001, 0x2c6001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2c8001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2ca001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2cc001ad, 0x00ae04c0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x00400040 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000005 }, { 0x00800001, 0x2ce00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d400169, 0x00000000, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000006 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000016 }, { 0x00800001, 0x2ce001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2d0001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2d2001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2d4001ad, 0x00ae04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2e8025a5, 0x008d8000, 0x008d0e00 }, { 0x00802041, 0x2e8024a5, 0x008d0e80, 0x008c0da0 }, { 0x0080200c, 0x2e802ca5, 0x008d0e80, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2ec025a5, 0x008d8000, 0x008d0e20 }, { 0x00802041, 0x2ec024a5, 0x008d0ec0, 0x008c0da0 }, { 0x0080200c, 0x2ec02ca5, 0x008d0ec0, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f0025a5, 0x008d8000, 0x008d0e40 }, { 0x00802041, 0x2f0024a5, 0x008d0f00, 0x008c0da0 }, { 0x0080200c, 0x2f002ca5, 0x008d0f00, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f4025a5, 0x008d8000, 0x008d0e60 }, { 0x00802041, 0x2f4024a5, 0x008d0f40, 0x008c0da0 }, { 0x0080200c, 0x2f402ca5, 0x008d0f40, 0x00040004 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000001a }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00000400 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00000400 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00000400 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00000400 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x0000000b }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x0000000b }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x0000000b }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x0000000b }, { 0x00800001, 0x2dc001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2de001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2e0001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2e2001ad, 0x00ae04c0, 0x00000000 }, { 0x00000001, 0x2a000001, 0x00210200, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x0db00da0 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00080000 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00080000 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00080000 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00080000 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x00000014 }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x00000014 }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x00000014 }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x00000014 }, { 0x00000001, 0x22000020, 0x00210a00, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x34000c20, 0x00210fc0, 0x00000020 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/lib.g4b.gen5000066400000000000000000000407651267532330400253200ustar00rootroot00000000000000 { 0x00000005, 0x2da02d29, 0x00210a48, 0x001f001f }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00200020 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000024 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00090009 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000022 }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00110011 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x05000010, 0x20002d3c, 0x00210da0, 0x00190019 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000010 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffe7ffe7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00030003 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x00400040 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000012 }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xfff7fff7 }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00010001 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x000a000a }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00000040, 0x2da03d29, 0x00210da0, 0xffefffef }, { 0x00000009, 0x2da02d29, 0x00210da0, 0x00020002 }, { 0x00000040, 0x2da02d29, 0x00210da0, 0x001c001c }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000002 }, { 0x00000009, 0x2da00d29, 0x00210da0, 0x00000001 }, { 0x00000001, 0x2dc00129, 0x00210da0, 0x00000000 }, { 0x00800001, 0x2e000229, 0x00b10060, 0x00000000 }, { 0x00800001, 0x2e200229, 0x00b10070, 0x00000000 }, { 0x00800001, 0x2e400229, 0x00b10080, 0x00000000 }, { 0x00800001, 0x2e600229, 0x00b10090, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x03f003e0 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x08000800 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000142 }, { 0x00800001, 0x270001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x272001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x274001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x276001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x04000400 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000132 }, { 0x00800001, 0x278001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x27a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x27c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x27e001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x02000200 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000122 }, { 0x00800001, 0x280001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x282001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x284001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x286001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x01000100 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000112 }, { 0x00800001, 0x288001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x28a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x28c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x28e001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00800080 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000102 }, { 0x00800001, 0x290001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x292001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x294001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x296001ad, 0x00ae0f40, 0x00000000 }, { 0x01000005, 0x20002d3c, 0x00210a48, 0x00400040 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000f2 }, { 0x00800001, 0x298001ad, 0x00ae0e80, 0x00000000 }, { 0x00800001, 0x29a001ad, 0x00ae0ec0, 0x00000000 }, { 0x00800001, 0x29c001ad, 0x00ae0f00, 0x00000000 }, { 0x00800001, 0x29e001ad, 0x00ae0f40, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x06f006e0 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x08000800 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00600001, 0x2a600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2a800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2aa00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ac00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ae00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b400169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000ee }, { 0x00600001, 0x2a6001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2a8001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2aa001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2ac001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2ae001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2b0001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2b2001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2b4001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x04000400 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00600001, 0x2a700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2a900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ab00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ad00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2af00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b500169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x000000c2 }, { 0x00600001, 0x2a7001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2a9001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2ab001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2ad001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2af001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2b1001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2b3001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2b5001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x02000200 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00600001, 0x2b600169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b800169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2ba00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bc00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2be00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c000169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c200169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c400169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000096 }, { 0x00600001, 0x2b6001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2b8001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2ba001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2bc001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2be001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2c0001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2c2001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2c4001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x01000100 }, { 0x00010020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00600001, 0x2b700169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2b900169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bb00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bd00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2bf00169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c100169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c300169, 0x00000000, 0x00000000 }, { 0x00600001, 0x2c500169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000006a }, { 0x00600001, 0x2b7001ad, 0x00ae0400, 0x00000000 }, { 0x00600001, 0x2b9001ad, 0x00ae0420, 0x00000000 }, { 0x00600001, 0x2bb001ad, 0x00ae0440, 0x00000000 }, { 0x00600001, 0x2bd001ad, 0x00ae0460, 0x00000000 }, { 0x00600001, 0x2bf001ad, 0x00ae0480, 0x00000000 }, { 0x00600001, 0x2c1001ad, 0x00ae04a0, 0x00000000 }, { 0x00600001, 0x2c3001ad, 0x00ae04c0, 0x00000000 }, { 0x00600001, 0x2c5001ad, 0x00ae04e0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x00800080 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00800001, 0x2c600169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2c800169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2ca00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2cc00169, 0x00000000, 0x00000000 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00800080 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000046 }, { 0x00800001, 0x2c6001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2c8001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2ca001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2cc001ad, 0x00ae04c0, 0x00000000 }, { 0x02000005, 0x20002d3c, 0x00210a48, 0x00400040 }, { 0x00010020, 0x34001c00, 0x00001400, 0x0000000a }, { 0x00800001, 0x2ce00169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d000169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d200169, 0x00000000, 0x00000000 }, { 0x00800001, 0x2d400169, 0x00000000, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000000c }, { 0x00000001, 0x2fa00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x0000002c }, { 0x00800001, 0x2ce001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2d0001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2d2001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2d4001ad, 0x00ae04c0, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fc8, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2e8025a5, 0x008d8000, 0x008d0e00 }, { 0x00802041, 0x2e8024a5, 0x008d0e80, 0x008c0da0 }, { 0x0080200c, 0x2e802ca5, 0x008d0e80, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2ec025a5, 0x008d8000, 0x008d0e20 }, { 0x00802041, 0x2ec024a5, 0x008d0ec0, 0x008c0da0 }, { 0x0080200c, 0x2ec02ca5, 0x008d0ec0, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f0025a5, 0x008d8000, 0x008d0e40 }, { 0x00802041, 0x2f0024a5, 0x008d0f00, 0x008c0da0 }, { 0x0080200c, 0x2f002ca5, 0x008d0f00, 0x00040004 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802041, 0x2f4025a5, 0x008d8000, 0x008d0e60 }, { 0x00802041, 0x2f4024a5, 0x008d0f40, 0x008c0da0 }, { 0x0080200c, 0x2f402ca5, 0x008d0f40, 0x00040004 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000034 }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00000400 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00000400 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00000400 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00000400 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x0000000b }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x0000000b }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x0000000b }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x0000000b }, { 0x00800001, 0x2dc001ad, 0x00ae0400, 0x00000000 }, { 0x00800001, 0x2de001ad, 0x00ae0440, 0x00000000 }, { 0x00800001, 0x2e0001ad, 0x00ae0480, 0x00000000 }, { 0x00800001, 0x2e2001ad, 0x00ae04c0, 0x00000000 }, { 0x00000001, 0x2a000001, 0x00210200, 0x00000000 }, { 0x00000001, 0x22000060, 0x00000000, 0x0db00da0 }, { 0x00000001, 0x2fc00001, 0x00001400, 0x00000000 }, { 0x00000020, 0x34001c00, 0x00001400, 0x00000014 }, { 0x00802040, 0x24000ca5, 0x008d0400, 0x00080000 }, { 0x00802040, 0x24400ca5, 0x008d0440, 0x00080000 }, { 0x00802040, 0x24800ca5, 0x008d0480, 0x00080000 }, { 0x00802040, 0x24c00ca5, 0x008d04c0, 0x00080000 }, { 0x00802008, 0x24000ca5, 0x008d0400, 0x00000014 }, { 0x00802008, 0x24400ca5, 0x008d0440, 0x00000014 }, { 0x00802008, 0x24800ca5, 0x008d0480, 0x00000014 }, { 0x00802008, 0x24c00ca5, 0x008d04c0, 0x00000014 }, { 0x00000001, 0x22000020, 0x00210a00, 0x00000000 }, { 0x00000040, 0x34000c20, 0x00210fa0, 0x00000020 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x240814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x242814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x244814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x246814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x248814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24a814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24c814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24e814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241014a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243014a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245014a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247014a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249014a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b014a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d014a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f014a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x22000c00, 0x00210200, 0x00200020 }, { 0x00802054, 0x250015a5, 0x008d8000, 0x008d00a0 }, { 0x00802054, 0x254015a5, 0x008d8000, 0x008d00e0 }, { 0x00802054, 0x258015a5, 0x008d8000, 0x008d0120 }, { 0x00802054, 0x25c015a5, 0x008d8000, 0x008d0160 }, { 0x00802054, 0x260015a5, 0x008d8000, 0x008d01a0 }, { 0x00802054, 0x264015a5, 0x008d8000, 0x008d01e0 }, { 0x00802054, 0x268015a5, 0x008d8000, 0x008d0220 }, { 0x00802054, 0x26c015a5, 0x008d8000, 0x008d0260 }, { 0x00200040, 0x241814a5, 0x00800500, 0x00800510 }, { 0x00200040, 0x243814a5, 0x00800540, 0x00800550 }, { 0x00200040, 0x245814a5, 0x00800580, 0x00800590 }, { 0x00200040, 0x247814a5, 0x008005c0, 0x008005d0 }, { 0x00200040, 0x249814a5, 0x00800600, 0x00800610 }, { 0x00200040, 0x24b814a5, 0x00800640, 0x00800650 }, { 0x00200040, 0x24d814a5, 0x00800680, 0x00800690 }, { 0x00200040, 0x24f814a5, 0x008006c0, 0x008006d0 }, { 0x00000040, 0x34000c20, 0x00210fc0, 0x00000020 }, xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/motion_field_uv.g4i000066400000000000000000000033421267532330400270740ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and.z (1) null mv1<1,1,1>W 1W {align1}; (f0) jmpi L1; and.z (1) null mv2<1,1,1>W 1W {align1}; (f0) jmpi L2; include(`read_field_x1y1_uv.g4i') jmpi L5; L2: include(`read_field_x1y0_uv.g4i') jmpi L5; L1: and.z (1) null mv2<1,1,1>W 1W {align1}; (f0) jmpi L4; include(`read_field_x0y1_uv.g4i') jmpi L5; L4: include(`read_field_x0y0_uv.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/motion_field_y.g4i000066400000000000000000000032001267532330400267030ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ and.z (1) null mv1<1,1,1>W 1UW {align1}; (f0) jmpi L1; and.z (1) null mv2<1,1,1>W 1UW {align1}; (f0) jmpi L2; include(`read_field_x1y1_y.g4i') jmpi L5; L2: include(`read_field_x1y0_y.g4i') jmpi L5; L1: and.z (1) null mv2<1,1,1>W 1UW {align1}; (f0) jmpi L4; include(`read_field_x0y1_y.g4i') jmpi L5; L4: include(`read_field_x0y0_y.g4i') L5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/motion_frame_uv.g4i000066400000000000000000000032211267532330400270770ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng */ and.z (1) null mv1<1,1,1>UW 2UD {align1}; (f0) jmpi LL1; and.z (1) null mv2<1,1,1>UW 2UD {align1}; (f0) jmpi LL2; include(`read_frame_x1y1_uv.g4i') jmpi LL5; LL2: include(`read_frame_x1y0_uv.g4i') jmpi LL5; LL1: and.z (1) null mv2<1,1,1>UW 2UD {align1}; (f0) jmpi LL4; include(`read_frame_x0y1_uv.g4i') jmpi LL5; LL4: include(`read_frame_x0y0_uv.g4i') LL5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/motion_frame_y.g4i000066400000000000000000000034141267532330400267210ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai */ /* if (motion_vect.x & 1) { * if (motion_vect.y & 1) * half_pixel in x and y; * else * half_pixel in x; * } else { * if (motion_vect.y & 1) * half_pixel y; * else * full_pixel_read; * } */ and.z (1) null mv1<1,1,1>UW 1UD {align1}; (f0) jmpi LL1; and.z (1) null mv2<1,1,1>UW 1UD {align1}; (f0) jmpi LL2; include(`read_frame_x1y1_y.g4i') jmpi LL5; LL2: include(`read_frame_x1y0_y.g4i') jmpi LL5; LL1: and.z (1) null mv2<1,1,1>UW 1UD {align1}; (f0) jmpi LL4; include(`read_frame_x0y1_y.g4i') jmpi LL5; LL4: include(`read_frame_x0y0_y.g4i') LL5: xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x0y0_uv.g4i000066400000000000000000000042311267532330400273600ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x7000FUD {align1}; // 8*16/32=4 send (16) 0 g40.0<1>UW g115<16,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<16,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (16) g32.0<1>UW g40.0<16,8,1>UB {align1}; mov (16) g33.0<1>UW g41.0<16,8,1>UB {align1}; mov (16) g34.0<1>UW g42.0<16,8,1>UB {align1}; mov (16) g35.0<1>UW g43.0<16,8,1>UB {align1}; mov (16) g36.0<1>UW g45.0<16,8,1>UB {align1}; mov (16) g37.0<1>UW g46.0<16,8,1>UB {align1}; mov (16) g38.0<1>UW g47.0<16,8,1>UB {align1}; mov (16) g39.0<1>UW g48.0<16,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x0y0_y.g4i000066400000000000000000000051431267532330400272010ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g42.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g46.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; mov (16) g32.0<1>UW g40.0<16,16,1>UB {align1}; mov (16) g33.0<1>UW g42.0<16,16,1>UB {align1}; mov (16) g34.0<1>UW g44.0<16,16,1>UB {align1}; mov (16) g35.0<1>UW g46.0<16,16,1>UB {align1}; mov (16) g36.0<1>UW g48.0<16,16,1>UB {align1}; mov (16) g37.0<1>UW g50.0<16,16,1>UB {align1}; mov (16) g38.0<1>UW g52.0<16,16,1>UB {align1}; mov (16) g39.0<1>UW g54.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x0y1_uv.g4i000066400000000000000000000024361267532330400273660ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; // 8*16/32=4 send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0xFUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 1 {align1};//V avg (16) g32.0<1>UW g40.0<16,8,1>UB g41.0<16,8,1>UB {align1}; avg (16) g33.0<1>UW g41.0<16,8,1>UB g42.0<16,8,1>UB {align1}; avg (16) g34.0<1>UW g42.0<16,8,1>UB g43.0<16,8,1>UB {align1}; avg (16) g35.0<1>UW g43.0<16,8,1>UB g44.0<16,8,1>UB {align1}; avg (16) g36.0<1>UW g45.0<16,8,1>UB g46.0<16,8,1>UB {align1}; avg (16) g37.0<1>UW g46.0<16,8,1>UB g47.0<16,8,1>UB {align1}; avg (16) g38.0<1>UW g47.0<16,8,1>UB g48.0<16,8,1>UB {align1}; avg (16) g39.0<1>UW g48.0<16,8,1>UB g49.0<16,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x0y1_y.g4i000066400000000000000000000056631267532330400272110ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g42.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g46.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; avg.sat (16) g32.0<1>UW g40.0<16,16,1>UB g42.0<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g42.0<16,16,1>UB g44.0<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g44.0<16,16,1>UB g46.0<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g46.0<16,16,1>UB g48.0<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g48.0<16,16,1>UB g50.0<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g50.0<16,16,1>UB g52.0<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g52.0<16,16,1>UB g54.0<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g54.0<16,16,1>UB g56.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x1y0_uv.g4i000066400000000000000000000020261267532330400273610ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; // 8*16/32=4 send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V avg (16) g32.0<1>UW g40.0<16,8,1>UB g40.1<16,8,1>UB {align1}; avg (16) g33.0<1>UW g41.0<16,8,1>UB g41.1<16,8,1>UB {align1}; avg (16) g34.0<1>UW g42.0<16,8,1>UB g42.1<16,8,1>UB {align1}; avg (16) g35.0<1>UW g43.0<16,8,1>UB g43.1<16,8,1>UB {align1}; avg (16) g36.0<1>UW g44.0<16,8,1>UB g44.1<16,8,1>UB {align1}; avg (16) g37.0<1>UW g45.0<16,8,1>UB g45.1<16,8,1>UB {align1}; avg (16) g38.0<1>UW g46.0<16,8,1>UB g46.1<16,8,1>UB {align1}; avg (16) g39.0<1>UW g47.0<16,8,1>UB g47.1<16,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x1y0_y.g4i000066400000000000000000000054131267532330400272020ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g42.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g46.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; avg.sat (16) g32.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; avg.sat (16) g33.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; avg.sat (16) g34.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; avg.sat (16) g35.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; avg.sat (16) g36.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; avg.sat (16) g37.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; avg.sat (16) g38.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; avg.sat (16) g39.0<1>UW g54.0<16,16,1>UB g54.1<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x1y1_uv.g4i000066400000000000000000000047451267532330400273740ustar00rootroot00000000000000/* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x07000FUD {align1}; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 4 {align1};//U send (16) 0 g45.0<1>UW g115<8,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 4 {align1};//V mov (1) g115.8<1>UD 0x01000FUD {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface_u, 2, 0, 2) mlen 1 rlen 1 {align1};//U send (16) 0 g49.0<1>UW g115<8,8,1>UW read(surface_v, 2, 0, 2) mlen 1 rlen 1 {align1};//V //U add (16) g32.0<1>UW g40.0<16,8,1>UB g41.0<16,8,1>UB {align1}; add (16) g33.0<1>UW g41.0<16,8,1>UB g42.0<16,8,1>UB {align1}; add (16) g34.0<1>UW g42.0<16,8,1>UB g43.0<16,8,1>UB {align1}; add (16) g35.0<1>UW g43.0<16,8,1>UB g44.0<16,8,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,8,1>UW g40.1<16,8,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,8,1>UW g41.1<16,8,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,8,1>UW g42.1<16,8,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,8,1>UW g43.1<16,8,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,8,1>UW g41.1<16,8,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,8,1>UW g42.1<16,8,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,8,1>UW g43.1<16,8,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,8,1>UW g44.1<16,8,1>UB {align1}; //V add (16) g36.0<1>UW g45.0<16,8,1>UB g46.0<16,8,1>UB {align1}; add (16) g37.0<1>UW g46.0<16,8,1>UB g47.0<16,8,1>UB {align1}; add (16) g38.0<1>UW g47.0<16,8,1>UB g48.0<16,8,1>UB {align1}; add (16) g39.0<1>UW g48.0<16,8,1>UB g49.0<16,8,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,8,1>UW g45.1<16,8,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,8,1>UW g46.1<16,8,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,8,1>UW g47.1<16,8,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,8,1>UW g48.1<16,8,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,8,1>UW g46.1<16,8,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,8,1>UW g47.1<16,8,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,8,1>UW g48.1<16,8,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,8,1>UW g49.1<16,8,1>UB {align1}; shr (32) g32.0<1>UW g32.0<16,16,1>UW 2UW {align1 compr}; shr (32) g34.0<1>UW g34.0<16,16,1>UW 2UW {align1 compr}; shr (32) g36.0<1>UW g36.0<16,16,1>UW 2UW {align1 compr}; shr (32) g38.0<1>UW g38.0<16,16,1>UW 2UW {align1 compr}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_field_x1y1_y.g4i000066400000000000000000000104561267532330400272060ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g58~g81:reference data g82: thread payload backup g83~g106:IDCT data g115: message descriptor for reading reference data */ mov (1) g115.8<1>UD 0x01FUD {align1}; send (16) 0 g40.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g42.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g44.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; send (16) 0 g46.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 2UD {align1}; mov (1) g115.8<1>UD 0x07001FUD {align1}; send (16) 0 g48.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 8 {align1}; add (1) g115.4<1>UD g115.4<1,1,1>UD 8UD {align1}; mov (1) g115.8<1>UD 0x1FUD {align1}; send (16) 0 g56.0<1>UW g115<8,8,1>UW read(surface,2,0,2) mlen 1 rlen 1 {align1}; add (16) g32.0<1>UW g40.0<16,16,1>UB g42.0<16,16,1>UB {align1}; add (16) g33.0<1>UW g42.0<16,16,1>UB g44.0<16,16,1>UB {align1}; add (16) g34.0<1>UW g44.0<16,16,1>UB g46.0<16,16,1>UB {align1}; add (16) g35.0<1>UW g46.0<16,16,1>UB g48.0<16,16,1>UB {align1}; add (16) g36.0<1>UW g48.0<16,16,1>UB g50.0<16,16,1>UB {align1}; add (16) g37.0<1>UW g50.0<16,16,1>UB g52.0<16,16,1>UB {align1}; add (16) g38.0<1>UW g52.0<16,16,1>UB g54.0<16,16,1>UB {align1}; add (16) g39.0<1>UW g54.0<16,16,1>UB g56.0<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g40.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g54.1<16,16,1>UB {align1}; add (16) g32.0<1>UW g32.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g33.0<1>UW g33.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g34.0<1>UW g34.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g35.0<1>UW g35.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g36.0<1>UW g36.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g37.0<1>UW g37.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g38.0<1>UW g38.0<16,16,1>UW g54.1<16,16,1>UB {align1}; add (16) g39.0<1>UW g39.0<16,16,1>UW g56.1<16,16,1>UB {align1}; shr (16) g32.0<1>UW g32.0<16,16,1>UW 2UW {align1}; shr (16) g33.0<1>UW g33.0<16,16,1>UW 2UW {align1}; shr (16) g34.0<1>UW g34.0<16,16,1>UW 2UW {align1}; shr (16) g35.0<1>UW g35.0<16,16,1>UW 2UW {align1}; shr (16) g36.0<1>UW g36.0<16,16,1>UW 2UW {align1}; shr (16) g37.0<1>UW g37.0<16,16,1>UW 2UW {align1}; shr (16) g38.0<1>UW g38.0<16,16,1>UW 2UW {align1}; shr (16) g39.0<1>UW g39.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x0y0_uv.g4i000066400000000000000000000042451267532330400273740ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007000fUD {align1}; send (16) 0 g36.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g40.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; mov (16) g74.0<1>UW g36.0<16,8,1>UB {align1}; mov (16) g75.0<1>UW g37.0<16,8,1>UB {align1}; mov (16) g76.0<1>UW g38.0<16,8,1>UB {align1}; mov (16) g77.0<1>UW g39.0<16,8,1>UB {align1}; mov (16) g78.0<1>UW g40.0<16,8,1>UB {align1}; mov (16) g79.0<1>UW g41.0<16,8,1>UB {align1}; mov (16) g80.0<1>UW g42.0<16,8,1>UB {align1}; mov (16) g81.0<1>UW g43.0<16,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x0y0_y.g4i000066400000000000000000000051221267532330400272050ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; mov (16) g58.0<1>UW g38.0<16,16,1>UB {align1}; mov (16) g59.0<1>UW g39.0<16,16,1>UB {align1}; mov (16) g60.0<1>UW g40.0<16,16,1>UB {align1}; mov (16) g61.0<1>UW g41.0<16,16,1>UB {align1}; mov (16) g62.0<1>UW g42.0<16,16,1>UB {align1}; mov (16) g63.0<1>UW g43.0<16,16,1>UB {align1}; mov (16) g64.0<1>UW g44.0<16,16,1>UB {align1}; mov (16) g65.0<1>UW g45.0<16,16,1>UB {align1}; mov (16) g66.0<1>UW g46.0<16,16,1>UB {align1}; mov (16) g67.0<1>UW g47.0<16,16,1>UB {align1}; mov (16) g68.0<1>UW g48.0<16,16,1>UB {align1}; mov (16) g69.0<1>UW g49.0<16,16,1>UB {align1}; mov (16) g70.0<1>UW g50.0<16,16,1>UB {align1}; mov (16) g71.0<1>UW g51.0<16,16,1>UB {align1}; mov (16) g72.0<1>UW g52.0<16,16,1>UB {align1}; mov (16) g73.0<1>UW g53.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x0y1_uv.g4i000066400000000000000000000053341267532330400273750ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDINg BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINgEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIgHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAgES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISINg FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINgS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g34.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 8 {align1}; //U send (16) 0 g44.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 8 {align1}; //V add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g42.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; //U send (16) 0 g52.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; //V //U avg (8) g74.0<1>UW g34.0<8,8,1>UB g35.0<8,8,1>UB {align1}; avg (8) g74.16<1>UW g35.0<8,8,1>UB g36.0<8,8,1>UB {align1}; avg (8) g75.0<1>UW g36.0<8,8,1>UB g37.0<8,8,1>UB {align1}; avg (8) g75.16<1>UW g37.0<8,8,1>UB g38.0<8,8,1>UB {align1}; avg (8) g76.0<1>UW g38.0<8,8,1>UB g39.0<8,8,1>UB {align1}; avg (8) g76.16<1>UW g39.0<8,8,1>UB g40.0<8,8,1>UB {align1}; avg (8) g77.0<1>UW g40.0<8,8,1>UB g41.0<8,8,1>UB {align1}; avg (8) g77.16<1>UW g41.0<8,8,1>UB g42.0<8,8,1>UB {align1}; //V avg (8) g78.0<1>UW g44.0<8,8,1>UB g45.0<8,8,1>UB {align1}; avg (8) g78.16<1>UW g45.0<8,8,1>UB g46.0<8,8,1>UB {align1}; avg (8) g79.0<1>UW g46.0<8,8,1>UB g47.0<8,8,1>UB {align1}; avg (8) g79.16<1>UW g47.0<8,8,1>UB g48.0<8,8,1>UB {align1}; avg (8) g80.0<1>UW g48.0<8,8,1>UB g49.0<8,8,1>UB {align1}; avg (8) g80.16<1>UW g49.0<8,8,1>UB g50.0<8,8,1>UB {align1}; avg (8) g81.0<1>UW g50.0<8,8,1>UB g51.0<8,8,1>UB {align1}; avg (8) g81.16<1>UW g51.0<8,8,1>UB g52.0<8,8,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x0y1_y.g4i000066400000000000000000000061171267532330400272130ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 1 {align1}; avg.sat (16) g58.0<1>UW g38.0<16,16,1>UB g39.0<16,16,1>UB {align1}; avg.sat (16) g59.0<1>UW g39.0<16,16,1>UB g40.0<16,16,1>UB {align1}; avg.sat (16) g60.0<1>UW g40.0<16,16,1>UB g41.0<16,16,1>UB {align1}; avg.sat (16) g61.0<1>UW g41.0<16,16,1>UB g42.0<16,16,1>UB {align1}; avg.sat (16) g62.0<1>UW g42.0<16,16,1>UB g43.0<16,16,1>UB {align1}; avg.sat (16) g63.0<1>UW g43.0<16,16,1>UB g44.0<16,16,1>UB {align1}; avg.sat (16) g64.0<1>UW g44.0<16,16,1>UB g45.0<16,16,1>UB {align1}; avg.sat (16) g65.0<1>UW g45.0<16,16,1>UB g46.0<16,16,1>UB {align1}; avg.sat (16) g66.0<1>UW g46.0<16,16,1>UB g47.0<16,16,1>UB {align1}; avg.sat (16) g67.0<1>UW g47.0<16,16,1>UB g48.0<16,16,1>UB {align1}; avg.sat (16) g68.0<1>UW g48.0<16,16,1>UB g49.0<16,16,1>UB {align1}; avg.sat (16) g69.0<1>UW g49.0<16,16,1>UB g50.0<16,16,1>UB {align1}; avg.sat (16) g70.0<1>UW g50.0<16,16,1>UB g51.0<16,16,1>UB {align1}; avg.sat (16) g71.0<1>UW g51.0<16,16,1>UB g52.0<16,16,1>UB {align1}; avg.sat (16) g72.0<1>UW g52.0<16,16,1>UB g53.0<16,16,1>UB {align1}; avg.sat (16) g73.0<1>UW g53.0<16,16,1>UB g54.0<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x1y0_uv.g4i000066400000000000000000000037451267532330400274010ustar00rootroot00000000000000/* * Copyright © 2008 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Zhang Hua jun * Xing Dong sheng * */ mov (1) g32.8<1>UD 0x007000fUD {align1}; send (16) 0 g34.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 4 {align1}; send (16) 0 g44.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 4 {align1}; avg (16) g74.0<1>UW g34.0<16,8,1>UB g34.1<16,8,1>UB{align1}; avg (16) g75.0<1>UW g35.0<16,8,1>UB g35.1<16,8,1>UB{align1}; avg (16) g76.0<1>UW g36.0<16,8,1>UB g36.1<16,8,1>UB{align1}; avg (16) g77.0<1>UW g37.0<16,8,1>UB g37.1<16,8,1>UB{align1}; avg (16) g78.0<1>UW g44.0<16,8,1>UB g44.1<16,8,1>UB{align1}; avg (16) g79.0<1>UW g45.0<16,8,1>UB g45.1<16,8,1>UB{align1}; avg (16) g80.0<1>UW g46.0<16,8,1>UB g46.1<16,8,1>UB{align1}; avg (16) g81.0<1>UW g47.0<16,8,1>UB g47.1<16,8,1>UB{align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x1y0_y.g4i000066400000000000000000000056421267532330400272150ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; avg.sat (16) g58.0<1>UW g38.0<16,16,1>UB g38.1<16,16,1>UB {align1}; avg.sat (16) g59.0<1>UW g39.0<16,16,1>UB g39.1<16,16,1>UB {align1}; avg.sat (16) g60.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; avg.sat (16) g61.0<1>UW g41.0<16,16,1>UB g41.1<16,16,1>UB {align1}; avg.sat (16) g62.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; avg.sat (16) g63.0<1>UW g43.0<16,16,1>UB g43.1<16,16,1>UB {align1}; avg.sat (16) g64.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; avg.sat (16) g65.0<1>UW g45.0<16,16,1>UB g45.1<16,16,1>UB {align1}; avg.sat (16) g66.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; avg.sat (16) g67.0<1>UW g47.0<16,16,1>UB g47.1<16,16,1>UB {align1}; avg.sat (16) g68.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; avg.sat (16) g69.0<1>UW g49.0<16,16,1>UB g49.1<16,16,1>UB {align1}; avg.sat (16) g70.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; avg.sat (16) g71.0<1>UW g51.0<16,16,1>UB g51.1<16,16,1>UB {align1}; avg.sat (16) g72.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; avg.sat (16) g73.0<1>UW g53.0<16,16,1>UB g53.1<16,16,1>UB {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x1y1_uv.g4i000066400000000000000000000074031267532330400273750ustar00rootroot00000000000000/* */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g34.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 8 {align1}; //U send (16) 0 g44.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 8 {align1}; //V add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g42.0<1>UW g32<8,8,1>UW read(input_surface1, 2, 0, 2) mlen 1 rlen 1 {align1}; //U send (16) 0 g52.0<1>UW g32<8,8,1>UW read(input_surface2, 2, 0, 2) mlen 1 rlen 1 {align1}; //V //U add (8) g74.0<1>UW g34.0<8,8,1>UB g34.1<8,8,1>UB {align1}; add (8) g74.16<1>UW g35.0<8,8,1>UB g35.1<8,8,1>UB {align1}; add (8) g75.0<1>UW g36.0<8,8,1>UB g36.1<8,8,1>UB {align1}; add (8) g75.16<1>UW g37.0<8,8,1>UB g37.1<8,8,1>UB {align1}; add (8) g76.0<1>UW g38.0<8,8,1>UB g38.1<8,8,1>UB {align1}; add (8) g76.16<1>UW g39.0<8,8,1>UB g39.1<8,8,1>UB {align1}; add (8) g77.0<1>UW g40.0<8,8,1>UB g40.1<8,8,1>UB {align1}; add (8) g77.16<1>UW g41.0<8,8,1>UB g41.1<8,8,1>UB {align1}; add (8) g74.0<1>UW g74.0<8,8,1>UW g35.0<8,8,1>UB {align1}; add (8) g74.16<1>UW g74.16<8,8,1>UW g36.0<8,8,1>UB {align1}; add (8) g75.0<1>UW g75.0<8,8,1>UW g37.0<8,8,1>UB {align1}; add (8) g75.16<1>UW g75.16<8,8,1>UW g38.0<8,8,1>UB {align1}; add (8) g76.0<1>UW g76.0<8,8,1>UW g39.0<8,8,1>UB {align1}; add (8) g76.16<1>UW g76.16<8,8,1>UW g40.0<8,8,1>UB {align1}; add (8) g77.0<1>UW g77.0<8,8,1>UW g41.0<8,8,1>UB {align1}; add (8) g77.16<1>UW g77.16<8,8,1>UW g42.0<8,8,1>UB {align1}; add (8) g74.0<1>UW g74.0<8,8,1>UW g35.1<8,8,1>UB {align1}; add (8) g74.16<1>UW g74.16<8,8,1>UW g36.1<8,8,1>UB {align1}; add (8) g75.0<1>UW g75.0<8,8,1>UW g37.1<8,8,1>UB {align1}; add (8) g75.16<1>UW g75.16<8,8,1>UW g38.1<8,8,1>UB {align1}; add (8) g76.0<1>UW g76.0<8,8,1>UW g39.1<8,8,1>UB {align1}; add (8) g76.16<1>UW g76.16<8,8,1>UW g40.1<8,8,1>UB {align1}; add (8) g77.0<1>UW g77.0<8,8,1>UW g41.1<8,8,1>UB {align1}; add (8) g77.16<1>UW g77.16<8,8,1>UW g42.1<8,8,1>UB {align1}; //V add (8) g78.0<1>UW g44.0<8,8,1>UB g44.1<8,8,1>UB {align1}; add (8) g78.16<1>UW g45.0<8,8,1>UB g45.1<8,8,1>UB {align1}; add (8) g79.0<1>UW g46.0<8,8,1>UB g46.1<8,8,1>UB {align1}; add (8) g79.16<1>UW g47.0<8,8,1>UB g47.1<8,8,1>UB {align1}; add (8) g80.0<1>UW g48.0<8,8,1>UB g48.1<8,8,1>UB {align1}; add (8) g80.16<1>UW g49.0<8,8,1>UB g49.1<8,8,1>UB {align1}; add (8) g81.0<1>UW g50.0<8,8,1>UB g50.1<8,8,1>UB {align1}; add (8) g81.16<1>UW g51.0<8,8,1>UB g51.1<8,8,1>UB {align1}; add (8) g78.0<1>UW g78.0<8,8,1>UW g45.0<8,8,1>UB {align1}; add (8) g78.16<1>UW g78.16<8,8,1>UW g46.0<8,8,1>UB {align1}; add (8) g79.0<1>UW g79.0<8,8,1>UW g47.0<8,8,1>UB {align1}; add (8) g79.16<1>UW g79.16<8,8,1>UW g48.0<8,8,1>UB {align1}; add (8) g80.0<1>UW g80.0<8,8,1>UW g49.0<8,8,1>UB {align1}; add (8) g80.16<1>UW g80.16<8,8,1>UW g50.0<8,8,1>UB {align1}; add (8) g81.0<1>UW g81.0<8,8,1>UW g51.0<8,8,1>UB {align1}; add (8) g81.16<1>UW g81.16<8,8,1>UW g52.0<8,8,1>UB {align1}; add (8) g78.0<1>UW g78.0<8,8,1>UW g45.1<8,8,1>UB {align1}; add (8) g78.16<1>UW g78.16<8,8,1>UW g46.1<8,8,1>UB {align1}; add (8) g79.0<1>UW g79.0<8,8,1>UW g47.1<8,8,1>UB {align1}; add (8) g79.16<1>UW g79.16<8,8,1>UW g48.1<8,8,1>UB {align1}; add (8) g80.0<1>UW g80.0<8,8,1>UW g49.1<8,8,1>UB {align1}; add (8) g80.16<1>UW g80.16<8,8,1>UW g50.1<8,8,1>UB {align1}; add (8) g81.0<1>UW g81.0<8,8,1>UW g51.1<8,8,1>UB {align1}; add (8) g81.16<1>UW g81.16<8,8,1>UW g52.1<8,8,1>UB {align1}; shr (16) g74.0<1>UW g74.0<16,16,1>UW 2UW {align1}; shr (16) g75.0<1>UW g75.0<16,16,1>UW 2UW {align1}; shr (16) g76.0<1>UW g76.0<16,16,1>UW 2UW {align1}; shr (16) g77.0<1>UW g77.0<16,16,1>UW 2UW {align1}; shr (16) g78.0<1>UW g78.0<16,16,1>UW 2UW {align1}; shr (16) g79.0<1>UW g79.0<16,16,1>UW 2UW {align1}; shr (16) g80.0<1>UW g80.0<16,16,1>UW 2UW {align1}; shr (16) g81.0<1>UW g81.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/shader/vld/read_frame_x1y1_y.g4i000066400000000000000000000136021267532330400272110ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai * Yan Li * Liu Xi bin */ /* GRF allocation: g1~g30: constant buffer g1~g2:intra IQ matrix g3~g4:non intra IQ matrix g5~g20:IDCT table g31: thread payload g32: message descriptor for reading reference data g58~g81:reference data g82: thread payload backup g83~g106:IDCT data */ mov (1) g32.8<1>UD 0x007001FUD {align1}; send (16) 0 g38.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; send (16) 0 g46.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 8 {align1}; add (1) g32.4<1>UD g32.4<1,1,1>UD 8UD {align1}; mov (1) g32.8<1>UD 0x1FUD {align1}; send (16) 0 g54.0<1>UW g32<8,8,1>UW read(input_surface, 2, 0, 2) mlen 1 rlen 1 {align1}; add (16) g58.0<1>UW g38.0<16,16,1>UB g38.1<16,16,1>UB {align1}; add (16) g59.0<1>UW g39.0<16,16,1>UB g39.1<16,16,1>UB {align1}; add (16) g60.0<1>UW g40.0<16,16,1>UB g40.1<16,16,1>UB {align1}; add (16) g61.0<1>UW g41.0<16,16,1>UB g41.1<16,16,1>UB {align1}; add (16) g62.0<1>UW g42.0<16,16,1>UB g42.1<16,16,1>UB {align1}; add (16) g63.0<1>UW g43.0<16,16,1>UB g43.1<16,16,1>UB {align1}; add (16) g64.0<1>UW g44.0<16,16,1>UB g44.1<16,16,1>UB {align1}; add (16) g65.0<1>UW g45.0<16,16,1>UB g45.1<16,16,1>UB {align1}; add (16) g66.0<1>UW g46.0<16,16,1>UB g46.1<16,16,1>UB {align1}; add (16) g67.0<1>UW g47.0<16,16,1>UB g47.1<16,16,1>UB {align1}; add (16) g68.0<1>UW g48.0<16,16,1>UB g48.1<16,16,1>UB {align1}; add (16) g69.0<1>UW g49.0<16,16,1>UB g49.1<16,16,1>UB {align1}; add (16) g70.0<1>UW g50.0<16,16,1>UB g50.1<16,16,1>UB {align1}; add (16) g71.0<1>UW g51.0<16,16,1>UB g51.1<16,16,1>UB {align1}; add (16) g72.0<1>UW g52.0<16,16,1>UB g52.1<16,16,1>UB {align1}; add (16) g73.0<1>UW g53.0<16,16,1>UB g53.1<16,16,1>UB {align1}; add (16) g58.0<1>UW g58.0<16,16,1>UW g39.0<16,16,1>UB {align1}; add (16) g59.0<1>UW g59.0<16,16,1>UW g40.0<16,16,1>UB {align1}; add (16) g60.0<1>UW g60.0<16,16,1>UW g41.0<16,16,1>UB {align1}; add (16) g61.0<1>UW g61.0<16,16,1>UW g42.0<16,16,1>UB {align1}; add (16) g62.0<1>UW g62.0<16,16,1>UW g43.0<16,16,1>UB {align1}; add (16) g63.0<1>UW g63.0<16,16,1>UW g44.0<16,16,1>UB {align1}; add (16) g64.0<1>UW g64.0<16,16,1>UW g45.0<16,16,1>UB {align1}; add (16) g65.0<1>UW g65.0<16,16,1>UW g46.0<16,16,1>UB {align1}; add (16) g66.0<1>UW g66.0<16,16,1>UW g47.0<16,16,1>UB {align1}; add (16) g67.0<1>UW g67.0<16,16,1>UW g48.0<16,16,1>UB {align1}; add (16) g68.0<1>UW g68.0<16,16,1>UW g49.0<16,16,1>UB {align1}; add (16) g69.0<1>UW g69.0<16,16,1>UW g50.0<16,16,1>UB {align1}; add (16) g70.0<1>UW g70.0<16,16,1>UW g51.0<16,16,1>UB {align1}; add (16) g71.0<1>UW g71.0<16,16,1>UW g52.0<16,16,1>UB {align1}; add (16) g72.0<1>UW g72.0<16,16,1>UW g53.0<16,16,1>UB {align1}; add (16) g73.0<1>UW g73.0<16,16,1>UW g54.0<16,16,1>UB {align1}; add (16) g58.0<1>UW g58.0<16,16,1>UW g39.1<16,16,1>UB {align1}; add (16) g59.0<1>UW g59.0<16,16,1>UW g40.1<16,16,1>UB {align1}; add (16) g60.0<1>UW g60.0<16,16,1>UW g41.1<16,16,1>UB {align1}; add (16) g61.0<1>UW g61.0<16,16,1>UW g42.1<16,16,1>UB {align1}; add (16) g62.0<1>UW g62.0<16,16,1>UW g43.1<16,16,1>UB {align1}; add (16) g63.0<1>UW g63.0<16,16,1>UW g44.1<16,16,1>UB {align1}; add (16) g64.0<1>UW g64.0<16,16,1>UW g45.1<16,16,1>UB {align1}; add (16) g65.0<1>UW g65.0<16,16,1>UW g46.1<16,16,1>UB {align1}; add (16) g66.0<1>UW g66.0<16,16,1>UW g47.1<16,16,1>UB {align1}; add (16) g67.0<1>UW g67.0<16,16,1>UW g48.1<16,16,1>UB {align1}; add (16) g68.0<1>UW g68.0<16,16,1>UW g49.1<16,16,1>UB {align1}; add (16) g69.0<1>UW g69.0<16,16,1>UW g50.1<16,16,1>UB {align1}; add (16) g70.0<1>UW g70.0<16,16,1>UW g51.1<16,16,1>UB {align1}; add (16) g71.0<1>UW g71.0<16,16,1>UW g52.1<16,16,1>UB {align1}; add (16) g72.0<1>UW g72.0<16,16,1>UW g53.1<16,16,1>UB {align1}; add (16) g73.0<1>UW g73.0<16,16,1>UW g54.1<16,16,1>UB {align1}; shr.sat (16) g58.0<1>UW g58.0<16,16,1>UW 2UW {align1}; shr.sat (16) g59.0<1>UW g59.0<16,16,1>UW 2UW {align1}; shr.sat (16) g60.0<1>UW g60.0<16,16,1>UW 2UW {align1}; shr.sat (16) g61.0<1>UW g61.0<16,16,1>UW 2UW {align1}; shr.sat (16) g62.0<1>UW g62.0<16,16,1>UW 2UW {align1}; shr.sat (16) g63.0<1>UW g63.0<16,16,1>UW 2UW {align1}; shr.sat (16) g64.0<1>UW g64.0<16,16,1>UW 2UW {align1}; shr.sat (16) g65.0<1>UW g65.0<16,16,1>UW 2UW {align1}; shr.sat (16) g66.0<1>UW g66.0<16,16,1>UW 2UW {align1}; shr.sat (16) g67.0<1>UW g67.0<16,16,1>UW 2UW {align1}; shr.sat (16) g68.0<1>UW g68.0<16,16,1>UW 2UW {align1}; shr.sat (16) g69.0<1>UW g69.0<16,16,1>UW 2UW {align1}; shr.sat (16) g70.0<1>UW g70.0<16,16,1>UW 2UW {align1}; shr.sat (16) g71.0<1>UW g71.0<16,16,1>UW 2UW {align1}; shr.sat (16) g72.0<1>UW g72.0<16,16,1>UW 2UW {align1}; shr.sat (16) g73.0<1>UW g73.0<16,16,1>UW 2UW {align1}; xserver-xorg-video-intel-2.99.917+git20160325/xvmc/xvmc_vld.c000066400000000000000000001020301267532330400232320ustar00rootroot00000000000000/* * Copyright © 2009 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Author: * Zou Nan hai */ #include "intel_xvmc_private.h" #include "i830_reg.h" #include "i965_reg.h" #include "brw_defines.h" #include "brw_structs.h" #ifndef ALIGN #define ALIGN(m,n) (((m) + (n) - 1) & ~((n) - 1)) #endif #define BATCH_STRUCT(x) intelBatchbufferData(&x, sizeof(x), 0) #define VLD_MAX_SLICE_SIZE (32 * 1024) #define CS_SIZE 30 #define URB_SIZE 384 /* idct table */ #define C0 23170 #define C1 22725 #define C2 21407 #define C3 19266 #define C4 16383 #define C5 12873 #define C6 8867 #define C7 4520 const uint32_t idct_table[] = { C4, C1, C2, C3, C4, C5, C6, C7, //g5 C4, C1, C2, C3, C4, C5, C6, C7, C4, C3, C6, -C7, -C4, -C1, -C2, -C5, C4, C3, C6, -C7, -C4, -C1, -C2, -C5, C4, C5, -C6, -C1, -C4, C7, C2, C3, C4, C5, -C6, -C1, -C4, C7, C2, C3, C4, C7, -C2, -C5, C4, C3, -C6, -C1, C4, C7, -C2, -C5, C4, C3, -C6, -C1, C4, -C7, -C2, C5, C4, -C3, -C6, C1, C4, -C7, -C2, C5, C4, -C3, -C6, C1, C4, -C5, -C6, C1, -C4, -C7, C2, -C3, C4, -C5, -C6, C1, -C4, -C7, C2, -C3, C4, -C3, C6, C7, -C4, C1, -C2, C5, C4, -C3, C6, C7, -C4, C1, -C2, C5, C4, -C1, C2, -C3, C4, -C5, C6, -C7, C4, -C1, C2, -C3, C4, -C5, C6, -C7 //g20 }; #undef C0 #undef C1 #undef C2 #undef C3 #undef C4 #undef C5 #undef C6 #undef C7 #define INTERFACE_NUM 8 enum interface { FRAME_INTRA = 0, FRAME_FRAME_PRED_FORWARD, FRAME_FRAME_PRED_BACKWARD, FRAME_FRAME_PRED_BIDIRECT, FRAME_FIELD_PRED_FORWARD, FRAME_FIELD_PRED_BACKWARD, FRAME_FIELD_PRED_BIDIRECT, LIB_INTERFACE }; /*kernels for vld mode*/ static uint32_t lib_kernel[][4] = { #include "shader/vld/lib.g4b" }; static uint32_t ipicture_kernel[][4] = { #include "shader/vld/ipicture.g4b" }; static uint32_t frame_forward_kernel[][4] = { #include "shader/vld/frame_forward.g4b" }; static uint32_t frame_backward_kernel[][4] = { #include "shader/vld/frame_backward.g4b" }; static uint32_t frame_f_b_kernel[][4] = { #include "shader/vld/frame_f_b.g4b" }; static uint32_t field_forward_kernel[][4] = { #include "shader/vld/field_forward.g4b" }; static uint32_t field_backward_kernel[][4] = { #include "shader/vld/field_backward.g4b" }; static uint32_t field_f_b_kernel[][4] = { #include "shader/vld/field_f_b.g4b" }; /* on Ironlake */ static uint32_t lib_kernel_gen5[][4] = { #include "shader/vld/lib.g4b.gen5" }; static uint32_t ipicture_kernel_gen5[][4] = { #include "shader/vld/ipicture.g4b.gen5" }; static uint32_t frame_forward_kernel_gen5[][4] = { #include "shader/vld/frame_forward.g4b.gen5" }; static uint32_t frame_backward_kernel_gen5[][4] = { #include "shader/vld/frame_backward.g4b.gen5" }; static uint32_t frame_f_b_kernel_gen5[][4] = { #include "shader/vld/frame_f_b.g4b.gen5" }; static uint32_t field_forward_kernel_gen5[][4] = { #include "shader/vld/field_forward.g4b.gen5" }; static uint32_t field_backward_kernel_gen5[][4] = { #include "shader/vld/field_backward.g4b.gen5" }; static uint32_t field_f_b_kernel_gen5[][4] = { #include "shader/vld/field_f_b.g4b.gen5" }; /*kernels for mc mode*/ static uint32_t lib_kernel_idct[][4] = { #include "shader/mc/lib_igd.g4b" }; static uint32_t ipicture_kernel_idct[][4] = { #include "shader/mc/ipicture_igd.g4b" }; static uint32_t frame_forward_kernel_idct[][4] = { #include "shader/mc/frame_forward_igd.g4b" }; static uint32_t frame_backward_kernel_idct[][4] = { #include "shader/mc/frame_backward_igd.g4b" }; static uint32_t frame_f_b_kernel_idct[][4] = { #include "shader/mc/frame_f_b_igd.g4b" }; static uint32_t field_forward_kernel_idct[][4] = { #include "shader/mc/field_forward_igd.g4b" }; static uint32_t field_backward_kernel_idct[][4] = { #include "shader/mc/field_backward_igd.g4b" }; static uint32_t field_f_b_kernel_idct[][4] = { #include "shader/mc/field_f_b_igd.g4b" }; /* on Ironlake */ static uint32_t lib_kernel_idct_gen5[][4] = { #include "shader/mc/lib_igd.g4b.gen5" }; static uint32_t ipicture_kernel_idct_gen5[][4] = { #include "shader/mc/ipicture_igd.g4b.gen5" }; static uint32_t frame_forward_kernel_idct_gen5[][4] = { #include "shader/mc/frame_forward_igd.g4b.gen5" }; static uint32_t frame_backward_kernel_idct_gen5[][4] = { #include "shader/mc/frame_backward_igd.g4b.gen5" }; static uint32_t frame_f_b_kernel_idct_gen5[][4] = { #include "shader/mc/frame_f_b_igd.g4b.gen5" }; static uint32_t field_forward_kernel_idct_gen5[][4] = { #include "shader/mc/field_forward_igd.g4b.gen5" }; static uint32_t field_backward_kernel_idct_gen5[][4] = { #include "shader/mc/field_backward_igd.g4b.gen5" }; static uint32_t field_f_b_kernel_idct_gen5[][4] = { #include "shader/mc/field_f_b_igd.g4b.gen5" }; struct media_kernel { uint32_t(*bin)[4]; int size; }; static struct media_kernel media_kernels[] = { /*kernels for vld mode */ {ipicture_kernel, sizeof(ipicture_kernel)} , {frame_forward_kernel, sizeof(frame_forward_kernel)} , {frame_backward_kernel, sizeof(frame_backward_kernel)} , {frame_f_b_kernel, sizeof(frame_f_b_kernel)} , {field_forward_kernel, sizeof(field_forward_kernel)} , {field_backward_kernel, sizeof(field_backward_kernel)} , {field_f_b_kernel, sizeof(field_f_b_kernel)} , {lib_kernel, sizeof(lib_kernel)} , /*kernels for mc mode */ {ipicture_kernel_idct, sizeof(ipicture_kernel_idct)} , {frame_forward_kernel_idct, sizeof(frame_forward_kernel_idct)} , {frame_backward_kernel_idct, sizeof(frame_backward_kernel_idct)} , {frame_f_b_kernel_idct, sizeof(frame_f_b_kernel_idct)} , {field_forward_kernel_idct, sizeof(field_forward_kernel_idct)} , {field_backward_kernel_idct, sizeof(field_backward_kernel_idct)} , {field_f_b_kernel_idct, sizeof(field_f_b_kernel_idct)} , {lib_kernel_idct, sizeof(lib_kernel_idct)} }; static struct media_kernel media_gen5_kernels[] = { /*kernels for vld mode */ {ipicture_kernel_gen5, sizeof(ipicture_kernel_gen5)} , {frame_forward_kernel_gen5, sizeof(frame_forward_kernel_gen5)} , {frame_backward_kernel_gen5, sizeof(frame_backward_kernel_gen5)} , {frame_f_b_kernel_gen5, sizeof(frame_f_b_kernel_gen5)} , {field_forward_kernel_gen5, sizeof(field_forward_kernel_gen5)} , {field_backward_kernel_gen5, sizeof(field_backward_kernel_gen5)} , {field_f_b_kernel_gen5, sizeof(field_f_b_kernel_gen5)} , {lib_kernel_gen5, sizeof(lib_kernel_gen5)} , /*kernels for mc mode */ {ipicture_kernel_idct_gen5, sizeof(ipicture_kernel_idct_gen5)} , {frame_forward_kernel_idct_gen5, sizeof(frame_forward_kernel_idct_gen5)} , {frame_backward_kernel_idct_gen5, sizeof(frame_backward_kernel_idct_gen5)} , {frame_f_b_kernel_idct_gen5, sizeof(frame_f_b_kernel_idct_gen5)} , {field_forward_kernel_idct_gen5, sizeof(field_forward_kernel_idct_gen5)} , {field_backward_kernel_idct_gen5, sizeof(field_backward_kernel_idct_gen5)} , {field_f_b_kernel_idct_gen5, sizeof(field_f_b_kernel_idct_gen5)} , {lib_kernel_idct_gen5, sizeof(lib_kernel_idct_gen5)} }; #define MEDIA_KERNEL_NUM (sizeof(media_kernels)/sizeof(media_kernels[0])) struct media_kernel_obj { dri_bo *bo; }; struct interface_descriptor_obj { dri_bo *bo; struct media_kernel_obj kernels[MEDIA_KERNEL_NUM]; }; struct vfe_state_obj { dri_bo *bo; struct interface_descriptor_obj interface; }; struct vld_state_obj { dri_bo *bo; }; struct surface_obj { dri_bo *bo; }; struct surface_state_obj { struct surface_obj surface; dri_bo *bo; }; #define MAX_SURFACES 12 struct binding_table_obj { dri_bo *bo; struct surface_state_obj surface_states[MAX_SURFACES]; }; struct slice_data_obj { dri_bo *bo; }; struct mb_data_obj { dri_bo *bo; }; struct cs_state_obj { dri_bo *bo; }; static struct media_state { struct vfe_state_obj vfe_state; struct vld_state_obj vld_state; struct binding_table_obj binding_table; struct cs_state_obj cs_object; struct slice_data_obj slice_data; struct mb_data_obj mb_data; } media_state; /* XvMCQMatrix * 2 + idct_table + 8 * kernel offset pointer */ #define CS_OBJECT_SIZE (32*20 + sizeof(unsigned int) * 8) static void free_object(struct media_state *s) { int i; #define FREE_ONE_BO(bo) \ if (bo) \ drm_intel_bo_unreference(bo) FREE_ONE_BO(s->vfe_state.bo); FREE_ONE_BO(s->vfe_state.interface.bo); for (i = 0; i < MEDIA_KERNEL_NUM; i++) FREE_ONE_BO(s->vfe_state.interface.kernels[i].bo); FREE_ONE_BO(s->binding_table.bo); for (i = 0; i < MAX_SURFACES; i++) FREE_ONE_BO(s->binding_table.surface_states[i].bo); FREE_ONE_BO(s->slice_data.bo); FREE_ONE_BO(s->mb_data.bo); FREE_ONE_BO(s->cs_object.bo); FREE_ONE_BO(s->vld_state.bo); } static int alloc_object(struct media_state *s) { int i; for (i = 0; i < MAX_SURFACES; i++) { s->binding_table.surface_states[i].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", sizeof(struct brw_surface_state), 0x1000); if (!s->binding_table.surface_states[i].bo) goto out; } return 0; out: free_object(s); return BadAlloc; } static void flush() { #define FLUSH_STATE_CACHE 1 struct brw_mi_flush f; memset(&f, 0, sizeof(f)); f.opcode = CMD_MI_FLUSH; f.flags = (1 << FLUSH_STATE_CACHE); BATCH_STRUCT(f); } static Status vfe_state(int vfe_mode) { struct brw_vfe_state tmp, *vfe_state = &tmp; memset(vfe_state, 0, sizeof(*vfe_state)); if (vfe_mode == VFE_VLD_MODE) { vfe_state->vfe0.extend_vfe_state_present = 1; } else { vfe_state->vfe0.extend_vfe_state_present = 0; } vfe_state->vfe1.vfe_mode = vfe_mode; vfe_state->vfe1.num_urb_entries = 1; vfe_state->vfe1.children_present = 0; vfe_state->vfe1.urb_entry_alloc_size = 2; vfe_state->vfe1.max_threads = 31; vfe_state->vfe2.interface_descriptor_base = media_state.vfe_state.interface.bo->offset >> 4; if (media_state.vfe_state.bo) drm_intel_bo_unreference(media_state.vfe_state.bo); media_state.vfe_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "vfe state", sizeof(struct brw_vfe_state), 0x1000); if (!media_state.vfe_state.bo) return BadAlloc; drm_intel_bo_subdata(media_state.vfe_state.bo, 0, sizeof(tmp), &tmp); drm_intel_bo_emit_reloc(media_state.vfe_state.bo, offsetof(struct brw_vfe_state, vfe2), media_state.vfe_state.interface.bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0); return Success; } static Status interface_descriptor() { int i; struct brw_interface_descriptor tmp, *desc = &tmp; if (media_state.vfe_state.interface.bo) drm_intel_bo_unreference(media_state.vfe_state.interface.bo); media_state.vfe_state.interface.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "interfaces", MEDIA_KERNEL_NUM * sizeof(struct brw_interface_descriptor), 0x1000); if (!media_state.vfe_state.interface.bo) return BadAlloc; for (i = 0; i < MEDIA_KERNEL_NUM; i++) { memset(desc, 0, sizeof(*desc)); desc->desc0.grf_reg_blocks = 15; desc->desc0.kernel_start_pointer = media_state.vfe_state.interface.kernels[i].bo->offset >> 6; desc->desc1.const_urb_entry_read_offset = 0; desc->desc1.const_urb_entry_read_len = 30; desc->desc3.binding_table_entry_count = MAX_SURFACES - 1; desc->desc3.binding_table_pointer = media_state.binding_table.bo->offset >> 5; drm_intel_bo_subdata(media_state.vfe_state.interface.bo, i * sizeof(tmp), sizeof(tmp), desc); drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo, i * sizeof(*desc) + offsetof(struct brw_interface_descriptor, desc0), media_state.vfe_state. interface.kernels[i].bo, desc->desc0.grf_reg_blocks, I915_GEM_DOMAIN_INSTRUCTION, 0); drm_intel_bo_emit_reloc(media_state.vfe_state.interface.bo, i * sizeof(*desc) + offsetof(struct brw_interface_descriptor, desc3), media_state.binding_table.bo, desc->desc3.binding_table_entry_count, I915_GEM_DOMAIN_INSTRUCTION, 0); } return Success; } static int setup_media_kernels(struct intel_xvmc_hw_context *ctx) { int i; assert(MEDIA_KERNEL_NUM == sizeof(media_gen5_kernels) / sizeof(media_gen5_kernels[0])); for (i = 0; i < MEDIA_KERNEL_NUM; i++) { if (ctx->i965.is_igdng) media_state.vfe_state.interface.kernels[i].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernel", media_gen5_kernels[i].size, 0x1000); else media_state.vfe_state.interface.kernels[i].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "kernels", media_kernels[i].size, 0x1000); if (!media_state.vfe_state.interface.kernels[i].bo) goto out; } for (i = 0; i < MEDIA_KERNEL_NUM; i++) { dri_bo *bo = media_state.vfe_state.interface.kernels[i].bo; if (ctx->i965.is_igdng) drm_intel_bo_subdata(bo, 0, media_gen5_kernels[i].size, media_gen5_kernels[i].bin); else drm_intel_bo_subdata(bo, 0, media_kernels[i].size, media_kernels[i].bin); } return 0; out: free_object(&media_state); return BadAlloc; } static Status binding_tables() { unsigned int table[MAX_SURFACES]; int i; if (media_state.binding_table.bo) drm_intel_bo_unreference(media_state.binding_table.bo); media_state.binding_table.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "binding_table", MAX_SURFACES * 4, 0x1000); if (!media_state.binding_table.bo) return BadAlloc; for (i = 0; i < MAX_SURFACES; i++) { table[i] = media_state.binding_table.surface_states[i].bo->offset; drm_intel_bo_emit_reloc(media_state.binding_table.bo, i * sizeof(unsigned int), media_state. binding_table.surface_states[i].bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0); } drm_intel_bo_subdata(media_state.binding_table.bo, 0, sizeof(table), table); return Success; } static Status cs_init(int interface_offset) { char buf[CS_OBJECT_SIZE]; unsigned int *lib_reloc; int i; if (media_state.cs_object.bo) drm_intel_bo_unreference(media_state.cs_object.bo); media_state.cs_object.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "cs object", CS_OBJECT_SIZE, 64); if (!media_state.cs_object.bo) return BadAlloc; memcpy(buf + 32 * 4, idct_table, sizeof(idct_table)); /* idct lib reloction */ lib_reloc = (unsigned int *)(buf + 32 * 20); for (i = 0; i < 8; i++) lib_reloc[i] = media_state.vfe_state.interface.kernels[LIB_INTERFACE + interface_offset].bo-> offset; drm_intel_bo_subdata(media_state.cs_object.bo, 32 * 4, 32 * 16 + 8 * sizeof(unsigned int), buf + 32 * 4); for (i = 0; i < 8; i++) drm_intel_bo_emit_reloc(media_state.cs_object.bo, 32 * 20 + sizeof(unsigned int) * i, media_state.vfe_state. interface.kernels[LIB_INTERFACE + interface_offset].bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0); return Success; } #define STRIDE(w) (w) #define SIZE_YUV420(w, h) (h * (STRIDE(w) + STRIDE(w >> 1))) static Status create_context(Display * display, XvMCContext * context, int priv_count, CARD32 * priv_data) { struct intel_xvmc_context *intel_ctx; struct intel_xvmc_hw_context *hw_ctx; hw_ctx = (struct intel_xvmc_hw_context *)priv_data; intel_ctx = calloc(1, sizeof(struct intel_xvmc_context)); if (!intel_ctx) return BadAlloc; intel_ctx->hw = hw_ctx; context->privData = intel_ctx; intel_ctx->surface_bo_size = SIZE_YUV420(context->width, context->height); if (alloc_object(&media_state)) return BadAlloc; if (setup_media_kernels(hw_ctx)) return BadAlloc; return Success; } static Status destroy_context(Display * display, XvMCContext * context) { struct intel_xvmc_context *intel_ctx; intel_ctx = context->privData; free(intel_ctx->hw); free(intel_ctx); return Success; } static Status load_qmatrix(Display * display, XvMCContext * context, const XvMCQMatrix * qmx) { Status ret; ret = cs_init(0); if (ret != Success) return ret; drm_intel_bo_subdata(media_state.cs_object.bo, 0, 64, qmx->intra_quantiser_matrix); drm_intel_bo_subdata(media_state.cs_object.bo, 64, 64, qmx->non_intra_quantiser_matrix); return Success; } static Status vld_state(const XvMCMpegControl * control) { struct brw_vld_state tmp, *vld = &tmp; if (media_state.vld_state.bo) drm_intel_bo_unreference(media_state.vld_state.bo); media_state.vld_state.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "vld state", sizeof(struct brw_vld_state), 64); if (!media_state.vld_state.bo) return BadAlloc; memset(vld, 0, sizeof(*vld)); vld->vld0.f_code_0_0 = control->FHMV_range + 1; vld->vld0.f_code_0_1 = control->FVMV_range + 1; vld->vld0.f_code_1_0 = control->BHMV_range + 1; vld->vld0.f_code_1_1 = control->BVMV_range + 1; vld->vld0.intra_dc_precision = control->intra_dc_precision; vld->vld0.picture_structure = control->picture_structure; vld->vld0.top_field_first = !!(control->flags & XVMC_TOP_FIELD_FIRST); vld->vld0.frame_predict_frame_dct = !!(control->flags & XVMC_PRED_DCT_FRAME); vld->vld0.concealment_motion_vector = !!(control->flags & XVMC_CONCEALMENT_MOTION_VECTORS); vld->vld0.quantizer_scale_type = !!(control->flags & XVMC_Q_SCALE_TYPE); vld->vld0.intra_vlc_format = !!(control->flags & XVMC_INTRA_VLC_FORMAT); vld->vld0.scan_order = !!(control->flags & XVMC_ALTERNATE_SCAN); vld->vld1.picture_coding_type = control->picture_coding_type; vld->desc_remap_table0.index_0 = FRAME_INTRA; vld->desc_remap_table0.index_1 = FRAME_FRAME_PRED_FORWARD; vld->desc_remap_table0.index_2 = FRAME_FIELD_PRED_FORWARD; vld->desc_remap_table0.index_3 = FRAME_FIELD_PRED_BIDIRECT; /* dual prime */ vld->desc_remap_table0.index_4 = FRAME_FRAME_PRED_BACKWARD; vld->desc_remap_table0.index_5 = FRAME_FIELD_PRED_BACKWARD; vld->desc_remap_table0.index_6 = FRAME_FRAME_PRED_BIDIRECT; vld->desc_remap_table0.index_7 = FRAME_FIELD_PRED_BIDIRECT; vld->desc_remap_table1.index_8 = FRAME_INTRA; vld->desc_remap_table1.index_9 = FRAME_FRAME_PRED_FORWARD; vld->desc_remap_table1.index_10 = FRAME_FIELD_PRED_FORWARD; vld->desc_remap_table1.index_11 = FRAME_FIELD_PRED_BIDIRECT; vld->desc_remap_table1.index_12 = FRAME_FRAME_PRED_BACKWARD; vld->desc_remap_table1.index_13 = FRAME_FIELD_PRED_BACKWARD; vld->desc_remap_table1.index_14 = FRAME_FRAME_PRED_BIDIRECT; vld->desc_remap_table1.index_15 = FRAME_FIELD_PRED_BIDIRECT; drm_intel_bo_subdata(media_state.vld_state.bo, 0, sizeof(tmp), vld); return Success; } static Status setup_media_surface(int index, dri_bo * bo, unsigned long offset, int w, int h, Bool write) { struct brw_surface_state tmp, *ss = &tmp; memset(ss, 0, sizeof(*ss)); ss->ss0.surface_type = BRW_SURFACE_2D; ss->ss0.surface_format = BRW_SURFACEFORMAT_R8_SINT; ss->ss1.base_addr = offset + bo->offset; ss->ss2.width = w - 1; ss->ss2.height = h - 1; ss->ss3.pitch = w - 1; if (media_state.binding_table.surface_states[index].bo) drm_intel_bo_unreference(media_state. binding_table.surface_states[index]. bo); media_state.binding_table.surface_states[index].bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "surface_state", sizeof(struct brw_surface_state), 0x1000); if (!media_state.binding_table.surface_states[index].bo) return BadAlloc; drm_intel_bo_subdata(media_state.binding_table.surface_states[index].bo, 0, sizeof(*ss), ss); drm_intel_bo_emit_reloc(media_state.binding_table. surface_states[index].bo, offsetof(struct brw_surface_state, ss1), bo, offset, I915_GEM_DOMAIN_RENDER, write ? I915_GEM_DOMAIN_RENDER : 0); return Success; } static Status setup_surface(struct intel_xvmc_surface *target, struct intel_xvmc_surface *past, struct intel_xvmc_surface *future, int w, int h) { Status ret; ret = setup_media_surface(0, target->bo, 0, w, h, TRUE); if (ret != Success) return ret; ret = setup_media_surface(1, target->bo, w * h, w / 2, h / 2, TRUE); if (ret != Success) return ret; ret = setup_media_surface(2, target->bo, w * h + w * h / 4, w / 2, h / 2, TRUE); if (ret != Success) return ret; if (past) { ret = setup_media_surface(4, past->bo, 0, w, h, FALSE); if (ret != Success) return ret; ret = setup_media_surface(5, past->bo, w * h, w / 2, h / 2, FALSE); if (ret != Success) return ret; ret = setup_media_surface(6, past->bo, w * h + w * h / 4, w / 2, h / 2, FALSE); if (ret != Success) return ret; } if (future) { ret = setup_media_surface(7, future->bo, 0, w, h, FALSE); if (ret != Success) return ret; ret = setup_media_surface(8, future->bo, w * h, w / 2, h / 2, FALSE); if (ret != Success) return ret; ret = setup_media_surface(9, future->bo, w * h + w * h / 4, w / 2, h / 2, FALSE); if (ret != Success) return ret; } return Success; } static Status begin_surface(Display * display, XvMCContext * context, XvMCSurface * target, XvMCSurface * past, XvMCSurface * future, const XvMCMpegControl * control) { struct intel_xvmc_surface *priv_target, *priv_past, *priv_future; intel_xvmc_context_ptr intel_ctx = context->privData; Status ret; priv_target = target->privData; priv_past = past ? past->privData : NULL; priv_future = future ? future->privData : NULL; ret = vld_state(control); if (ret != Success) return ret; ret = setup_surface(priv_target, priv_past, priv_future, context->width, context->height); if (ret != Success) return ret; ret = binding_tables(); if (ret != Success) return ret; ret = interface_descriptor(); if (ret != Success) return ret; ret = vfe_state(VFE_VLD_MODE); if (ret != Success) return ret; LOCK_HARDWARE(intel_ctx->hw_context); flush(); UNLOCK_HARDWARE(intel_ctx->hw_context); return Success; } static Status put_slice(Display * display, XvMCContext * context, unsigned char *slice, int nbytes) { return Success; } static void state_base_address(struct intel_xvmc_hw_context *ctx) { BATCH_LOCALS; if (ctx->i965.is_igdng) { BEGIN_BATCH(8); OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); ADVANCE_BATCH(); } else { BEGIN_BATCH(6); OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); OUT_BATCH(0 | BASE_ADDRESS_MODIFY); ADVANCE_BATCH(); } } static void pipeline_select() { BATCH_LOCALS; BEGIN_BATCH(1); OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA); ADVANCE_BATCH(); } static void media_state_pointers(int vfe_mode) { BATCH_LOCALS; BEGIN_BATCH(3); OUT_BATCH(BRW_MEDIA_STATE_POINTERS | 1); if (vfe_mode == VFE_VLD_MODE) OUT_RELOC(media_state.vld_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1); else OUT_BATCH(0); OUT_RELOC(media_state.vfe_state.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); ADVANCE_BATCH(); } static void align_urb_fence() { BATCH_LOCALS; int i, offset_to_next_cacheline; unsigned long batch_offset; BEGIN_BATCH(3); batch_offset = (void *)batch_ptr - xvmc_driver->alloc.ptr; offset_to_next_cacheline = ALIGN(batch_offset, 64) - batch_offset; if (offset_to_next_cacheline <= 12 && offset_to_next_cacheline != 0) { for (i = 0; i < offset_to_next_cacheline / 4; i++) OUT_BATCH(0); ADVANCE_BATCH(); } } static void urb_layout() { BATCH_LOCALS; align_urb_fence(); BEGIN_BATCH(3); OUT_BATCH(BRW_URB_FENCE | UF0_VFE_REALLOC | UF0_CS_REALLOC | UF0_SF_REALLOC | UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); OUT_BATCH((0 << UF1_CLIP_FENCE_SHIFT) | (0 << UF1_GS_FENCE_SHIFT) | (0 << UF1_VS_FENCE_SHIFT)); OUT_BATCH((0 << UF2_CS_FENCE_SHIFT) | (0 << UF2_SF_FENCE_SHIFT) | ((URB_SIZE - CS_SIZE - 1) << UF2_VFE_FENCE_SHIFT) | /* VFE_SIZE */ ((URB_SIZE) << UF2_CS_FENCE_SHIFT)); /* CS_SIZE */ ADVANCE_BATCH(); } static void cs_urb_layout() { BATCH_LOCALS; BEGIN_BATCH(2); OUT_BATCH(BRW_CS_URB_STATE | 0); OUT_BATCH((CS_SIZE << 4) | /* URB Entry Allocation Size */ (1 << 0)); /* Number of URB Entries */ ADVANCE_BATCH(); } static void cs_buffer() { BATCH_LOCALS; BEGIN_BATCH(2); OUT_BATCH(BRW_CONSTANT_BUFFER | 0 | (1 << 8)); OUT_RELOC(media_state.cs_object.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, CS_SIZE); ADVANCE_BATCH(); } /* kick media object to gpu in idct mode*/ static void send_media_object(XvMCMacroBlock * mb, dri_bo * bo, uint32_t offset, enum interface interface) { BATCH_LOCALS; BEGIN_BATCH(13); OUT_BATCH(BRW_MEDIA_OBJECT | 11); OUT_BATCH(interface); OUT_BATCH(6 * 128); OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); OUT_BATCH(mb->x << 4); OUT_BATCH(mb->y << 4); OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, offset); OUT_BATCH_SHORT(mb->coded_block_pattern); OUT_BATCH_SHORT(mb->PMV[0][0][0]); OUT_BATCH_SHORT(mb->PMV[0][0][1]); OUT_BATCH_SHORT(mb->PMV[0][1][0]); OUT_BATCH_SHORT(mb->PMV[0][1][1]); OUT_BATCH_SHORT(mb->PMV[1][0][0]); OUT_BATCH_SHORT(mb->PMV[1][0][1]); OUT_BATCH_SHORT(mb->PMV[1][1][0]); OUT_BATCH_SHORT(mb->PMV[1][1][1]); OUT_BATCH_CHAR(mb->dct_type); OUT_BATCH_CHAR(mb->motion_vertical_field_select); OUT_BATCH(0xffffffff); ADVANCE_BATCH(); } /* kick media object to gpu in vld mode*/ static void vld_send_media_object(dri_bo * bo, int slice_len, int mb_h_pos, int mb_v_pos, int mb_bit_offset, int mb_count, int q_scale_code) { BATCH_LOCALS; BEGIN_BATCH(6); OUT_BATCH(BRW_MEDIA_OBJECT | 4); OUT_BATCH(0); OUT_BATCH(slice_len); OUT_RELOC(bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); OUT_BATCH((mb_h_pos << 24) | (mb_v_pos << 16) | (mb_count << 8) | (mb_bit_offset)); OUT_BATCH(q_scale_code << 24); ADVANCE_BATCH(); } static Status put_slice2(Display * display, XvMCContext * context, unsigned char *slice, int nbytes, int sliceCode) { unsigned int bit_buf; intel_xvmc_context_ptr intel_ctx = context->privData; struct intel_xvmc_hw_context *hw_ctx = intel_ctx->hw; int q_scale_code, mb_row; mb_row = *(slice - 1) - 1; bit_buf = (slice[0] << 24) | (slice[1] << 16) | (slice[2] << 8) | (slice[3]); q_scale_code = bit_buf >> 27; if (media_state.slice_data.bo) { drm_intel_gem_bo_unmap_gtt(media_state.slice_data.bo); drm_intel_bo_unreference(media_state.slice_data.bo); } media_state.slice_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "slice data", VLD_MAX_SLICE_SIZE, 64); if (!media_state.slice_data.bo) return BadAlloc; drm_intel_gem_bo_map_gtt(media_state.slice_data.bo); memcpy(media_state.slice_data.bo->virtual, slice, nbytes); LOCK_HARDWARE(intel_ctx->hw_context); state_base_address(hw_ctx); pipeline_select(); media_state_pointers(VFE_VLD_MODE); urb_layout(); cs_urb_layout(); cs_buffer(); vld_send_media_object(media_state.slice_data.bo, nbytes, 0, mb_row, 6, 127, q_scale_code); intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); return Success; } static Status render_surface(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) { struct intel_xvmc_surface *priv_target, *priv_past, *priv_future; intel_xvmc_context_ptr intel_ctx; XvMCMacroBlock *mb; Status ret; unsigned short *block_ptr; int i, j; int block_offset = 0; struct intel_xvmc_hw_context *hw_ctx; intel_ctx = context->privData; hw_ctx = (struct intel_xvmc_hw_context *)context->privData; priv_target = target_surface->privData; priv_past = past_surface ? past_surface->privData : NULL; priv_future = future_surface ? future_surface->privData : NULL; ret = setup_surface(priv_target, priv_past, priv_future, context->width, context->height); if (ret != Success) return ret; ret = binding_tables(); if (ret != Success) return ret; ret = interface_descriptor(); if (ret != Success) return ret; ret = cs_init(INTERFACE_NUM); if (ret != Success) return ret; ret = vfe_state(VFE_GENERIC_MODE); if (ret != Success) return ret; if (media_state.mb_data.bo) { drm_intel_gem_bo_unmap_gtt(media_state.mb_data.bo); drm_intel_bo_unreference(media_state.mb_data.bo); } unsigned int block_num = (((context->width + 15) >> 4) * ((context->height + 15) >> 4)); unsigned int surface_size = (64 * sizeof(short) * 6 * block_num); media_state.mb_data.bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, "macroblock data", surface_size, 64); if (!media_state.mb_data.bo) return BadAlloc; drm_intel_gem_bo_map_gtt(media_state.mb_data.bo); block_ptr = media_state.mb_data.bo->virtual; unsigned short *mb_block_ptr; for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++) { mb = ¯oblock_array->macro_blocks[i]; mb_block_ptr = &blocks->blocks[(mb->index << 6)]; if (mb->coded_block_pattern & 0x20) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } if (mb->coded_block_pattern & 0x10) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j + 8, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } block_ptr += 2 * 64; if (mb->coded_block_pattern & 0x08) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } if (mb->coded_block_pattern & 0x04) { for (j = 0; j < 8; j++) memcpy(block_ptr + 16 * j + 8, mb_block_ptr + 8 * j, 16); mb_block_ptr += 64; } block_ptr += 2 * 64; if (mb->coded_block_pattern & 0x2) { memcpy(block_ptr, mb_block_ptr, 128); mb_block_ptr += 64; } block_ptr += 64; if (mb->coded_block_pattern & 0x1) memcpy(block_ptr, mb_block_ptr, 128); block_ptr += 64; } LOCK_HARDWARE(intel_ctx->hw_context); state_base_address(hw_ctx); flush(); pipeline_select(); urb_layout(); media_state_pointers(VFE_GENERIC_MODE); cs_urb_layout(); cs_buffer(); for (i = first_macroblock; i < num_macroblocks + first_macroblock; i++, block_offset += 128 * 6) { mb = ¯oblock_array->macro_blocks[i]; if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) { send_media_object(mb, media_state.mb_data.bo, block_offset, FRAME_INTRA + INTERFACE_NUM); } else { if (((mb->motion_type & 3) == XVMC_PREDICTION_FRAME)) { if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD)) { if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)) { send_media_object(mb, media_state.mb_data. bo, block_offset, FRAME_FRAME_PRED_BIDIRECT + INTERFACE_NUM); } else { send_media_object(mb, media_state.mb_data. bo, block_offset, FRAME_FRAME_PRED_FORWARD + INTERFACE_NUM); } } else if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)) { send_media_object(mb, media_state. mb_data.bo, block_offset, FRAME_FRAME_PRED_BACKWARD + INTERFACE_NUM); } } else if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) { if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD)) { if (((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD))) { send_media_object(mb, media_state.mb_data. bo, block_offset, FRAME_FIELD_PRED_BIDIRECT + INTERFACE_NUM); } else { send_media_object(mb, media_state.mb_data. bo, block_offset, FRAME_FIELD_PRED_FORWARD + INTERFACE_NUM); } } else if ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD)) { send_media_object(mb, media_state. mb_data.bo, block_offset, FRAME_FIELD_PRED_BACKWARD + INTERFACE_NUM); } } else { send_media_object(mb, media_state.mb_data.bo, block_offset, FRAME_FIELD_PRED_BIDIRECT + INTERFACE_NUM); /*dual prime */ } } } intelFlushBatch(); UNLOCK_HARDWARE(intel_ctx->hw_context); return Success; } struct _intel_xvmc_driver xvmc_vld_driver = { .type = XVMC_I965_MPEG2_VLD, .create_context = create_context, .destroy_context = destroy_context, .load_qmatrix = load_qmatrix, .begin_surface = begin_surface, .render_surface = render_surface, .put_slice = put_slice, .put_slice2 = put_slice2 };