📄 r128_dri.c
字号:
/* This is really an AGP card, force PCI GART mode */ chunk = INREG(R128_BM_CHUNK_0_VAL); chunk |= (R128_BM_PTR_FORCE_TO_PCI | R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); OUTREG(R128_BM_CHUNK_0_VAL, chunk); OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ } return GL_TRUE;}/* Add a map for the MMIO registers that will be accessed by any DRI-based clients. */static GLboolean R128DRIMapInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; int flags; if (info->CCESecure) flags = DRM_READ_ONLY; else flags = 0; /* Map registers */ if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize, DRM_REGISTERS, flags, &info->registerHandle) < 0) { return GL_FALSE; } fprintf(stderr, "[drm] register handle = 0x%08x\n", info->registerHandle); return GL_TRUE;}/* Initialize the kernel data structures. */static int R128DRIKernelInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; drm_r128_init_t drmInfo; memset( &drmInfo, 0, sizeof(&drmInfo) ); drmInfo.func = R128_INIT_CCE; drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); drmInfo.is_pci = info->IsPCI; drmInfo.cce_mode = info->CCEMode; drmInfo.cce_secure = info->CCESecure; drmInfo.ring_size = info->ringSize*1024*1024; drmInfo.usec_timeout = info->CCEusecTimeout; drmInfo.fb_bpp = ctx->bpp; drmInfo.depth_bpp = ctx->bpp; drmInfo.front_offset = info->frontOffset; drmInfo.front_pitch = info->frontPitch; drmInfo.back_offset = info->backOffset; drmInfo.back_pitch = info->backPitch; drmInfo.depth_offset = info->depthOffset; drmInfo.depth_pitch = info->depthPitch; drmInfo.span_offset = info->spanOffset; drmInfo.fb_offset = info->LinearAddr; drmInfo.mmio_offset = info->registerHandle; drmInfo.ring_offset = info->ringHandle; drmInfo.ring_rptr_offset = info->ringReadPtrHandle; drmInfo.buffers_offset = info->bufHandle; drmInfo.agp_textures_offset = info->agpTexHandle; if (drmCommandWrite(ctx->drmFD, DRM_R128_INIT, &drmInfo, sizeof(drmInfo)) < 0) return GL_FALSE; return GL_TRUE;}/* Add a map for the vertex buffers that will be accessed by any DRI-based clients. */static GLboolean R128DRIBufInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; /* Initialize vertex buffers */ if (info->IsPCI) { info->bufNumBufs = drmAddBufs(ctx->drmFD, info->bufMapSize / R128_BUFFER_SIZE, R128_BUFFER_SIZE, DRM_SG_BUFFER, info->bufStart); } else { info->bufNumBufs = drmAddBufs(ctx->drmFD, info->bufMapSize / R128_BUFFER_SIZE, R128_BUFFER_SIZE, DRM_AGP_BUFFER, info->bufStart); } if (info->bufNumBufs <= 0) { fprintf(stderr, "[drm] Could not create vertex/indirect buffers list\n"); return GL_FALSE; } fprintf(stderr, "[drm] Added %d %d byte vertex/indirect buffers\n", info->bufNumBufs, R128_BUFFER_SIZE); if (!(info->buffers = drmMapBufs(ctx->drmFD))) { fprintf(stderr, "[drm] Failed to map vertex/indirect buffers list\n"); return GL_FALSE; } fprintf(stderr, "[drm] Mapped %d vertex/indirect buffers\n", info->buffers->count); return GL_TRUE;}static void R128DRIIrqInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; unsigned char *R128MMIO = ctx->MMIOAddress; if (!info->irq) { info->irq = drmGetInterruptFromBusID( ctx->drmFD, ctx->pciBus, ctx->pciDevice, ctx->pciFunc); if((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) { fprintf(stderr, "[drm] failure adding irq handler, " "there is a device already using that irq\n" "[drm] falling back to irq-free operation\n"); info->irq = 0; } else { info->gen_int_cntl = INREG( R128_GEN_INT_CNTL ); } } if (info->irq) fprintf(stderr, "[drm] dma control initialized, using IRQ %d\n", info->irq);}static int R128CCEStop(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; drm_r128_cce_stop_t stop; int ret, i; stop.flush = 1; stop.idle = 1; ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, &stop, sizeof(stop) ); if ( ret == 0 ) { return 0; } else if ( errno != EBUSY ) { return -errno; } stop.flush = 0; i = 0; do { ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, &stop, sizeof(stop) ); } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); if ( ret == 0 ) { return 0; } else if ( errno != EBUSY ) { return -errno; } stop.idle = 0; if ( drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, &stop, sizeof(stop) )) { return -errno; } else { return 0; }}/* Initialize the CCE state, and start the CCE (if used by the X server) */static void R128DRICCEInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; /* Turn on bus mastering */ info->BusCntl &= ~R128_BUS_MASTER_DIS; /* CCEMode is initialized in r128_driver.c */ switch (info->CCEMode) { case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; case R128_PM4_192PIO: info->CCEFifoSize = 192; break; case R128_PM4_192BM: info->CCEFifoSize = 192; break; case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; } /* Make sure the CCE is on for the X server */ R128CCE_START(ctx, info);}static int R128MemoryInit(const DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; int width_bytes = ctx->shared.virtualWidth * ctx->cpp; int cpp = ctx->cpp; int bufferSize = ((ctx->shared.virtualHeight * width_bytes + R128_BUFFER_ALIGN) & ~R128_BUFFER_ALIGN); int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + R128_BUFFER_ALIGN) & ~R128_BUFFER_ALIGN); int l; info->frontOffset = 0; info->frontPitch = ctx->shared.virtualWidth; fprintf(stderr, "Using %d MB AGP aperture\n", info->agpSize); fprintf(stderr, "Using %d MB for the ring buffer\n", info->ringSize); fprintf(stderr, "Using %d MB for vertex/indirect buffers\n", info->bufSize); fprintf(stderr, "Using %d MB for AGP textures\n", info->agpTexSize); /* Front, back and depth buffers - everything else texture?? */ info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; if (info->textureSize < 0) return 0; l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; /* Round the texture size up to the nearest whole number of * texture regions. Again, be greedy about this, don't * round down. */ info->log2TexGran = l; info->textureSize = (info->textureSize >> l) << l; /* Set a minimum usable local texture heap size. This will fit * two 256x256x32bpp textures. */ if (info->textureSize < 512 * 1024) { info->textureOffset = 0; info->textureSize = 0; } /* Reserve space for textures */ info->textureOffset = ((ctx->shared.fbSize - info->textureSize + R128_BUFFER_ALIGN) & ~R128_BUFFER_ALIGN); /* Reserve space for the shared depth * buffer. */ info->depthOffset = ((info->textureOffset - depthSize + R128_BUFFER_ALIGN) & ~R128_BUFFER_ALIGN); info->depthPitch = ctx->shared.virtualWidth; info->backOffset = ((info->depthOffset - bufferSize + R128_BUFFER_ALIGN) & ~R128_BUFFER_ALIGN); info->backPitch = ctx->shared.virtualWidth; fprintf(stderr, "Will use back buffer at offset 0x%x\n", info->backOffset); fprintf(stderr, "Will use depth buffer at offset 0x%x\n", info->depthOffset); fprintf(stderr, "Will use %d kb for textures at offset 0x%x\n", info->textureSize/1024, info->textureOffset); return 1;} /* Initialize the screen-specific data structures for the DRI and the Rage 128. This is the main entry point to the device-specific initialization code. It calls device-independent DRI functions to create the DRI data structures and initialize the DRI state. */static GLboolean R128DRIScreenInit(DRIDriverContext *ctx){ R128InfoPtr info = ctx->driverPrivate; R128DRIPtr pR128DRI; int err, major, minor, patch; drmVersionPtr version; drm_r128_sarea_t *pSAREAPriv; switch (ctx->bpp) { case 8: /* These modes are not supported (yet). */ case 15: case 24: fprintf(stderr, "[dri] R128DRIScreenInit failed (depth %d not supported). " "[dri] Disabling DRI.\n", ctx->bpp); return GL_FALSE; /* Only 16 and 32 color depths are supports currently. */ case 16: case 32: break; } r128_drm_page_size = getpagesize(); info->registerSize = ctx->MMIOSize; ctx->shared.SAREASize = SAREA_MAX; /* Note that drmOpen will try to load the kernel module, if needed. */ ctx->drmFD = drmOpen("r128", NULL ); if (ctx->drmFD < 0) { fprintf(stderr, "[drm] drmOpen failed\n"); return 0; } /* Check the r128 DRM version */ version = drmGetVersion(ctx->drmFD); if (version) { if (version->version_major != 2 || version->version_minor < 2) { /* incompatible drm version */ fprintf(stderr, "[dri] R128DRIScreenInit failed because of a version mismatch.\n" "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" "[dri] Disabling the DRI.\n", version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return GL_FALSE; } info->drmMinor = version->version_minor; drmFreeVersion(version); } if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", ctx->drmFD, ctx->pciBusID, strerror(-err)); return 0; } if (drmAddMap( ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM, DRM_CONTAINS_LOCK, &ctx->shared.hSAREA) < 0) { fprintf(stderr, "[drm] drmAddMap failed\n"); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -