i830_accel.c revision fa225cbc
1fa225cbcSrjs/************************************************************************** 2fa225cbcSrjs 3fa225cbcSrjsCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4fa225cbcSrjsAll Rights Reserved. 5fa225cbcSrjs 6fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a 7fa225cbcSrjscopy of this software and associated documentation files (the 8fa225cbcSrjs"Software"), to deal in the Software without restriction, including 9fa225cbcSrjswithout limitation the rights to use, copy, modify, merge, publish, 10fa225cbcSrjsdistribute, sub license, and/or sell copies of the Software, and to 11fa225cbcSrjspermit persons to whom the Software is furnished to do so, subject to 12fa225cbcSrjsthe following conditions: 13fa225cbcSrjs 14fa225cbcSrjsThe above copyright notice and this permission notice (including the 15fa225cbcSrjsnext paragraph) shall be included in all copies or substantial portions 16fa225cbcSrjsof the Software. 17fa225cbcSrjs 18fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19fa225cbcSrjsOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20fa225cbcSrjsMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21fa225cbcSrjsIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 22fa225cbcSrjsANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23fa225cbcSrjsTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24fa225cbcSrjsSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25fa225cbcSrjs 26fa225cbcSrjs**************************************************************************/ 27fa225cbcSrjs 28fa225cbcSrjs/* 29fa225cbcSrjs * Authors: 30fa225cbcSrjs * Keith Whitwell <keith@tungstengraphics.com> 31fa225cbcSrjs * 32fa225cbcSrjs */ 33fa225cbcSrjs 34fa225cbcSrjs/* 35fa225cbcSrjs * XXX So far, for GXxor this is about 40% of the speed of SW, but CPU 36fa225cbcSrjs * utilisation falls from 95% to < 5%. 37fa225cbcSrjs */ 38fa225cbcSrjs 39fa225cbcSrjs#ifdef HAVE_CONFIG_H 40fa225cbcSrjs#include "config.h" 41fa225cbcSrjs#endif 42fa225cbcSrjs 43fa225cbcSrjs#include <errno.h> 44fa225cbcSrjs 45fa225cbcSrjs#include "xf86.h" 46fa225cbcSrjs#include "i830.h" 47fa225cbcSrjs#include "i810_reg.h" 48fa225cbcSrjs#include "i830_debug.h" 49fa225cbcSrjs#include "i830_ring.h" 50fa225cbcSrjs#include "i915_drm.h" 51fa225cbcSrjs 52fa225cbcSrjsunsigned long 53fa225cbcSrjsintel_get_pixmap_offset(PixmapPtr pPix) 54fa225cbcSrjs{ 55fa225cbcSrjs ScreenPtr pScreen = pPix->drawable.pScreen; 56fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 57fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 58fa225cbcSrjs 59fa225cbcSrjs return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase; 60fa225cbcSrjs} 61fa225cbcSrjs 62fa225cbcSrjsunsigned long 63fa225cbcSrjsintel_get_pixmap_pitch(PixmapPtr pPix) 64fa225cbcSrjs{ 65fa225cbcSrjs return (unsigned long)pPix->devKind; 66fa225cbcSrjs} 67fa225cbcSrjs 68fa225cbcSrjsint 69fa225cbcSrjsI830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) 70fa225cbcSrjs{ 71fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 72fa225cbcSrjs I830RingBuffer *ring = &pI830->ring; 73fa225cbcSrjs int iters = 0; 74fa225cbcSrjs unsigned int start = 0; 75fa225cbcSrjs unsigned int now = 0; 76fa225cbcSrjs int last_head = 0; 77fa225cbcSrjs unsigned int first = 0; 78fa225cbcSrjs 79fa225cbcSrjs /* If your system hasn't moved the head pointer in 2 seconds, I'm going to 80fa225cbcSrjs * call it crashed. 81fa225cbcSrjs */ 82fa225cbcSrjs if (timeout_millis == 0) 83fa225cbcSrjs timeout_millis = 2000; 84fa225cbcSrjs 85fa225cbcSrjs if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { 86fa225cbcSrjs ErrorF("I830WaitLpRing %d\n", n); 87fa225cbcSrjs first = GetTimeInMillis(); 88fa225cbcSrjs } 89fa225cbcSrjs 90fa225cbcSrjs while (ring->space < n) { 91fa225cbcSrjs ring->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; 92fa225cbcSrjs ring->space = ring->head - (ring->tail + 8); 93fa225cbcSrjs 94fa225cbcSrjs if (ring->space < 0) 95fa225cbcSrjs ring->space += ring->mem->size; 96fa225cbcSrjs 97fa225cbcSrjs iters++; 98fa225cbcSrjs now = GetTimeInMillis(); 99fa225cbcSrjs if (start == 0 || now < start || ring->head != last_head) { 100fa225cbcSrjs if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) 101fa225cbcSrjs if (now > start) 102fa225cbcSrjs ErrorF("space: %d wanted %d\n", ring->space, n); 103fa225cbcSrjs start = now; 104fa225cbcSrjs last_head = ring->head; 105fa225cbcSrjs } else if (now - start > timeout_millis) { 106fa225cbcSrjs ErrorF("Error in I830WaitLpRing(), timeout for %d seconds\n", 107fa225cbcSrjs timeout_millis/1000); 108fa225cbcSrjs if (IS_I965G(pI830)) 109fa225cbcSrjs i965_dump_error_state(pScrn); 110fa225cbcSrjs else 111fa225cbcSrjs i830_dump_error_state(pScrn); 112fa225cbcSrjs ErrorF("space: %d wanted %d\n", ring->space, n); 113fa225cbcSrjs pI830->uxa_driver = NULL; 114fa225cbcSrjs FatalError("lockup\n"); 115fa225cbcSrjs } 116fa225cbcSrjs 117fa225cbcSrjs DELAY(10); 118fa225cbcSrjs } 119fa225cbcSrjs 120fa225cbcSrjs if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { 121fa225cbcSrjs now = GetTimeInMillis(); 122fa225cbcSrjs if (now - first) { 123fa225cbcSrjs ErrorF("Elapsed %u ms\n", now - first); 124fa225cbcSrjs ErrorF("space: %d wanted %d\n", ring->space, n); 125fa225cbcSrjs } 126fa225cbcSrjs } 127fa225cbcSrjs 128fa225cbcSrjs return iters; 129fa225cbcSrjs} 130fa225cbcSrjs 131fa225cbcSrjsvoid 132fa225cbcSrjsI830Sync(ScrnInfoPtr pScrn) 133fa225cbcSrjs{ 134fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 135fa225cbcSrjs 136fa225cbcSrjs if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC)) 137fa225cbcSrjs ErrorF("I830Sync\n"); 138fa225cbcSrjs 139fa225cbcSrjs if (!pScrn->vtSema || !pI830->batch_bo) 140fa225cbcSrjs return; 141fa225cbcSrjs 142fa225cbcSrjs I830EmitFlush(pScrn); 143fa225cbcSrjs 144fa225cbcSrjs intel_batch_flush(pScrn, TRUE); 145fa225cbcSrjs intel_batch_wait_last(pScrn); 146fa225cbcSrjs} 147fa225cbcSrjs 148fa225cbcSrjsvoid 149fa225cbcSrjsI830EmitFlush(ScrnInfoPtr pScrn) 150fa225cbcSrjs{ 151fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 152fa225cbcSrjs int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; 153fa225cbcSrjs 154fa225cbcSrjs if (IS_I965G(pI830)) 155fa225cbcSrjs flags = 0; 156fa225cbcSrjs 157fa225cbcSrjs { 158fa225cbcSrjs BEGIN_BATCH(1); 159fa225cbcSrjs OUT_BATCH(MI_FLUSH | flags); 160fa225cbcSrjs ADVANCE_BATCH(); 161fa225cbcSrjs } 162fa225cbcSrjs} 163fa225cbcSrjs 164fa225cbcSrjs 165fa225cbcSrjs#if (ALWAYS_SYNC || ALWAYS_FLUSH) 166fa225cbcSrjsvoid 167fa225cbcSrjsi830_debug_sync(ScrnInfoPtr scrn) 168fa225cbcSrjs{ 169fa225cbcSrjs if (ALWAYS_SYNC) 170fa225cbcSrjs I830Sync(scrn); 171fa225cbcSrjs else 172fa225cbcSrjs intel_batch_flush(scrn, FALSE); 173fa225cbcSrjs} 174fa225cbcSrjs#endif 175fa225cbcSrjs 176fa225cbcSrjs/* The following function sets up the supported acceleration. Call it 177fa225cbcSrjs * from the FbInit() function in the SVGA driver, or before ScreenInit 178fa225cbcSrjs * in a monolithic server. 179fa225cbcSrjs */ 180fa225cbcSrjsBool 181fa225cbcSrjsI830AccelInit(ScreenPtr pScreen) 182fa225cbcSrjs{ 183fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 184fa225cbcSrjs I830Ptr pI830 = I830PTR(pScrn); 185fa225cbcSrjs 186fa225cbcSrjs /* Limits are described in the BLT engine chapter under Graphics Data Size 187fa225cbcSrjs * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO, 188fa225cbcSrjs * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO. 189fa225cbcSrjs * 190fa225cbcSrjs * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768. 191fa225cbcSrjs * 192fa225cbcSrjs * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled. 193fa225cbcSrjs * i965 limits 3D surface to 4kB-aligned offset if tiled. 194fa225cbcSrjs * i965 limits 3D surfaces to w,h of ?,8192. 195fa225cbcSrjs * i965 limits 3D surface to pitch of 1B - 128kB. 196fa225cbcSrjs * i965 limits 3D surface pitch alignment to 1 or 2 times the element size. 197fa225cbcSrjs * i965 limits 3D surface pitch alignment to 512B if tiled. 198fa225cbcSrjs * i965 limits 3D destination drawing rect to w,h of 8192,8192. 199fa225cbcSrjs * 200fa225cbcSrjs * i915 limits 3D textures to 4B-aligned offset if un-tiled. 201fa225cbcSrjs * i915 limits 3D textures to ~4kB-aligned offset if tiled. 202fa225cbcSrjs * i915 limits 3D textures to width,height of 2048,2048. 203fa225cbcSrjs * i915 limits 3D textures to pitch of 16B - 8kB, in dwords. 204fa225cbcSrjs * i915 limits 3D destination to ~4kB-aligned offset if tiled. 205fa225cbcSrjs * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled. 206fa225cbcSrjs * i915 limits 3D destination to pitch 64B-aligned if used with depth. 207fa225cbcSrjs * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled. 208fa225cbcSrjs * i915 limits 3D destination to POT aligned pitch if tiled. 209fa225cbcSrjs * i915 limits 3D destination drawing rect to w,h of 2048,2048. 210fa225cbcSrjs * 211fa225cbcSrjs * i845 limits 3D textures to 4B-aligned offset if un-tiled. 212fa225cbcSrjs * i845 limits 3D textures to ~4kB-aligned offset if tiled. 213fa225cbcSrjs * i845 limits 3D textures to width,height of 2048,2048. 214fa225cbcSrjs * i845 limits 3D textures to pitch of 4B - 8kB, in dwords. 215fa225cbcSrjs * i845 limits 3D destination to 4B-aligned offset if un-tiled. 216fa225cbcSrjs * i845 limits 3D destination to ~4kB-aligned offset if tiled. 217fa225cbcSrjs * i845 limits 3D destination to pitch of 8B - 8kB, in dwords. 218fa225cbcSrjs * i845 limits 3D destination drawing rect to w,h of 2048,2048. 219fa225cbcSrjs * 220fa225cbcSrjs * For the tiled issues, the only tiled buffer we draw to should be 221fa225cbcSrjs * the front, which will have an appropriate pitch/offset already set up, 222fa225cbcSrjs * so UXA doesn't need to worry. 223fa225cbcSrjs */ 224fa225cbcSrjs if (IS_I965G(pI830)) { 225fa225cbcSrjs pI830->accel_pixmap_offset_alignment = 4 * 2; 226fa225cbcSrjs pI830->accel_pixmap_pitch_alignment = 64; 227fa225cbcSrjs pI830->accel_max_x = 8192; 228fa225cbcSrjs pI830->accel_max_y = 8192; 229fa225cbcSrjs } else { 230fa225cbcSrjs pI830->accel_pixmap_offset_alignment = 4; 231fa225cbcSrjs pI830->accel_pixmap_pitch_alignment = 64; 232fa225cbcSrjs pI830->accel_max_x = 2048; 233fa225cbcSrjs pI830->accel_max_y = 2048; 234fa225cbcSrjs } 235fa225cbcSrjs 236fa225cbcSrjs return i830_uxa_init(pScreen); 237fa225cbcSrjs} 238