Commit 01e9cc85 authored by Eric Anholt's avatar Eric Anholt

- 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.
parent f2bedd17
......@@ -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 */
......
......@@ -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_ */
......@@ -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;
......
......@@ -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)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment