- FIX: flickering

- Scissor support works now
This commit is contained in:
Nicolai Haehnle 2004-10-17 20:26:06 +00:00
parent 158a251a6b
commit ff42a00402
12 changed files with 276 additions and 83 deletions

View file

@ -80,15 +80,6 @@ struct r200_depthbuffer_state {
GLfloat scale;
};
struct r200_scissor_state {
drm_clip_rect_t rect;
GLboolean enabled;
GLuint numClipRects; /* Cliprects active */
GLuint numAllocedClipRects; /* Cliprects available */
drm_clip_rect_t *pClipRects;
};
struct r200_stencilbuffer_state {
GLboolean hwBuffer;
GLuint clear; /* rb3d_stencilrefmask value */
@ -502,7 +493,6 @@ struct r200_state {
*/
struct r200_colorbuffer_state color;
struct r200_depthbuffer_state depth;
struct r200_scissor_state scissor;
struct r200_stencilbuffer_state stencil;
struct r200_stipple_state stipple;
struct r200_texture_state texture;

View file

@ -45,7 +45,6 @@ extern void r200InitTnlFuncs(GLcontext * ctx);
extern void r200UpdateMaterial(GLcontext * ctx);
extern void r200RecalcScissorRects(r200ContextPtr rmesa);
extern void r200UpdateViewportOffset(GLcontext * ctx);
extern void r200UpdateWindow(GLcontext * ctx);

View file

@ -80,17 +80,13 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)
cmd.buf = (char*)(r300->cmdbuf.cmd_buf + start);
cmd.bufsz = (r300->cmdbuf.count_used - start) * 4;
#if 0 // TODO: scissors
if (rmesa->state.scissor.enabled) {
cmd.nbox = rmesa->state.scissor.numClipRects;
cmd.boxes = (drm_clip_rect_t *) rmesa->state.scissor.pClipRects;
if (r300->radeon.state.scissor.enabled) {
cmd.nbox = r300->radeon.state.scissor.numClipRects;
cmd.boxes = (drm_clip_rect_t *)r300->radeon.state.scissor.pClipRects;
} else {
#endif
cmd.nbox = r300->radeon.numClipRects;
cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects;
#if 0
cmd.boxes = (drm_clip_rect_t *)r300->radeon.pClipRects;
}
#endif
if (cmd.nbox) {
ret = drmCommandWrite(r300->radeon.dri.fd,

View file

@ -156,7 +156,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
assert(screen);
/* Allocate the R300 context */
r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
if (!r300)
return GL_FALSE;
@ -172,7 +172,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
*/
_mesa_init_driver_functions(&functions);
r300InitIoctlFuncs(&functions);
//r200InitStateFuncs(&functions);
r300InitStateFuncs(&functions);
//r200InitTextureFuncs(&functions);
if (!radeonInitContext(&r300->radeon, &functions,
@ -296,9 +296,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
r300DestroyCmdBuf(r300);
/* free the Mesa context */
r300->radeon.glCtx->DriverCtx = NULL;
_mesa_destroy_context(r300->radeon.glCtx);
radeonCleanupContext(&r300->radeon);
/* free the option cache */
driDestroyOptionCache(&r300->radeon.optionCache);

View file

@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "glheader.h"
#include "state.h"
#include "imports.h"
#include "enums.h"
#include "macros.h"
#include "context.h"
#include "dd.h"
@ -49,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tnl/tnl.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "r300_context.h"
#include "r300_ioctl.h"
#include "r300_state.h"
@ -56,6 +58,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_program.h"
/**
* Handle glEnable()/glDisable().
*/
static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
{
if (RADEON_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(cap),
state ? "GL_TRUE" : "GL_FALSE");
switch (cap) {
default:
radeonEnable(ctx, cap, state);
return;
}
}
/**
* Called by Mesa after an internal state update.
*/
@ -317,6 +337,7 @@ void r300ResetHwState(r300ContextPtr r300)
}
/**
* Calculate initial hardware state and register state functions.
* Assumes that the command buffer and state atoms have been
@ -324,12 +345,20 @@ void r300ResetHwState(r300ContextPtr r300)
*/
void r300InitState(r300ContextPtr r300)
{
struct dd_function_table* functions;
radeonInitState(&r300->radeon);
r300ResetHwState(r300);
/* Setup state functions */
functions = &r300->radeon.glCtx->Driver;
functions->UpdateState = r300InvalidateState;
}
/**
* Initialize driver's state callback functions
*/
void r300InitStateFuncs(struct dd_function_table* functions)
{
radeonInitStateFuncs(functions);
functions->UpdateState = r300InvalidateState;
functions->Enable= r300Enable;
}

View file

@ -44,6 +44,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
} while(0)
extern void r300ResetHwState(r300ContextPtr r300);
extern void r300InitState(r300ContextPtr r300);
extern void r300InitStateFuncs(struct dd_function_table* functions);
#endif /* __R300_STATE_H__ */

View file

@ -206,6 +206,23 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
}
/**
* Cleanup common context fields.
* Called by r200DestroyContext/r300DestroyContext
*/
void radeonCleanupContext(radeonContextPtr radeon)
{
/* free the Mesa context */
radeon->glCtx->DriverCtx = NULL;
_mesa_destroy_context(radeon->glCtx);
if (radeon->state.scissor.pClipRects) {
FREE(radeon->state.scissor.pClipRects);
radeon->state.scissor.pClipRects = 0;
}
}
/**
* Swap front and back buffer.
*/

View file

@ -113,6 +113,15 @@ struct radeon_dri_mirror {
/**
* Derived state for internal purposes.
*/
struct radeon_scissor_state {
drm_clip_rect_t rect;
GLboolean enabled;
GLuint numClipRects; /* Cliprects active */
GLuint numAllocedClipRects; /* Cliprects available */
drm_clip_rect_t *pClipRects;
};
struct radeon_colorbuffer_state {
GLuint clear;
GLint drawOffset, drawPitch;
@ -125,6 +134,7 @@ struct radeon_pixel_state {
struct radeon_state {
struct radeon_colorbuffer_state color;
struct radeon_pixel_state pixel;
struct radeon_scissor_state scissor;
};
/**
@ -187,6 +197,7 @@ extern GLboolean radeonInitContext(radeonContextPtr radeon,
const __GLcontextModes * glVisual,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
extern void radeonCleanupContext(radeonContextPtr radeon);
extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
__DRIdrawablePrivate * driDrawPriv,
__DRIdrawablePrivate * driReadPriv);

View file

@ -53,7 +53,7 @@ static void radeonUpdatePageFlipping(radeonContextPtr radeon)
radeon->doPageFlip = radeon->sarea->pfState;
use_back = (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT);
use_back = (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT);
use_back ^= (radeon->sarea->pfCurrentPage == 1);
if (use_back) {
@ -82,7 +82,7 @@ static void r200RegainedLock(r200ContextPtr r200)
r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] =
r200->radeon.state.color.drawPitch;
if (r200->radeon.glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
if (r200->radeon.glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT)
radeonSetCliprects(&r200->radeon, GL_BACK_LEFT);
else
radeonSetCliprects(&r200->radeon, GL_FRONT_LEFT);
@ -102,14 +102,12 @@ static void r300RegainedLock(radeonContextPtr radeon)
if (radeon->lastStamp != dPriv->lastStamp) {
radeonUpdatePageFlipping(radeon);
if (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
if (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT)
radeonSetCliprects(radeon, GL_BACK_LEFT);
else
radeonSetCliprects(radeon, GL_FRONT_LEFT);
#if 0
r200UpdateViewportOffset(r200->radeon.glCtx);
#endif
radeonUpdateScissor(radeon->glCtx);
radeon->lastStamp = dPriv->lastStamp;
}

View file

@ -330,53 +330,46 @@ static void radeonSetBuffer(GLcontext * ctx,
GLframebuffer * colorBuffer, GLuint bufferBit)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
int buffer;
switch (bufferBit) {
case DD_FRONT_LEFT_BIT:
if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
radeon->state.pixel.readOffset =
radeon->radeonScreen->backOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->backPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->backOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->backPitch;
} else {
radeon->state.pixel.readOffset =
radeon->radeonScreen->frontOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->frontPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->frontOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->frontPitch;
}
buffer = 0;
break;
case DD_BACK_LEFT_BIT:
if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
radeon->state.pixel.readOffset =
radeon->radeonScreen->frontOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->frontPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->frontOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->frontPitch;
} else {
radeon->state.pixel.readOffset =
radeon->radeonScreen->backOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->backPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->backOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->backPitch;
}
buffer = 1;
break;
default:
_mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__);
break;
return;
}
if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1)
buffer ^= 1;
fprintf(stderr, "%s: using %s buffer\n", __FUNCTION__,
buffer ? "back" : "front");
if (buffer) {
radeon->state.pixel.readOffset =
radeon->radeonScreen->backOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->backPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->backOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->backPitch;
} else {
radeon->state.pixel.readOffset =
radeon->radeonScreen->frontOffset;
radeon->state.pixel.readPitch =
radeon->radeonScreen->frontPitch;
radeon->state.color.drawOffset =
radeon->radeonScreen->frontOffset;
radeon->state.color.drawPitch =
radeon->radeonScreen->frontPitch;
}
}

View file

@ -50,6 +50,106 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "r200_state.h"
#include "r300_ioctl.h"
/* =============================================================
* Scissoring
*/
static GLboolean intersect_rect(drm_clip_rect_t * out,
drm_clip_rect_t * a, drm_clip_rect_t * b)
{
*out = *a;
if (b->x1 > out->x1)
out->x1 = b->x1;
if (b->y1 > out->y1)
out->y1 = b->y1;
if (b->x2 < out->x2)
out->x2 = b->x2;
if (b->y2 < out->y2)
out->y2 = b->y2;
if (out->x1 >= out->x2)
return GL_FALSE;
if (out->y1 >= out->y2)
return GL_FALSE;
return GL_TRUE;
}
void radeonRecalcScissorRects(radeonContextPtr radeon)
{
drm_clip_rect_t *out;
int i;
/* Grow cliprect store?
*/
if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) {
while (radeon->state.scissor.numAllocedClipRects <
radeon->numClipRects) {
radeon->state.scissor.numAllocedClipRects += 1; /* zero case */
radeon->state.scissor.numAllocedClipRects *= 2;
}
if (radeon->state.scissor.pClipRects)
FREE(radeon->state.scissor.pClipRects);
radeon->state.scissor.pClipRects =
MALLOC(radeon->state.scissor.numAllocedClipRects *
sizeof(drm_clip_rect_t));
if (radeon->state.scissor.pClipRects == NULL) {
radeon->state.scissor.numAllocedClipRects = 0;
return;
}
}
out = radeon->state.scissor.pClipRects;
radeon->state.scissor.numClipRects = 0;
for (i = 0; i < radeon->numClipRects; i++) {
if (intersect_rect(out,
&radeon->pClipRects[i],
&radeon->state.scissor.rect)) {
radeon->state.scissor.numClipRects++;
out++;
}
}
}
void radeonUpdateScissor(GLcontext* ctx)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
assert(radeon->state.scissor.enabled == ctx->Scissor.Enabled);
if (radeon->dri.drawable) {
__DRIdrawablePrivate *dPriv = radeon->dri.drawable;
int x1 = dPriv->x + ctx->Scissor.X;
int y1 = dPriv->y + dPriv->h - (ctx->Scissor.Y + ctx->Scissor.Height);
radeon->state.scissor.rect.x1 = x1;
radeon->state.scissor.rect.y1 = y1;
radeon->state.scissor.rect.x2 = x1 + ctx->Scissor.Width - 1;
radeon->state.scissor.rect.y2 = y1 + ctx->Scissor.Height - 1;
radeonRecalcScissorRects(radeon);
}
}
static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
if (ctx->Scissor.Enabled) {
/* We don't pipeline cliprect changes */
if (IS_FAMILY_R200(radeon))
R200_FIREVERTICES((r200ContextPtr)radeon);
else
r300Flush(ctx);
radeonUpdateScissor(ctx);
}
}
/**
@ -77,12 +177,69 @@ void radeonSetCliprects(radeonContextPtr radeon, GLenum mode)
break;
default:
fprintf(stderr, "bad mode in radeonSetCliprects\n");
radeon->numClipRects = 0;
radeon->pClipRects = 0;
return;
}
if (IS_FAMILY_R200(radeon)) {
if (((r200ContextPtr)radeon)->state.scissor.enabled)
r200RecalcScissorRects((r200ContextPtr)radeon);
if (radeon->state.scissor.enabled)
radeonRecalcScissorRects(radeon);
}
/**
* Handle common enable bits.
* Called as a fallback by r200Enable/r300Enable.
*/
void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
switch(cap) {
case GL_SCISSOR_TEST:
/* We don't pipeline cliprect & scissor changes */
if (IS_FAMILY_R200(radeon))
R200_FIREVERTICES((r200ContextPtr)radeon);
else
r300Flush(ctx);
radeon->state.scissor.enabled = state;
radeonUpdateScissor(ctx);
break;
default:
return;
}
}
/**
* Initialize default state.
* This function is called once at context init time from
* r200InitState/r300InitState
*/
void radeonInitState(radeonContextPtr radeon)
{
radeon->Fallback = 0;
if (radeon->glCtx->Visual.doubleBufferMode && radeon->sarea->pfCurrentPage == 0) {
radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
} else {
radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
}
radeon->state.pixel.readOffset = radeon->state.color.drawOffset;
radeon->state.pixel.readPitch = radeon->state.color.drawPitch;
}
/**
* Initialize common state functions.
* Called by r200InitStateFuncs/r300InitStateFuncs
*/
void radeonInitStateFuncs(struct dd_function_table *functions)
{
functions->Scissor = radeonScissor;
}

View file

@ -1,9 +1,5 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Copyright (C) 2004 Nicolai Haehnle. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@ -29,7 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Nicolai Haehnle <prefect_@gmx.net>
*/
#ifndef __RADEON_STATE_H__
@ -37,6 +33,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_context.h"
extern void radeonRecalcScissorRects(radeonContextPtr radeon);
extern void radeonSetCliprects(radeonContextPtr radeon, GLenum mode);
extern void radeonUpdateScissor(GLcontext* ctx);
extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state);
extern void radeonInitState(radeonContextPtr radeon);
extern void radeonInitStateFuncs(struct dd_function_table* functions);
#endif