From 01e9cc858ac646b3140d1d85ea9c069bc708fb28 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 25 Jan 2004 01:30:33 +0000 Subject: - Add glx visuals code based on XFree86's Radeon driver. - Reserve areas for back/depth/span when USING_DRI && GLXEXT. This would be better in a TransitionTo3d, but we'd need to work with the offscreen memory manager for that. - Misc. fixes to ati_dri.c for DRI+GLX. Needs more work still. --- hw/kdrive/ati/ati.c | 82 ++++++++++++++-- hw/kdrive/ati/ati.h | 13 +++ hw/kdrive/ati/ati_dri.c | 200 +++++++++++++++++++++++++++++++++------ hw/kdrive/ati/radeon_composite.c | 13 --- 4 files changed, 260 insertions(+), 48 deletions(-) diff --git a/hw/kdrive/ati/ati.c b/hw/kdrive/ati/ati.c index 97a28f2e4..69d0ef6d5 100644 --- a/hw/kdrive/ati/ati.c +++ b/hw/kdrive/ati/ati.c @@ -28,6 +28,9 @@ #endif #include "ati.h" #include "ati_reg.h" +#if defined(USE_DRI) && defined(GLXEXT) +#include "ati_sarea.h" +#endif #define CAP_R128 0x1 /* If it's a Rage 128 */ #define CAP_R100 0x2 /* If it's an r100 series radeon. */ @@ -270,7 +273,11 @@ ATIScreenInit(KdScreenInfo *screen) { ATIScreenInfo *atis; ATICardInfo(screen); - int success = FALSE; + Bool success = FALSE; + int screen_size = 0; +#if defined(USE_DRI) && defined(GLXEXT) + int l; +#endif atis = xcalloc(sizeof(ATIScreenInfo), 1); if (atis == NULL) @@ -285,8 +292,7 @@ ATIScreenInit(KdScreenInfo *screen) success = fbdevScreenInitialize(screen, &atis->backend_priv.fbdev); screen->memory_size = atic->backend_priv.fbdev.fix.smem_len; - screen->off_screen_base = - atic->backend_priv.fbdev.var.yres_virtual * + screen_size = atic->backend_priv.fbdev.var.yres_virtual * screen->fb[0].byteStride; } #endif @@ -296,6 +302,7 @@ ATIScreenInit(KdScreenInfo *screen) screen->fb[0].depth = 16; success = vesaScreenInitialize(screen, &atis->backend_priv.vesa); + screen_size = screen->off_screen_base; } #endif @@ -305,16 +312,66 @@ ATIScreenInit(KdScreenInfo *screen) return FALSE; } + screen->off_screen_base = screen_size; +#if defined(USE_DRI) && defined(GLXEXT) + /* Reserve a static area for the back buffer the same size as the + * visible screen. XXX: This would be better initialized in ati_dri.c + * when GLX is set up, but I'm not sure when the offscreen memory + * manager gets set up. + */ + atis->frontOffset = 0; + atis->frontPitch = screen->fb[0].byteStride; + + if (screen->off_screen_base + screen_size <= screen->memory_size) { + atis->backOffset = screen->off_screen_base; + atis->backPitch = screen->fb[0].byteStride; + screen->off_screen_base += screen_size; + } + + /* Reserve the depth span for Rage 128 */ + if (!atic->is_radeon && screen->off_screen_base + + screen->fb[0].byteStride <= screen->memory_size) { + atis->spanOffset = screen->off_screen_base; + screen->off_screen_base += screen->fb[0].byteStride; + } + + /* Reserve the static depth buffer, which happens to be the same + * bitsPerPixel as the screen. + */ + if (screen->off_screen_base + screen_size <= screen->memory_size) { + atis->depthOffset = screen->off_screen_base; + atis->depthPitch = screen->fb[0].byteStride; + screen->off_screen_base += screen_size; + } + + /* Reserve approx. half of remaining offscreen memory for local + * textures. Round down to a whole number of texture regions. + */ + atis->textureSize = (screen->memory_size - screen->off_screen_base) / 2; + l = ATILog2(atis->textureSize / ATI_NR_TEX_REGIONS); + if (l < ATI_LOG_TEX_GRANULARITY) + l = ATI_LOG_TEX_GRANULARITY; + atis->textureSize = (atis->textureSize >> l) << l; + if (atis->textureSize >= 512 * 1024) { + atis->textureOffset = screen->off_screen_base; + screen->off_screen_base += atis->textureSize; + } else { + /* Minimum texture size is for 2 256x256x32bpp textures */ + atis->textureSize = 0; + } +#endif /* USE_DRI && GLXEXT */ + /* Reserve a scratch area. It'll be used for storing glyph data during * Composite operations, because glyphs aren't in real pixmaps and thus * can't be migrated. */ atis->scratch_size = 65536; /* big enough for 128x128@32bpp */ - if (screen->off_screen_base + atis->scratch_size > screen->memory_size) - atis->scratch_size = 0; - else { + if (screen->off_screen_base + atis->scratch_size <= screen->memory_size) + { atis->scratch_offset = screen->off_screen_base; screen->off_screen_base += atis->scratch_size; + } else { + atis->scratch_size = 0; } return TRUE; @@ -458,6 +515,19 @@ ATIPutColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) atic->backend_funcs.putColors(pScreen, fb, n, pdefs); } +/* Compute log base 2 of val. */ +int +ATILog2(int val) +{ + int bits; + + if (!val) + return 1; + for (bits = 0; val != 0; val >>= 1, ++bits) + ; + return bits; +} + KdCardFuncs ATIFuncs = { ATICardInit, /* cardinit */ ATIScreenInit, /* scrinit */ diff --git a/hw/kdrive/ati/ati.h b/hw/kdrive/ati/ati.h index ea95abdb4..9270f080b 100644 --- a/hw/kdrive/ati/ati.h +++ b/hw/kdrive/ati/ati.h @@ -39,6 +39,11 @@ #define USE_DRI #include "libdrm.h" #include "dri.h" +#ifdef GLXEXT +#include "GL/glxint.h" +#include "GL/glxtokens.h" +#include "ati_dripriv.h" +#endif #endif #define RADEON_REG_BASE(c) ((c)->attr.address[1]) @@ -224,6 +229,11 @@ typedef struct _ATIScreenInfo { int serverContext; DRIInfoPtr pDRIInfo; +#ifdef GLXEXT + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + ATIConfigPrivPtr pVisualConfigsPriv; +#endif /* GLXEXT */ #endif /* USE_DRI */ } ATIScreenInfo; @@ -262,6 +272,9 @@ void ATIDRICloseScreen(ScreenPtr pScreen); #endif /* USE_DRI */ +int +ATILog2(int val); + extern KdCardFuncs ATIFuncs; #endif /* _ATI_H_ */ diff --git a/hw/kdrive/ati/ati_dri.c b/hw/kdrive/ati/ati_dri.c index a6f92ae37..c6da406fe 100644 --- a/hw/kdrive/ati/ati_dri.c +++ b/hw/kdrive/ati/ati_dri.c @@ -48,19 +48,169 @@ void XFree86DRIExtensionInit(void); -static Bool ATIDRIFinishScreenInit(ScreenPtr pScreen); - -/* Compute log base 2 of val. */ -static int -ATILog2(int val) +/* Initialize the visual configs that are supported by the hardware. + * These are combined with the visual configs that the indirect + * rendering core supports, and the intersection is exported to the + * client. + */ +static Bool ATIInitVisualConfigs(ScreenPtr pScreen) { - int bits; + KdScreenPriv(pScreen); + ATIScreenInfo(pScreenPriv); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = NULL; + ATIConfigPrivPtr pATIConfigs = NULL; + ATIConfigPrivPtr *pATIConfigPtrs = NULL; + int i, accum, stencil, db, use_db; + int depth = pScreenPriv->screen->fb[0].depth; + int bpp = pScreenPriv->screen->fb[0].bitsPerPixel; + + if (depth != 16 && (depth != 24 || bpp != 32)) + ErrorF("DRI GLX unsupported at %d/%d depth/bpp\n", depth, bpp); + + /* Same number of configs for 16 and 24bpp, so I factored this part out. + */ + if (atis->depthOffset != 0) + use_db = 1; + else + use_db = 0; + + numConfigs = 4; + if (use_db) + numConfigs *= 2; + + pConfigs = xcalloc(sizeof(__GLXvisualConfig), numConfigs); + pATIConfigs = xcalloc(sizeof(ATIConfigPrivRec), numConfigs); + pATIConfigPtrs = xcalloc(sizeof(ATIConfigPrivPtr), numConfigs); + if (pConfigs == NULL || pATIConfigs == NULL || pATIConfigPtrs == NULL) { + xfree(pConfigs); + xfree(pATIConfigs); + xfree(pATIConfigPtrs); + return FALSE; + } - if (!val) - return 1; - for (bits = 0; val != 0; val >>= 1, ++bits) - ; - return bits; + i = 0; + if (depth == 16) { + for (db = 0; db <= use_db; db++) { + for (accum = 0; accum <= 1; accum++) { + for (stencil = 0; stencil <= 1; stencil++) { + pATIConfigPtrs[i] = &pATIConfigs[i]; + + pConfigs[i].vid = (VisualID)(-1); + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 6; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x0000F800; + pConfigs[i].greenMask = 0x000007E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0x00000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (db) + pConfigs[i].doubleBuffer = TRUE; + else + pConfigs[i].doubleBuffer = FALSE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 16; + pConfigs[i].depthSize = 16; + if (stencil) + pConfigs[i].stencilSize = 8; + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum) { + pConfigs[i].visualRating = GLX_SLOW_CONFIG; + } else { + pConfigs[i].visualRating = GLX_NONE; + } + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + } else { + for (db = 0; db <= use_db; db++) { + for (accum = 0; accum <= 1; accum++) { + for (stencil = 0; stencil <= 1; stencil++) { + pATIConfigPtrs[i] = &pATIConfigs[i]; + + pConfigs[i].vid = (VisualID)(-1); + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 8; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0xFF000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 16; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + if (db) + pConfigs[i].doubleBuffer = TRUE; + else + pConfigs[i].doubleBuffer = FALSE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 32; + if (stencil) { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + } else { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum) { + pConfigs[i].visualRating = GLX_SLOW_CONFIG; + } else { + pConfigs[i].visualRating = GLX_NONE; + } + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + } + } + + atis->numVisualConfigs = numConfigs; + atis->pVisualConfigs = pConfigs; + atis->pVisualConfigsPriv = pATIConfigs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pATIConfigPtrs); + return TRUE; } static void @@ -225,7 +375,7 @@ ATIDRIAgpInit(ScreenPtr pScreen) R128_BM_PM4_RD_FORCE_TO_PCI | R128_BM_GLOBAL_FORCE_TO_PCI); MMIO_OUT32(mmio, R128_REG_BM_CHUNK_0_VAL, chunk); - + /* Ensure AGP GART is used (for now) */ MMIO_OUT32(mmio, R128_REG_PCI_GART_PAGE, 1); } @@ -307,8 +457,8 @@ R128DRIKernelInit(ScreenPtr pScreen) drmInfo.ring_size = atis->ringSize*1024*1024; drmInfo.usec_timeout = atis->DMAusecTimeout; - drmInfo.fb_bpp = pScreenPriv->screen->fb[0].depth; - drmInfo.depth_bpp = pScreenPriv->screen->fb[0].depth; + drmInfo.fb_bpp = pScreenPriv->screen->fb[0].bitsPerPixel; + drmInfo.depth_bpp = pScreenPriv->screen->fb[0].bitsPerPixel; /* XXX: pitches are in pixels on r128. */ drmInfo.front_offset = atis->frontOffset; @@ -358,8 +508,8 @@ RadeonDRIKernelInit(ScreenPtr pScreen) drmInfo.ring_size = atis->ringSize*1024*1024; drmInfo.usec_timeout = atis->DMAusecTimeout; - drmInfo.fb_bpp = pScreenPriv->screen->fb[0].depth; - drmInfo.depth_bpp = pScreenPriv->screen->fb[0].depth; + drmInfo.fb_bpp = pScreenPriv->screen->fb[0].bitsPerPixel; + drmInfo.depth_bpp = pScreenPriv->screen->fb[0].bitsPerPixel; drmInfo.front_offset = atis->frontOffset; drmInfo.front_pitch = atis->frontPitch; @@ -452,8 +602,7 @@ static void ATIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ - /* XXX: XFree86 sets NeedToSync */ - + KdMarkSync(pScreen); } if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && (newContextType==DRI_2D_CONTEXT)) { @@ -463,6 +612,8 @@ static void ATIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } } +static Bool ATIDRIFinishScreenInit(ScreenPtr pScreen); + /* 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 @@ -497,14 +648,6 @@ ATIDRIScreenInit(ScreenPtr pScreen) atis->gartTexSize = 1; atis->DMAusecTimeout = 10000; - atis->frontOffset = 0; - atis->frontPitch = pScreenPriv->screen->fb[0].byteStride; - atis->backOffset = 0; /* XXX */ - atis->backPitch = pScreenPriv->screen->fb[0].byteStride; - atis->depthOffset = 0; /* XXX */ - atis->depthPitch = 0; /* XXX */ - atis->spanOffset = 0; /* XXX */ - if (atic->drmFd < 0) return FALSE; @@ -549,6 +692,7 @@ ATIDRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverMajorVersion = 4; pDRIInfo->ddxDriverMinorVersion = 0; pDRIInfo->ddxDriverPatchVersion = 0; + /* XXX: RADEON_FB_BASE(pScreenPriv->card); */ pDRIInfo->frameBufferPhysicalAddress = (unsigned long)pScreenPriv->screen->memory_base; pDRIInfo->frameBufferSize = pScreenPriv->screen->memory_size; @@ -634,7 +778,7 @@ ATIDRIScreenInit(ScreenPtr pScreen) } #ifdef GLXEXT - if (!R128InitVisualConfigs(pScreen)) { + if (!ATIInitVisualConfigs(pScreen)) { ATIDRICloseScreen(pScreen); return FALSE; } @@ -824,8 +968,6 @@ ATIDRIFinishScreenInit(ScreenPtr pScreen) } } - XFree86DRIExtensionInit(); - atis->using_dri = TRUE; return TRUE; diff --git a/hw/kdrive/ati/radeon_composite.c b/hw/kdrive/ati/radeon_composite.c index 7dc368dbd..94f43e2a1 100644 --- a/hw/kdrive/ati/radeon_composite.c +++ b/hw/kdrive/ati/radeon_composite.c @@ -79,19 +79,6 @@ static CARD32 RadeonBlendOp[] = { RADEON_SRC_BLEND_GL_ZERO | RADEON_DST_BLEND_GL_ONE, }; -/* Compute log base 2 of val. */ -static int -ATILog2(int val) -{ - int bits; - - if (!val) - return 1; - for (bits = 0; val != 0; val >>= 1, ++bits) - ; - return bits; -} - static Bool RadeonTextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit) { -- cgit v1.2.3