Dave Reveman's patch for GLX_MESA_copy_sub_buffer support

This commit is contained in:
Brian Paul 2006-03-31 15:48:04 +00:00
parent df3d4e0bb9
commit f2ad1b60c0
23 changed files with 373 additions and 83 deletions

View file

@ -472,6 +472,14 @@ struct __DRIdrawableRec {
* \since Internal API version 20030317.
*/
unsigned swap_interval;
/**
* Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
*
* \since Internal API version 20060314.
*/
void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
int x, int y, int w, int h);
};
#endif

View file

@ -2570,18 +2570,69 @@ PUBLIC GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
return 0;
}
#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
PUBLIC void glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
int x, int y, int width, int height)
{
(void) dpy;
(void) drawable;
(void) x;
(void) y;
(void) width;
(void) height;
}
xGLXVendorPrivateReq *req;
GLXContext gc;
GLXContextTag tag;
CARD32 *drawable_ptr;
INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
CARD8 opcode;
#ifdef GLX_DIRECT_RENDERING
int screen;
__DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
if ( pdraw != NULL ) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) {
(*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height);
}
return;
}
#endif
opcode = __glXSetupForCommand(dpy);
if (!opcode)
return;
/*
** The calling thread may or may not have a current context. If it
** does, send the context tag so the server can do a flush.
*/
gc = __glXGetCurrentContext();
if ((gc != NULL) && (dpy == gc->currentDpy) &&
((drawable == gc->currentDrawable) ||
(drawable == gc->currentReadable)) ) {
tag = gc->currentContextTag;
} else {
tag = 0;
}
LockDisplay(dpy);
GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4,req);
req->reqType = opcode;
req->glxCode = X_GLXVendorPrivate;
req->vendorCode = X_GLXvop_CopySubBufferMESA;
req->contextTag = tag;
drawable_ptr = (CARD32 *) (req + 1);
x_ptr = (INT32 *) (drawable_ptr + 1);
y_ptr = (INT32 *) (drawable_ptr + 2);
w_ptr = (INT32 *) (drawable_ptr + 3);
h_ptr = (INT32 *) (drawable_ptr + 4);
*drawable_ptr = drawable;
*x_ptr = x;
*y_ptr = y;
*w_ptr = width;
*h_ptr = height;
UnlockDisplay(dpy);
SyncHandle();
}
PUBLIC Bool glXSet3DfxModeMESA( int mode )
{
@ -2973,8 +3024,9 @@ int __glXGetInternalVersion(void)
* months ago. :(
* 20050727 - Gut all the old interfaces. This breaks compatability with
* any DRI driver built to any previous version.
* 20060314 - Added support for GLX_MESA_copy_sub_buffer.
*/
return 20050727;
return 20060314;
}

View file

@ -79,7 +79,7 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(EXT_visual_rating), VER(0,0), Y, Y, N, N },
{ GLX(MESA_agp_offset), VER(0,0), N, N, N, Y }, /* Deprecated */
{ GLX(MESA_allocate_memory), VER(0,0), Y, N, N, Y },
{ GLX(MESA_copy_sub_buffer), VER(0,0), N, N, N, N }, /* Deprecated? */
{ GLX(MESA_copy_sub_buffer), VER(0,0), Y, N, N, N },
{ GLX(MESA_pixmap_colormap), VER(0,0), N, N, N, N }, /* Deprecated */
{ GLX(MESA_release_buffers), VER(0,0), N, N, N, N }, /* Deprecated */
{ GLX(MESA_set_3dfx_mode), VER(0,0), N, N, N, N }, /* Deprecated */

View file

@ -547,6 +547,13 @@ static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
remainder );
}
static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
int x, int y, int w, int h)
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
(void) dpy;
}
/**
* This is called via __DRIscreenRec's createNewDrawable pointer.
@ -623,6 +630,9 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdraw->frameTracking = NULL;
pdraw->queryFrameTracking = driQueryFrameTracking;
if (driCompareGLXAPIVersion (20060314) >= 0)
pdraw->copySubBuffer = driCopySubBuffer;
/* This special default value is replaced with the configured
* default value when the drawable is first bound to a direct
* rendering context.

View file

@ -189,6 +189,8 @@ struct __DriverAPIRec {
int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc,
int64_t divisor, int64_t remainder );
/*@}*/
void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv,
int x, int y, int w, int h);
};

View file

@ -366,7 +366,8 @@ static void intelWaitForFrameCompletion( intelContextPtr intel )
/*
* Copy the back buffer to the front buffer.
*/
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
intelContextPtr intel;
GLboolean missed_target;
@ -385,15 +386,19 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
LOCK_HARDWARE( intel );
intelWaitForFrameCompletion( intel );
UNLOCK_HARDWARE( intel );
driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
LOCK_HARDWARE( intel );
if (!rect)
{
UNLOCK_HARDWARE( intel );
driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
LOCK_HARDWARE( intel );
}
{
const intelScreenPrivate *intelScreen = intel->intelScreen;
const __DRIdrawablePrivate *dPriv = intel->driDrawable;
const int nbox = dPriv->numClipRects;
const drm_clip_rect_t *pbox = dPriv->pClipRects;
drm_clip_rect_t box;
const int cpp = intelScreen->cpp;
const int pitch = intelScreen->front.pitch; /* in bytes */
int i;
@ -429,18 +434,35 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
continue;
}
box = *pbox;
if (rect)
{
if (rect->x1 > box.x1)
box.x1 = rect->x1;
if (rect->y1 > box.y1)
box.y1 = rect->y1;
if (rect->x2 < box.x2)
box.x2 = rect->x2;
if (rect->y2 < box.y2)
box.y2 = rect->y2;
if (box.x1 > box.x2 || box.y1 > box.y2)
continue;
}
BEGIN_BATCH( 8);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
OUT_BATCH( (box.y1 << 16) | box.x1 );
OUT_BATCH( (box.y2 << 16) | box.x2 );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->front.offset );
else
OUT_BATCH( intelScreen->back.offset );
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
OUT_BATCH( (box.y1 << 16) | box.x1 );
OUT_BATCH( BR13 & 0xffff );
if (intel->sarea->pf_current_page == 0)
@ -454,14 +476,17 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
UNLOCK_HARDWARE( intel );
intel->swap_count++;
(*dri_interface->getUST)(&ust);
if (missed_target) {
intel->swap_missed_count++;
intel->swap_missed_ust = ust - intel->swap_ust;
}
if (!rect)
{
intel->swap_count++;
(*dri_interface->getUST)(&ust);
if (missed_target) {
intel->swap_missed_count++;
intel->swap_missed_ust = ust - intel->swap_ust;
}
intel->swap_ust = ust;
intel->swap_ust = ust;
}
}

View file

@ -75,7 +75,8 @@ extern void intelRestartInlinePrimitive( intelContextPtr intel );
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
int primitive, int dwords,
int vertex_size);
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv,
const drm_clip_rect_t *rect);
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch);

View file

@ -722,7 +722,7 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
intelCopyBuffer( dPriv );
intelCopyBuffer( dPriv, NULL );
}
if (screen->current_rotation != 0) {
intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
@ -734,6 +734,29 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
}
}
void intelCopySubBuffer( __DRIdrawablePrivate *dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
intelContextPtr intel;
GLcontext *ctx;
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = &intel->ctx;
if (ctx->Visual.doubleBufferMode) {
intelScreenPrivate *screen = intel->intelScreen;
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
intelCopyBuffer( dPriv, &rect );
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
}
}
void intelInitState( GLcontext *ctx )
{

View file

@ -341,6 +341,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
(*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
(*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
(*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
(*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
}
sPriv->psc->allocateMemory = (void *) intelAllocateMemoryMESA;
@ -534,7 +535,8 @@ static const struct __DriverAPIRec intelAPI = {
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
.SwapBuffersMSC = NULL,
.CopySubBuffer = intelCopySubBuffer
};

View file

@ -106,4 +106,7 @@ intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
extern void
intelSwapBuffers(__DRIdrawablePrivate *dPriv);
extern void
intelCopySubBuffer( __DRIdrawablePrivate *dPriv, int x, int y, int w, int h );
#endif

View file

@ -637,7 +637,7 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv )
r200PageFlip( dPriv );
}
else {
r200CopyBuffer( dPriv );
r200CopyBuffer( dPriv, NULL );
}
}
}
@ -647,6 +647,30 @@ r200SwapBuffers( __DRIdrawablePrivate *dPriv )
}
}
void
r200CopySubBuffer( __DRIdrawablePrivate *dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
r200ContextPtr rmesa;
GLcontext *ctx;
rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = rmesa->glCtx;
if (ctx->Visual.doubleBufferMode) {
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
r200CopyBuffer( dPriv, &rect );
}
}
else {
/* XXX this shouldn't be an error but we can't handle it for now */
_mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__);
}
}
/* Force the context `c' to be the current context and associate with it
* buffer `b'.

View file

@ -1006,6 +1006,8 @@ extern GLboolean r200CreateContext( const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern void r200SwapBuffers( __DRIdrawablePrivate *dPriv );
extern void r200CopySubBuffer( __DRIdrawablePrivate * dPriv,
int x, int y, int w, int h );
extern GLboolean r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv );

View file

@ -420,7 +420,8 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa )
/* Copy the back color buffer to the front color buffer.
*/
void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
r200ContextPtr rmesa;
GLint nbox, i, ret;
@ -446,9 +447,12 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
* request at a time.
*/
r200WaitForFrameCompletion( rmesa );
UNLOCK_HARDWARE( rmesa );
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
LOCK_HARDWARE( rmesa );
if (!rect)
{
UNLOCK_HARDWARE( rmesa );
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
LOCK_HARDWARE( rmesa );
}
nbox = dPriv->numClipRects; /* must be in locked region */
@ -459,8 +463,27 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
GLint n = 0;
for ( ; i < nr ; i++ ) {
*b++ = box[i];
n++;
*b = box[i];
if (rect)
{
if (rect->x1 > b->x1)
b->x1 = rect->x1;
if (rect->y1 > b->y1)
b->y1 = rect->y1;
if (rect->x2 < b->x2)
b->x2 = rect->x2;
if (rect->y2 < b->y2)
b->y2 = rect->y2;
if (b->x1 < b->x2 && b->y1 < b->y2)
b++;
}
else
b++;
n++;
}
rmesa->sarea->nbox = n;
@ -474,18 +497,21 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
}
UNLOCK_HARDWARE( rmesa );
rmesa->hw.all_dirty = GL_TRUE;
if (!rect)
{
rmesa->hw.all_dirty = GL_TRUE;
rmesa->swap_count++;
(*dri_interface->getUST)( & ust );
if ( missed_target ) {
rmesa->swap_missed_count++;
rmesa->swap_missed_ust = ust - rmesa->swap_ust;
rmesa->swap_count++;
(*dri_interface->getUST)( & ust );
if ( missed_target ) {
rmesa->swap_missed_count++;
rmesa->swap_missed_ust = ust - rmesa->swap_ust;
}
rmesa->swap_ust = ust;
sched_yield();
}
rmesa->swap_ust = ust;
sched_yield();
}
void r200PageFlip( const __DRIdrawablePrivate *dPriv )

View file

@ -90,7 +90,8 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa,
struct r200_dma_region *region,
const char *caller );
extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable );
extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable,
const drm_clip_rect_t *rect);
extern void r200PageFlip( const __DRIdrawablePrivate *drawable );
extern void r200Flush( GLcontext *ctx );
extern void r200Finish( GLcontext *ctx );

View file

@ -231,7 +231,7 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
if (radeon->doPageFlip) {
radeonPageFlip(dPriv);
} else {
radeonCopyBuffer(dPriv);
radeonCopyBuffer(dPriv, NULL);
}
}
} else {
@ -241,6 +241,31 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
}
}
void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
radeonContextPtr radeon;
GLcontext *ctx;
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = radeon->glCtx;
if (ctx->Visual.doubleBufferMode) {
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
radeonCopyBuffer(dPriv, &rect);
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
_mesa_problem(NULL, "%s: drawable has no context!",
__FUNCTION__);
}
}
/* Force the context `c' to be the current context and associate with it
* buffer `b'.

View file

@ -203,6 +203,8 @@ struct radeon_context {
#define RADEON_CONTEXT(glctx) ((radeonContextPtr)(ctx->DriverCtx))
extern void radeonSwapBuffers(__DRIdrawablePrivate * dPriv);
extern void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
int x, int y, int w, int h);
extern GLboolean radeonInitContext(radeonContextPtr radeon,
struct dd_function_table* functions,
const __GLcontextModes * glVisual,

View file

@ -164,7 +164,8 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
/* Copy the back color buffer to the front color buffer.
*/
void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
const drm_clip_rect_t * rect)
{
radeonContextPtr radeon;
GLint nbox, i, ret;
@ -193,10 +194,13 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
* request at a time.
*/
radeonWaitForFrameCompletion(radeon);
UNLOCK_HARDWARE(radeon);
driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
&missed_target);
LOCK_HARDWARE(radeon);
if (!rect)
{
UNLOCK_HARDWARE(radeon);
driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
&missed_target);
LOCK_HARDWARE(radeon);
}
nbox = dPriv->numClipRects; /* must be in locked region */
@ -206,9 +210,28 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
drm_clip_rect_t *b = radeon->sarea->boxes;
GLint n = 0;
for (; i < nr; i++) {
*b++ = box[i];
n++;
for ( ; i < nr ; i++ ) {
*b = box[i];
if (rect)
{
if (rect->x1 > b->x1)
b->x1 = rect->x1;
if (rect->y1 > b->y1)
b->y1 = rect->y1;
if (rect->x2 < b->x2)
b->x2 = rect->x2;
if (rect->y2 < b->y2)
b->y2 = rect->y2;
if (b->x1 < b->x2 && b->y1 < b->y2)
b++;
}
else
b++;
n++;
}
radeon->sarea->nbox = n;
@ -223,22 +246,24 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
}
UNLOCK_HARDWARE(radeon);
if (IS_R200_CLASS(radeon->radeonScreen))
if (!rect)
{
if (IS_R200_CLASS(radeon->radeonScreen))
((r200ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
else
else
((r300ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
radeon->swap_count++;
(*dri_interface->getUST) (&ust);
if (missed_target) {
radeon->swap_count++;
(*dri_interface->getUST) (&ust);
if (missed_target) {
radeon->swap_missed_count++;
radeon->swap_missed_ust = ust - radeon->swap_ust;
}
radeon->swap_ust = ust;
sched_yield();
}
radeon->swap_ust = ust;
sched_yield();
}
void radeonPageFlip(const __DRIdrawablePrivate * dPriv)

View file

@ -44,7 +44,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_context.h"
#include "radeon_drm.h"
extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable);
extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable,
const drm_clip_rect_t * rect);
extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
extern void radeonFlush(GLcontext * ctx);
extern void radeonFinish(GLcontext * ctx);

View file

@ -572,7 +572,7 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
radeonPageFlip( dPriv );
}
else {
radeonCopyBuffer( dPriv );
radeonCopyBuffer( dPriv, NULL );
}
}
}
@ -582,6 +582,31 @@ radeonSwapBuffers( __DRIdrawablePrivate *dPriv )
}
}
void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
int x, int y, int w, int h )
{
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
radeonContextPtr radeon;
GLcontext *ctx;
radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
ctx = radeon->glCtx;
if (ctx->Visual.doubleBufferMode) {
drm_clip_rect_t rect;
rect.x1 = x + dPriv->x;
rect.y1 = (dPriv->h - y - h) + dPriv->y;
rect.x2 = rect.x1 + w;
rect.y2 = rect.y1 + h;
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
radeonCopyBuffer(dPriv, &rect);
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
_mesa_problem(NULL, "%s: drawable has no context!",
__FUNCTION__);
}
}
/* Make context `c' the current context and bind it to the given
* drawing and reading surfaces.

View file

@ -850,6 +850,8 @@ extern GLboolean radeonCreateContext(const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern void radeonSwapBuffers( __DRIdrawablePrivate *dPriv );
extern void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
int x, int y, int w, int h);
extern GLboolean radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv );

View file

@ -875,7 +875,8 @@ static void radeonWaitForFrameCompletion( radeonContextPtr rmesa )
/* Copy the back color buffer to the front color buffer.
*/
void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect)
{
radeonContextPtr rmesa;
GLint nbox, i, ret;
@ -899,9 +900,12 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
* request at a time.
*/
radeonWaitForFrameCompletion( rmesa );
UNLOCK_HARDWARE( rmesa );
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
LOCK_HARDWARE( rmesa );
if (!rect)
{
UNLOCK_HARDWARE( rmesa );
driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
LOCK_HARDWARE( rmesa );
}
nbox = dPriv->numClipRects; /* must be in locked region */
@ -912,8 +916,27 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
GLint n = 0;
for ( ; i < nr ; i++ ) {
*b++ = box[i];
n++;
*b = box[i];
if (rect)
{
if (rect->x1 > b->x1)
b->x1 = rect->x1;
if (rect->y1 > b->y1)
b->y1 = rect->y1;
if (rect->x2 < b->x2)
b->x2 = rect->x2;
if (rect->y2 < b->y2)
b->y2 = rect->y2;
if (b->x1 < b->x2 && b->y1 < b->y2)
b++;
}
else
b++;
n++;
}
rmesa->sarea->nbox = n;
@ -927,15 +950,18 @@ void radeonCopyBuffer( const __DRIdrawablePrivate *dPriv )
}
UNLOCK_HARDWARE( rmesa );
rmesa->swap_count++;
(*dri_interface->getUST)( & ust );
if ( missed_target ) {
rmesa->swap_missed_count++;
rmesa->swap_missed_ust = ust - rmesa->swap_ust;
}
if (!rect)
{
rmesa->swap_count++;
(*dri_interface->getUST)( & ust );
if ( missed_target ) {
rmesa->swap_missed_count++;
rmesa->swap_missed_ust = ust - rmesa->swap_ust;
}
rmesa->swap_ust = ust;
rmesa->hw.all_dirty = GL_TRUE;
rmesa->swap_ust = ust;
rmesa->hw.all_dirty = GL_TRUE;
}
}
void radeonPageFlip( const __DRIdrawablePrivate *dPriv )

View file

@ -87,7 +87,8 @@ extern void radeonReleaseDmaRegion( radeonContextPtr rmesa,
struct radeon_dma_region *region,
const char *caller );
extern void radeonCopyBuffer( const __DRIdrawablePrivate *drawable );
extern void radeonCopyBuffer( const __DRIdrawablePrivate *drawable,
const drm_clip_rect_t *rect);
extern void radeonPageFlip( const __DRIdrawablePrivate *drawable );
extern void radeonFlush( GLcontext *ctx );
extern void radeonFinish( GLcontext *ctx );

View file

@ -716,6 +716,8 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
(*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
if (IS_R200_CLASS(screen))
(*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
(*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" );
}
#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
@ -923,7 +925,8 @@ static struct __DriverAPIRec radeonAPI = {
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
.SwapBuffersMSC = NULL,
.CopySubBuffer = radeonCopySubBuffer,
};
#else
static const struct __DriverAPIRec r200API = {
@ -940,7 +943,8 @@ static const struct __DriverAPIRec r200API = {
.GetMSC = driGetMSC32,
.WaitForMSC = driWaitForMSC32,
.WaitForSBC = NULL,
.SwapBuffersMSC = NULL
.SwapBuffersMSC = NULL,
.CopySubBuffer = r200CopySubBuffer
};
#endif