radeon: refactor framebuffer code like intel

this is a step towards fbos and should fix pageflipping, but
I think the first flip seems broken.
This commit is contained in:
Dave Airlie 2009-03-03 03:27:59 +10:00
parent 863c76a7bb
commit 2b85fccae5
17 changed files with 617 additions and 570 deletions

View file

@ -261,9 +261,9 @@ static void r200_init_vtbl(radeonContextPtr radeon)
{
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;
}

View file

@ -203,7 +203,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
GLint ret;
if ( R200_DEBUG & DEBUG_IOCTL ) {
fprintf( stderr, "r200Clear\n");
fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
}
{

View file

@ -1639,6 +1639,8 @@ static void r200Viewport( GLcontext *ctx, GLint x, GLint y,
* values, or keep the originals hanging around.
*/
r200UpdateWindow( ctx );
radeon_viewport(ctx, x, y, width, height);
}
static void r200DepthRange( GLcontext *ctx, GLclampd nearval,
@ -1754,47 +1756,6 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode )
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
*/
@ -2289,47 +2250,6 @@ static void update_texturematrix( GLcontext *ctx )
}
}
/**
* 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);
@ -2395,7 +2315,11 @@ GLboolean r200ValidateState( GLcontext *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)) {
@ -2523,8 +2447,8 @@ void r200InitStateFuncs( struct dd_function_table *functions )
functions->UpdateState = r200InvalidateState;
functions->LightingSpaceChange = r200LightingSpaceChange;
functions->DrawBuffer = r200DrawBuffer;
functions->ReadBuffer = r200ReadBuffer;
functions->DrawBuffer = radeonDrawBuffer;
functions->ReadBuffer = radeonReadBuffer;
functions->AlphaFunc = r200AlphaFunc;
functions->BlendColor = r200BlendColor;

View file

@ -235,26 +235,35 @@ static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes
static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
{
r300ContextPtr r300 = (r300ContextPtr)radeon;
BATCH_LOCALS(radeon);
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);
}
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);
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;
}

View file

@ -541,7 +541,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
{
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;
@ -594,16 +594,16 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
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;
}

View file

@ -427,7 +427,8 @@ static int r300Fallback(GLcontext * ctx)
{
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) {

View file

@ -1083,20 +1083,13 @@ static void r300UpdateWindow(GLcontext * ctx)
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)
@ -1129,34 +1122,6 @@ void r300UpdateViewportOffset(GLcontext * ctx)
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],
@ -2653,7 +2618,11 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
_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);
@ -2705,28 +2674,6 @@ void r300UpdateClipPlanes( GLcontext *ctx )
}
}
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
*/
@ -2770,6 +2717,6 @@ void r300InitStateFuncs(struct dd_function_table *functions)
functions->ClipPlane = r300ClipPlane;
functions->Scissor = radeonScissor;
functions->DrawBuffer = r300DrawBuffer;
functions->ReadBuffer = r300ReadBuffer;
functions->DrawBuffer = radeonDrawBuffer;
functions->ReadBuffer = radeonReadBuffer;
}

View file

@ -393,7 +393,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
radeon_texture_image *rImage;
radeonContextPtr radeon;
r300ContextPtr rmesa;
GLframebuffer *fb;
struct radeon_framebuffer *rfb;
radeonTexObjPtr t;
uint32_t pitch_val;
@ -402,7 +402,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
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);
@ -415,17 +415,17 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
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;

View file

@ -51,7 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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"
@ -132,6 +132,38 @@ void radeonRecalcScissorRects(radeonContextPtr radeon)
}
}
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.
*/
@ -139,49 +171,37 @@ void radeonSetCliprects(radeonContextPtr radeon)
{
__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);
@ -348,6 +368,37 @@ static void radeonWaitForIdle(radeonContextPtr radeon)
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.
*/
@ -355,10 +406,8 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
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);
@ -366,24 +415,12 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
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 ; ) {
@ -429,45 +466,13 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
}
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;
}
}
void radeonPageFlip( __DRIdrawablePrivate *dPriv )
static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target)
{
radeonContextPtr rmesa;
GLint ret;
GLboolean missed_target;
__DRIscreenPrivate *psp;
struct radeon_renderbuffer *rrb;
GLframebuffer *fb = dPriv->driverPrivate;
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
psp = dPriv->driScreenPriv;
if ( RADEON_DEBUG & DEBUG_IOCTL ) {
fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
rmesa->sarea->pfCurrentPage);
}
radeon_firevertices(rmesa);
LOCK_HARDWARE( rmesa );
@ -475,48 +480,62 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv )
if (!dPriv->numClipRects) {
UNLOCK_HARDWARE(rmesa);
usleep(10000); /* throttle invisible client 10ms */
return;
return 0;
}
radeonWaitForFrameCompletion(rmesa);
UNLOCK_HARDWARE(rmesa);
driWaitForVBlank(dPriv, missed_target);
LOCK_HARDWARE(rmesa);
return 0;
}
static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv )
{
radeonContextPtr radeon;
GLint ret;
__DRIscreenPrivate *psp;
struct radeon_renderbuffer *rrb;
struct radeon_framebuffer *rfb;
assert(dPriv);
assert(dPriv->driContextPriv);
assert(dPriv->driContextPriv->driverPrivate);
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 %d\n", __FUNCTION__,
radeon->sarea->pfCurrentPage, radeon->sarea->pfState);
}
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;
radeon->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 );
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;
if (rmesa->vtbl.update_draw_buffer)
rmesa->vtbl.update_draw_buffer(rmesa->glCtx);
rfb->pf_current_page = radeon->sarea->pfCurrentPage;
radeon_flip_renderbuffers(rfb);
radeon_draw_buffer(radeon->glCtx, &rfb->base);
return GL_TRUE;
}
@ -525,6 +544,9 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv )
*/
void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
{
int64_t ust;
__DRIscreenPrivate *psp;
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
radeonContextPtr radeon;
GLcontext *ctx;
@ -533,12 +555,29 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
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 */
@ -573,7 +612,224 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
}
}
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;

View file

@ -14,7 +14,6 @@ void radeonWaitForIdleLocked(radeonContextPtr radeon);
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 );
@ -25,6 +24,12 @@ void radeonFlush(GLcontext *ctx);
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;
@ -38,11 +43,11 @@ static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPt
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;

View file

@ -35,7 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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"
@ -165,8 +164,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
radeon->do_usleeps ? "usleeps" : "busy waits",
fthrottle_mode, radeon->radeonScreen->irq);
(*sPriv->systemTime->getUST) (&radeon->swap_ust);
return GL_TRUE;
}
@ -180,39 +177,39 @@ void radeonCleanupContext(radeonContextPtr radeon)
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;
@ -260,12 +257,12 @@ GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
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,
@ -277,7 +274,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
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,
@ -289,7 +286,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
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,
@ -301,7 +298,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
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,
@ -317,7 +314,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
static void
radeon_make_renderbuffer_current(radeonContextPtr radeon,
GLframebuffer *draw)
struct radeon_framebuffer *draw)
{
int size = 4096*4096*4;
/* if radeon->fake */
@ -329,7 +326,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
}
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 +
@ -342,7 +339,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
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 +
@ -355,7 +352,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
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 +
@ -368,7 +365,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
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 +
@ -392,7 +389,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
__DRIscreen *screen;
struct radeon_renderbuffer *rb;
int i, count;
GLframebuffer *draw;
struct radeon_framebuffer *draw;
radeonContextPtr radeon;
if (RADEON_DEBUG & DEBUG_DRI)
@ -402,13 +399,13 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
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;
}
@ -439,7 +436,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
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;
@ -461,7 +458,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
}
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;
@ -479,7 +476,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
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;
@ -518,7 +515,8 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
__DRIdrawablePrivate * driReadPriv)
{
radeonContextPtr radeon;
GLframebuffer *dfb, *rfb;
struct radeon_framebuffer *drfb;
struct gl_framebuffer *readfb;
if (!driContextPriv) {
if (RADEON_DEBUG & DEBUG_DRI)
@ -526,62 +524,66 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
_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, 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);
}
}
radeon->dri.readable = driReadPriv;
if (radeon->dri.drawable != driDrawPriv ||
radeon->lastStamp != driDrawPriv->lastStamp) {
radeon->dri.drawable = driDrawPriv;
radeonSetCliprects(radeon);
radeon->vtbl.update_viewport_offset(radeon->glCtx);
}
_mesa_make_current(radeon->glCtx, &drfb->base, readfb);
_mesa_update_state(radeon->glCtx);
if (!driContextPriv->driScreenPriv->dri2.enabled) {
radeonUpdatePageFlipping(radeon);
if (radeon->glCtx->DrawBuffer == &drfb->base) {
if (radeon->dri.readable != driReadPriv)
radeon->dri.readable = driReadPriv;
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);
}
if (RADEON_DEBUG & DEBUG_DRI)
fprintf(stderr, "End %s\n", __FUNCTION__);
return GL_TRUE;

View file

@ -39,6 +39,8 @@ typedef struct radeon_context *radeonContextPtr;
#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
@ -81,9 +83,34 @@ struct radeon_renderbuffer
/* 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;
@ -387,9 +414,6 @@ struct radeon_context {
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;
@ -406,13 +430,6 @@ struct radeon_context {
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;
@ -422,15 +439,19 @@ struct radeon_context {
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;
};

View file

@ -186,10 +186,10 @@ static void r100_init_vtbl(radeonContextPtr radeon)
{
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.
@ -369,8 +369,6 @@ radeonCreateContext( const __GLcontextModes *glVisual,
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" ),

View file

@ -48,37 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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
@ -112,13 +81,52 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
}
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 );
}
}

View file

@ -48,73 +48,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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

View file

@ -1262,7 +1262,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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;
@ -1271,7 +1271,16 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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;
@ -1279,26 +1288,22 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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;
}
@ -1306,18 +1311,18 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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);
}
@ -1325,21 +1330,21 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
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;
@ -1541,21 +1546,21 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
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;

View file

@ -1418,6 +1418,8 @@ static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
* values, or keep the originals hanging around.
*/
radeonUpdateWindow( ctx );
radeon_viewport(ctx, x, y, width, height);
}
static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
@ -1532,50 +1534,6 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
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
*/
@ -2066,42 +2024,16 @@ static void update_texturematrix( GLcontext *ctx )
}
/**
* 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) {