📄 radeon_egl.c
字号:
/* * 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 intRADEONSetParam(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 intRADEONCheckDRMVersion(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 intRADEONMemoryInit(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -