radeon_dri.c
来自「Mesa is an open-source implementation of」· C语言 代码 · 共 1,338 行 · 第 1/3 页
C
1,338 行
int ret; int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; int s, l; ret = drmScatterGatherAlloc(ctx->drmFD, info->gartSize*1024*1024, &info->gartMemHandle); if (ret < 0) { fprintf(stderr, "[pci] Out of memory (%d)\n", ret); return 0; } fprintf(stderr, "[pci] %d kB allocated with handle 0x%08lx\n", info->gartSize*1024, info->gartMemHandle); info->gartOffset = 0; /* Initialize the CP ring buffer data */ info->ringStart = info->gartOffset; info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; info->ringReadOffset = info->ringStart + info->ringMapSize; info->ringReadMapSize = radeon_drm_page_size; /* Reserve space for vertex/indirect buffers */ info->bufStart = info->ringReadOffset + info->ringReadMapSize; info->bufMapSize = info->bufSize*1024*1024; /* Reserve the rest for AGP textures */ info->gartTexStart = info->bufStart + info->bufMapSize; s = (info->gartSize*1024*1024 - info->gartTexStart); l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; info->gartTexMapSize = (s >> l) << l; info->log2GARTTexGran = l; if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { fprintf(stderr, "[pci] Could not add ring mapping\n"); return 0; } fprintf(stderr, "[pci] ring handle = 0x%08x\n", info->ringHandle); if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { fprintf(stderr, "[pci] Could not add ring read ptr mapping\n"); return 0; } fprintf(stderr, "[pci] ring read ptr handle = 0x%08lx\n", info->ringReadPtrHandle); if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { fprintf(stderr, "[pci] Could not add vertex/indirect buffers mapping\n"); return 0; } fprintf(stderr, "[pci] vertex/indirect buffers handle = 0x%08lx\n", info->bufHandle); if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize, DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) { fprintf(stderr, "[pci] Could not add GART texture map mapping\n"); return 0; } fprintf(stderr, "[pci] GART texture map handle = 0x%08x\n", info->gartTexHandle); return 1;}/** * \brief Initialize the kernel data structures and enable the CP engine. * * \param ctx display handle. * \param info driver private data. * * \return non-zero on success, or zero on failure. * * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing * all the parameters in a drm_radeon_init_t structure. */static int RADEONDRIKernelInit( const DRIDriverContext *ctx, RADEONInfoPtr info){ int cpp = ctx->bpp / 8; drm_radeon_init_t drmInfo; int ret; memset(&drmInfo, 0, sizeof(drm_radeon_init_t)); if ( (info->ChipFamily == CHIP_FAMILY_R200) || (info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_M9) || (info->ChipFamily == CHIP_FAMILY_RV280) ) drmInfo.func = RADEON_INIT_R200_CP; else drmInfo.func = RADEON_INIT_CP; /* This is the struct passed to the kernel module for its initialization */ drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); drmInfo.is_pci = ctx->isPCI; drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE; drmInfo.gart_size = info->gartSize*1024*1024; drmInfo.ring_size = info->ringSize*1024*1024; drmInfo.usec_timeout = 1000; drmInfo.fb_bpp = ctx->bpp; drmInfo.depth_bpp = ctx->bpp; drmInfo.front_offset = info->frontOffset; drmInfo.front_pitch = info->frontPitch * cpp; drmInfo.back_offset = info->backOffset; drmInfo.back_pitch = info->backPitch * cpp; drmInfo.depth_offset = info->depthOffset; drmInfo.depth_pitch = info->depthPitch * cpp; 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.gart_textures_offset = info->gartTexHandle; ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drm_radeon_init_t)); return ret >= 0;}/** * \brief Initialize the AGP heap. * * \param ctx display handle. * \param info driver private data. * * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing * all the parameters in a drm_radeon_mem_init_heap structure. */static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx, RADEONInfoPtr info){ drm_radeon_mem_init_heap_t drmHeap; /* Start up the simple memory manager for gart space */ drmHeap.region = RADEON_MEM_REGION_GART; drmHeap.start = 0; drmHeap.size = info->gartTexMapSize; if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP, &drmHeap, sizeof(drmHeap))) { fprintf(stderr, "[drm] Failed to initialized gart heap manager\n"); } else { fprintf(stderr, "[drm] Initialized kernel gart heap manager, %d\n", info->gartTexMapSize); }}/** * \brief Add a map for the vertex buffers that will be accessed by any * DRI-based clients. * * \param ctx display handle. * \param info driver private data. * * \return one on success, or zero on failure. * * Calls drmAddBufs() with the previously allocated vertex buffers. */static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info ){ /* Initialize vertex buffers */ info->bufNumBufs = drmAddBufs(ctx->drmFD, info->bufMapSize / RADEON_BUFFER_SIZE, RADEON_BUFFER_SIZE, ctx->isPCI ? DRM_SG_BUFFER : DRM_AGP_BUFFER, info->bufStart); if (info->bufNumBufs <= 0) { fprintf(stderr, "[drm] Could not create vertex/indirect buffers list\n"); return 0; } fprintf(stderr, "[drm] Added %d %d byte vertex/indirect buffers\n", info->bufNumBufs, RADEON_BUFFER_SIZE); return 1;}/** * \brief Install an IRQ handler. * * \param ctx display handle. * \param info driver private data. * * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to * IRQ-free operation on failure. */static void RADEONDRIIrqInit(const DRIDriverContext *ctx, RADEONInfoPtr info){ 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; } } if (info->irq) fprintf(stderr, "[drm] dma control initialized, using IRQ %d\n", info->irq);}static int RADEONCheckDRMVersion( const DRIDriverContext *ctx, RADEONInfoPtr info ){ drmVersionPtr version; version = drmGetVersion(ctx->drmFD); if (version) { int req_minor, req_patch; /* Need 1.8.x for proper cleanup-on-client-exit behaviour. */ req_minor = 8; req_patch = 0; if (version->version_major != 1 || version->version_minor < req_minor || (version->version_minor == req_minor && version->version_patchlevel < req_patch)) { /* Incompatible drm version */ fprintf(stderr, "[dri] RADEONDRIScreenInit failed because of a version " "mismatch.\n" "[dri] radeon.o kernel module version is %d.%d.%d " "but version 1.%d.%d or newer is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, version->version_patchlevel, req_minor, req_patch); drmFreeVersion(version); return 0; } info->drmMinor = version->version_minor; drmFreeVersion(version); } return 1;}static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info ){ int width_bytes = ctx->shared.virtualWidth * ctx->cpp; int cpp = ctx->cpp; int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); int l; info->frontOffset = 0; info->frontPitch = ctx->shared.virtualWidth; fprintf(stderr, "Using %d MB AGP aperture\n", info->gartSize); 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->gartTexSize); /* Front, back and depth buffers - everything else texture?? */ info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; if (ctx->colorTiling==1) { info->textureSize = ctx->shared.fbSize - ((ctx->shared.fbSize - info->textureSize + width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes*16); } if (info->textureSize < 0) return 0; l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_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 */ if (ctx->colorTiling==1) { info->textureOffset = ((ctx->shared.fbSize - info->textureSize) / (width_bytes * 16)) * (width_bytes*16); } else { info->textureOffset = ((ctx->shared.fbSize - info->textureSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); } /* Reserve space for the shared depth * buffer. */ info->depthOffset = ((info->textureOffset - depthSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); info->depthPitch = ctx->shared.virtualWidth; info->backOffset = ((info->depthOffset - bufferSize + RADEON_BUFFER_ALIGN) & ~RADEON_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); info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | (info->frontOffset >> 10)); info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | (info->backOffset >> 10)); info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | (info->depthOffset >> 10)); return 1;}static int RADEONColorTilingInit( const DRIDriverContext *ctx, RADEONInfoPtr info ){ int width_bytes = ctx->shared.virtualWidth * ctx->cpp; int bufferSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); /* Setup color tiling */ if (info->drmMinor<14) info->colorTiling=0; if (info->colorTiling) { int colorTilingFlag; drm_radeon_surface_alloc_t front,back; RadeonSetParam(ctx, RADEON_SETPARAM_SWITCH_TILING, info->colorTiling ? 1 : 0); /* Setup the surfaces */ if (info->ChipFamily < CHIP_FAMILY_R200) colorTilingFlag=RADEON_SURF_TILE_COLOR_MACRO; else colorTilingFlag=R200_SURF_TILE_COLOR_MACRO; front.address = info->frontOffset; front.size = bufferSize; front.flags = (width_bytes) | colorTilingFlag; drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &front,sizeof(front)); back.address = info->backOffset; back.size = bufferSize; back.flags = (width_bytes) | colorTilingFlag; drmCommandWrite(ctx->drmFD, DRM_RADEON_SURF_ALLOC, &back,sizeof(back)); } return 1;} /** * Called at the start of each server generation. * * \param ctx display handle. * \param info driver private data. * * \return non-zero on success, or zero on failure. * * Performs static frame buffer allocation. Opens the DRM device and add maps * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more * information. Creates a \e server context to grab the lock for the * initialization ioctls and calls the other initilization functions in this * file. Starts the CP engine via the DRM_RADEON_CP_START command. * * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its * initialization. */static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info ){ RADEONDRIPtr pRADEONDRI; int err; usleep(100); /*assert(!ctx->IsClient);*/ { int width_bytes = (ctx->shared.virtualWidth * ctx->cpp); int maxy = ctx->shared.fbSize / width_bytes; if (maxy <= ctx->shared.virtualHeight * 3) { fprintf(stderr, "Static buffer allocation failed -- " "need at least %d kB video memory (have %d kB)\n", (ctx->shared.virtualWidth * ctx->shared.virtualHeight * ctx->cpp * 3 + 1023) / 1024, ctx->shared.fbSize / 1024);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?