#include "r128_dri.h"
#include "r128_context.h"
#include "r128_ioctl.h"
#include "r128_tris.h"
#include "r128_vb.h"
#include "context.h"
#include "imports.h"
#include "utils.h"
#include "vblank.h"
#include "glxextensions.h"
#if 1
#define PCI_CHIP_RAGE128LE 0x4C45
#define PCI_CHIP_RAGE128LF 0x4C46
#define PCI_CHIP_RAGE128PF 0x5046
#define PCI_CHIP_RAGE128PR 0x5052
#define PCI_CHIP_RAGE128RE 0x5245
#define PCI_CHIP_RAGE128RF 0x5246
#define PCI_CHIP_RAGE128RK 0x524B
#define PCI_CHIP_RAGE128RL 0x524C
#endif
static r128ScreenPtr
r128CreateScreen( __DRIscreenPrivate *sPriv )
{
r128ScreenPtr r128Screen;
R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv;
if ( ! driCheckDriDdxDrmVersions( sPriv, "Rage128", 4, 0, 4, 0, 2, 2 ) )
return NULL;
r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) );
if ( !r128Screen ) return NULL;
r128Screen->IsPCI = r128DRIPriv->IsPCI;
r128Screen->sarea_priv_offset = r128DRIPriv->sarea_priv_offset;
if (sPriv->drmMinor >= 3) {
drmR128GetParam gp;
int ret;
gp.param = R128_PARAM_IRQ_NR;
gp.value = &r128Screen->irq;
ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM,
&gp, sizeof(gp));
if (ret) {
fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret);
FREE( r128Screen );
return NULL;
}
}
r128Screen->mmio.handle = r128DRIPriv->registerHandle;
r128Screen->mmio.size = r128DRIPriv->registerSize;
if ( drmMap( sPriv->fd,
r128Screen->mmio.handle,
r128Screen->mmio.size,
(drmAddressPtr)&r128Screen->mmio.map ) ) {
FREE( r128Screen );
return NULL;
}
r128Screen->buffers = drmMapBufs( sPriv->fd );
if ( !r128Screen->buffers ) {
drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
FREE( r128Screen );
return NULL;
}
if ( !r128Screen->IsPCI ) {
r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle;
r128Screen->agpTextures.size = r128DRIPriv->agpTexMapSize;
if ( drmMap( sPriv->fd,
r128Screen->agpTextures.handle,
r128Screen->agpTextures.size,
(drmAddressPtr)&r128Screen->agpTextures.map ) ) {
drmUnmapBufs( r128Screen->buffers );
drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
FREE( r128Screen );
return NULL;
}
}
switch ( r128DRIPriv->deviceID ) {
case PCI_CHIP_RAGE128RE:
case PCI_CHIP_RAGE128RF:
case PCI_CHIP_RAGE128RK:
case PCI_CHIP_RAGE128RL:
r128Screen->chipset = R128_CARD_TYPE_R128;
break;
case PCI_CHIP_RAGE128PF:
r128Screen->chipset = R128_CARD_TYPE_R128_PRO;
break;
case PCI_CHIP_RAGE128LE:
case PCI_CHIP_RAGE128LF:
r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY;
break;
default:
r128Screen->chipset = R128_CARD_TYPE_R128;
break;
}
r128Screen->cpp = r128DRIPriv->bpp / 8;
r128Screen->AGPMode = r128DRIPriv->AGPMode;
r128Screen->frontOffset = r128DRIPriv->frontOffset;
r128Screen->frontPitch = r128DRIPriv->frontPitch;
r128Screen->backOffset = r128DRIPriv->backOffset;
r128Screen->backPitch = r128DRIPriv->backPitch;
r128Screen->depthOffset = r128DRIPriv->depthOffset;
r128Screen->depthPitch = r128DRIPriv->depthPitch;
r128Screen->spanOffset = r128DRIPriv->spanOffset;
r128Screen->texOffset[R128_CARD_HEAP] = r128DRIPriv->textureOffset;
r128Screen->texSize[R128_CARD_HEAP] = r128DRIPriv->textureSize;
r128Screen->logTexGranularity[R128_CARD_HEAP] = r128DRIPriv->log2TexGran;
if ( r128Screen->IsPCI ) {
r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1;
r128Screen->texOffset[R128_AGP_HEAP] = 0;
r128Screen->texSize[R128_AGP_HEAP] = 0;
r128Screen->logTexGranularity[R128_AGP_HEAP] = 0;
} else {
r128Screen->numTexHeaps = R128_NR_TEX_HEAPS;
r128Screen->texOffset[R128_AGP_HEAP] =
r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET;
r128Screen->texSize[R128_AGP_HEAP] = r128DRIPriv->agpTexMapSize;
r128Screen->logTexGranularity[R128_AGP_HEAP] =
r128DRIPriv->log2AGPTexGran;
}
r128Screen->driScreen = sPriv;
if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
(PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
void * const psc = sPriv->psc->screenConfigs;
if ( glx_enable_extension != NULL ) {
if ( r128Screen->irq != 0 ) {
(*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
(*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
(*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
}
(*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
}
}
return r128Screen;
}
static void
r128DestroyScreen( __DRIscreenPrivate *sPriv )
{
r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private;
if ( !r128Screen )
return;
if ( !r128Screen->IsPCI ) {
drmUnmap( (drmAddress)r128Screen->agpTextures.map,
r128Screen->agpTextures.size );
}
drmUnmapBufs( r128Screen->buffers );
drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size );
FREE( r128Screen );
sPriv->private = NULL;
}
static GLboolean
r128OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
{
return GL_TRUE;
}
static GLboolean
r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
if (isPixmap) {
return GL_FALSE;
}
else {
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer( mesaVis,
GL_FALSE,
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
mesaVis->alphaBits > 0 );
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
_mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
}
static void
r128SwapBuffers(__DRIdrawablePrivate *dPriv)
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
r128ContextPtr rmesa;
GLcontext *ctx;
rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = rmesa->glCtx;
if (ctx->Visual.doubleBufferMode) {
_mesa_notifySwapBuffers( ctx );
if ( rmesa->doPageFlip ) {
r128PageFlip( dPriv );
}
else {
r128CopyBuffer( dPriv );
}
}
}
else {
_mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
}
}
static GLboolean
r128InitDriver( __DRIscreenPrivate *sPriv )
{
sPriv->private = (void *) r128CreateScreen( sPriv );
if ( !sPriv->private ) {
r128DestroyScreen( sPriv );
return GL_FALSE;
}
return GL_TRUE;
}
void __driRegisterExtensions( void )
{
PFNGLXENABLEEXTENSIONPROC glx_enable_extension;
if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC)
glXGetProcAddress( (const GLubyte *) "__glXEnableExtension" );
if ( glx_enable_extension != NULL ) {
glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE );
glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE );
glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE );
}
}
}
static struct __DriverAPIRec r128API = {
.InitDriver = r128InitDriver,
.DestroyScreen = r128DestroyScreen,
.CreateContext = r128CreateContext,
.DestroyContext = r128DestroyContext,
.CreateBuffer = r128CreateBuffer,
.DestroyBuffer = r128DestroyBuffer,
.SwapBuffers = r128SwapBuffers,
.MakeCurrent = r128MakeCurrent,
.UnbindContext = r128UnbindContext,
.OpenFullScreen = r128OpenCloseFullScreen,
.CloseFullScreen = r128OpenCloseFullScreen,
.GetSwapInfo = NULL,
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
};
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r128API);
return (void *) psp;
}