diff options
Diffstat (limited to 'src/mesa/drivers/dri/radeon/server/radeon_egl.c')
-rw-r--r-- | src/mesa/drivers/dri/radeon/server/radeon_egl.c | 1088 |
1 files changed, 0 insertions, 1088 deletions
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_egl.c b/src/mesa/drivers/dri/radeon/server/radeon_egl.c deleted file mode 100644 index c16d66e4ec..0000000000 --- a/src/mesa/drivers/dri/radeon/server/radeon_egl.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * EGL driver for radeon_dri.so - */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "egllog.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egldri.h" - -#include "mtypes.h" -#include "memops.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_dri.h" -#include "radeon.h" - -static size_t radeon_drm_page_size; - -/** - * radeon driver-specific driver class derived from _EGLDriver - */ -typedef struct radeon_driver -{ - _EGLDriver Base; /* base class/object */ - GLuint radeonStuff; -} radeonDriver; - -static int -RADEONSetParam(driDisplay *disp, int param, int value) -{ - drm_radeon_setparam_t sp; - int ret; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if ((ret=drmCommandWrite(disp->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp)))) { - fprintf(stderr,"Set param failed\n", ret); - return -1; - } - - return 0; -} - -static int -RADEONCheckDRMVersion(driDisplay *disp, RADEONInfoPtr info) -{ - drmVersionPtr version; - - version = drmGetVersion(disp->drmFD); - if (version) { - int req_minor, req_patch; - - /* Need 1.21.x for card type detection getparam - */ - req_minor = 21; - 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; -} - - -/** - * \brief Compute base 2 logarithm. - * - * \param val value. - * - * \return base 2 logarithm of \p val. - */ -static int RADEONMinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - - -/* Initialize the PCI GART state. Request memory for use in PCI space, - * and initialize the Radeon registers to point to that memory. - */ -static int RADEONDRIPciInit(driDisplay *disp, RADEONInfoPtr info) -{ - int ret; - int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; - int s, l; - - ret = drmScatterGatherAlloc(disp->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%04lx\n", - info->gartSize*1024, (long) 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(disp->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%08lx\n", info->ringHandle); - - if (drmAddMap(disp->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(disp->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(disp->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%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * \brief Initialize the AGP state - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Acquires and enables the AGP device. Reserves memory in the AGP space for - * the ring buffer, vertex buffers and textures. Initialize the Radeon - * registers to point to that memory and add client mappings. - */ -static int RADEONDRIAgpInit( driDisplay *disp, RADEONInfoPtr info) -{ - int mode, ret; - int s, l; - int agpmode = 1; - - if (drmAgpAcquire(disp->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - mode = drmAgpGetMode(disp->drmFD); /* Default mode */ - /* Disable fast write entirely - too many lockups. - */ - mode &= ~RADEON_AGP_MODE_MASK; - switch (agpmode) { - case 4: mode |= RADEON_AGP_4X_MODE; - case 2: mode |= RADEON_AGP_2X_MODE; - case 1: default: mode |= RADEON_AGP_1X_MODE; - } - - if (drmAgpEnable(disp->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(disp->drmFD); - return 0; - } - -#if 0 - /* Workaround for some hardware bugs */ - if (info->ChipFamily < CHIP_FAMILY_R200) - OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); -#endif - info->gartOffset = 0; - - if ((ret = drmAgpAlloc(disp->drmFD, info->gartSize*1024*1024, 0, NULL, - &info->gartMemHandle)) < 0) { - fprintf(stderr, "[gart] Out of memory (%d)\n", ret); - drmAgpRelease(disp->drmFD); - return 0; - } - fprintf(stderr, - "[gart] %d kB allocated with handle 0x%08x\n", - info->gartSize*1024, (unsigned)info->gartMemHandle); - - if (drmAgpBind(disp->drmFD, - info->gartMemHandle, info->gartOffset) < 0) { - fprintf(stderr, "[gart] Could not bind\n"); - drmAgpFree(disp->drmFD, info->gartMemHandle); - drmAgpRelease(disp->drmFD); - return 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(disp->drmFD, info->ringStart, info->ringMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) { - fprintf(stderr, "[gart] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, "[gart] ring handle = 0x%08lx\n", info->ringHandle); - - - if (drmAddMap(disp->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[gart] Could not add ring read ptr mapping\n"); - return 0; - } - - fprintf(stderr, - "[gart] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(disp->drmFD, info->bufStart, info->bufMapSize, - DRM_AGP, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[gart] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(disp->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_AGP, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[gart] Could not add AGP texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] AGP texture map handle = 0x%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * Initialize all the memory-related fields of the RADEONInfo object. - * This includes the various 'offset' and 'size' fields. - */ -static int -RADEONMemoryInit(driDisplay *disp, RADEONInfoPtr info) -{ - int width_bytes = disp->virtualWidth * disp->cpp; - int cpp = disp->cpp; - int bufferSize = ((disp->virtualHeight * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int depthSize = ((((disp->virtualHeight+15) & ~15) * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int l; - int pcie_gart_table_size = 0; - - info->frontOffset = 0; - info->frontPitch = disp->virtualWidth; - - if (disp->card_type==RADEON_CARD_PCIE) - pcie_gart_table_size = RADEON_PCIGART_TABLE_SIZE; - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = disp->fbSize - pcie_gart_table_size - 2 * bufferSize - depthSize; - - 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 */ - 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 int -RADEONScreenInit( 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; - pRADEONDRI->gartTexHandle = info->gartTexHandle; - pRADEONDRI->gartTexMapSize = info->gartTexMapSize; - pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran; - pRADEONDRI->gartTexOffset = info->gartTexStart; - pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t); - - /* Don't release the lock now - let the VT switch handler do it. */ - - return 1; -} - - -/** - * \brief Get Radeon chip family from chipset number. - * - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily - * according to the value of RADEONInfoRec::Chipset. Fails if the - * chipset is unrecognized or not appropriate for this driver (i.e., not - * an r100 style radeon) - */ -static int get_chipfamily_from_chipset( RADEONInfoPtr info ) -{ - switch (info->Chipset) { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: - info->ChipFamily = CHIP_FAMILY_M6; - break; - - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: - info->ChipFamily = CHIP_FAMILY_VE; - break; - - case PCI_CHIP_R200_QL: - case PCI_CHIP_R200_QN: - case PCI_CHIP_R200_QO: - case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: - info->ChipFamily = CHIP_FAMILY_R200; - break; - - case PCI_CHIP_RV200_QW: /* RV200 desktop */ - case PCI_CHIP_RV200_QX: - info->ChipFamily = CHIP_FAMILY_RV200; - break; - - case PCI_CHIP_RADEON_LW: - case PCI_CHIP_RADEON_LX: - info->ChipFamily = CHIP_FAMILY_M7; - break; - - case PCI_CHIP_RV250_Id: - case PCI_CHIP_RV250_Ie: - case PCI_CHIP_RV250_If: - case PCI_CHIP_RV250_Ig: - info->ChipFamily = CHIP_FAMILY_RV250; - break; - - case PCI_CHIP_RV250_Ld: - case PCI_CHIP_RV250_Le: - case PCI_CHIP_RV250_Lf: - case PCI_CHIP_RV250_Lg: - info->ChipFamily = CHIP_FAMILY_M9; - break; - - case PCI_CHIP_RV280_Y_: - case PCI_CHIP_RV280_Ya: - case PCI_CHIP_RV280_Yb: - case PCI_CHIP_RV280_Yc: - info->ChipFamily = CHIP_FAMILY_RV280; - break; - - case PCI_CHIP_R300_ND: - case PCI_CHIP_R300_NE: - case PCI_CHIP_R300_NF: - case PCI_CHIP_R300_NG: - info->ChipFamily = CHIP_FAMILY_R300; - break; - - case PCI_CHIP_RV370_5460: - info->ChipFamily = CHIP_FAMILY_RV380; - break; - - default: - /* Original Radeon/7200 */ - info->ChipFamily = CHIP_FAMILY_RADEON; - } - - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param disp display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p disp - * and then calls RADEONScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int radeonInitFBDev( driDisplay *disp, RADEONDRIPtr pRADEONDRI ) -{ - int err; - RADEONInfoPtr info = calloc(1, sizeof(*info)); - - disp->driverPrivate = (void *)info; - - info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE; - info->gartSize = RADEON_DEFAULT_AGP_SIZE; - info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; - info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; - info->ringSize = RADEON_DEFAULT_RING_SIZE; - info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP; - - 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); - fprintf(stderr, - "page flipping %sabled\n", info->page_flip_enable?"en":"dis"); - - info->Chipset = disp->chipset; - - if (!get_chipfamily_from_chipset( info )) { - fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n"); - fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n"); - return 0; - } -#if 0 - if (info->ChipFamily >= CHIP_FAMILY_R300) { - fprintf(stderr, - "Direct rendering not yet supported on " - "Radeon 9700 and newer cards\n"); - return 0; - } -#endif - -#if 00 - /* don't seem to need this here */ - info->frontPitch = disp->virtualWidth; -#endif - - /* Check the radeon DRM version */ - if (!RADEONCheckDRMVersion(disp, info)) { - return 0; - } - - if (RADEONGetCardType(disp, info)<0) - return 0; - - if (disp->card_type!=RADEON_CARD_AGP) { - /* Initialize PCI */ - if (!RADEONDRIPciInit(disp, info)) - return 0; - } - else { - /* Initialize AGP */ - if (!RADEONDRIAgpInit(disp, info)) - return 0; - } - - if (!RADEONScreenInit( disp, info, pRADEONDRI)) - return 0; - - /* Initialize and start the CP if required */ - if ((err = drmCommandNone(disp->drmFD, DRM_RADEON_CP_START)) != 0) { - fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err); - return 0; - } - - return 1; -} - - -/** - * Create list of all supported surface configs, attach list to the display. - */ -static EGLBoolean -radeonFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, - unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - _EGLConfig *configs; - _EGLConfig *c; - unsigned int i, num_configs; - unsigned int depth_buffer_factor; - unsigned int back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy - * enough to add support. Basically, if a context is created with an - * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping - * will never be used. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ - }; - - uint8_t depth_bits_array[2]; - uint8_t stencil_bits_array[2]; - - depth_bits_array[0] = depth_bits; - depth_bits_array[1] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; - back_buffer_factor = (have_back_buffer) ? 2 : 1; - - num_configs = depth_buffer_factor * back_buffer_factor * 2; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_RGBA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = calloc(sizeof(*configs), num_configs); - c = configs; - if (!_eglFillInConfigs(c, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return EGL_FALSE; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (i = 0, c = configs; i < num_configs; i++, c++) { - int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); - if ((stencil != 0) && (stencil != stencil_bits)) { - SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); - } - } - - for (i = 0, c = configs; i < num_configs; i++, c++) - _eglAddConfig(disp, c); - - free(configs); - - return EGL_TRUE; -} - - -/** - * Show the given surface on the named screen. - * If surface is EGL_NO_SURFACE, disable the screen's output. - */ -static EGLBoolean -radeonShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - EGLBoolean b = _eglDRIShowScreenSurfaceMESA(drv, dpy, screen, surface, m); - return b; -} - - -/** - * Called via eglInitialize() by user. - */ -static EGLBoolean -radeonInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - __DRIframebuffer framebuffer; - driDisplay *display; - - /* one-time init */ - radeon_drm_page_size = getpagesize(); - - if (!_eglDRIInitialize(drv, dpy, major, minor)) - return EGL_FALSE; - - display = Lookup_driDisplay(dpy); - - framebuffer.dev_priv_size = sizeof(RADEONDRIRec); - framebuffer.dev_priv = malloc(sizeof(RADEONDRIRec)); - - /* XXX we shouldn't hard-code values here! */ - /* we won't know the screen surface size until the user calls - * eglCreateScreenSurfaceMESA(). - */ -#if 0 - display->virtualWidth = 1024; - display->virtualHeight = 768; -#else - display->virtualWidth = 1280; - display->virtualHeight = 1024; -#endif - display->bpp = 32; - display->cpp = 4; - - if (!_eglDRIGetDisplayInfo(display)) - return EGL_FALSE; - - framebuffer.base = display->pFB; - framebuffer.width = display->virtualWidth; - framebuffer.height = display->virtualHeight; - framebuffer.stride = display->virtualWidth; - framebuffer.size = display->fbSize; - radeonInitFBDev( display, framebuffer.dev_priv ); - - if (!_eglDRICreateDisplay(display, &framebuffer)) - return EGL_FALSE; - - if (!_eglDRICreateScreens(display)) - return EGL_FALSE; - - /* create a variety of both 32 and 16-bit configurations */ - radeonFillInConfigs(&display->Base, 32, 24, 8, GL_TRUE); - radeonFillInConfigs(&display->Base, 16, 16, 0, GL_TRUE); - - drv->Initialized = EGL_TRUE; - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new radeonDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy) -{ - radeonDriver *radeon; - - radeon = (radeonDriver *) calloc(1, sizeof(*radeon)); - if (!radeon) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglDRIInitDriverFallbacks(&radeon->Base); - - /* then plug in our radeon-specific functions */ - radeon->Base.API.Initialize = radeonInitialize; - radeon->Base.API.ShowScreenSurfaceMESA = radeonShowScreenSurfaceMESA; - - return &radeon->Base; -} |