mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
Dave Reveman's patch for GLX_MESA_copy_sub_buffer support
This commit is contained in:
parent
df3d4e0bb9
commit
f2ad1b60c0
23 changed files with 373 additions and 83 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'.
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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'.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue