r128_dri.c revision 42a55b46
1c582b7e3Smrg/* 2c582b7e3Smrg * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, 3c582b7e3Smrg * Precision Insight, Inc., Cedar Park, Texas, and 4c582b7e3Smrg * VA Linux Systems Inc., Fremont, California. 5c582b7e3Smrg * 6c582b7e3Smrg * All Rights Reserved. 7c582b7e3Smrg * 8c582b7e3Smrg * Permission is hereby granted, free of charge, to any person obtaining 9c582b7e3Smrg * a copy of this software and associated documentation files (the 10c582b7e3Smrg * "Software"), to deal in the Software without restriction, including 11c582b7e3Smrg * without limitation on the rights to use, copy, modify, merge, 12c582b7e3Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 13c582b7e3Smrg * and to permit persons to whom the Software is furnished to do so, 14c582b7e3Smrg * subject to the following conditions: 15c582b7e3Smrg * 16c582b7e3Smrg * The above copyright notice and this permission notice (including the 17c582b7e3Smrg * next paragraph) shall be included in all copies or substantial 18c582b7e3Smrg * portions of the Software. 19c582b7e3Smrg * 20c582b7e3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21c582b7e3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22c582b7e3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23c582b7e3Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX 24c582b7e3Smrg * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25c582b7e3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26c582b7e3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27c582b7e3Smrg * OTHER DEALINGS IN THE SOFTWARE. 28c582b7e3Smrg */ 29c582b7e3Smrg 30c582b7e3Smrg#ifdef HAVE_CONFIG_H 31c582b7e3Smrg#include "config.h" 32c582b7e3Smrg#endif 33c582b7e3Smrg 34c582b7e3Smrg#include <string.h> 35c582b7e3Smrg#include <stdio.h> 36c582b7e3Smrg 37c582b7e3Smrg/* 38c582b7e3Smrg * Authors: 39c582b7e3Smrg * Kevin E. Martin <martin@valinux.com> 40c582b7e3Smrg * Rickard E. Faith <faith@valinux.com> 41c582b7e3Smrg * Daryll Strauss <daryll@valinux.com> 42c582b7e3Smrg * Gareth Hughes <gareth@valinux.com> 43c582b7e3Smrg * 44c582b7e3Smrg */ 45c582b7e3Smrg 46c582b7e3Smrg /* Driver data structures */ 47c582b7e3Smrg#include "r128.h" 48c582b7e3Smrg#include "r128_dri.h" 49c582b7e3Smrg#include "r128_common.h" 50c582b7e3Smrg#include "r128_reg.h" 51c582b7e3Smrg#include "r128_sarea.h" 52c582b7e3Smrg#include "r128_version.h" 53c582b7e3Smrg 54c582b7e3Smrg /* X and server generic header files */ 55c582b7e3Smrg#include "xf86.h" 56c582b7e3Smrg#include "xf86PciInfo.h" 57c582b7e3Smrg#include "windowstr.h" 58c582b7e3Smrg 59c582b7e3Smrg#include "shadowfb.h" 60c582b7e3Smrg /* GLX/DRI/DRM definitions */ 61c582b7e3Smrg#define _XF86DRI_SERVER_ 62c582b7e3Smrg#include "GL/glxtokens.h" 63c582b7e3Smrg#include "sarea.h" 64c582b7e3Smrg 65c582b7e3Smrgstatic size_t r128_drm_page_size; 66c582b7e3Smrg 67c582b7e3Smrgstatic void R128DRITransitionTo2d(ScreenPtr pScreen); 68c582b7e3Smrgstatic void R128DRITransitionTo3d(ScreenPtr pScreen); 69c582b7e3Smrgstatic void R128DRITransitionMultiToSingle3d(ScreenPtr pScreen); 70c582b7e3Smrgstatic void R128DRITransitionSingleToMulti3d(ScreenPtr pScreen); 71c582b7e3Smrg 72c582b7e3Smrgstatic void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 73c582b7e3Smrg 74c582b7e3Smrg/* Initialize the visual configs that are supported by the hardware. 75c582b7e3Smrg These are combined with the visual configs that the indirect 76c582b7e3Smrg rendering core supports, and the intersection is exported to the 77c582b7e3Smrg client. */ 78c582b7e3Smrgstatic Bool R128InitVisualConfigs(ScreenPtr pScreen) 79c582b7e3Smrg{ 8042a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 81c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 82c582b7e3Smrg int numConfigs = 0; 83c582b7e3Smrg __GLXvisualConfig *pConfigs = NULL; 84c582b7e3Smrg R128ConfigPrivPtr pR128Configs = NULL; 85c582b7e3Smrg R128ConfigPrivPtr *pR128ConfigPtrs = NULL; 86c582b7e3Smrg int i, accum, stencil, db; 87c582b7e3Smrg 88c582b7e3Smrg switch (info->CurrentLayout.pixel_code) { 89c582b7e3Smrg case 8: /* 8bpp mode is not support */ 90c582b7e3Smrg case 15: /* FIXME */ 91c582b7e3Smrg case 24: /* FIXME */ 92c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 93c582b7e3Smrg "[dri] R128DRIScreenInit failed (depth %d not supported). " 94c582b7e3Smrg "Disabling DRI.\n", info->CurrentLayout.pixel_code); 95c582b7e3Smrg return FALSE; 96c582b7e3Smrg 97c582b7e3Smrg#define R128_USE_ACCUM 1 98c582b7e3Smrg#define R128_USE_STENCIL 1 99c582b7e3Smrg#define R128_USE_DB 1 100c582b7e3Smrg 101c582b7e3Smrg case 16: 102c582b7e3Smrg numConfigs = 1; 103c582b7e3Smrg if (R128_USE_ACCUM) numConfigs *= 2; 104c582b7e3Smrg if (R128_USE_STENCIL) numConfigs *= 2; 105c582b7e3Smrg if (R128_USE_DB) numConfigs *= 2; 106c582b7e3Smrg 107c582b7e3Smrg if (!(pConfigs 10842a55b46Smrg = (__GLXvisualConfig*)calloc(sizeof(__GLXvisualConfig), 109c582b7e3Smrg numConfigs))) { 110c582b7e3Smrg return FALSE; 111c582b7e3Smrg } 112c582b7e3Smrg if (!(pR128Configs 11342a55b46Smrg = (R128ConfigPrivPtr)calloc(sizeof(R128ConfigPrivRec), 114c582b7e3Smrg numConfigs))) { 11542a55b46Smrg free(pConfigs); 116c582b7e3Smrg return FALSE; 117c582b7e3Smrg } 118c582b7e3Smrg if (!(pR128ConfigPtrs 11942a55b46Smrg = (R128ConfigPrivPtr*)calloc(sizeof(R128ConfigPrivPtr), 120c582b7e3Smrg numConfigs))) { 12142a55b46Smrg free(pConfigs); 12242a55b46Smrg free(pR128Configs); 123c582b7e3Smrg return FALSE; 124c582b7e3Smrg } 125c582b7e3Smrg 126c582b7e3Smrg i = 0; 127c582b7e3Smrg for (db = 0; db <= R128_USE_DB; db++) { 128c582b7e3Smrg for (accum = 0; accum <= R128_USE_ACCUM; accum++) { 129c582b7e3Smrg for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { 130c582b7e3Smrg pR128ConfigPtrs[i] = &pR128Configs[i]; 131c582b7e3Smrg 132c582b7e3Smrg pConfigs[i].vid = (VisualID)(-1); 133c582b7e3Smrg pConfigs[i].class = -1; 134c582b7e3Smrg pConfigs[i].rgba = TRUE; 135c582b7e3Smrg pConfigs[i].redSize = 5; 136c582b7e3Smrg pConfigs[i].greenSize = 6; 137c582b7e3Smrg pConfigs[i].blueSize = 5; 138c582b7e3Smrg pConfigs[i].alphaSize = 0; 139c582b7e3Smrg pConfigs[i].redMask = 0x0000F800; 140c582b7e3Smrg pConfigs[i].greenMask = 0x000007E0; 141c582b7e3Smrg pConfigs[i].blueMask = 0x0000001F; 142c582b7e3Smrg pConfigs[i].alphaMask = 0x00000000; 143c582b7e3Smrg if (accum) { /* Simulated in software */ 144c582b7e3Smrg pConfigs[i].accumRedSize = 16; 145c582b7e3Smrg pConfigs[i].accumGreenSize = 16; 146c582b7e3Smrg pConfigs[i].accumBlueSize = 16; 147c582b7e3Smrg pConfigs[i].accumAlphaSize = 0; 148c582b7e3Smrg } else { 149c582b7e3Smrg pConfigs[i].accumRedSize = 0; 150c582b7e3Smrg pConfigs[i].accumGreenSize = 0; 151c582b7e3Smrg pConfigs[i].accumBlueSize = 0; 152c582b7e3Smrg pConfigs[i].accumAlphaSize = 0; 153c582b7e3Smrg } 154c582b7e3Smrg if (db) 155c582b7e3Smrg pConfigs[i].doubleBuffer = TRUE; 156c582b7e3Smrg else 157c582b7e3Smrg pConfigs[i].doubleBuffer = FALSE; 158c582b7e3Smrg pConfigs[i].stereo = FALSE; 159c582b7e3Smrg pConfigs[i].bufferSize = 16; 160c582b7e3Smrg pConfigs[i].depthSize = 16; 161c582b7e3Smrg if (stencil) 162c582b7e3Smrg pConfigs[i].stencilSize = 8; /* Simulated in software */ 163c582b7e3Smrg else 164c582b7e3Smrg pConfigs[i].stencilSize = 0; 165c582b7e3Smrg pConfigs[i].auxBuffers = 0; 166c582b7e3Smrg pConfigs[i].level = 0; 167c582b7e3Smrg if (accum || stencil) { 168c582b7e3Smrg pConfigs[i].visualRating = GLX_SLOW_CONFIG; 169c582b7e3Smrg } else { 170c582b7e3Smrg pConfigs[i].visualRating = GLX_NONE; 171c582b7e3Smrg } 172c582b7e3Smrg pConfigs[i].transparentPixel = GLX_NONE; 173c582b7e3Smrg pConfigs[i].transparentRed = 0; 174c582b7e3Smrg pConfigs[i].transparentGreen = 0; 175c582b7e3Smrg pConfigs[i].transparentBlue = 0; 176c582b7e3Smrg pConfigs[i].transparentAlpha = 0; 177c582b7e3Smrg pConfigs[i].transparentIndex = 0; 178c582b7e3Smrg i++; 179c582b7e3Smrg } 180c582b7e3Smrg } 181c582b7e3Smrg } 182c582b7e3Smrg break; 183c582b7e3Smrg 184c582b7e3Smrg case 32: 185c582b7e3Smrg numConfigs = 1; 186c582b7e3Smrg if (R128_USE_ACCUM) numConfigs *= 2; 187c582b7e3Smrg if (R128_USE_STENCIL) numConfigs *= 2; 188c582b7e3Smrg if (R128_USE_DB) numConfigs *= 2; 189c582b7e3Smrg 190c582b7e3Smrg if (!(pConfigs 19142a55b46Smrg = (__GLXvisualConfig*)calloc(sizeof(__GLXvisualConfig), 192c582b7e3Smrg numConfigs))) { 193c582b7e3Smrg return FALSE; 194c582b7e3Smrg } 195c582b7e3Smrg if (!(pR128Configs 19642a55b46Smrg = (R128ConfigPrivPtr)calloc(sizeof(R128ConfigPrivRec), 197c582b7e3Smrg numConfigs))) { 19842a55b46Smrg free(pConfigs); 199c582b7e3Smrg return FALSE; 200c582b7e3Smrg } 201c582b7e3Smrg if (!(pR128ConfigPtrs 20242a55b46Smrg = (R128ConfigPrivPtr*)calloc(sizeof(R128ConfigPrivPtr), 203c582b7e3Smrg numConfigs))) { 20442a55b46Smrg free(pConfigs); 20542a55b46Smrg free(pR128Configs); 206c582b7e3Smrg return FALSE; 207c582b7e3Smrg } 208c582b7e3Smrg 209c582b7e3Smrg i = 0; 210c582b7e3Smrg for (db = 0; db <= R128_USE_DB; db++) { 211c582b7e3Smrg for (accum = 0; accum <= R128_USE_ACCUM; accum++) { 212c582b7e3Smrg for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { 213c582b7e3Smrg pR128ConfigPtrs[i] = &pR128Configs[i]; 214c582b7e3Smrg 215c582b7e3Smrg pConfigs[i].vid = (VisualID)(-1); 216c582b7e3Smrg pConfigs[i].class = -1; 217c582b7e3Smrg pConfigs[i].rgba = TRUE; 218c582b7e3Smrg pConfigs[i].redSize = 8; 219c582b7e3Smrg pConfigs[i].greenSize = 8; 220c582b7e3Smrg pConfigs[i].blueSize = 8; 221c582b7e3Smrg pConfigs[i].alphaSize = 0; 222c582b7e3Smrg pConfigs[i].redMask = 0x00FF0000; 223c582b7e3Smrg pConfigs[i].greenMask = 0x0000FF00; 224c582b7e3Smrg pConfigs[i].blueMask = 0x000000FF; 225c582b7e3Smrg pConfigs[i].alphaMask = 0x00000000; 226c582b7e3Smrg if (accum) { /* Simulated in software */ 227c582b7e3Smrg pConfigs[i].accumRedSize = 16; 228c582b7e3Smrg pConfigs[i].accumGreenSize = 16; 229c582b7e3Smrg pConfigs[i].accumBlueSize = 16; 230c582b7e3Smrg pConfigs[i].accumAlphaSize = 0; 231c582b7e3Smrg } else { 232c582b7e3Smrg pConfigs[i].accumRedSize = 0; 233c582b7e3Smrg pConfigs[i].accumGreenSize = 0; 234c582b7e3Smrg pConfigs[i].accumBlueSize = 0; 235c582b7e3Smrg pConfigs[i].accumAlphaSize = 0; 236c582b7e3Smrg } 237c582b7e3Smrg if (db) 238c582b7e3Smrg pConfigs[i].doubleBuffer = TRUE; 239c582b7e3Smrg else 240c582b7e3Smrg pConfigs[i].doubleBuffer = FALSE; 241c582b7e3Smrg pConfigs[i].stereo = FALSE; 242c582b7e3Smrg pConfigs[i].bufferSize = 24; 243c582b7e3Smrg if (stencil) { 244c582b7e3Smrg pConfigs[i].depthSize = 24; 245c582b7e3Smrg pConfigs[i].stencilSize = 8; 246c582b7e3Smrg } else { 247c582b7e3Smrg pConfigs[i].depthSize = 24; 248c582b7e3Smrg pConfigs[i].stencilSize = 0; 249c582b7e3Smrg } 250c582b7e3Smrg pConfigs[i].auxBuffers = 0; 251c582b7e3Smrg pConfigs[i].level = 0; 252c582b7e3Smrg if (accum) { 253c582b7e3Smrg pConfigs[i].visualRating = GLX_SLOW_CONFIG; 254c582b7e3Smrg } else { 255c582b7e3Smrg pConfigs[i].visualRating = GLX_NONE; 256c582b7e3Smrg } 257c582b7e3Smrg pConfigs[i].transparentPixel = GLX_NONE; 258c582b7e3Smrg pConfigs[i].transparentRed = 0; 259c582b7e3Smrg pConfigs[i].transparentGreen = 0; 260c582b7e3Smrg pConfigs[i].transparentBlue = 0; 261c582b7e3Smrg pConfigs[i].transparentAlpha = 0; 262c582b7e3Smrg pConfigs[i].transparentIndex = 0; 263c582b7e3Smrg i++; 264c582b7e3Smrg } 265c582b7e3Smrg } 266c582b7e3Smrg } 267c582b7e3Smrg break; 268c582b7e3Smrg } 269c582b7e3Smrg 270c582b7e3Smrg info->numVisualConfigs = numConfigs; 271c582b7e3Smrg info->pVisualConfigs = pConfigs; 272c582b7e3Smrg info->pVisualConfigsPriv = pR128Configs; 273c582b7e3Smrg GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pR128ConfigPtrs); 274c582b7e3Smrg return TRUE; 275c582b7e3Smrg} 276c582b7e3Smrg 277c582b7e3Smrg/* Create the Rage 128-specific context information */ 278c582b7e3Smrgstatic Bool R128CreateContext(ScreenPtr pScreen, VisualPtr visual, 279c582b7e3Smrg drm_context_t hwContext, void *pVisualConfigPriv, 280c582b7e3Smrg DRIContextType contextStore) 281c582b7e3Smrg{ 28242a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 283c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 284c582b7e3Smrg 285c582b7e3Smrg info->drmCtx = hwContext; 286c582b7e3Smrg return TRUE; 287c582b7e3Smrg} 288c582b7e3Smrg 289c582b7e3Smrg/* Destroy the Rage 128-specific context information */ 290c582b7e3Smrgstatic void R128DestroyContext(ScreenPtr pScreen, drm_context_t hwContext, 291c582b7e3Smrg DRIContextType contextStore) 292c582b7e3Smrg{ 293c582b7e3Smrg /* Nothing yet */ 294c582b7e3Smrg} 295c582b7e3Smrg 296c582b7e3Smrg/* Called when the X server is woken up to allow the last client's 297c582b7e3Smrg context to be saved and the X server's context to be loaded. This is 298c582b7e3Smrg not necessary for the Rage 128 since the client detects when it's 299c582b7e3Smrg context is not currently loaded and then load's it itself. Since the 300c582b7e3Smrg registers to start and stop the CCE are privileged, only the X server 301c582b7e3Smrg can start/stop the engine. */ 302c582b7e3Smrgstatic void R128EnterServer(ScreenPtr pScreen) 303c582b7e3Smrg{ 30442a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 305c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 306c582b7e3Smrg 30742a55b46Smrg#ifdef HAVE_XAA_H 308c582b7e3Smrg if (info->accel) info->accel->NeedToSync = TRUE; 30942a55b46Smrg#endif 31042a55b46Smrg#ifdef USE_EXA 31142a55b46Smrg if (info->ExaDriver) exaMarkSync(pScreen); 31242a55b46Smrg info->state_2d.composite_setup = FALSE; 31342a55b46Smrg#endif 314c582b7e3Smrg} 315c582b7e3Smrg 316c582b7e3Smrg/* Called when the X server goes to sleep to allow the X server's 317c582b7e3Smrg context to be saved and the last client's context to be loaded. This 318c582b7e3Smrg is not necessary for the Rage 128 since the client detects when it's 319c582b7e3Smrg context is not currently loaded and then load's it itself. Since the 320c582b7e3Smrg registers to start and stop the CCE are privileged, only the X server 321c582b7e3Smrg can start/stop the engine. */ 322c582b7e3Smrgstatic void R128LeaveServer(ScreenPtr pScreen) 323c582b7e3Smrg{ 32442a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 325c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 326c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 327c582b7e3Smrg 328c582b7e3Smrg if (!info->directRenderingEnabled) { 329c582b7e3Smrg /* Save all hardware scissors */ 330c582b7e3Smrg info->sc_left = INREG(R128_SC_LEFT); 331c582b7e3Smrg info->sc_right = INREG(R128_SC_RIGHT); 332c582b7e3Smrg info->sc_top = INREG(R128_SC_TOP); 333c582b7e3Smrg info->sc_bottom = INREG(R128_SC_BOTTOM); 334c582b7e3Smrg info->aux_sc_cntl = INREG(R128_SC_BOTTOM); 335c582b7e3Smrg } else if (info->CCEInUse) { 336c582b7e3Smrg R128CCEReleaseIndirect(pScrn); 337c582b7e3Smrg 338c582b7e3Smrg info->CCEInUse = FALSE; 339c582b7e3Smrg } 340c582b7e3Smrg} 341c582b7e3Smrg 342c582b7e3Smrg/* Contexts can be swapped by the X server if necessary. This callback 343c582b7e3Smrg is currently only used to perform any functions necessary when 344c582b7e3Smrg entering or leaving the X server, and in the future might not be 345c582b7e3Smrg necessary. */ 346c582b7e3Smrgstatic void R128DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, 347c582b7e3Smrg DRIContextType oldContextType, void *oldContext, 348c582b7e3Smrg DRIContextType newContextType, void *newContext) 349c582b7e3Smrg{ 350c582b7e3Smrg if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && 351c582b7e3Smrg (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ 352c582b7e3Smrg R128EnterServer(pScreen); 353c582b7e3Smrg } 354c582b7e3Smrg if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && 355c582b7e3Smrg (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ 356c582b7e3Smrg R128LeaveServer(pScreen); 357c582b7e3Smrg } 358c582b7e3Smrg} 359c582b7e3Smrg 360c582b7e3Smrg/* Initialize the state of the back and depth buffers. */ 361c582b7e3Smrgstatic void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) 362c582b7e3Smrg{ 363c582b7e3Smrg /* FIXME: This routine needs to have acceleration turned on */ 364c582b7e3Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 36542a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 366c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 36742a55b46Smrg#ifdef HAVE_XAA_H 368c582b7e3Smrg BoxPtr pbox, pboxSave; 369c582b7e3Smrg int nbox, nboxSave; 370c582b7e3Smrg int depth; 37142a55b46Smrg#endif 372c582b7e3Smrg 373c582b7e3Smrg /* FIXME: Use accel when CCE 2D code is written 374c582b7e3Smrg * EA: What is this code kept for? Radeon doesn't have it and 375c582b7e3Smrg * has a comment: "There's no need for the 2d driver to be clearing 376c582b7e3Smrg * buffers for the 3d client. It knows how to do that on its own." 377c582b7e3Smrg */ 378c582b7e3Smrg if (info->directRenderingEnabled) 379c582b7e3Smrg return; 38042a55b46Smrg#ifdef HAVE_XAA_H 381c582b7e3Smrg /* FIXME: This should be based on the __GLXvisualConfig info */ 382c582b7e3Smrg switch (pScrn->bitsPerPixel) { 383c582b7e3Smrg case 8: depth = 0x000000ff; break; 384c582b7e3Smrg case 16: depth = 0x0000ffff; break; 385c582b7e3Smrg case 24: depth = 0x00ffffff; break; 386c582b7e3Smrg case 32: depth = 0xffffffff; break; 387c582b7e3Smrg default: depth = 0x00000000; break; 388c582b7e3Smrg } 389c582b7e3Smrg 390c582b7e3Smrg /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ 391c582b7e3Smrg /* FIXME: Only initialize the back and depth buffers for contexts 392c582b7e3Smrg that request them */ 393c582b7e3Smrg 394c582b7e3Smrg pboxSave = pbox = REGION_RECTS(prgn); 395c582b7e3Smrg nboxSave = nbox = REGION_NUM_RECTS(prgn); 396c582b7e3Smrg 397c582b7e3Smrg (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, (CARD32)(-1)); 398c582b7e3Smrg for (; nbox; nbox--, pbox++) { 399c582b7e3Smrg (*info->accel->SubsequentSolidFillRect)(pScrn, 400c582b7e3Smrg pbox->x1 + info->fbX, 401c582b7e3Smrg pbox->y1 + info->fbY, 402c582b7e3Smrg pbox->x2 - pbox->x1, 403c582b7e3Smrg pbox->y2 - pbox->y1); 404c582b7e3Smrg (*info->accel->SubsequentSolidFillRect)(pScrn, 405c582b7e3Smrg pbox->x1 + info->backX, 406c582b7e3Smrg pbox->y1 + info->backY, 407c582b7e3Smrg pbox->x2 - pbox->x1, 408c582b7e3Smrg pbox->y2 - pbox->y1); 409c582b7e3Smrg } 410c582b7e3Smrg 411c582b7e3Smrg pbox = pboxSave; 412c582b7e3Smrg nbox = nboxSave; 413c582b7e3Smrg 414c582b7e3Smrg /* FIXME: this needs to consider depth tiling. */ 415c582b7e3Smrg (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, (CARD32)(-1)); 416c582b7e3Smrg for (; nbox; nbox--, pbox++) 417c582b7e3Smrg (*info->accel->SubsequentSolidFillRect)(pScrn, 418c582b7e3Smrg pbox->x1 + info->depthX, 419c582b7e3Smrg pbox->y1 + info->depthY, 420c582b7e3Smrg pbox->x2 - pbox->x1, 421c582b7e3Smrg pbox->y2 - pbox->y1); 422c582b7e3Smrg 423c582b7e3Smrg info->accel->NeedToSync = TRUE; 42442a55b46Smrg#endif 425c582b7e3Smrg} 426c582b7e3Smrg 427c582b7e3Smrg/* Copy the back and depth buffers when the X server moves a window. */ 428c582b7e3Smrgstatic void R128DRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg, 429c582b7e3Smrg RegionPtr prgnSrc, CARD32 indx) 430c582b7e3Smrg{ 431c582b7e3Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 43242a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 433c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 434c582b7e3Smrg 435c582b7e3Smrg /* FIXME: This routine needs to have acceleration turned on */ 436c582b7e3Smrg /* FIXME: Copy XAACopyWindow() and use REGION_TRANSLATE() */ 437c582b7e3Smrg /* FIXME: Only initialize the back and depth buffers for contexts 438c582b7e3Smrg that request them */ 439c582b7e3Smrg 440c582b7e3Smrg /* FIXME: Use accel when CCE 2D code is written */ 441c582b7e3Smrg if (info->directRenderingEnabled) 442c582b7e3Smrg return; 443c582b7e3Smrg} 444c582b7e3Smrg 445c582b7e3Smrg/* Initialize the AGP state. Request memory for use in AGP space, and 446c582b7e3Smrg initialize the Rage 128 registers to point to that memory. */ 447c582b7e3Smrgstatic Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) 448c582b7e3Smrg{ 449c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 450c582b7e3Smrg unsigned long mode; 451c582b7e3Smrg unsigned int vendor, device; 452c582b7e3Smrg int ret; 453c582b7e3Smrg unsigned long cntl, chunk; 454c582b7e3Smrg int s, l; 455c582b7e3Smrg int flags; 456c582b7e3Smrg unsigned long agpBase; 457c582b7e3Smrg 458c582b7e3Smrg if (drmAgpAcquire(info->drmFD) < 0) { 459c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n"); 460c582b7e3Smrg return FALSE; 461c582b7e3Smrg } 462c582b7e3Smrg 463c582b7e3Smrg /* Modify the mode if the default mode is 464c582b7e3Smrg not appropriate for this particular 465c582b7e3Smrg combination of graphics card and AGP 466c582b7e3Smrg chipset. */ 467c582b7e3Smrg 468c582b7e3Smrg mode = drmAgpGetMode(info->drmFD); /* Default mode */ 469c582b7e3Smrg vendor = drmAgpVendorId(info->drmFD); 470c582b7e3Smrg device = drmAgpDeviceId(info->drmFD); 471c582b7e3Smrg 472c582b7e3Smrg mode &= ~R128_AGP_MODE_MASK; 473c582b7e3Smrg switch (info->agpMode) { 474c582b7e3Smrg case 4: mode |= R128_AGP_4X_MODE; 475c582b7e3Smrg case 2: mode |= R128_AGP_2X_MODE; 476c582b7e3Smrg case 1: default: mode |= R128_AGP_1X_MODE; 477c582b7e3Smrg } 478c582b7e3Smrg 479c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 480c582b7e3Smrg "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", 481c582b7e3Smrg mode, vendor, device, 482c582b7e3Smrg PCI_DEV_VENDOR_ID(info->PciInfo), 483c582b7e3Smrg PCI_DEV_DEVICE_ID(info->PciInfo)); 484c582b7e3Smrg 485c582b7e3Smrg if (drmAgpEnable(info->drmFD, mode) < 0) { 486c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n"); 487c582b7e3Smrg drmAgpRelease(info->drmFD); 488c582b7e3Smrg return FALSE; 489c582b7e3Smrg } 490c582b7e3Smrg 491c582b7e3Smrg info->agpOffset = 0; 492c582b7e3Smrg 493c582b7e3Smrg if ((ret = drmAgpAlloc(info->drmFD, info->agpSize*1024*1024, 0, NULL, 494c582b7e3Smrg &info->agpMemHandle)) < 0) { 495c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); 496c582b7e3Smrg drmAgpRelease(info->drmFD); 497c582b7e3Smrg return FALSE; 498c582b7e3Smrg } 499c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 500c582b7e3Smrg "[agp] %d kB allocated with handle 0x%08x\n", 501c582b7e3Smrg info->agpSize*1024, info->agpMemHandle); 502c582b7e3Smrg 503c582b7e3Smrg if (drmAgpBind(info->drmFD, info->agpMemHandle, info->agpOffset) < 0) { 504c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n"); 505c582b7e3Smrg drmAgpFree(info->drmFD, info->agpMemHandle); 506c582b7e3Smrg drmAgpRelease(info->drmFD); 507c582b7e3Smrg return FALSE; 508c582b7e3Smrg } 509c582b7e3Smrg 510c582b7e3Smrg /* Initialize the CCE ring buffer data */ 511c582b7e3Smrg info->ringStart = info->agpOffset; 512c582b7e3Smrg info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; 513c582b7e3Smrg info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; 514c582b7e3Smrg 515c582b7e3Smrg info->ringReadOffset = info->ringStart + info->ringMapSize; 516c582b7e3Smrg info->ringReadMapSize = r128_drm_page_size; 517c582b7e3Smrg 518c582b7e3Smrg /* Reserve space for vertex/indirect buffers */ 519c582b7e3Smrg info->bufStart = info->ringReadOffset + info->ringReadMapSize; 520c582b7e3Smrg info->bufMapSize = info->bufSize*1024*1024; 521c582b7e3Smrg 522c582b7e3Smrg /* Reserve the rest for AGP textures */ 523c582b7e3Smrg info->agpTexStart = info->bufStart + info->bufMapSize; 524c582b7e3Smrg s = (info->agpSize*1024*1024 - info->agpTexStart); 525c582b7e3Smrg l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); 526c582b7e3Smrg if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; 527c582b7e3Smrg info->agpTexMapSize = (s >> l) << l; 528c582b7e3Smrg info->log2AGPTexGran = l; 529c582b7e3Smrg 530c582b7e3Smrg if (info->CCESecure) flags = DRM_READ_ONLY; 531c582b7e3Smrg else flags = 0; 532c582b7e3Smrg 533c582b7e3Smrg if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, 534c582b7e3Smrg DRM_AGP, flags, &info->ringHandle) < 0) { 535c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 536c582b7e3Smrg "[agp] Could not add ring mapping\n"); 537c582b7e3Smrg return FALSE; 538c582b7e3Smrg } 539c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 540c582b7e3Smrg "[agp] ring handle = 0x%08x\n", info->ringHandle); 541c582b7e3Smrg 542c582b7e3Smrg if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, 543c582b7e3Smrg &info->ring) < 0) { 544c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); 545c582b7e3Smrg return FALSE; 546c582b7e3Smrg } 547c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 548c582b7e3Smrg "[agp] Ring mapped at 0x%08lx\n", 549c582b7e3Smrg (unsigned long)info->ring); 550c582b7e3Smrg 551c582b7e3Smrg if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, 552c582b7e3Smrg DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { 553c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 554c582b7e3Smrg "[agp] Could not add ring read ptr mapping\n"); 555c582b7e3Smrg return FALSE; 556c582b7e3Smrg } 557c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 558c582b7e3Smrg "[agp] ring read ptr handle = 0x%08x\n", 559c582b7e3Smrg info->ringReadPtrHandle); 560c582b7e3Smrg 561c582b7e3Smrg if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, 562c582b7e3Smrg &info->ringReadPtr) < 0) { 563c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 564c582b7e3Smrg "[agp] Could not map ring read ptr\n"); 565c582b7e3Smrg return FALSE; 566c582b7e3Smrg } 567c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 568c582b7e3Smrg "[agp] Ring read ptr mapped at 0x%08lx\n", 569c582b7e3Smrg (unsigned long)info->ringReadPtr); 570c582b7e3Smrg 571c582b7e3Smrg if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize, 572c582b7e3Smrg DRM_AGP, 0, &info->bufHandle) < 0) { 573c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 574c582b7e3Smrg "[agp] Could not add vertex/indirect buffers mapping\n"); 575c582b7e3Smrg return FALSE; 576c582b7e3Smrg } 577c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 578c582b7e3Smrg "[agp] vertex/indirect buffers handle = 0x%08x\n", 579c582b7e3Smrg info->bufHandle); 580c582b7e3Smrg 581c582b7e3Smrg if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize, 582c582b7e3Smrg &info->buf) < 0) { 583c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 584c582b7e3Smrg "[agp] Could not map vertex/indirect buffers\n"); 585c582b7e3Smrg return FALSE; 586c582b7e3Smrg } 587c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 588c582b7e3Smrg "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", 589c582b7e3Smrg (unsigned long)info->buf); 590c582b7e3Smrg 591c582b7e3Smrg if (drmAddMap(info->drmFD, info->agpTexStart, info->agpTexMapSize, 592c582b7e3Smrg DRM_AGP, 0, &info->agpTexHandle) < 0) { 593c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 594c582b7e3Smrg "[agp] Could not add AGP texture map mapping\n"); 595c582b7e3Smrg return FALSE; 596c582b7e3Smrg } 597c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 598c582b7e3Smrg "[agp] AGP texture map handle = 0x%08x\n", 599c582b7e3Smrg info->agpTexHandle); 600c582b7e3Smrg 601c582b7e3Smrg if (drmMap(info->drmFD, info->agpTexHandle, info->agpTexMapSize, 602c582b7e3Smrg &info->agpTex) < 0) { 603c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 604c582b7e3Smrg "[agp] Could not map AGP texture map\n"); 605c582b7e3Smrg return FALSE; 606c582b7e3Smrg } 607c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 608c582b7e3Smrg "[agp] AGP Texture map mapped at 0x%08lx\n", 609c582b7e3Smrg (unsigned long)info->agpTex); 610c582b7e3Smrg 611c582b7e3Smrg /* Initialize Rage 128's AGP registers */ 612c582b7e3Smrg cntl = INREG(R128_AGP_CNTL); 613c582b7e3Smrg cntl &= ~R128_AGP_APER_SIZE_MASK; 614c582b7e3Smrg switch (info->agpSize) { 615c582b7e3Smrg case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; 616c582b7e3Smrg case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; 617c582b7e3Smrg case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; 618c582b7e3Smrg case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; 619c582b7e3Smrg case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; 620c582b7e3Smrg case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; 621c582b7e3Smrg case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; 622c582b7e3Smrg default: 623c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 624c582b7e3Smrg "[agp] Illegal aperture size %d kB\n", 625c582b7e3Smrg info->agpSize*1024); 626c582b7e3Smrg return FALSE; 627c582b7e3Smrg } 628c582b7e3Smrg agpBase = drmAgpBase(info->drmFD); 629c582b7e3Smrg OUTREG(R128_AGP_BASE, agpBase); 630c582b7e3Smrg OUTREG(R128_AGP_CNTL, cntl); 631c582b7e3Smrg 632c582b7e3Smrg /* Disable Rage 128's PCIGART registers */ 633c582b7e3Smrg chunk = INREG(R128_BM_CHUNK_0_VAL); 634c582b7e3Smrg chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | 635c582b7e3Smrg R128_BM_PM4_RD_FORCE_TO_PCI | 636c582b7e3Smrg R128_BM_GLOBAL_FORCE_TO_PCI); 637c582b7e3Smrg OUTREG(R128_BM_CHUNK_0_VAL, chunk); 638c582b7e3Smrg 639c582b7e3Smrg OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ 640c582b7e3Smrg 641c582b7e3Smrg return TRUE; 642c582b7e3Smrg} 643c582b7e3Smrg 644c582b7e3Smrgstatic Bool R128DRIPciInit(R128InfoPtr info, ScreenPtr pScreen) 645c582b7e3Smrg{ 646c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 647c582b7e3Smrg CARD32 chunk; 648c582b7e3Smrg int ret; 649c582b7e3Smrg int flags; 650c582b7e3Smrg 651c582b7e3Smrg info->agpOffset = 0; 652c582b7e3Smrg 653c582b7e3Smrg ret = drmScatterGatherAlloc(info->drmFD, info->agpSize*1024*1024, 654c582b7e3Smrg &info->pciMemHandle); 655c582b7e3Smrg if (ret < 0) { 656c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret); 657c582b7e3Smrg return FALSE; 658c582b7e3Smrg } 659c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 660c582b7e3Smrg "[pci] %d kB allocated with handle 0x%08x\n", 661c582b7e3Smrg info->agpSize*1024, info->pciMemHandle); 662c582b7e3Smrg 663c582b7e3Smrg /* Initialize the CCE ring buffer data */ 664c582b7e3Smrg info->ringStart = info->agpOffset; 665c582b7e3Smrg info->ringMapSize = info->ringSize*1024*1024 + r128_drm_page_size; 666c582b7e3Smrg info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; 667c582b7e3Smrg 668c582b7e3Smrg info->ringReadOffset = info->ringStart + info->ringMapSize; 669c582b7e3Smrg info->ringReadMapSize = r128_drm_page_size; 670c582b7e3Smrg 671c582b7e3Smrg /* Reserve space for vertex/indirect buffers */ 672c582b7e3Smrg info->bufStart = info->ringReadOffset + info->ringReadMapSize; 673c582b7e3Smrg info->bufMapSize = info->bufSize*1024*1024; 674c582b7e3Smrg 675c582b7e3Smrg flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; 676c582b7e3Smrg 677c582b7e3Smrg if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, 678c582b7e3Smrg DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { 679c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 680c582b7e3Smrg "[pci] Could not add ring mapping\n"); 681c582b7e3Smrg return FALSE; 682c582b7e3Smrg } 683c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 684c582b7e3Smrg "[pci] ring handle = 0x%08x\n", info->ringHandle); 685c582b7e3Smrg 686c582b7e3Smrg if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, 687c582b7e3Smrg &info->ring) < 0) { 688c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n"); 689c582b7e3Smrg return FALSE; 690c582b7e3Smrg } 691c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 692c582b7e3Smrg "[pci] Ring mapped at 0x%08lx\n", 693c582b7e3Smrg (unsigned long)info->ring); 694c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 695c582b7e3Smrg "[pci] Ring contents 0x%08lx\n", 696c582b7e3Smrg *(unsigned long *)(pointer)info->ring); 697c582b7e3Smrg 698c582b7e3Smrg if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, 699c582b7e3Smrg DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { 700c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 701c582b7e3Smrg "[pci] Could not add ring read ptr mapping\n"); 702c582b7e3Smrg return FALSE; 703c582b7e3Smrg } 704c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 705c582b7e3Smrg "[pci] ring read ptr handle = 0x%08x\n", 706c582b7e3Smrg info->ringReadPtrHandle); 707c582b7e3Smrg 708c582b7e3Smrg if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, 709c582b7e3Smrg &info->ringReadPtr) < 0) { 710c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 711c582b7e3Smrg "[pci] Could not map ring read ptr\n"); 712c582b7e3Smrg return FALSE; 713c582b7e3Smrg } 714c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 715c582b7e3Smrg "[pci] Ring read ptr mapped at 0x%08lx\n", 716c582b7e3Smrg (unsigned long)info->ringReadPtr); 717c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 718c582b7e3Smrg "[pci] Ring read ptr contents 0x%08lx\n", 719c582b7e3Smrg *(unsigned long *)(pointer)info->ringReadPtr); 720c582b7e3Smrg 721c582b7e3Smrg if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize, 722c582b7e3Smrg DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { 723c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 724c582b7e3Smrg "[pci] Could not add vertex/indirect buffers mapping\n"); 725c582b7e3Smrg return FALSE; 726c582b7e3Smrg } 727c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 728c582b7e3Smrg "[pci] vertex/indirect buffers handle = 0x%08x\n", 729c582b7e3Smrg info->bufHandle); 730c582b7e3Smrg 731c582b7e3Smrg if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize, 732c582b7e3Smrg &info->buf) < 0) { 733c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 734c582b7e3Smrg "[pci] Could not map vertex/indirect buffers\n"); 735c582b7e3Smrg return FALSE; 736c582b7e3Smrg } 737c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 738c582b7e3Smrg "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", 739c582b7e3Smrg (unsigned long)info->buf); 740c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 741c582b7e3Smrg "[pci] Vertex/indirect buffers contents 0x%08lx\n", 742c582b7e3Smrg *(unsigned long *)(pointer)info->buf); 743c582b7e3Smrg 744c582b7e3Smrg switch (info->Chipset) { 745c582b7e3Smrg case PCI_CHIP_RAGE128LE: 746c582b7e3Smrg case PCI_CHIP_RAGE128RE: 747c582b7e3Smrg case PCI_CHIP_RAGE128RK: 748c582b7e3Smrg case PCI_CHIP_RAGE128PD: 749c582b7e3Smrg case PCI_CHIP_RAGE128PP: 750c582b7e3Smrg case PCI_CHIP_RAGE128PR: 751c582b7e3Smrg /* This is a PCI card, do nothing */ 752c582b7e3Smrg break; 753c582b7e3Smrg 754c582b7e3Smrg case PCI_CHIP_RAGE128LF: 755c582b7e3Smrg case PCI_CHIP_RAGE128MF: 756c582b7e3Smrg case PCI_CHIP_RAGE128ML: 757c582b7e3Smrg case PCI_CHIP_RAGE128RF: 758c582b7e3Smrg case PCI_CHIP_RAGE128RG: 759c582b7e3Smrg case PCI_CHIP_RAGE128RL: 760c582b7e3Smrg case PCI_CHIP_RAGE128SM: 761c582b7e3Smrg case PCI_CHIP_RAGE128PF: 762c582b7e3Smrg case PCI_CHIP_RAGE128TF: 763c582b7e3Smrg case PCI_CHIP_RAGE128TL: 764c582b7e3Smrg case PCI_CHIP_RAGE128TR: 765c582b7e3Smrg /* FIXME: ATI documentation does not specify if the following chips are 766c582b7e3Smrg * AGP or PCI, it just mentions their PCI IDs. I'm assuming they're AGP 767c582b7e3Smrg * until I get more correct information. <mharris@redhat.com> 768c582b7e3Smrg */ 769c582b7e3Smrg case PCI_CHIP_RAGE128PA: 770c582b7e3Smrg case PCI_CHIP_RAGE128PB: 771c582b7e3Smrg case PCI_CHIP_RAGE128PC: 772c582b7e3Smrg case PCI_CHIP_RAGE128PE: 773c582b7e3Smrg case PCI_CHIP_RAGE128PG: 774c582b7e3Smrg case PCI_CHIP_RAGE128PH: 775c582b7e3Smrg case PCI_CHIP_RAGE128PI: 776c582b7e3Smrg case PCI_CHIP_RAGE128PJ: 777c582b7e3Smrg case PCI_CHIP_RAGE128PK: 778c582b7e3Smrg case PCI_CHIP_RAGE128PL: 779c582b7e3Smrg case PCI_CHIP_RAGE128PM: 780c582b7e3Smrg case PCI_CHIP_RAGE128PN: 781c582b7e3Smrg case PCI_CHIP_RAGE128PO: 782c582b7e3Smrg case PCI_CHIP_RAGE128PQ: 783c582b7e3Smrg case PCI_CHIP_RAGE128PS: 784c582b7e3Smrg case PCI_CHIP_RAGE128PT: 785c582b7e3Smrg case PCI_CHIP_RAGE128PU: 786c582b7e3Smrg case PCI_CHIP_RAGE128PV: 787c582b7e3Smrg case PCI_CHIP_RAGE128PW: 788c582b7e3Smrg case PCI_CHIP_RAGE128PX: 789c582b7e3Smrg case PCI_CHIP_RAGE128SE: 790c582b7e3Smrg case PCI_CHIP_RAGE128SF: 791c582b7e3Smrg case PCI_CHIP_RAGE128SG: 792c582b7e3Smrg case PCI_CHIP_RAGE128SH: 793c582b7e3Smrg case PCI_CHIP_RAGE128SK: 794c582b7e3Smrg case PCI_CHIP_RAGE128SL: 795c582b7e3Smrg case PCI_CHIP_RAGE128SN: 796c582b7e3Smrg case PCI_CHIP_RAGE128TS: 797c582b7e3Smrg case PCI_CHIP_RAGE128TT: 798c582b7e3Smrg case PCI_CHIP_RAGE128TU: 799c582b7e3Smrg default: 800c582b7e3Smrg /* This is really an AGP card, force PCI GART mode */ 801c582b7e3Smrg chunk = INREG(R128_BM_CHUNK_0_VAL); 802c582b7e3Smrg chunk |= (R128_BM_PTR_FORCE_TO_PCI | 803c582b7e3Smrg R128_BM_PM4_RD_FORCE_TO_PCI | 804c582b7e3Smrg R128_BM_GLOBAL_FORCE_TO_PCI); 805c582b7e3Smrg OUTREG(R128_BM_CHUNK_0_VAL, chunk); 806c582b7e3Smrg OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ 807c582b7e3Smrg break; 808c582b7e3Smrg } 809c582b7e3Smrg 810c582b7e3Smrg return TRUE; 811c582b7e3Smrg} 812c582b7e3Smrg 813c582b7e3Smrg/* Add a map for the MMIO registers that will be accessed by any 814c582b7e3Smrg DRI-based clients. */ 815c582b7e3Smrgstatic Bool R128DRIMapInit(R128InfoPtr info, ScreenPtr pScreen) 816c582b7e3Smrg{ 817c582b7e3Smrg int flags; 818c582b7e3Smrg 819c582b7e3Smrg if (info->CCESecure) flags = DRM_READ_ONLY; 820c582b7e3Smrg else flags = 0; 821c582b7e3Smrg 822c582b7e3Smrg /* Map registers */ 823c582b7e3Smrg info->registerSize = R128_MMIOSIZE; 824c582b7e3Smrg if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, 825c582b7e3Smrg DRM_REGISTERS, flags, &info->registerHandle) < 0) { 826c582b7e3Smrg return FALSE; 827c582b7e3Smrg } 828c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 829c582b7e3Smrg "[drm] register handle = 0x%08x\n", info->registerHandle); 830c582b7e3Smrg 831c582b7e3Smrg return TRUE; 832c582b7e3Smrg} 833c582b7e3Smrg 834c582b7e3Smrg/* Initialize the kernel data structures. */ 835c582b7e3Smrgstatic int R128DRIKernelInit(R128InfoPtr info, ScreenPtr pScreen) 836c582b7e3Smrg{ 837c582b7e3Smrg drmR128Init drmInfo; 838c582b7e3Smrg 839c582b7e3Smrg memset( &drmInfo, 0, sizeof(drmR128Init) ); 840c582b7e3Smrg 841c582b7e3Smrg drmInfo.func = DRM_R128_INIT_CCE; 842c582b7e3Smrg drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); 843c582b7e3Smrg drmInfo.is_pci = info->IsPCI; 844c582b7e3Smrg drmInfo.cce_mode = info->CCEMode; 845c582b7e3Smrg drmInfo.cce_secure = info->CCESecure; 846c582b7e3Smrg drmInfo.ring_size = info->ringSize*1024*1024; 847c582b7e3Smrg drmInfo.usec_timeout = info->CCEusecTimeout; 848c582b7e3Smrg 849c582b7e3Smrg drmInfo.fb_bpp = info->CurrentLayout.pixel_code; 850c582b7e3Smrg drmInfo.depth_bpp = info->CurrentLayout.pixel_code; 851c582b7e3Smrg 852c582b7e3Smrg drmInfo.front_offset = info->frontOffset; 853c582b7e3Smrg drmInfo.front_pitch = info->frontPitch; 854c582b7e3Smrg 855c582b7e3Smrg drmInfo.back_offset = info->backOffset; 856c582b7e3Smrg drmInfo.back_pitch = info->backPitch; 857c582b7e3Smrg 858c582b7e3Smrg drmInfo.depth_offset = info->depthOffset; 859c582b7e3Smrg drmInfo.depth_pitch = info->depthPitch; 860c582b7e3Smrg drmInfo.span_offset = info->spanOffset; 861c582b7e3Smrg 862c582b7e3Smrg drmInfo.fb_offset = info->fbHandle; 863c582b7e3Smrg drmInfo.mmio_offset = info->registerHandle; 864c582b7e3Smrg drmInfo.ring_offset = info->ringHandle; 865c582b7e3Smrg drmInfo.ring_rptr_offset = info->ringReadPtrHandle; 866c582b7e3Smrg drmInfo.buffers_offset = info->bufHandle; 867c582b7e3Smrg drmInfo.agp_textures_offset = info->agpTexHandle; 868c582b7e3Smrg 869c582b7e3Smrg if (drmCommandWrite(info->drmFD, DRM_R128_INIT, 870c582b7e3Smrg &drmInfo, sizeof(drmR128Init)) < 0) 871c582b7e3Smrg return FALSE; 872c582b7e3Smrg 873c582b7e3Smrg return TRUE; 874c582b7e3Smrg} 875c582b7e3Smrg 876c582b7e3Smrg/* Add a map for the vertex buffers that will be accessed by any 877c582b7e3Smrg DRI-based clients. */ 878c582b7e3Smrgstatic Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen) 879c582b7e3Smrg{ 880c582b7e3Smrg /* Initialize vertex buffers */ 881c582b7e3Smrg if (info->IsPCI) { 882c582b7e3Smrg info->bufNumBufs = drmAddBufs(info->drmFD, 883c582b7e3Smrg info->bufMapSize / R128_BUFFER_SIZE, 884c582b7e3Smrg R128_BUFFER_SIZE, 885c582b7e3Smrg DRM_SG_BUFFER, 886c582b7e3Smrg info->bufStart); 887c582b7e3Smrg } else { 888c582b7e3Smrg info->bufNumBufs = drmAddBufs(info->drmFD, 889c582b7e3Smrg info->bufMapSize / R128_BUFFER_SIZE, 890c582b7e3Smrg R128_BUFFER_SIZE, 891c582b7e3Smrg DRM_AGP_BUFFER, 892c582b7e3Smrg info->bufStart); 893c582b7e3Smrg } 894c582b7e3Smrg if (info->bufNumBufs <= 0) { 895c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 896c582b7e3Smrg "[drm] Could not create vertex/indirect buffers list\n"); 897c582b7e3Smrg return FALSE; 898c582b7e3Smrg } 899c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 900c582b7e3Smrg "[drm] Added %d %d byte vertex/indirect buffers\n", 901c582b7e3Smrg info->bufNumBufs, R128_BUFFER_SIZE); 902c582b7e3Smrg 903c582b7e3Smrg if (!(info->buffers = drmMapBufs(info->drmFD))) { 904c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 905c582b7e3Smrg "[drm] Failed to map vertex/indirect buffers list\n"); 906c582b7e3Smrg return FALSE; 907c582b7e3Smrg } 908c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_INFO, 909c582b7e3Smrg "[drm] Mapped %d vertex/indirect buffers\n", 910c582b7e3Smrg info->buffers->count); 911c582b7e3Smrg 912c582b7e3Smrg return TRUE; 913c582b7e3Smrg} 914c582b7e3Smrg 915c582b7e3Smrgstatic void R128DRIIrqInit(R128InfoPtr info, ScreenPtr pScreen) 916c582b7e3Smrg{ 91742a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 918c582b7e3Smrg 919c582b7e3Smrg if (!info->irq) { 920c582b7e3Smrg info->irq = drmGetInterruptFromBusID( 921c582b7e3Smrg info->drmFD, 922c582b7e3Smrg PCI_CFG_BUS(info->PciInfo), 923c582b7e3Smrg PCI_CFG_DEV(info->PciInfo), 924c582b7e3Smrg PCI_CFG_FUNC(info->PciInfo)); 925c582b7e3Smrg 926c582b7e3Smrg if((drmCtlInstHandler(info->drmFD, info->irq)) != 0) { 927c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 928c582b7e3Smrg "[drm] failure adding irq handler, " 929c582b7e3Smrg "there is a device already using that irq\n" 930c582b7e3Smrg "[drm] falling back to irq-free operation\n"); 931c582b7e3Smrg info->irq = 0; 932c582b7e3Smrg } else { 933c582b7e3Smrg unsigned char *R128MMIO = info->MMIO; 934c582b7e3Smrg info->gen_int_cntl = INREG( R128_GEN_INT_CNTL ); 935c582b7e3Smrg } 936c582b7e3Smrg } 937c582b7e3Smrg 938c582b7e3Smrg if (info->irq) 939c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 940c582b7e3Smrg "[drm] dma control initialized, using IRQ %d\n", 941c582b7e3Smrg info->irq); 942c582b7e3Smrg} 943c582b7e3Smrg 944c582b7e3Smrg/* Initialize the CCE state, and start the CCE (if used by the X server) */ 945c582b7e3Smrgstatic void R128DRICCEInit(ScrnInfoPtr pScrn) 946c582b7e3Smrg{ 947c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 948c582b7e3Smrg 949c582b7e3Smrg /* Turn on bus mastering */ 950c582b7e3Smrg info->BusCntl &= ~R128_BUS_MASTER_DIS; 951c582b7e3Smrg 952c582b7e3Smrg /* CCEMode is initialized in r128_driver.c */ 953c582b7e3Smrg switch (info->CCEMode) { 954c582b7e3Smrg case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; 955c582b7e3Smrg case R128_PM4_192PIO: info->CCEFifoSize = 192; break; 956c582b7e3Smrg case R128_PM4_192BM: info->CCEFifoSize = 192; break; 957c582b7e3Smrg case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; 958c582b7e3Smrg case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; 959c582b7e3Smrg case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; 960c582b7e3Smrg case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; 961c582b7e3Smrg case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; 962c582b7e3Smrg case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; 963c582b7e3Smrg case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; 964c582b7e3Smrg } 965c582b7e3Smrg 966c582b7e3Smrg if (info->directRenderingEnabled) { 967c582b7e3Smrg /* Make sure the CCE is on for the X server */ 968c582b7e3Smrg R128CCE_START(pScrn, info); 969c582b7e3Smrg } else { 970c582b7e3Smrg /* Make sure the CCE is off for the X server */ 971c582b7e3Smrg R128CCE_STOP(pScrn, info); 972c582b7e3Smrg } 973c582b7e3Smrg} 974c582b7e3Smrg 975c582b7e3Smrg/* Initialize the screen-specific data structures for the DRI and the 976c582b7e3Smrg Rage 128. This is the main entry point to the device-specific 977c582b7e3Smrg initialization code. It calls device-independent DRI functions to 978c582b7e3Smrg create the DRI data structures and initialize the DRI state. */ 979c582b7e3SmrgBool R128DRIScreenInit(ScreenPtr pScreen) 980c582b7e3Smrg{ 98142a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 982c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 983c582b7e3Smrg DRIInfoPtr pDRIInfo; 984c582b7e3Smrg R128DRIPtr pR128DRI; 985c582b7e3Smrg int major, minor, patch; 986c582b7e3Smrg drmVersionPtr version; 987c582b7e3Smrg 988c582b7e3Smrg /* Check that the GLX, DRI, and DRM modules have been loaded by testing 989c582b7e3Smrg * for known symbols in each module. */ 990c582b7e3Smrg if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; 991c582b7e3Smrg if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; 992c582b7e3Smrg if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { 993c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 994c582b7e3Smrg "[dri] R128DRIScreenInit failed (libdri.a too old)\n"); 995c582b7e3Smrg return FALSE; 996c582b7e3Smrg } 997c582b7e3Smrg 998c582b7e3Smrg /* Check the DRI version */ 999c582b7e3Smrg DRIQueryVersion(&major, &minor, &patch); 1000c582b7e3Smrg if (major != DRIINFO_MAJOR_VERSION || minor < 0) { 1001c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1002c582b7e3Smrg "[dri] R128DRIScreenInit failed because of a version mismatch.\n" 1003c582b7e3Smrg "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n" 1004c582b7e3Smrg "[dri] Disabling the DRI.\n", 1005c582b7e3Smrg major, minor, patch, 1006c582b7e3Smrg DRIINFO_MAJOR_VERSION, 0); 1007c582b7e3Smrg return FALSE; 1008c582b7e3Smrg } 1009c582b7e3Smrg 1010c582b7e3Smrg switch (info->CurrentLayout.pixel_code) { 1011c582b7e3Smrg case 8: 1012c582b7e3Smrg /* These modes are not supported (yet). */ 1013c582b7e3Smrg case 15: 1014c582b7e3Smrg case 24: 1015c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1016c582b7e3Smrg "[dri] R128DRIScreenInit failed (depth %d not supported). " 1017c582b7e3Smrg "[dri] Disabling DRI.\n", info->CurrentLayout.pixel_code); 1018c582b7e3Smrg return FALSE; 1019c582b7e3Smrg 1020c582b7e3Smrg /* Only 16 and 32 color depths are supports currently. */ 1021c582b7e3Smrg case 16: 1022c582b7e3Smrg case 32: 1023c582b7e3Smrg break; 1024c582b7e3Smrg } 1025c582b7e3Smrg 1026c582b7e3Smrg r128_drm_page_size = getpagesize(); 1027c582b7e3Smrg 1028c582b7e3Smrg /* Create the DRI data structure, and fill it in before calling the 1029c582b7e3Smrg DRIScreenInit(). */ 1030c582b7e3Smrg if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; 1031c582b7e3Smrg 1032c582b7e3Smrg info->pDRIInfo = pDRIInfo; 1033c582b7e3Smrg pDRIInfo->drmDriverName = R128_DRIVER_NAME; 1034c582b7e3Smrg pDRIInfo->clientDriverName = R128_DRIVER_NAME; 1035c582b7e3Smrg if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 1036c582b7e3Smrg pDRIInfo->busIdString = DRICreatePCIBusID(info->PciInfo); 1037c582b7e3Smrg } else { 103842a55b46Smrg pDRIInfo->busIdString = malloc(64); 1039c582b7e3Smrg sprintf(pDRIInfo->busIdString, 1040c582b7e3Smrg "PCI:%d:%d:%d", 1041c582b7e3Smrg PCI_DEV_BUS(info->PciInfo), 1042c582b7e3Smrg PCI_DEV_DEV(info->PciInfo), 1043c582b7e3Smrg PCI_DEV_FUNC(info->PciInfo)); 1044c582b7e3Smrg } 1045c582b7e3Smrg pDRIInfo->ddxDriverMajorVersion = R128_VERSION_MAJOR; 1046c582b7e3Smrg pDRIInfo->ddxDriverMinorVersion = R128_VERSION_MINOR; 1047c582b7e3Smrg pDRIInfo->ddxDriverPatchVersion = R128_VERSION_PATCH; 1048c582b7e3Smrg pDRIInfo->frameBufferPhysicalAddress = (void *)info->LinearAddr; 1049c582b7e3Smrg pDRIInfo->frameBufferSize = info->FbMapSize; 1050c582b7e3Smrg pDRIInfo->frameBufferStride = (pScrn->displayWidth * 1051c582b7e3Smrg info->CurrentLayout.pixel_bytes); 1052c582b7e3Smrg pDRIInfo->ddxDrawableTableEntry = R128_MAX_DRAWABLES; 1053c582b7e3Smrg pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES 1054c582b7e3Smrg < R128_MAX_DRAWABLES 1055c582b7e3Smrg ? SAREA_MAX_DRAWABLES 1056c582b7e3Smrg : R128_MAX_DRAWABLES); 1057c582b7e3Smrg 1058c582b7e3Smrg#ifdef NOT_DONE 1059c582b7e3Smrg /* FIXME: Need to extend DRI protocol to pass this size back to 1060c582b7e3Smrg * client for SAREA mapping that includes a device private record 1061c582b7e3Smrg */ 1062c582b7e3Smrg pDRIInfo->SAREASize = 1063c582b7e3Smrg ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ 1064c582b7e3Smrg /* + shared memory device private rec */ 1065c582b7e3Smrg#else 1066c582b7e3Smrg /* For now the mapping works by using a fixed size defined 1067c582b7e3Smrg * in the SAREA header 1068c582b7e3Smrg */ 1069c582b7e3Smrg if (sizeof(XF86DRISAREARec)+sizeof(R128SAREAPriv)>SAREA_MAX) { 1070c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1071c582b7e3Smrg "[dri] Data does not fit in SAREA. Disabling DRI.\n"); 1072c582b7e3Smrg return FALSE; 1073c582b7e3Smrg } 1074c582b7e3Smrg pDRIInfo->SAREASize = SAREA_MAX; 1075c582b7e3Smrg#endif 1076c582b7e3Smrg 107742a55b46Smrg if (!(pR128DRI = (R128DRIPtr)calloc(sizeof(R128DRIRec),1))) { 1078c582b7e3Smrg DRIDestroyInfoRec(info->pDRIInfo); 1079c582b7e3Smrg info->pDRIInfo = NULL; 1080c582b7e3Smrg return FALSE; 1081c582b7e3Smrg } 1082c582b7e3Smrg pDRIInfo->devPrivate = pR128DRI; 1083c582b7e3Smrg pDRIInfo->devPrivateSize = sizeof(R128DRIRec); 1084c582b7e3Smrg pDRIInfo->contextSize = sizeof(R128DRIContextRec); 1085c582b7e3Smrg 1086c582b7e3Smrg pDRIInfo->CreateContext = R128CreateContext; 1087c582b7e3Smrg pDRIInfo->DestroyContext = R128DestroyContext; 1088c582b7e3Smrg pDRIInfo->SwapContext = R128DRISwapContext; 1089c582b7e3Smrg pDRIInfo->InitBuffers = R128DRIInitBuffers; 1090c582b7e3Smrg pDRIInfo->MoveBuffers = R128DRIMoveBuffers; 1091c582b7e3Smrg pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 1092c582b7e3Smrg pDRIInfo->TransitionTo2d = R128DRITransitionTo2d; 1093c582b7e3Smrg pDRIInfo->TransitionTo3d = R128DRITransitionTo3d; 1094c582b7e3Smrg pDRIInfo->TransitionSingleToMulti3D = R128DRITransitionSingleToMulti3d; 1095c582b7e3Smrg pDRIInfo->TransitionMultiToSingle3D = R128DRITransitionMultiToSingle3d; 1096c582b7e3Smrg 1097c582b7e3Smrg pDRIInfo->createDummyCtx = TRUE; 1098c582b7e3Smrg pDRIInfo->createDummyCtxPriv = FALSE; 1099c582b7e3Smrg 1100c582b7e3Smrg if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { 1101c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1102c582b7e3Smrg "[dri] DRIScreenInit failed. Disabling DRI.\n"); 110342a55b46Smrg free(pDRIInfo->devPrivate); 1104c582b7e3Smrg pDRIInfo->devPrivate = NULL; 1105c582b7e3Smrg DRIDestroyInfoRec(pDRIInfo); 1106c582b7e3Smrg pDRIInfo = NULL; 1107c582b7e3Smrg return FALSE; 1108c582b7e3Smrg } 1109c582b7e3Smrg 1110c582b7e3Smrg /* Check the DRM lib version. 1111c582b7e3Smrg drmGetLibVersion was not supported in version 1.0, so check for 1112c582b7e3Smrg symbol first to avoid possible crash or hang. 1113c582b7e3Smrg */ 1114c582b7e3Smrg if (xf86LoaderCheckSymbol("drmGetLibVersion")) { 1115c582b7e3Smrg version = drmGetLibVersion(info->drmFD); 1116c582b7e3Smrg } 1117c582b7e3Smrg else { 1118c582b7e3Smrg /* drmlib version 1.0.0 didn't have the drmGetLibVersion 1119c582b7e3Smrg entry point. Fake it by allocating a version record 1120c582b7e3Smrg via drmGetVersion and changing it to version 1.0.0 1121c582b7e3Smrg */ 1122c582b7e3Smrg version = drmGetVersion(info->drmFD); 1123c582b7e3Smrg version->version_major = 1; 1124c582b7e3Smrg version->version_minor = 0; 1125c582b7e3Smrg version->version_patchlevel = 0; 1126c582b7e3Smrg } 1127c582b7e3Smrg 1128c582b7e3Smrg if (version) { 1129c582b7e3Smrg if (version->version_major != 1 || 1130c582b7e3Smrg version->version_minor < 1) { 1131c582b7e3Smrg /* incompatible drm library version */ 1132c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1133c582b7e3Smrg "[dri] R128DRIScreenInit failed because of a version mismatch.\n" 1134c582b7e3Smrg "[dri] libdrm.a module version is %d.%d.%d but version 1.1.x is needed.\n" 1135c582b7e3Smrg "[dri] Disabling DRI.\n", 1136c582b7e3Smrg version->version_major, 1137c582b7e3Smrg version->version_minor, 1138c582b7e3Smrg version->version_patchlevel); 1139c582b7e3Smrg drmFreeVersion(version); 1140c582b7e3Smrg R128DRICloseScreen(pScreen); 1141c582b7e3Smrg return FALSE; 1142c582b7e3Smrg } 1143c582b7e3Smrg drmFreeVersion(version); 1144c582b7e3Smrg } 1145c582b7e3Smrg 1146c582b7e3Smrg /* Check the r128 DRM version */ 1147c582b7e3Smrg version = drmGetVersion(info->drmFD); 1148c582b7e3Smrg if (version) { 1149c582b7e3Smrg if (version->version_major != 2 || 1150c582b7e3Smrg version->version_minor < 2) { 1151c582b7e3Smrg /* incompatible drm version */ 1152c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_ERROR, 1153c582b7e3Smrg "[dri] R128DRIScreenInit failed because of a version mismatch.\n" 1154c582b7e3Smrg "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" 1155c582b7e3Smrg "[dri] Disabling the DRI.\n", 1156c582b7e3Smrg version->version_major, 1157c582b7e3Smrg version->version_minor, 1158c582b7e3Smrg version->version_patchlevel); 1159c582b7e3Smrg drmFreeVersion(version); 1160c582b7e3Smrg R128DRICloseScreen(pScreen); 1161c582b7e3Smrg return FALSE; 1162c582b7e3Smrg } 1163c582b7e3Smrg info->drmMinor = version->version_minor; 1164c582b7e3Smrg drmFreeVersion(version); 1165c582b7e3Smrg } 1166c582b7e3Smrg 1167c582b7e3Smrg /* Initialize AGP */ 1168c582b7e3Smrg if (!info->IsPCI && !R128DRIAgpInit(info, pScreen)) { 1169c582b7e3Smrg info->IsPCI = TRUE; 1170c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_WARNING, 1171c582b7e3Smrg "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); 1172c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_WARNING, 1173c582b7e3Smrg "[agp] Make sure you have the agpgart kernel module loaded.\n"); 1174c582b7e3Smrg } 1175c582b7e3Smrg 1176c582b7e3Smrg /* Initialize PCIGART */ 1177c582b7e3Smrg if (info->IsPCI && !R128DRIPciInit(info, pScreen)) { 1178c582b7e3Smrg R128DRICloseScreen(pScreen); 1179c582b7e3Smrg return FALSE; 1180c582b7e3Smrg } 1181c582b7e3Smrg 1182c582b7e3Smrg /* DRIScreenInit doesn't add all the 1183c582b7e3Smrg common mappings. Add additional 1184c582b7e3Smrg mappings here. */ 1185c582b7e3Smrg if (!R128DRIMapInit(info, pScreen)) { 1186c582b7e3Smrg R128DRICloseScreen(pScreen); 1187c582b7e3Smrg return FALSE; 1188c582b7e3Smrg } 1189c582b7e3Smrg 1190c582b7e3Smrg /* DRIScreenInit adds the frame buffer 1191c582b7e3Smrg map, but we need it as well */ 1192c582b7e3Smrg { 1193c582b7e3Smrg void *scratch_ptr; 1194c582b7e3Smrg int scratch_int; 1195c582b7e3Smrg 1196c582b7e3Smrg DRIGetDeviceInfo(pScreen, &info->fbHandle, 1197c582b7e3Smrg &scratch_int, &scratch_int, 1198c582b7e3Smrg &scratch_int, &scratch_int, 1199c582b7e3Smrg &scratch_ptr); 1200c582b7e3Smrg } 1201c582b7e3Smrg 1202c582b7e3Smrg /* FIXME: When are these mappings unmapped? */ 1203c582b7e3Smrg 1204c582b7e3Smrg if (!R128InitVisualConfigs(pScreen)) { 1205c582b7e3Smrg R128DRICloseScreen(pScreen); 1206c582b7e3Smrg return FALSE; 1207c582b7e3Smrg } 1208c582b7e3Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] Visual configs initialized\n"); 1209c582b7e3Smrg 1210c582b7e3Smrg return TRUE; 1211c582b7e3Smrg} 1212c582b7e3Smrg 1213c582b7e3Smrg/* Finish initializing the device-dependent DRI state, and call 1214c582b7e3Smrg DRIFinishScreenInit() to complete the device-independent DRI 1215c582b7e3Smrg initialization. */ 1216c582b7e3SmrgBool R128DRIFinishScreenInit(ScreenPtr pScreen) 1217c582b7e3Smrg{ 121842a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1219c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1220c582b7e3Smrg R128SAREAPrivPtr pSAREAPriv; 1221c582b7e3Smrg R128DRIPtr pR128DRI; 1222c582b7e3Smrg 1223c582b7e3Smrg info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; 1224c582b7e3Smrg /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ 1225c582b7e3Smrg 1226c582b7e3Smrg /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit 1227c582b7e3Smrg because *DRIKernelInit requires that the hardware lock is held by 1228c582b7e3Smrg the X server, and the first time the hardware lock is grabbed is 1229c582b7e3Smrg in DRIFinishScreenInit. */ 1230c582b7e3Smrg if (!DRIFinishScreenInit(pScreen)) { 1231c582b7e3Smrg R128DRICloseScreen(pScreen); 1232c582b7e3Smrg return FALSE; 1233c582b7e3Smrg } 1234c582b7e3Smrg 1235c582b7e3Smrg /* Initialize the kernel data structures */ 1236c582b7e3Smrg if (!R128DRIKernelInit(info, pScreen)) { 1237c582b7e3Smrg R128DRICloseScreen(pScreen); 1238c582b7e3Smrg return FALSE; 1239c582b7e3Smrg } 1240c582b7e3Smrg 1241c582b7e3Smrg /* Initialize the vertex buffers list */ 1242c582b7e3Smrg if (!R128DRIBufInit(info, pScreen)) { 1243c582b7e3Smrg R128DRICloseScreen(pScreen); 1244c582b7e3Smrg return FALSE; 1245c582b7e3Smrg } 1246c582b7e3Smrg 1247c582b7e3Smrg /* Initialize IRQ */ 1248c582b7e3Smrg R128DRIIrqInit(info, pScreen); 1249c582b7e3Smrg 1250c582b7e3Smrg /* Initialize and start the CCE if required */ 1251c582b7e3Smrg R128DRICCEInit(pScrn); 1252c582b7e3Smrg 1253c582b7e3Smrg pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen); 1254c582b7e3Smrg memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); 1255c582b7e3Smrg 1256c582b7e3Smrg pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; 1257c582b7e3Smrg 1258c582b7e3Smrg pR128DRI->deviceID = info->Chipset; 1259c582b7e3Smrg pR128DRI->width = pScrn->virtualX; 1260c582b7e3Smrg pR128DRI->height = pScrn->virtualY; 1261c582b7e3Smrg pR128DRI->depth = pScrn->depth; 1262c582b7e3Smrg pR128DRI->bpp = pScrn->bitsPerPixel; 1263c582b7e3Smrg 1264c582b7e3Smrg pR128DRI->IsPCI = info->IsPCI; 1265c582b7e3Smrg pR128DRI->AGPMode = info->agpMode; 1266c582b7e3Smrg 1267c582b7e3Smrg pR128DRI->frontOffset = info->frontOffset; 1268c582b7e3Smrg pR128DRI->frontPitch = info->frontPitch; 1269c582b7e3Smrg pR128DRI->backOffset = info->backOffset; 1270c582b7e3Smrg pR128DRI->backPitch = info->backPitch; 1271c582b7e3Smrg pR128DRI->depthOffset = info->depthOffset; 1272c582b7e3Smrg pR128DRI->depthPitch = info->depthPitch; 1273c582b7e3Smrg pR128DRI->spanOffset = info->spanOffset; 1274c582b7e3Smrg pR128DRI->textureOffset = info->textureOffset; 1275c582b7e3Smrg pR128DRI->textureSize = info->textureSize; 1276c582b7e3Smrg pR128DRI->log2TexGran = info->log2TexGran; 1277c582b7e3Smrg 1278c582b7e3Smrg pR128DRI->registerHandle = info->registerHandle; 1279c582b7e3Smrg pR128DRI->registerSize = info->registerSize; 1280c582b7e3Smrg 1281c582b7e3Smrg pR128DRI->agpTexHandle = info->agpTexHandle; 1282c582b7e3Smrg pR128DRI->agpTexMapSize = info->agpTexMapSize; 1283c582b7e3Smrg pR128DRI->log2AGPTexGran = info->log2AGPTexGran; 1284c582b7e3Smrg pR128DRI->agpTexOffset = info->agpTexStart; 1285c582b7e3Smrg pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 1286c582b7e3Smrg 1287c582b7e3Smrg /* Have shadowfb run only while there is 3d active. */ 1288c582b7e3Smrg if (info->allowPageFlip && info->drmMinor >= 5 ) { 1289c582b7e3Smrg ShadowFBInit( pScreen, R128DRIRefreshArea ); 1290c582b7e3Smrg } else if (info->allowPageFlip) { 1291c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_WARNING, 1292c582b7e3Smrg "[dri] Kernel module version 2.5.0 or newer is required for pageflipping.\n"); 1293c582b7e3Smrg info->allowPageFlip = 0; 1294c582b7e3Smrg } 1295c582b7e3Smrg 1296c582b7e3Smrg return TRUE; 1297c582b7e3Smrg} 1298c582b7e3Smrg 1299c582b7e3Smrg/* The screen is being closed, so clean up any state and free any 1300c582b7e3Smrg resources used by the DRI. */ 1301c582b7e3Smrgvoid R128DRICloseScreen(ScreenPtr pScreen) 1302c582b7e3Smrg{ 130342a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1304c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1305c582b7e3Smrg drmR128Init drmInfo; 1306c582b7e3Smrg 1307c582b7e3Smrg /* Stop the CCE if it is still in use */ 1308c582b7e3Smrg if (info->directRenderingEnabled) { 1309c582b7e3Smrg R128CCE_STOP(pScrn, info); 1310c582b7e3Smrg } 1311c582b7e3Smrg 1312c582b7e3Smrg if (info->irq) { 1313c582b7e3Smrg drmCtlUninstHandler(info->drmFD); 1314c582b7e3Smrg info->irq = 0; 1315c582b7e3Smrg info->gen_int_cntl = 0; 1316c582b7e3Smrg } 1317c582b7e3Smrg 1318c582b7e3Smrg /* De-allocate vertex buffers */ 1319c582b7e3Smrg if (info->buffers) { 1320c582b7e3Smrg drmUnmapBufs(info->buffers); 1321c582b7e3Smrg info->buffers = NULL; 1322c582b7e3Smrg } 1323c582b7e3Smrg 1324c582b7e3Smrg /* De-allocate all kernel resources */ 1325c582b7e3Smrg memset(&drmInfo, 0, sizeof(drmR128Init)); 1326c582b7e3Smrg drmInfo.func = DRM_R128_CLEANUP_CCE; 1327c582b7e3Smrg drmCommandWrite(info->drmFD, DRM_R128_INIT, 1328c582b7e3Smrg &drmInfo, sizeof(drmR128Init)); 1329c582b7e3Smrg 1330c582b7e3Smrg /* De-allocate all AGP resources */ 1331c582b7e3Smrg if (info->agpTex) { 1332c582b7e3Smrg drmUnmap(info->agpTex, info->agpTexMapSize); 1333c582b7e3Smrg info->agpTex = NULL; 1334c582b7e3Smrg } 1335c582b7e3Smrg if (info->buf) { 1336c582b7e3Smrg drmUnmap(info->buf, info->bufMapSize); 1337c582b7e3Smrg info->buf = NULL; 1338c582b7e3Smrg } 1339c582b7e3Smrg if (info->ringReadPtr) { 1340c582b7e3Smrg drmUnmap(info->ringReadPtr, info->ringReadMapSize); 1341c582b7e3Smrg info->ringReadPtr = NULL; 1342c582b7e3Smrg } 1343c582b7e3Smrg if (info->ring) { 1344c582b7e3Smrg drmUnmap(info->ring, info->ringMapSize); 1345c582b7e3Smrg info->ring = NULL; 1346c582b7e3Smrg } 1347c582b7e3Smrg if (info->agpMemHandle != DRM_AGP_NO_HANDLE) { 1348c582b7e3Smrg drmAgpUnbind(info->drmFD, info->agpMemHandle); 1349c582b7e3Smrg drmAgpFree(info->drmFD, info->agpMemHandle); 1350c582b7e3Smrg info->agpMemHandle = DRM_AGP_NO_HANDLE; 1351c582b7e3Smrg drmAgpRelease(info->drmFD); 1352c582b7e3Smrg } 1353c582b7e3Smrg if (info->pciMemHandle) { 1354c582b7e3Smrg drmScatterGatherFree(info->drmFD, info->pciMemHandle); 1355c582b7e3Smrg info->pciMemHandle = 0; 1356c582b7e3Smrg } 1357c582b7e3Smrg 1358c582b7e3Smrg /* De-allocate all DRI resources */ 1359c582b7e3Smrg DRICloseScreen(pScreen); 1360c582b7e3Smrg 1361c582b7e3Smrg /* De-allocate all DRI data structures */ 1362c582b7e3Smrg if (info->pDRIInfo) { 1363c582b7e3Smrg if (info->pDRIInfo->devPrivate) { 136442a55b46Smrg free(info->pDRIInfo->devPrivate); 1365c582b7e3Smrg info->pDRIInfo->devPrivate = NULL; 1366c582b7e3Smrg } 1367c582b7e3Smrg DRIDestroyInfoRec(info->pDRIInfo); 1368c582b7e3Smrg info->pDRIInfo = NULL; 1369c582b7e3Smrg } 1370c582b7e3Smrg if (info->pVisualConfigs) { 137142a55b46Smrg free(info->pVisualConfigs); 1372c582b7e3Smrg info->pVisualConfigs = NULL; 1373c582b7e3Smrg } 1374c582b7e3Smrg if (info->pVisualConfigsPriv) { 137542a55b46Smrg free(info->pVisualConfigsPriv); 1376c582b7e3Smrg info->pVisualConfigsPriv = NULL; 1377c582b7e3Smrg } 1378c582b7e3Smrg} 1379c582b7e3Smrg 1380c582b7e3Smrg/* Use callbacks from dri.c to support pageflipping mode for a single 1381c582b7e3Smrg * 3d context without need for any specific full-screen extension. 1382c582b7e3Smrg */ 1383c582b7e3Smrg 1384c582b7e3Smrg/* Use the shadowfb module to maintain a list of dirty rectangles. 1385c582b7e3Smrg * These are blitted to the back buffer to keep both buffers clean 1386c582b7e3Smrg * during page-flipping when the 3d application isn't fullscreen. 1387c582b7e3Smrg * 1388c582b7e3Smrg * Unlike most use of the shadowfb code, both buffers are in video memory. 1389c582b7e3Smrg * 1390c582b7e3Smrg * An alternative to this would be to organize for all on-screen drawing 1391c582b7e3Smrg * operations to be duplicated for the two buffers. That might be 1392c582b7e3Smrg * faster, but seems like a lot more work... 1393c582b7e3Smrg */ 1394c582b7e3Smrg 1395c582b7e3Smrg 1396c582b7e3Smrgstatic void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 1397c582b7e3Smrg{ 1398c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1399c582b7e3Smrg int i; 1400c582b7e3Smrg R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); 140142a55b46Smrg PixmapPtr pPix = pScrn->pScreen->GetScreenPixmap(pScrn->pScreen); 1402c582b7e3Smrg 1403c582b7e3Smrg /* Don't want to do this when no 3d is active and pages are 1404c582b7e3Smrg * right-way-round 1405c582b7e3Smrg */ 1406c582b7e3Smrg if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0) 1407c582b7e3Smrg return; 1408c582b7e3Smrg 140942a55b46Smrg#ifdef HAVE_XAA_H 141042a55b46Smrg if (!info->useEXA) { 141142a55b46Smrg (*info->accel->SetupForScreenToScreenCopy)(pScrn, 1412c582b7e3Smrg 1, 1, GXcopy, 1413c582b7e3Smrg (CARD32)(-1), -1); 141442a55b46Smrg } 141542a55b46Smrg#endif 141642a55b46Smrg#ifdef USE_EXA 141742a55b46Smrg if (info->useEXA) { 141842a55b46Smrg CARD32 src_pitch_offset, dst_pitch_offset, datatype; 141942a55b46Smrg 142042a55b46Smrg R128GetPixmapOffsetPitch(pPix, &src_pitch_offset); 142142a55b46Smrg dst_pitch_offset = src_pitch_offset + (info->backOffset >> 5); 142242a55b46Smrg R128GetDatatypeBpp(pScrn->bitsPerPixel, &datatype); 142342a55b46Smrg info->xdir = info->ydir = 1; 142442a55b46Smrg 142542a55b46Smrg R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, GXcopy, ~0); 142642a55b46Smrg } 142742a55b46Smrg#endif 1428c582b7e3Smrg 1429c582b7e3Smrg for (i = 0 ; i < num ; i++, pbox++) { 1430c582b7e3Smrg int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1); 1431c582b7e3Smrg int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); 1432c582b7e3Smrg 1433c582b7e3Smrg if (xa <= xb && ya <= yb) { 143442a55b46Smrg#ifdef HAVE_XAA_H 143542a55b46Smrg if (!info->useEXA) { 143642a55b46Smrg (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, 1437c582b7e3Smrg xa + info->backX, 1438c582b7e3Smrg ya + info->backY, 1439c582b7e3Smrg xb - xa + 1, 1440c582b7e3Smrg yb - ya + 1); 144142a55b46Smrg } 144242a55b46Smrg#endif 144342a55b46Smrg#ifdef USE_EXA 144442a55b46Smrg if (info->useEXA) { 144542a55b46Smrg (*info->ExaDriver->Copy)(pPix, xa, ya, xa, ya, xb - xa + 1, yb - ya + 1); 144642a55b46Smrg } 144742a55b46Smrg#endif 1448c582b7e3Smrg } 1449c582b7e3Smrg } 1450c582b7e3Smrg} 1451c582b7e3Smrg 1452c582b7e3Smrgstatic void R128EnablePageFlip(ScreenPtr pScreen) 1453c582b7e3Smrg{ 145442a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1455c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1456c582b7e3Smrg R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 145742a55b46Smrg PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); 1458c582b7e3Smrg 1459c582b7e3Smrg if (info->allowPageFlip) { 1460c582b7e3Smrg /* Duplicate the frontbuffer to the backbuffer */ 146142a55b46Smrg#ifdef HAVE_XAA_H 146242a55b46Smrg if (!info->useEXA) { 146342a55b46Smrg (*info->accel->SetupForScreenToScreenCopy)(pScrn, 1464c582b7e3Smrg 1, 1, GXcopy, 1465c582b7e3Smrg (CARD32)(-1), -1); 1466c582b7e3Smrg 146742a55b46Smrg (*info->accel->SubsequentScreenToScreenCopy)(pScrn, 1468c582b7e3Smrg 0, 1469c582b7e3Smrg 0, 1470c582b7e3Smrg info->backX, 1471c582b7e3Smrg info->backY, 1472c582b7e3Smrg pScrn->virtualX, 1473c582b7e3Smrg pScrn->virtualY); 147442a55b46Smrg } 147542a55b46Smrg#endif 147642a55b46Smrg#ifdef USE_EXA 147742a55b46Smrg if (info->useEXA) { 147842a55b46Smrg CARD32 src_pitch_offset, dst_pitch_offset, datatype; 147942a55b46Smrg 148042a55b46Smrg R128GetPixmapOffsetPitch(pPix, &src_pitch_offset); 148142a55b46Smrg dst_pitch_offset = src_pitch_offset + (info->backOffset >> 5); 148242a55b46Smrg R128GetDatatypeBpp(pScrn->bitsPerPixel, &datatype); 148342a55b46Smrg info->xdir = info->ydir = 1; 148442a55b46Smrg 148542a55b46Smrg R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, GXcopy, ~0); 148642a55b46Smrg 148742a55b46Smrg (*info->ExaDriver->Copy)(pPix, 0, 0, 0, 0, pScrn->virtualX, pScrn->virtualY); 148842a55b46Smrg } 148942a55b46Smrg#endif 1490c582b7e3Smrg 1491c582b7e3Smrg pSAREAPriv->pfAllowPageFlip = 1; 1492c582b7e3Smrg } 1493c582b7e3Smrg} 1494c582b7e3Smrg 1495c582b7e3Smrgstatic void R128DisablePageFlip(ScreenPtr pScreen) 1496c582b7e3Smrg{ 1497c582b7e3Smrg /* Tell the clients not to pageflip. How? 1498c582b7e3Smrg * -- Field in sarea, plus bumping the window counters. 1499c582b7e3Smrg * -- DRM needs to cope with Front-to-Back swapbuffers. 1500c582b7e3Smrg */ 1501c582b7e3Smrg R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 1502c582b7e3Smrg 1503c582b7e3Smrg pSAREAPriv->pfAllowPageFlip = 0; 1504c582b7e3Smrg} 1505c582b7e3Smrg 1506c582b7e3Smrgstatic void R128DRITransitionSingleToMulti3d(ScreenPtr pScreen) 1507c582b7e3Smrg{ 1508c582b7e3Smrg R128DisablePageFlip(pScreen); 1509c582b7e3Smrg} 1510c582b7e3Smrg 1511c582b7e3Smrgstatic void R128DRITransitionMultiToSingle3d(ScreenPtr pScreen) 1512c582b7e3Smrg{ 1513c582b7e3Smrg /* Let the remaining 3d app start page flipping again */ 1514c582b7e3Smrg R128EnablePageFlip(pScreen); 1515c582b7e3Smrg} 1516c582b7e3Smrg 1517c582b7e3Smrgstatic void R128DRITransitionTo3d(ScreenPtr pScreen) 1518c582b7e3Smrg{ 151942a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1520c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1521c582b7e3Smrg 1522c582b7e3Smrg R128EnablePageFlip(pScreen); 1523c582b7e3Smrg 1524c582b7e3Smrg info->have3DWindows = 1; 1525c582b7e3Smrg 1526c582b7e3Smrg if (info->cursor_start) 1527c582b7e3Smrg xf86ForceHWCursor(pScreen, TRUE); 1528c582b7e3Smrg} 1529c582b7e3Smrg 1530c582b7e3Smrgstatic void R128DRITransitionTo2d(ScreenPtr pScreen) 1531c582b7e3Smrg{ 153242a55b46Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1533c582b7e3Smrg R128InfoPtr info = R128PTR(pScrn); 1534c582b7e3Smrg R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); 1535c582b7e3Smrg 1536c582b7e3Smrg /* Try flipping back to the front page if necessary */ 1537c582b7e3Smrg if (pSAREAPriv->pfCurrentPage == 1) 1538c582b7e3Smrg drmCommandNone(info->drmFD, DRM_R128_FLIP); 1539c582b7e3Smrg 1540c582b7e3Smrg /* Shut down shadowing if we've made it back to the front page */ 1541c582b7e3Smrg if (pSAREAPriv->pfCurrentPage == 0) { 1542c582b7e3Smrg R128DisablePageFlip(pScreen); 1543c582b7e3Smrg } else { 1544c582b7e3Smrg xf86DrvMsg(pScreen->myNum, X_WARNING, 1545c582b7e3Smrg "[dri] R128DRITransitionTo2d: " 1546c582b7e3Smrg "kernel failed to unflip buffers.\n"); 1547c582b7e3Smrg } 1548c582b7e3Smrg 1549c582b7e3Smrg info->have3DWindows = 0; 1550c582b7e3Smrg 1551c582b7e3Smrg if (info->cursor_start) 1552c582b7e3Smrg xf86ForceHWCursor(pScreen, FALSE); 1553c582b7e3Smrg} 1554