{
radeon->vtbl.get_lock = r200_get_lock;
radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset;
- radeon->vtbl.update_draw_buffer = r200UpdateDrawBuffer;
radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
radeon->vtbl.swtcl_flush = r200_swtcl_flush;
+ radeon->vtbl.fallback = r200Fallback;
}
GLint ret;
if ( R200_DEBUG & DEBUG_IOCTL ) {
- fprintf( stderr, "r200Clear\n");
+ fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
}
{
* values, or keep the originals hanging around.
*/
r200UpdateWindow( ctx );
+
+ radeon_viewport(ctx, x, y, width, height);
}
static void r200DepthRange( GLcontext *ctx, GLclampd nearval,
rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop];
}
-
-static void r200DrawBuffer( GLcontext *ctx, GLenum mode )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (R200_DEBUG & DEBUG_DRI)
- fprintf(stderr, "%s %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
- radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */
-
- if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
- /* 0 (GL_NONE) buffers or multiple color drawing buffers */
- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE );
- return;
- }
-
- switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
- case BUFFER_FRONT_LEFT:
- case BUFFER_BACK_LEFT:
- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE );
- break;
- default:
- FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE );
- return;
- }
-
- radeonSetCliprects( &rmesa->radeon );
- radeonUpdatePageFlipping(&rmesa->radeon);
-
- /* We'll set the drawing engine's offset/pitch parameters later
- * when we update other state.
- */
-}
-
-
-static void r200ReadBuffer( GLcontext *ctx, GLenum mode )
-{
- /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
-}
-
/* =============================================================
* State enable/disable
*/
}
}
-
-
-/**
- * Tell the card where to render (offset, pitch).
- * Effected by glDrawBuffer, etc
- */
-void
-r200UpdateDrawBuffer(GLcontext *ctx)
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- struct radeon_renderbuffer *rrb;
-
- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
- /* draw to front */
- rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
- } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
- /* draw to back */
- rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
- } else {
- /* drawing to multiple buffers, or none */
- return;
- }
-
- assert(rrb);
- assert(rrb->pitch);
-
- R200_STATECHANGE( rmesa, ctx );
-
-#if 0
- /* Note: we used the (possibly) page-flipped values */
- rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET]
- = ((rrb->flippedOffset + rmesa->radeon.radeonScreen->fbLocation)
- & R200_COLOROFFSET_MASK);
- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;
- if (rmesa->radeon.sarea->tiling_enabled) {
- rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
- }
-#endif
-}
-
static GLboolean r200ValidateBuffers(GLcontext *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint new_state = rmesa->radeon.NewGLState;
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
- r200UpdateDrawBuffer(ctx);
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+
+ R200_STATECHANGE(rmesa, ctx);
}
if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) {
functions->UpdateState = r200InvalidateState;
functions->LightingSpaceChange = r200LightingSpaceChange;
- functions->DrawBuffer = r200DrawBuffer;
- functions->ReadBuffer = r200ReadBuffer;
+ functions->DrawBuffer = radeonDrawBuffer;
+ functions->ReadBuffer = radeonReadBuffer;
functions->AlphaFunc = r200AlphaFunc;
functions->BlendColor = r200BlendColor;
static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
{
- r300ContextPtr r300 = (r300ContextPtr)radeon;
- BATCH_LOCALS(radeon);
-
- r300->vap_flush_needed = GL_TRUE;
+ r300ContextPtr r300 = (r300ContextPtr)radeon;
+ BATCH_LOCALS(radeon);
+
+ r300->vap_flush_needed = GL_TRUE;
+
+ cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH);
+ END_BATCH();
+ end_3d(radeon);
+}
- cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
- BEGIN_BATCH_NO_AUTOSTATE(2);
- OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH);
- END_BATCH();
- end_3d(radeon);
+static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ if (mode)
+ r300->radeon.Fallback |= bit;
+ else
+ r300->radeon.Fallback &= ~bit;
}
static void r300_init_vtbl(radeonContextPtr radeon)
{
- radeon->vtbl.get_lock = r300_get_lock;
- radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset;
- radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer;
- radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header;
- radeon->vtbl.swtcl_flush = r300_swtcl_flush;
- radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
+ radeon->vtbl.get_lock = r300_get_lock;
+ radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset;
+ radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header;
+ radeon->vtbl.swtcl_flush = r300_swtcl_flush;
+ radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
+ radeon->vtbl.fallback = r300_fallback;
}
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
- GLframebuffer *fb = dPriv->driverPrivate;
+ struct radeon_framebuffer *rfb = dPriv->driverPrivate;
struct radeon_renderbuffer *rrb;
struct radeon_renderbuffer *rrbd;
int flags = 0;
rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
if (flags || bits)
r300EmitClearState(ctx);
- rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (flags & BUFFER_BIT_FRONT_LEFT) {
- rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
bits = 0;
}
if (flags & BUFFER_BIT_BACK_LEFT) {
- rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
bits = 0;
}
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
const unsigned back = ctx->Stencil._BackFace;
-
+
+ FALLBACK_IF(r300->radeon.Fallback);
/* Do we need to use new-style shaders?
* Also is there a better way to do this? */
if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
GLsizei width, GLsizei height)
{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- __DRIcontext *driContext = rmesa->radeon.dri.context;
/* Don't pipeline viewport changes, conflict with window offset
* setting below. Could apply deltas to rescue pipelined viewport
* values, or keep the originals hanging around.
*/
- if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) {
- radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
- if (driContext->driDrawablePriv != driContext->driReadablePriv) {
- radeon_update_renderbuffers(driContext,
- driContext->driReadablePriv);
- }
- }
r300UpdateWindow(ctx);
+
+ radeon_viewport(ctx, x, y, width, height);
}
static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
radeonUpdateScissor(ctx);
}
-/**
- * Tell the card where to render (offset, pitch).
- * Effected by glDrawBuffer, etc
- */
-void r300UpdateDrawBuffer(GLcontext * ctx)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- struct radeon_renderbuffer *rrb;
-
- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
- /* draw to front */
- rrb =
- (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
- } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
- /* draw to back */
- rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
- } else {
- /* drawing to multiple buffers, or none */
- return;
- }
-
- assert(rrb);
- assert(rrb->pitch);
-
- R300_STATECHANGE(rmesa, cb);
-}
-
static void
r300FetchStateParameter(GLcontext * ctx,
const gl_state_index state[STATE_LENGTH],
_ae_invalidate_state(ctx, new_state);
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
- r300UpdateDrawBuffer(ctx);
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+
+ R300_STATECHANGE(r300, cb);
}
r300UpdateStateParameters(ctx, new_state);
}
}
-static void r300DrawBuffer( GLcontext *ctx, GLenum mode )
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- if (RADEON_DEBUG & DEBUG_DRI)
- fprintf(stderr, "%s %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
- radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */
-
- radeonSetCliprects( &rmesa->radeon );
- if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled)
- radeonUpdatePageFlipping(&rmesa->radeon);
-}
-
-static void r300ReadBuffer( GLcontext *ctx, GLenum mode )
-{
- if (RADEON_DEBUG & DEBUG_DRI)
- fprintf(stderr, "%s %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
-};
-
/**
* Initialize driver's state callback functions
*/
functions->ClipPlane = r300ClipPlane;
functions->Scissor = radeonScissor;
- functions->DrawBuffer = r300DrawBuffer;
- functions->ReadBuffer = r300ReadBuffer;
+ functions->DrawBuffer = radeonDrawBuffer;
+ functions->ReadBuffer = radeonReadBuffer;
}
radeon_texture_image *rImage;
radeonContextPtr radeon;
r300ContextPtr rmesa;
- GLframebuffer *fb;
+ struct radeon_framebuffer *rfb;
radeonTexObjPtr t;
uint32_t pitch_val;
radeon = pDRICtx->driverPrivate;
rmesa = pDRICtx->driverPrivate;
- fb = dPriv->driverPrivate;
+ rfb = dPriv->driverPrivate;
texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
radeon_update_renderbuffers(pDRICtx, dPriv);
/* back & depth buffer are useless free them right away */
- rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rb = (void*)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
if (rb->bo == NULL) {
/* Failed to BO for the buffer */
return;
#include "main/light.h"
#include "main/framebuffer.h"
#include "main/simple_list.h"
-
+#include "main/renderbuffer.h"
#include "swrast/swrast.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
}
}
+static void radeon_get_cliprects(radeonContextPtr radeon,
+ struct drm_clip_rect **cliprects,
+ unsigned int *num_cliprects,
+ int *x_off, int *y_off)
+{
+ __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+ struct radeon_framebuffer *rfb = dPriv->driverPrivate;
+
+ if (radeon->constant_cliprect) {
+ radeon->fboRect.x1 = 0;
+ radeon->fboRect.y1 = 0;
+ radeon->fboRect.x2 = radeon->glCtx->DrawBuffer->Width;
+ radeon->fboRect.y2 = radeon->glCtx->DrawBuffer->Height;
+
+ *cliprects = &radeon->fboRect;
+ *num_cliprects = 1;
+ *x_off = 0;
+ *y_off = 0;
+ } else if (radeon->front_cliprects ||
+ rfb->pf_active || dPriv->numBackClipRects == 0) {
+ *cliprects = dPriv->pClipRects;
+ *num_cliprects = dPriv->numClipRects;
+ *x_off = dPriv->x;
+ *y_off = dPriv->y;
+ } else {
+ *num_cliprects = dPriv->numBackClipRects;
+ *cliprects = dPriv->pBackClipRects;
+ *x_off = dPriv->backX;
+ *y_off = dPriv->backY;
+ }
+}
+
/**
* Update cliprects and scissors.
*/
{
__DRIdrawablePrivate *const drawable = radeon->dri.drawable;
__DRIdrawablePrivate *const readable = radeon->dri.readable;
- GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate;
- GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate;
+ struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate;
+ struct radeon_framebuffer *const read_rfb = readable->driverPrivate;
+ int x_off, y_off;
- if (!radeon->radeonScreen->driScreen->dri2.enabled) {
- if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
- /* Can't ignore 2d windows if we are page flipping. */
- if (drawable->numBackClipRects == 0 || radeon->doPageFlip ||
- radeon->sarea->pfCurrentPage == 1) {
- radeon->numClipRects = drawable->numClipRects;
- radeon->pClipRects = drawable->pClipRects;
- } else {
- radeon->numClipRects = drawable->numBackClipRects;
- radeon->pClipRects = drawable->pBackClipRects;
- }
- } else {
- /* front buffer (or none, or multiple buffers */
- radeon->numClipRects = drawable->numClipRects;
- radeon->pClipRects = drawable->pClipRects;
- }
- }
+ fprintf(stderr,"cliprects %d %d\n", radeon->front_cliprects, radeon->constant_cliprect);
+ radeon_get_cliprects(radeon, &radeon->pClipRects,
+ &radeon->numClipRects, &x_off, &y_off);
- if ((draw_fb->Width != drawable->w) ||
- (draw_fb->Height != drawable->h)) {
- _mesa_resize_framebuffer(radeon->glCtx, draw_fb,
+ if ((draw_rfb->base.Width != drawable->w) ||
+ (draw_rfb->base.Height != drawable->h)) {
+ _mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base,
drawable->w, drawable->h);
- draw_fb->Initialized = GL_TRUE;
+ draw_rfb->base.Initialized = GL_TRUE;
}
if (drawable != readable) {
- if ((read_fb->Width != readable->w) ||
- (read_fb->Height != readable->h)) {
- _mesa_resize_framebuffer(radeon->glCtx, read_fb,
+ if ((read_rfb->base.Width != readable->w) ||
+ (read_rfb->base.Height != readable->h)) {
+ _mesa_resize_framebuffer(radeon->glCtx, &read_rfb->base,
readable->w, readable->h);
- read_fb->Initialized = GL_TRUE;
+ read_rfb->base.Initialized = GL_TRUE;
}
}
if (radeon->state.scissor.enabled)
radeonRecalcScissorRects(radeon);
- radeon->lastStamp = drawable->lastStamp;
}
+
+
void radeonUpdateScissor( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
UNLOCK_HARDWARE(radeon);
}
+static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb)
+{
+ int current_page = rfb->pf_current_page;
+ int next_page = (current_page + 1) % rfb->pf_num_pages;
+ struct gl_renderbuffer *tmp_rb;
+
+ /* Exchange renderbuffers if necessary but make sure their
+ * reference counts are preserved.
+ */
+ if (rfb->color_rb[current_page] &&
+ rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer !=
+ &rfb->color_rb[current_page]->base) {
+ tmp_rb = NULL;
+ _mesa_reference_renderbuffer(&tmp_rb,
+ rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ tmp_rb = &rfb->color_rb[current_page]->base;
+ _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb);
+ _mesa_reference_renderbuffer(&tmp_rb, NULL);
+ }
+
+ if (rfb->color_rb[next_page] &&
+ rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer !=
+ &rfb->color_rb[next_page]->base) {
+ tmp_rb = NULL;
+ _mesa_reference_renderbuffer(&tmp_rb,
+ rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+ tmp_rb = &rfb->color_rb[next_page]->base;
+ _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb);
+ _mesa_reference_renderbuffer(&tmp_rb, NULL);
+ }
+}
/* Copy the back color buffer to the front color buffer.
*/
const drm_clip_rect_t *rect)
{
radeonContextPtr rmesa;
+ struct radeon_framebuffer *rfb;
GLint nbox, i, ret;
- GLboolean missed_target;
- int64_t ust;
- __DRIscreenPrivate *psp;
assert(dPriv);
assert(dPriv->driContextPriv);
rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+ rfb = dPriv->driverPrivate;
+
if ( RADEON_DEBUG & DEBUG_IOCTL ) {
fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
}
- radeon_firevertices(rmesa);
- LOCK_HARDWARE( rmesa );
-
- /* Throttle the frame rate -- only allow one pending swap buffers
- * request at a time.
- */
- radeonWaitForFrameCompletion( rmesa );
- if (!rect)
- {
- UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & missed_target );
- LOCK_HARDWARE( rmesa );
- }
-
nbox = dPriv->numClipRects; /* must be in locked region */
for ( i = 0 ; i < nbox ; ) {
}
UNLOCK_HARDWARE( rmesa );
- if (!rect)
- {
- psp = dPriv->driScreenPriv;
- rmesa->swap_count++;
- (*psp->systemTime->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;
+static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target)
+{
+ radeonContextPtr rmesa;
+
+ rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+ radeon_firevertices(rmesa);
+ LOCK_HARDWARE( rmesa );
+
+ if (!dPriv->numClipRects) {
+ UNLOCK_HARDWARE(rmesa);
+ usleep(10000); /* throttle invisible client 10ms */
+ return 0;
}
+
+ radeonWaitForFrameCompletion(rmesa);
+
+ UNLOCK_HARDWARE(rmesa);
+ driWaitForVBlank(dPriv, missed_target);
+ LOCK_HARDWARE(rmesa);
+
+ return 0;
}
-void radeonPageFlip( __DRIdrawablePrivate *dPriv )
+static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv )
{
- radeonContextPtr rmesa;
+ radeonContextPtr radeon;
GLint ret;
- GLboolean missed_target;
__DRIscreenPrivate *psp;
struct radeon_renderbuffer *rrb;
- GLframebuffer *fb = dPriv->driverPrivate;
-
+ struct radeon_framebuffer *rfb;
+
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
- rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
- rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
+ rfb = dPriv->driverPrivate;
+ rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
psp = dPriv->driScreenPriv;
if ( RADEON_DEBUG & DEBUG_IOCTL ) {
- fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
- rmesa->sarea->pfCurrentPage);
+ fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__,
+ radeon->sarea->pfCurrentPage, radeon->sarea->pfState);
}
-
- radeon_firevertices(rmesa);
-
- LOCK_HARDWARE( rmesa );
-
- if (!dPriv->numClipRects) {
- UNLOCK_HARDWARE(rmesa);
- usleep(10000); /* throttle invisible client 10ms */
- return;
- }
-
drm_clip_rect_t *box = dPriv->pClipRects;
- drm_clip_rect_t *b = rmesa->sarea->boxes;
+ drm_clip_rect_t *b = radeon->sarea->boxes;
b[0] = box[0];
- rmesa->sarea->nbox = 1;
-
- /* Throttle the frame rate -- only allow a few pending swap buffers
- * request at a time.
- */
- radeonWaitForFrameCompletion( rmesa );
- UNLOCK_HARDWARE( rmesa );
- driWaitForVBlank( dPriv, & missed_target );
- if ( missed_target ) {
- rmesa->swap_missed_count++;
- (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust );
- }
- LOCK_HARDWARE( rmesa );
+ radeon->sarea->nbox = 1;
- ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );
+ ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP );
- UNLOCK_HARDWARE( rmesa );
+ UNLOCK_HARDWARE( radeon );
if ( ret ) {
fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
- exit( 1 );
+ return GL_FALSE;
}
- rmesa->swap_count++;
- (void) (*psp->systemTime->getUST)( & rmesa->swap_ust );
-
- /* Get ready for drawing next frame. Update the renderbuffers'
- * flippedOffset/Pitch fields so we draw into the right place.
- */
- // driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
- // rmesa->sarea->pfCurrentPage);
-
- rmesa->state.color.rrb = rrb;
+ if (!rfb->pf_active)
+ return GL_FALSE;
+
+ rfb->pf_current_page = radeon->sarea->pfCurrentPage;
+ radeon_flip_renderbuffers(rfb);
+ radeon_draw_buffer(radeon->glCtx, &rfb->base);
- if (rmesa->vtbl.update_draw_buffer)
- rmesa->vtbl.update_draw_buffer(rmesa->glCtx);
+ return GL_TRUE;
}
*/
void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
{
+ int64_t ust;
+ __DRIscreenPrivate *psp;
+
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
radeonContextPtr radeon;
GLcontext *ctx;
ctx = radeon->glCtx;
if (ctx->Visual.doubleBufferMode) {
+ GLboolean missed_target;
+ struct radeon_framebuffer *rfb = dPriv->driverPrivate;
_mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */
- if (radeon->doPageFlip) {
+
+ radeonScheduleSwap(dPriv, &missed_target);
+
+ if (rfb->pf_active) {
radeonPageFlip(dPriv);
} else {
radeonCopyBuffer(dPriv, NULL);
}
+
+ psp = dPriv->driScreenPriv;
+
+ rfb->swap_count++;
+ (*psp->systemTime->getUST)( & ust );
+ if ( missed_target ) {
+ rfb->swap_missed_count++;
+ rfb->swap_missed_ust = ust - rfb->swap_ust;
+ }
+
+ rfb->swap_ust = ust;
+ radeon->hw.all_dirty = GL_TRUE;
}
} else {
/* XXX this shouldn't be an error but we can't handle it for now */
}
}
+void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL,
+ *rrbColor = NULL;
+
+
+ if (!fb) {
+ /* this can happen during the initial context initialization */
+ return;
+ }
+
+ /* radeons only handle 1 color draw so far */
+ if (fb->_NumColorDrawBuffers != 1) {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
+ return;
+ }
+
+ /* Do this here, note core Mesa, since this function is called from
+ * many places within the driver.
+ */
+ if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
+ /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+ }
+
+ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ /* this may occur when we're called by glBindFrameBuffer() during
+ * the process of someone setting up renderbuffers, etc.
+ */
+ /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
+ return;
+ }
+
+ if (fb->Name)
+ ;/* do something depthy/stencily TODO */
+
+
+ /* none */
+ if (fb->Name == 0) {
+ if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
+ rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ radeon->front_cliprects = GL_TRUE;
+ } else {
+ rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ radeon->front_cliprects = GL_FALSE;
+ }
+ } else {
+ /* user FBO in theory */
+ struct radeon_renderbuffer *rrb;
+ rrb = (void *)fb->_ColorDrawBuffers[0];
+ rrbColor = rrb;
+ radeon->constant_cliprect = GL_TRUE;
+ }
+
+ if (rrbColor == NULL)
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE);
+ else
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE);
+
+
+
+ if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
+ rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
+ if (rrbDepth && rrbDepth->bo) {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
+ } else {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE);
+ }
+ } else {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
+ rrbDepth = NULL;
+ }
+
+ /* TODO stencil things */
+ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
+ rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
+ if (rrbStencil && rrbStencil->bo) {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
+ /* need to re-compute stencil hw state */
+ if (ctx->Driver.Enable != NULL)
+ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
+ else
+ ctx->NewState |= _NEW_STENCIL;
+ if (!rrbDepth)
+ rrbDepth = rrbStencil;
+ } else {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE);
+ }
+ } else {
+ radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
+ if (ctx->Driver.Enable != NULL)
+ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
+ else
+ ctx->NewState |= _NEW_STENCIL;
+ }
+
+ /* Update culling direction which changes depending on the
+ * orientation of the buffer:
+ */
+ if (ctx->Driver.FrontFace)
+ ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
+ else
+ ctx->NewState |= _NEW_POLYGON;
+
+ /*
+ * Update depth test state
+ */
+ if (ctx->Driver.Enable) {
+ if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
+ ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+ } else {
+ ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
+ }
+ } else {
+ ctx->NewState |= _NEW_DEPTH;
+ }
+
+ radeon->state.depth.rrb = rrbDepth;
+
+ radeon->state.color.rrb = rrbColor;
+
+ /* update viewport since it depends on window size */
+ if (ctx->Driver.Viewport) {
+ ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
+ ctx->Viewport.Width, ctx->Viewport.Height);
+ } else {
+ ctx->NewState |= _NEW_VIEWPORT;
+ }
+
+ /* Set state we know depends on drawable parameters:
+ */
+ if (ctx->Driver.Scissor)
+ ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
+ ctx->Scissor.Width, ctx->Scissor.Height);
+ radeon->NewGLState |= _NEW_SCISSOR;
+}
+
+/**
+ * Called via glDrawBuffer.
+ */
+void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+ if (RADEON_DEBUG & DEBUG_DRI)
+ fprintf(stderr, "%s %s\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr( mode ));
+
+ radeon_firevertices(radeon); /* don't pipeline cliprect changes */
+
+ radeon_draw_buffer(ctx, ctx->DrawBuffer);
+}
+
+void radeonReadBuffer( GLcontext *ctx, GLenum mode )
+{
+ /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
+ if (ctx->ReadBuffer == ctx->DrawBuffer) {
+ /* This will update FBO completeness status.
+ * A framebuffer will be incomplete if the GL_READ_BUFFER setting
+ * refers to a missing renderbuffer. Calling glReadBuffer can set
+ * that straight and can make the drawing buffer complete.
+ */
+ radeon_draw_buffer(ctx, ctx->DrawBuffer);
+ }
+}
+
+/* Turn on/off page flipping according to the flags in the sarea:
+ */
+void radeonUpdatePageFlipping(radeonContextPtr radeon)
+{
+ struct radeon_framebuffer *rfb = radeon->dri.drawable->driverPrivate;
+
+ rfb->pf_active = radeon->sarea->pfState;
+ rfb->pf_current_page = radeon->sarea->pfCurrentPage;
+ rfb->pf_num_pages = 2;
+ radeon_flip_renderbuffers(rfb);
+ radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer);
+}
+
+void radeon_window_moved(radeonContextPtr radeon)
+{
+ GLcontext *ctx = radeon->glCtx;
+ __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+ struct radeon_framebuffer *rfb = dPriv->driverPrivate;
+
+ if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ radeonUpdatePageFlipping(radeon);
+ }
+ radeonSetCliprects(radeon);
+}
+
+void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ __DRIcontext *driContext = radeon->dri.context;
+ void (*old_viewport)(GLcontext *ctx, GLint x, GLint y,
+ GLsizei w, GLsizei h);
+
+ if (!driContext->driScreenPriv->dri2.enabled)
+ return;
+
+ radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
+ if (driContext->driDrawablePriv != driContext->driReadablePriv)
+ radeon_update_renderbuffers(driContext, driContext->driReadablePriv);
+
+ old_viewport = ctx->Driver.Viewport;
+ ctx->Driver.Viewport = NULL;
+ radeon->dri.drawable = driContext->driDrawablePriv;
+ radeon_window_moved(radeon);
+ radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer);
+ ctx->Driver.Viewport = old_viewport;
+
+
+}
static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state )
{
int i;
extern uint32_t radeonGetAge(radeonContextPtr radeon);
void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *rect);
-void radeonPageFlip( __DRIdrawablePrivate *dPriv );
void radeonSwapBuffers(__DRIdrawablePrivate * dPriv);
void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
int x, int y, int w, int h );
void radeonFinish(GLcontext * ctx);
void radeonEmitState(radeonContextPtr radeon);
+void radeon_window_moved(radeonContextPtr radeon);
+void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb);
+void radeonDrawBuffer( GLcontext *ctx, GLenum mode );
+void radeonReadBuffer( GLcontext *ctx, GLenum mode );
+void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height);
+
static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa)
{
struct radeon_renderbuffer *rrb;
static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa)
{
struct radeon_renderbuffer *rrb;
- GLframebuffer *fb = rmesa->dri.drawable->driverPrivate;
+ struct radeon_framebuffer *rfb = rmesa->dri.drawable->driverPrivate;
rrb = rmesa->state.color.rrb;
if (rmesa->radeonScreen->driScreen->dri2.enabled) {
- rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rrb = (struct radeon_renderbuffer *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
}
if (!rrb)
return NULL;
#include "radeon_common.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
#include "utils.h"
-#include "drirenderbuffer.h"
#include "vblank.h"
#include "main/state.h"
radeon->do_usleeps ? "usleeps" : "busy waits",
fthrottle_mode, radeon->radeonScreen->irq);
- (*sPriv->systemTime->getUST) (&radeon->swap_ust);
-
return GL_TRUE;
}
FILE *track;
#endif
struct radeon_renderbuffer *rb;
- GLframebuffer *fb;
+ struct radeon_framebuffer *rfb;
/* free the Mesa context */
_mesa_destroy_context(radeon->glCtx);
- fb = (void*)radeon->dri.drawable->driverPrivate;
- rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rfb = (void*)radeon->dri.drawable->driverPrivate;
+ rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- fb = (void*)radeon->dri.readable->driverPrivate;
- rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rfb = (void*)radeon->dri.readable->driverPrivate;
+ rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
static void
radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
- GLframebuffer *draw)
+ struct radeon_framebuffer *draw)
{
/* if radeon->fake */
struct radeon_renderbuffer *rb;
- if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->frontOffset,
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->backOffset,
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset,
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset,
static void
radeon_make_renderbuffer_current(radeonContextPtr radeon,
- GLframebuffer *draw)
+ struct radeon_framebuffer *draw)
{
int size = 4096*4096*4;
/* if radeon->fake */
}
- if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->frontOffset +
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->backOffset +
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset +
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
}
- if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
if (!rb->bo) {
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset +
__DRIscreen *screen;
struct radeon_renderbuffer *rb;
int i, count;
- GLframebuffer *draw;
+ struct radeon_framebuffer *draw;
radeonContextPtr radeon;
if (RADEON_DEBUG & DEBUG_DRI)
screen = context->driScreenPriv;
radeon = (radeonContextPtr) context->driverPrivate;
i = 0;
- if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
}
- if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
}
- if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) {
+ if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
attachments[i++] = __DRI_BUFFER_DEPTH;
}
for (i = 0; i < count; i++) {
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
- rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
if (rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
break;
case __DRI_BUFFER_BACK_LEFT:
- rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
buffers[i].flags);
break;
case __DRI_BUFFER_DEPTH:
- rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
__DRIdrawablePrivate * driReadPriv)
{
radeonContextPtr radeon;
- GLframebuffer *dfb, *rfb;
+ struct radeon_framebuffer *drfb;
+ struct gl_framebuffer *readfb;
if (!driContextPriv) {
if (RADEON_DEBUG & DEBUG_DRI)
_mesa_make_current(NULL, NULL, NULL);
return GL_TRUE;
}
+
radeon = (radeonContextPtr) driContextPriv->driverPrivate;
- dfb = driDrawPriv->driverPrivate;
- rfb = driReadPriv->driverPrivate;
+ drfb = driDrawPriv->driverPrivate;
+ readfb = driReadPriv->driverPrivate;
if (driContextPriv->driScreenPriv->dri2.enabled) {
radeon_update_renderbuffers(driContextPriv, driDrawPriv);
if (driDrawPriv != driReadPriv)
radeon_update_renderbuffers(driContextPriv, driReadPriv);
radeon->state.color.rrb =
- (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ (void *)drfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
radeon->state.depth.rrb =
- (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ (void *)drfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
} else {
- radeon_make_renderbuffer_current(radeon, dfb);
+ radeon_make_renderbuffer_current(radeon, drfb);
}
if (RADEON_DEBUG & DEBUG_DRI)
- fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb);
+ fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
if (driReadPriv != driDrawPriv)
driUpdateFramebufferSize(radeon->glCtx, driReadPriv);
+ _mesa_make_current(radeon->glCtx, &drfb->base, readfb);
-
- _mesa_make_current(radeon->glCtx, dfb, rfb);
-
- if (radeon->dri.drawable != driDrawPriv) {
- if (driDrawPriv->swap_interval == (unsigned)-1) {
- driDrawPriv->vblFlags =
- (radeon->radeonScreen->irq != 0)
- ? driGetDefaultVBlankFlags(&radeon->
- optionCache)
- : VBLANK_FLAG_NO_IRQ;
-
- driDrawableInitVBlank(driDrawPriv);
- }
- }
+ _mesa_update_state(radeon->glCtx);
- radeon->dri.readable = driReadPriv;
+ if (radeon->glCtx->DrawBuffer == &drfb->base) {
- if (radeon->dri.drawable != driDrawPriv ||
- radeon->lastStamp != driDrawPriv->lastStamp) {
- radeon->dri.drawable = driDrawPriv;
+ if (radeon->dri.readable != driReadPriv)
+ radeon->dri.readable = driReadPriv;
- radeonSetCliprects(radeon);
- radeon->vtbl.update_viewport_offset(radeon->glCtx);
+ if (radeon->dri.drawable != driDrawPriv) {
+ if (driDrawPriv->swap_interval == (unsigned)-1) {
+ int i;
+ driDrawPriv->vblFlags =
+ (radeon->radeonScreen->irq != 0)
+ ? driGetDefaultVBlankFlags(&radeon->
+ optionCache)
+ : VBLANK_FLAG_NO_IRQ;
+
+ driDrawableInitVBlank(driDrawPriv);
+ drfb->vbl_waited = driDrawPriv->vblSeq;
+
+ for (i = 0; i < 2; i++) {
+ if (drfb->color_rb[i])
+ drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
+ }
+
+ }
+ radeon->dri.drawable = driDrawPriv;
+
+// radeonWindowMoved(radeon);
+ }
+ radeon_draw_buffer(radeon->glCtx, &drfb->base);
}
- _mesa_update_state(radeon->glCtx);
-
- if (!driContextPriv->driScreenPriv->dri2.enabled) {
- radeonUpdatePageFlipping(radeon);
- }
if (RADEON_DEBUG & DEBUG_DRI)
fprintf(stderr, "End %s\n", __FUNCTION__);
#define RADEON_FALLBACK_BLEND_FUNC 0x0020
#define RADEON_FALLBACK_DISABLE 0x0040
#define RADEON_FALLBACK_BORDER_MODE 0x0080
+#define RADEON_FALLBACK_DEPTH_BUFFER 0x0100
+#define RADEON_FALLBACK_STENCIL_BUFFER 0x0200
#define R200_FALLBACK_TEXTURE 0x01
#define R200_FALLBACK_DRAW_BUFFER 0x02
/* boo Xorg 6.8.2 compat */
int has_surface;
+ GLuint pf_pending; /**< sequence number of pending flip */
+ GLuint vbl_pending; /**< vblank sequence number of pending flip */
__DRIdrawablePrivate *dPriv;
};
+struct radeon_framebuffer
+{
+ struct gl_framebuffer base;
+
+ struct radeon_renderbuffer *color_rb[2];
+
+ GLuint vbl_waited;
+
+ /* buffer swap */
+ int64_t swap_ust;
+ int64_t swap_missed_ust;
+
+ GLuint swap_count;
+ GLuint swap_missed_count;
+
+ /* Drawable page flipping state */
+ GLboolean pf_active;
+ GLint pf_current_page;
+ GLint pf_num_pages;
+
+};
+
+
struct radeon_colorbuffer_state {
GLuint clear;
int roundEnable;
GLuint NewGLState;
DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */
- /* Page flipping */
- GLuint doPageFlip;
-
/* Drawable, cliprect and scissor information */
GLuint numClipRects; /* Cliprects for the draw buffer */
drm_clip_rect_t *pClipRects;
GLuint irqsEmitted;
drm_radeon_irq_wait_t iw;
- /* buffer swap */
- int64_t swap_ust;
- int64_t swap_missed_ust;
-
- GLuint swap_count;
- GLuint swap_missed_count;
-
/* Derived state - for r300 only */
struct radeon_state state;
driOptionCache optionCache;
struct radeon_cmdbuf cmdbuf;
+
+ drm_clip_rect_t fboRect;
+ GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
+ GLboolean front_cliprects;
struct {
void (*get_lock)(radeonContextPtr radeon);
void (*update_viewport_offset)(GLcontext *ctx);
- void (*update_draw_buffer)(GLcontext *ctx);
void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa);
void (*swtcl_flush)(GLcontext *ctx, uint32_t offset);
void (*pre_emit_atoms)(radeonContextPtr rmesa);
void (*pre_emit_state)(radeonContextPtr rmesa);
+ void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode);
} vtbl;
};
{
radeon->vtbl.get_lock = r100_get_lock;
radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset;
- radeon->vtbl.update_draw_buffer = radeonUpdateDrawBuffer;
radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header;
radeon->vtbl.swtcl_flush = r100_swtcl_flush;
radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state;
+ radeon->vtbl.fallback = radeonFallback;
}
/* Create the device specific context.
rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
- (*sPriv->systemTime->getUST)( & rmesa->radeon.swap_ust );
-
#if DO_DEBUG
RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ),
#include "radeon_lock.h"
#include "drirenderbuffer.h"
-#if DEBUG_LOCKING
-char *prevLockFile = NULL;
-int prevLockLine = 0;
-#endif
-
-/* Turn on/off page flipping according to the flags in the sarea:
- */
-void radeonUpdatePageFlipping(radeonContextPtr rmesa)
-{
- int use_back;
- __DRIdrawablePrivate *const drawable = rmesa->dri.drawable;
- GLframebuffer *fb = drawable->driverPrivate;
-
- rmesa->doPageFlip = rmesa->sarea->pfState;
- if (rmesa->glCtx->WinSysDrawBuffer) {
- rmesa->vtbl.update_draw_buffer(rmesa->glCtx);
- }
-
- use_back = rmesa->glCtx->DrawBuffer ?
- (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] ==
- BUFFER_BACK_LEFT) : 1;
- use_back ^= (rmesa->sarea->pfCurrentPage == 1);
-
- if (use_back)
- rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
- else
- rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-
- rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
-}
-
/* Update the hardware state. This is called if another context has
* grabbed the hardware lock, which includes the X server. This
* function also updates the driver's window state after the X server
}
if (rmesa->lastStamp != drawable->lastStamp) {
- radeonUpdatePageFlipping(rmesa);
- radeonSetCliprects(rmesa);
- rmesa->vtbl.update_viewport_offset(rmesa->glCtx);
- driUpdateFramebufferSize(rmesa->glCtx, drawable);
+ radeon_window_moved(rmesa);
+ rmesa->lastStamp = drawable->lastStamp;
}
rmesa->vtbl.get_lock(rmesa);
rmesa->lost_context = GL_TRUE;
}
+
+static INLINE struct radeon_renderbuffer *
+radeon_get_renderbuffer(struct gl_framebuffer *fb, int attIndex)
+{
+ if (attIndex >= 0)
+ return (struct radeon_renderbuffer *)fb->Attachment[attIndex].Renderbuffer;
+ else
+ return NULL;
+}
+
+void radeon_lock_hardware(radeonContextPtr radeon)
+{
+ __DRIdrawable *dPriv = radeon->dri.drawable;
+ char ret = 0;
+ struct radeon_framebuffer *rfb = NULL;
+ struct radeon_renderbuffer *rrb = NULL;
+
+ if (radeon->dri.drawable) {
+ rfb = radeon->dri.drawable->driverPrivate;
+
+ if (rfb)
+ rrb = radeon_get_renderbuffer(&rfb->base,
+ rfb->base._ColorDrawBufferIndexes[0]);
+ }
+
+ if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext,
+ (DRM_LOCK_HELD | radeon->dri.hwContext), ret );
+ if (ret)
+ radeonGetLock(radeon, 0);
+ }
+}
+
+void radeon_unlock_hardware(radeonContextPtr radeon)
+{
+ if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ DRM_UNLOCK( radeon->dri.fd,
+ radeon->dri.hwLock,
+ radeon->dri.hwContext );
+ }
+}
extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags);
-/* Turn DEBUG_LOCKING on to find locking conflicts.
- */
-#define DEBUG_LOCKING 0
-
-#if DEBUG_LOCKING
-extern char *prevLockFile;
-extern int prevLockLine;
-
-#define DEBUG_LOCK() \
- do { \
- prevLockFile = (__FILE__); \
- prevLockLine = (__LINE__); \
- } while (0)
-
-#define DEBUG_RESET() \
- do { \
- prevLockFile = 0; \
- prevLockLine = 0; \
- } while (0)
-
-#define DEBUG_CHECK_LOCK() \
- do { \
- if ( prevLockFile ) { \
- fprintf( stderr, \
- "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \
- prevLockFile, prevLockLine, __FILE__, __LINE__ ); \
- exit( 1 ); \
- } \
- } while (0)
-
-#else
-
-#define DEBUG_LOCK()
-#define DEBUG_RESET()
-#define DEBUG_CHECK_LOCK()
-
-#endif
-
-/*
- * !!! We may want to separate locks from locks with validation. This
- * could be used to improve performance for those things commands that
- * do not do any drawing !!!
- */
+void radeon_lock_hardware(radeonContextPtr rmesa);
+void radeon_unlock_hardware(radeonContextPtr rmesa);
/* Lock the hardware and validate our state.
*/
-#define LOCK_HARDWARE( rmesa ) \
- do { \
- char __ret = 0; \
- DEBUG_CHECK_LOCK(); \
- if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \
- DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \
- (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \
- if ( __ret ) \
- radeonGetLock( (rmesa), 0 ); \
- } \
- DEBUG_LOCK(); \
- } while (0)
-
-#define UNLOCK_HARDWARE( rmesa ) \
- do { \
- if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \
- DRM_UNLOCK( (rmesa)->dri.fd, \
- (rmesa)->dri.hwLock, \
- (rmesa)->dri.hwContext ); \
- DEBUG_RESET(); \
- } \
- } while (0)
+#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa)
+#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa)
#endif
const __GLcontextModes *mesaVis,
GLboolean isPixmap )
{
- radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
+ radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
const GLboolean swDepth = GL_FALSE;
const GLboolean swAlpha = GL_FALSE;
mesaVis->depthBits != 24;
GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
GLenum depthFormat = GL_NONE;
- struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
+ struct radeon_framebuffer *rfb;
+
+ if (isPixmap)
+ return GL_FALSE; /* not implemented */
+
+ rfb = CALLOC_STRUCT(radeon_framebuffer);
+ if (!rfb)
+ return GL_FALSE;
+
+ _mesa_initialize_framebuffer(&rfb->base, mesaVis);
if (mesaVis->depthBits == 16)
depthFormat = GL_DEPTH_COMPONENT16;
depthFormat = GL_DEPTH_COMPONENT24;
/* front color renderbuffer */
- {
- struct radeon_renderbuffer *front =
- radeon_create_renderbuffer(rgbFormat, driDrawPriv);
- _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base);
- front->has_surface = 1;
- }
+ rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+ _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
+ rfb->color_rb[0]->has_surface = 1;
/* back color renderbuffer */
if (mesaVis->doubleBufferMode) {
- struct radeon_renderbuffer *back =
- radeon_create_renderbuffer(rgbFormat, driDrawPriv);
- _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base);
- back->has_surface = 1;
+ rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
+ _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
+ rfb->color_rb[1]->has_surface = 1;
}
/* depth renderbuffer */
if (depthFormat != GL_NONE) {
struct radeon_renderbuffer *depth =
radeon_create_renderbuffer(depthFormat, driDrawPriv);
- _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base);
+ _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
depth->has_surface = screen->depthHasSurface;
}
if (mesaVis->stencilBits > 0 && !swStencil) {
struct radeon_renderbuffer *stencil =
radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv);
- _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base);
+ _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base);
stencil->has_surface = screen->depthHasSurface;
}
- _mesa_add_soft_renderbuffers(fb,
+ _mesa_add_soft_renderbuffers(&rfb->base,
GL_FALSE, /* color */
swDepth,
swStencil,
swAccum,
swAlpha,
GL_FALSE /* aux */);
- driDrawPriv->driverPrivate = (void *) fb;
+ driDrawPriv->driverPrivate = (void *) rfb;
return (driDrawPriv->driverPrivate != NULL);
}
static void
radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
- struct radeon_renderbuffer *rb;
- GLframebuffer *fb;
+ struct radeon_renderbuffer *rb;
+ struct radeon_framebuffer *rfb;
- fb = (void*)driDrawPriv->driverPrivate;
- rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ rfb = (void*)driDrawPriv->driverPrivate;
+ rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
}
- rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
if (rb && rb->bo) {
radeon_bo_unref(rb->bo);
rb->bo = NULL;
static int
getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
{
- radeonContextPtr rmesa;
+ struct radeon_framebuffer *rfb;
- if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
- || (dPriv->driContextPriv->driverPrivate == NULL)
- || (sInfo == NULL) ) {
- return -1;
+ if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
+ || (dPriv->driContextPriv->driverPrivate == NULL)
+ || (sInfo == NULL) ) {
+ return -1;
}
- rmesa = dPriv->driContextPriv->driverPrivate;
- sInfo->swap_count = rmesa->swap_count;
- sInfo->swap_ust = rmesa->swap_ust;
- sInfo->swap_missed_count = rmesa->swap_missed_count;
+ rfb = dPriv->driverPrivate;
+ sInfo->swap_count = rfb->swap_count;
+ sInfo->swap_ust = rfb->swap_ust;
+ sInfo->swap_missed_count = rfb->swap_missed_count;
sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
- ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
+ ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust )
: 0.0;
return 0;
* values, or keep the originals hanging around.
*/
radeonUpdateWindow( ctx );
+
+ radeon_viewport(ctx, x, y, width, height);
}
static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
}
-
-/**
- * Called via glDrawBuffer.
- */
-static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
-{
- r100ContextPtr rmesa = R100_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_DRI)
- fprintf(stderr, "%s %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr( mode ));
-
- radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */
-
- if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
- /* 0 (GL_NONE) buffers or multiple color drawing buffers */
- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
- return;
- }
-
- switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
- case BUFFER_FRONT_LEFT:
- case BUFFER_BACK_LEFT:
- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
- break;
- default:
- FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
- return;
- }
-
- radeonSetCliprects( &rmesa->radeon );
- if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled)
- radeonUpdatePageFlipping(&rmesa->radeon);
- /* We'll set the drawing engine's offset/pitch parameters later
- * when we update other state.
- */
-}
-
-static void radeonReadBuffer( GLcontext *ctx, GLenum mode )
-{
- /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
-}
-
-
/* =============================================================
* State enable/disable
*/
}
-/**
- * Tell the card where to render (offset, pitch).
- * Effected by glDrawBuffer, etc
- */
-void
-radeonUpdateDrawBuffer(GLcontext *ctx)
-{
- r100ContextPtr rmesa = R100_CONTEXT(ctx);
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- struct radeon_renderbuffer *rrb;
-
- if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
- /* draw to front */
- rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
- } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
- /* draw to back */
- rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
- } else {
- /* drawing to multiple buffers, or none */
- return;
- }
-
- assert(rrb);
- assert(rrb->pitch);
-
- RADEON_STATECHANGE( rmesa, ctx );
-}
-
-
void radeonValidateState( GLcontext *ctx )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
GLuint new_state = rmesa->radeon.NewGLState;
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
- radeonUpdateDrawBuffer(ctx);
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+ RADEON_STATECHANGE(rmesa, ctx);
}
if (new_state & _NEW_TEXTURE) {