Add vsync swapbuffers. This waits on the irq so gears run in this mode

will have a very low cpu utilization (and also a very low framerate).

Fix up the pageflipping code.  This works now but is totally oblivious
to the X server (ie. it works but it's broken).  Turned off by a #define.
This commit is contained in:
Keith Whitwell 2004-12-21 11:57:03 +00:00
parent 91a04617c4
commit 314f8e4d9d
7 changed files with 215 additions and 50 deletions

View file

@ -62,6 +62,7 @@
#define DRIVER_DATE "20041215"
#include "vblank.h"
#include "utils.h"
viaContextPtr current_mesa;
@ -230,9 +231,14 @@ calculate_buffer_parameters( viaContextPtr vmesa )
vmesa->depth.size);
/*=* John Sheng [2003.5.31] flip *=*/
if( (vmesa->viaScreen->width == vmesa->driDrawable->w)
&& (vmesa->viaScreen->height == vmesa->driDrawable->h) ) {
if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
vmesa->viaScreen->height == vmesa->driDrawable->h ) {
#define ALLOW_EXPERIMENTAL_PAGEFLIP 1
#if ALLOW_EXPERIMENTAL_PAGEFLIP
vmesa->doPageFlip = GL_TRUE;
#else
vmesa->doPageFlip = GL_FALSE;
#endif
vmesa->currentPage = 0;
vmesa->back.pitch = vmesa->front.pitch;
}
@ -368,6 +374,13 @@ FreeBuffer(viaContextPtr vmesa)
via_free_dma_buffer(vmesa);
}
static int
get_ust_nop( int64_t * ust )
{
*ust = 1;
return 0;
}
GLboolean
viaCreateContext(const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
@ -387,6 +400,12 @@ viaCreateContext(const __GLcontextModes *mesaVis,
return GL_FALSE;
}
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
/* Parse configuration files.
*/
driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache,
sPriv->myNum, "via");
current_mesa = vmesa;
/* pick back buffer */
if (mesaVis->doubleBufferMode) {
@ -555,6 +574,24 @@ viaCreateContext(const __GLcontextModes *mesaVis,
}
#endif
/* I don't understand why this isn't working:
*/
vmesa->vblank_flags =
vmesa->viaScreen->irqEnabled ?
driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
/* Hack this up in its place:
*/
vmesa->vblank_flags = getenv("VIA_VSYNC") ? VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ;
vmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
if ( vmesa->get_ust == NULL ) {
vmesa->get_ust = get_ust_nop;
}
(*vmesa->get_ust)( & vmesa->swap_ust );
if (!AllocateDmaBuffer(mesaVis, vmesa)) {
fprintf(stderr ,"AllocateDmaBuffer fail\n");
FREE(vmesa);
@ -894,9 +931,12 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", vmesa->driDrawable->w);
vmesa->driDrawable = driDrawPriv;
if ( ! calculate_buffer_parameters( vmesa ) ) {
return GL_FALSE;
if ( vmesa->driDrawable != driDrawPriv ) {
driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags );
vmesa->driDrawable = driDrawPriv;
if ( ! calculate_buffer_parameters( vmesa ) ) {
return GL_FALSE;
}
}
_mesa_make_current2(vmesa->glCtx,
@ -938,6 +978,7 @@ void viaGetLock(viaContextPtr vmesa, GLuint flags)
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
}
#if 0
void viaLock(viaContextPtr vmesa, GLuint flags)
{
__DRIdrawablePrivate *dPriv = vmesa->driDrawable;
@ -968,6 +1009,7 @@ void viaLock(viaContextPtr vmesa, GLuint flags)
return;
}
#endif
void viaUnLock(viaContextPtr vmesa, GLuint flags)
{

View file

@ -291,6 +291,22 @@ struct via_context_t {
volatile GLuint* regTranSpace;
GLuint* agpBase;
GLuint drawType;
/* Configuration cache
*/
driOptionCache optionCache;
GLuint vblank_flags;
GLuint vbl_seq;
int64_t swap_ust;
int64_t swap_missed_ust;
GLuint swap_count;
GLuint swap_missed_count;
PFNGLXGETUSTPROC get_ust;
};
/*#define DMA_OFFSET 16*/
#define DMA_OFFSET 32

View file

@ -35,6 +35,7 @@ v * copy of this software and associated documentation files (the "Software"),
#include "via_ioctl.h"
#include "via_state.h"
#include "vblank.h"
#include "drm.h"
#include "xf86drm.h"
#include <sys/ioctl.h>
@ -316,6 +317,9 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
drm_clip_rect_t *pbox;
int nbox, i;
GLuint scrn = 0, side = 0;
GLboolean missed_target;
int64_t ust;
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
assert(dPriv);
assert(dPriv->driContextPriv);
@ -324,6 +328,8 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
VIA_FIREVERTICES(vmesa);
driWaitForVBlank( dPriv, & vmesa->vbl_seq, vmesa->vblank_flags, & missed_target );
LOCK_HARDWARE(vmesa);
scrn = vmesa->saam & S_MASK;
@ -400,6 +406,16 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
}
UNLOCK_HARDWARE(vmesa);
vmesa->uploadCliprects = GL_TRUE;
vmesa->swap_count++;
(*vmesa->get_ust)( & ust );
if ( missed_target ) {
vmesa->swap_missed_count++;
vmesa->swap_missed_ust = ust - vmesa->swap_ust;
}
vmesa->swap_ust = ust;
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
}
@ -414,6 +430,8 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
GLuint nBackBase;
viaBuffer buffer_tmp;
GLcontext *ctx;
GLboolean missed_target;
int retcode;
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
assert(dPriv);
@ -426,6 +444,29 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
if(DRAW_FRONT)
return;
VIA_FIREVERTICES(vmesa);
/* Now wait for the vblank:
*/
retcode = driWaitForVBlank( dPriv, &vmesa->vbl_seq,
vmesa->vblank_flags, &missed_target );
if ( missed_target ) {
vmesa->swap_missed_count++;
(void) (*vmesa->get_ust)( &vmesa->swap_missed_ust );
}
if (missed_target)
fprintf(stderr, "missed target\n");
/* else */
/* fprintf(stderr, "retcode %d vbl_seq %d vblank_flags %x missed_target %d\n", */
/* retcode, vmesa->vbl_seq, vmesa->vblank_flags, missed_target); */
LOCK_HARDWARE(vmesa);
/* Page Flip*/
if(GL_FALSE) {
viaFlushPrimsLocked(vmesa);
@ -454,17 +495,17 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
/* Auto Swap */
else {
viaFlushPrimsLocked(vmesa);
vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
if (nFirstSwap) {
vb = viaCheckDma(vmesa, 8 * 4);
if (nFirstFlip) {
*vb++ = HALCYON_HEADER2;
*vb++ = 0x00fe0000;
*vb++ = 0x0000000e;
*vb++ = 0x0000000e;
vmesa->dmaLow += 16;
nFirstSwap = GL_FALSE;
nFirstFlip = GL_FALSE;
}
nBackBase = (vmesa->back.offset << 1);
nBackBase = (vmesa->back.offset );
*vb++ = HALCYON_HEADER2;
*vb++ = 0x00fe0000;
@ -475,6 +516,8 @@ void viaPageFlip(const __DRIdrawablePrivate *dPriv)
viaFlushPrimsLocked(vmesa);
}
UNLOCK_HARDWARE(vmesa);
vmesa->uploadCliprects = GL_TRUE;
memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer));
memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer));

View file

@ -137,7 +137,7 @@ static GLboolean via_run_fastrender(GLcontext *ctx,
viaContextPtr vmesa = VIA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i, length, flags = 0;
GLuint i;
/* Don't handle clipping or indexed vertices.
*/

View file

@ -30,6 +30,7 @@
#include "context.h"
#include "matrix.h"
#include "simple_list.h"
#include "vblank.h"
#include "via_state.h"
#include "via_tex.h"
@ -38,14 +39,34 @@
#include "via_ioctl.h"
#include "via_screen.h"
#include "via_fb.h"
#include "via_dri.h"
#include "GL/internal/dri_interface.h"
/* Radeon configuration
*/
#include "xmlpool.h"
const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_DEBUG
DRI_CONF_NO_RAST(false)
DRI_CONF_SECTION_END
DRI_CONF_END;
static const GLuint __driNConfigOptions = 3;
extern viaContextPtr current_mesa;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
#endif /* USE_NEW_INTERFACE */
static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
static drmBufMapPtr via_create_empty_buffers(void)
{
@ -79,6 +100,11 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
return GL_FALSE;
}
/* parse information in __driConfigOptions */
driParseOptionInfo (&viaScreen->optionCache,
__driConfigOptions, __driNConfigOptions);
viaScreen->driScrnPriv = sPriv;
sPriv->private = (void *)viaScreen;
@ -90,6 +116,9 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
viaScreen->bytesPerPixel = gDRIPriv->bytesPerPixel;
viaScreen->fbOffset = 0;
viaScreen->fbSize = gDRIPriv->fbSize;
viaScreen->irqEnabled = gDRIPriv->irqEnabled;
viaScreen->irqEnabled = 1;
#ifdef USE_XINERAMA
viaScreen->drixinerama = gDRIPriv->drixinerama;
#endif
@ -141,6 +170,33 @@ viaInitDriver(__DRIscreenPrivate *sPriv)
viaScreen->agpLinearStart = 0;
viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
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 ( viaScreen->irqEnabled ) {
(*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" );
if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
(*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
(*glx_enable_extension)( psc, "GLX_OML_swap_method" );
}
}
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
return GL_TRUE;
}
@ -219,47 +275,22 @@ viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
}
#if 0
/* Initialize the fullscreen mode.
*/
GLboolean
XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
vmesa->doPageFlip = 1;
vmesa->currentPage = 0;
return GL_TRUE;
}
/* Shut down the fullscreen mode.
*/
GLboolean
XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
if (vmesa->currentPage == 1) {
viaPageFlip(vmesa);
vmesa->currentPage = 0;
}
vmesa->doPageFlip = GL_FALSE;
vmesa->Setup[VIA_DESTREG_DI0] = vmesa->driScreen->front_offset;
return GL_TRUE;
}
#endif
static struct __DriverAPIRec viaAPI = {
viaInitDriver,
viaDestroyScreen,
viaCreateContext,
viaDestroyContext,
viaCreateBuffer,
viaDestroyBuffer,
viaSwapBuffers,
viaMakeCurrent,
viaUnbindContext
.InitDriver = viaInitDriver,
.DestroyScreen = viaDestroyScreen,
.CreateContext = viaCreateContext,
.DestroyContext = viaDestroyContext,
.CreateBuffer = viaCreateBuffer,
.DestroyBuffer = viaDestroyBuffer,
.SwapBuffers = viaSwapBuffers,
.MakeCurrent = viaMakeCurrent,
.UnbindContext = viaUnbindContext,
.GetSwapInfo = getSwapInfo,
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
};
@ -395,3 +426,30 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
return (void *) psp;
}
#endif /* USE_NEW_INTERFACE */
/**
* Get information about previous buffer swaps.
*/
static int
getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
{
viaContextPtr vmesa;
if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
|| (dPriv->driContextPriv->driverPrivate == NULL)
|| (sInfo == NULL) ) {
return -1;
}
vmesa = (viaContextPtr) dPriv->driContextPriv->driverPrivate;
sInfo->swap_count = vmesa->swap_count;
sInfo->swap_ust = vmesa->swap_ust;
sInfo->swap_missed_count = vmesa->swap_missed_count;
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
? driCalculateSwapUsage( dPriv, 0, vmesa->swap_missed_ust )
: 0.0;
return 0;
}

View file

@ -28,6 +28,7 @@
#include <sys/time.h>
#include "dri_util.h"
#include "via_dri.h"
#include "xmlconfig.h"
typedef struct {
viaRegion regs;
@ -68,6 +69,10 @@ typedef struct {
unsigned int sareaPrivOffset;
/*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
int VQEnable;
int irqEnabled;
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
} viaScreenPrivate;
extern GLboolean

View file

@ -206,6 +206,7 @@ static void viaSetTexImages(viaContextPtr vmesa,
default:
_mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
fprintf(stderr, "-- TexFormat = %d\n",baseImage->TexFormat->MesaFormat);
return;
};
/* Compute which mipmap levels we really want to send to the hardware.