📄 radeon_egl.c
字号:
/* 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 = ((disp->fbSize - pcie_gart_table_size - 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 = disp->virtualWidth; info->backOffset = ((info->depthOffset - bufferSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN); info->backPitch = disp->virtualWidth; if (pcie_gart_table_size) info->pcieGartTableOffset = disp->fbSize - pcie_gart_table_size; fprintf(stderr, "Will use back buffer at offset 0x%x, pitch %d\n", info->backOffset, info->backPitch); fprintf(stderr, "Will use depth buffer at offset 0x%x, pitch %d\n", info->depthOffset, info->depthPitch); fprintf(stderr, "Will use %d kb for textures at offset 0x%x\n", info->textureSize/1024, info->textureOffset); if (pcie_gart_table_size) { fprintf(stderr, "Will use %d kb for PCIE GART Table at offset 0x%x\n", pcie_gart_table_size/1024, info->pcieGartTableOffset); } /* XXX I don't think these are needed. */#if 0 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));#endif if (pcie_gart_table_size) RADEONSetParam(disp, RADEON_SETPARAM_PCIGART_LOCATION, info->pcieGartTableOffset); 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( driDisplay *disp, RADEONInfoPtr info){ int cpp = disp->bpp / 8; drm_radeon_init_t drmInfo; int ret; memset(&drmInfo, 0, sizeof(drmInfo)); if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) drmInfo.func = RADEON_INIT_R300_CP; else 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 */ /* XXX problem here: * The front/back/depth_offset/pitch fields may change depending upon * which drawing surface we're using!!! They can't be set just once * during initialization. * Looks like we'll need a new ioctl to update these fields for drawing * to other surfaces... */ drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); 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 = disp->bpp; drmInfo.depth_bpp = disp->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.ring_offset = info->ringHandle; drmInfo.ring_rptr_offset = info->ringReadPtrHandle; drmInfo.buffers_offset = info->bufHandle; drmInfo.gart_textures_offset = info->gartTexHandle; ret = drmCommandWrite(disp->drmFD, DRM_RADEON_CP_INIT, &drmInfo, sizeof(drm_radeon_init_t)); return ret >= 0;}/** * \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( driDisplay *disp, RADEONInfoPtr info ){ /* Initialize vertex buffers */ info->bufNumBufs = drmAddBufs(disp->drmFD, info->bufMapSize / RADEON_BUFFER_SIZE, RADEON_BUFFER_SIZE, (disp->card_type!=RADEON_CARD_AGP) ? 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 disp 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(driDisplay *disp, RADEONInfoPtr info){ if ((drmCtlInstHandler(disp->drmFD, 0)) != 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");}/** * \brief Initialize the AGP heap. * * \param disp 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(driDisplay *disp, 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(disp->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); }}static int RADEONGetCardType(driDisplay *disp, RADEONInfoPtr info){ drm_radeon_getparam_t gp; int ret; gp.param = RADEON_PARAM_CARD_TYPE; gp.value = &disp->card_type; ret=drmCommandWriteRead(disp->drmFD, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); if (ret) { fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_CARD_TYPE) : %d\n", ret); return -1; } return disp->card_type;}/** * Called at the start of each server generation. * * \param disp 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 intRADEONScreenInit( driDisplay *disp, RADEONInfoPtr info, RADEONDRIPtr pRADEONDRI){ int i, err; /* XXX this probably isn't needed here */ { int width_bytes = (disp->virtualWidth * disp->cpp); int maxy = disp->fbSize / width_bytes; if (maxy <= disp->virtualHeight * 3) { _eglLog(_EGL_WARNING, "Static buffer allocation failed -- " "need at least %d kB video memory (have %d kB)\n", (disp->virtualWidth * disp->virtualHeight * disp->cpp * 3 + 1023) / 1024, disp->fbSize / 1024); return 0; } } /* Memory manager setup */ if (!RADEONMemoryInit(disp, info)) { return 0; } /* Create a 'server' context so we can grab the lock for * initialization ioctls. */ if ((err = drmCreateContext(disp->drmFD, &disp->serverContext)) != 0) { _eglLog(_EGL_WARNING, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); return 0; } DRM_LOCK(disp->drmFD, disp->pSAREA, disp->serverContext, 0); /* Initialize the kernel data structures */ if (!RADEONDRIKernelInit(disp, info)) { _eglLog(_EGL_WARNING, "RADEONDRIKernelInit failed\n"); DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); return 0; } /* Initialize the vertex buffers list */ if (!RADEONDRIBufInit(disp, info)) { fprintf(stderr, "RADEONDRIBufInit failed\n"); DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); return 0; } /* Initialize IRQ */ RADEONDRIIrqInit(disp, info); /* Initialize kernel gart memory manager */ RADEONDRIAgpHeapInit(disp, info); /* Initialize the SAREA private data structure */ { drm_radeon_sarea_t *pSAREAPriv; pSAREAPriv = (drm_radeon_sarea_t *)(((char*)disp->pSAREA) + sizeof(drm_sarea_t)); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); pSAREAPriv->pfState = info->page_flip_enable; } for ( i = 0;; i++ ) { drmMapType type; drmMapFlags flags; drm_handle_t handle, offset; drmSize size; int rc, mtrr; if ( ( rc = drmGetMap( disp->drmFD, i, &offset, &size, &type, &flags, &handle, &mtrr ) ) != 0 ) break; if ( type == DRM_REGISTERS ) { pRADEONDRI->registerHandle = offset; pRADEONDRI->registerSize = size; break; } } /* Quick hack to clear the front & back buffers. Could also use * the clear ioctl to do this, but would need to setup hw state * first. */ drimemsetio((char *)disp->pFB + info->frontOffset, 0xEE, info->frontPitch * disp->cpp * disp->virtualHeight ); drimemsetio((char *)disp->pFB + info->backOffset, 0x30, info->backPitch * disp->cpp * disp->virtualHeight ); /* This is the struct passed to radeon_dri.so for its initialization */ pRADEONDRI->deviceID = info->Chipset; pRADEONDRI->width = disp->virtualWidth; pRADEONDRI->height = disp->virtualHeight; pRADEONDRI->depth = disp->bpp; /* XXX: depth */ pRADEONDRI->bpp = disp->bpp; pRADEONDRI->IsPCI = (disp->card_type != RADEON_CARD_AGP);; pRADEONDRI->frontOffset = info->frontOffset; pRADEONDRI->frontPitch = info->frontPitch; pRADEONDRI->backOffset = info->backOffset; pRADEONDRI->backPitch = info->backPitch; pRADEONDRI->depthOffset = info->depthOffset; pRADEONDRI->depthPitch = info->depthPitch; pRADEONDRI->textureOffset = info->textureOffset; pRADEONDRI->textureSize = info->textureSize; pRADEONDRI->log2TexGran = info->log2TexGran; pRADEONDRI->statusHandle = info->ringReadPtrHandle; pRADEONDRI->statusSize = info->ringReadMapSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -