summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-04-02 18:58:49 +1000
committerDave Airlie <airlied@redhat.com>2009-04-02 18:58:49 +1000
commit05304d41f2d9ab7a66a8b976580c156b7b93a9d3 (patch)
treee6132b7fb98ce55039ae14f539527afeb542af38
parent41702160090a4c1325afc07c56682f3e1c4fcaf0 (diff)
radeon/r200/r300: fix up the whole buffer space checking.
This fixes up the buffer validation scheme, so that we keep a list of buffers to validate so cmdbuf flushes during a pipeline get all the buffers revalidated on the next emit. This also fixes radeonFlush to not flush unless we have something useful to send to the GPU, like a DMA buffer or something not state
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c48
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c46
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c56
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c25
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c50
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.h2
10 files changed, 149 insertions, 92 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index ca4dee8a5b..f040713980 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -2273,33 +2273,24 @@ static void update_texturematrix( GLcontext *ctx )
static GLboolean r200ValidateBuffers(GLcontext *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct radeon_cs_space_check bos[8];
struct radeon_renderbuffer *rrb;
- int num_bo = 0;
int i;
- int flushed = 0, ret;
-again:
- num_bo = 0;
+
+ radeon_validate_reset_bos(&rmesa->radeon);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- bos[num_bo].bo = rrb->bo;
- bos[num_bo].read_domains = 0;
- bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- bos[num_bo].bo = rrb->bo;
- bos[num_bo].read_domains = 0;
- bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -2307,26 +2298,17 @@ again:
if (!ctx->Texture.Unit[i]._ReallyEnabled)
continue;
-
+
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
- bos[num_bo].bo = t->mt->bo;
- bos[num_bo].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].write_domain = 0;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ if (t->image_override && t->bo)
+ radeon_validate_bo(&rmesa->radeon, t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ else if (t->mt->bo)
+ radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
-
- ret = radeon_cs_space_check(rmesa->radeon.cmdbuf.cs, bos, num_bo);
- if (ret == RADEON_CS_SPACE_OP_TO_BIG)
- return GL_FALSE;
- if (ret == RADEON_CS_SPACE_FLUSH) {
- radeonFlush(ctx);
- if (flushed)
- return GL_FALSE;
- flushed = 1;
- goto again;
- }
- return GL_TRUE;
+
+ return radeon_revalidate_bos(ctx);
}
GLboolean r200ValidateState( GLcontext *ctx )
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 3ce0ba68c9..bcf8803875 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -352,7 +352,7 @@ void r300EmitCacheFlush(r300ContextPtr rmesa)
{
BATCH_LOCALS(&rmesa->radeon);
- BEGIN_BATCH(4);
+ BEGIN_BATCH_NO_AUTOSTATE(4);
OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT,
R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index baaca5f1e5..5a87b5da43 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -268,40 +268,29 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object
return GL_TRUE;
}
-
/**
* Ensure all enabled and complete textures are uploaded along with any buffers being used.
*/
GLboolean r300ValidateBuffers(GLcontext * ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- struct radeon_cs_space_check bos[16];
struct radeon_renderbuffer *rrb;
- int num_bo = 0;
int i;
- int flushed = 0, ret;
-again:
- num_bo = 0;
+
+ radeon_validate_reset_bos(&rmesa->radeon);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
/* color buffer */
if (rrb && rrb->bo) {
- bos[num_bo].bo = rrb->bo;
- bos[num_bo].read_domains = 0;
- bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
/* depth buffer */
rrb = radeon_get_depthbuffer(&rmesa->radeon);
- /* color buffer */
if (rrb && rrb->bo) {
- bos[num_bo].bo = rrb->bo;
- bos[num_bo].read_domains = 0;
- bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
}
for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
@@ -317,26 +306,15 @@ again:
}
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
if (t->image_override && t->bo)
- bos[num_bo].bo = t->bo;
+ radeon_validate_bo(&rmesa->radeon, t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+
else if (t->mt->bo)
- bos[num_bo].bo = t->mt->bo;
- bos[num_bo].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
- bos[num_bo].write_domain = 0;
- bos[num_bo].new_accounted = 0;
- num_bo++;
+ radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- ret = radeon_cs_space_check(rmesa->radeon.cmdbuf.cs, bos, num_bo);
- if (ret == RADEON_CS_SPACE_OP_TO_BIG)
- return GL_FALSE;
- if (ret == RADEON_CS_SPACE_FLUSH) {
- radeonFlush(ctx);
- if (flushed)
- return GL_FALSE;
- flushed = 1;
- goto again;
- }
- return GL_TRUE;
+ return radeon_revalidate_bos(ctx);
}
void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 3ce868d2cf..4f7bfebf04 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -906,6 +906,49 @@ static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty)
COMMIT_BATCH();
}
+GLboolean radeon_revalidate_bos(GLcontext *ctx)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ int flushed = 0;
+ int ret;
+again:
+ ret = radeon_cs_space_check(radeon->cmdbuf.cs, radeon->state.bos, radeon->state.validated_bo_count);
+ if (ret == RADEON_CS_SPACE_OP_TO_BIG)
+ return GL_FALSE;
+ if (ret == RADEON_CS_SPACE_FLUSH) {
+ radeonFlush(ctx);
+ if (flushed)
+ return GL_FALSE;
+ flushed = 1;
+ goto again;
+ }
+ return GL_TRUE;
+}
+
+void radeon_validate_reset_bos(radeonContextPtr radeon)
+{
+ int i;
+
+ for (i = 0; i < radeon->state.validated_bo_count; i++) {
+ radeon->state.bos[i].bo = NULL;
+ radeon->state.bos[i].read_domains = 0;
+ radeon->state.bos[i].write_domain = 0;
+ radeon->state.bos[i].new_accounted = 0;
+ }
+ radeon->state.validated_bo_count = 0;
+}
+
+void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
+{
+ radeon->state.bos[radeon->state.validated_bo_count].bo = bo;
+ radeon->state.bos[radeon->state.validated_bo_count].read_domains = read_domains;
+ radeon->state.bos[radeon->state.validated_bo_count].write_domain = write_domain;
+ radeon->state.bos[radeon->state.validated_bo_count].new_accounted = 0;
+ radeon->state.validated_bo_count++;
+
+ assert(radeon->state.validated_bo_count < RADEON_MAX_BOS);
+}
+
void radeonEmitState(radeonContextPtr radeon)
{
if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
@@ -947,6 +990,14 @@ void radeonFlush(GLcontext *ctx)
if (RADEON_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw);
+ /* okay if we have no cmds in the buffer &&
+ we have no DMA flush &&
+ we have no DMA buffer allocated.
+ then no point flushing anything at all.
+ */
+ if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current)
+ return;
+
if (radeon->dma.flush)
radeon->dma.flush( ctx );
@@ -1015,6 +1066,11 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
}
radeon_cs_erase(rmesa->cmdbuf.cs);
rmesa->cmdbuf.flushing = 0;
+
+ if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE) {
+ fprintf(stderr,"failed to revalidate buffers\n");
+ }
+
return ret;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index f3e2290cab..c2fbb0950d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -47,6 +47,9 @@ void radeon_get_cliprects(radeonContextPtr radeon,
struct drm_clip_rect **cliprects,
unsigned int *num_cliprects,
int *x_off, int *y_off);
+GLboolean radeon_revalidate_bos(GLcontext *ctx);
+void radeon_validate_bo(radeonContextPtr radeon, struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain);
+void radeon_validate_reset_bos(radeonContextPtr radeon);
void radeon_fbo_init(struct radeon_context *radeon);
void
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index ef67c86f0b..ba74c97f2c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -219,7 +219,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
if (radeon) {
if (radeon->dma.current) {
- radeonReleaseDmaRegion( radeon );
rcommonFlushCmdBuf( radeon, __FUNCTION__ );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index c6e6be7484..d32e5af544 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -13,6 +13,10 @@
#include "dri_util.h"
#include "tnl/t_vertex.h"
+struct radeon_context;
+
+#include "radeon_bocs_wrapper.h"
+
/* This union is used to avoid warnings/miscompilation
with float to uint32_t casts due to strict-aliasing */
typedef union { GLfloat f; uint32_t ui32; } float_ui32_type;
@@ -384,11 +388,15 @@ typedef void (*radeon_line_func) (radeonContextPtr,
typedef void (*radeon_point_func) (radeonContextPtr, radeonVertex *);
+#define RADEON_MAX_BOS 24
struct radeon_state {
struct radeon_colorbuffer_state color;
struct radeon_depthbuffer_state depth;
struct radeon_scissor_state scissor;
struct radeon_stencilbuffer_state stencil;
+
+ struct radeon_cs_space_check bos[RADEON_MAX_BOS];
+ int validated_bo_count;
};
/**
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index 47f789e9cd..5ffee86e5a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -163,8 +163,6 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
{
- struct radeon_cs_space_check bos[1];
- int flushed = 0, ret;
size = MAX2(size, MAX_DMA_BUF_SZ * 16);
@@ -200,24 +198,11 @@ again_alloc:
rmesa->dma.current_used = 0;
rmesa->dma.current_vertexptr = 0;
- bos[0].bo = rmesa->dma.current;
- bos[0].read_domains = RADEON_GEM_DOMAIN_GTT;
- bos[0].write_domain =0 ;
- bos[0].new_accounted = 0;
-
- ret = radeon_cs_space_check(rmesa->cmdbuf.cs, bos, 1);
- if (ret == RADEON_CS_SPACE_OP_TO_BIG) {
- fprintf(stderr,"Got OPEARTION TO BIG ILLEGAL - this cannot happen");
- assert(0);
- } else if (ret == RADEON_CS_SPACE_FLUSH) {
- rcommonFlushCmdBuf(rmesa, __FUNCTION__);
- if (flushed) {
- fprintf(stderr,"flushed but still no space\n");
- assert(0);
- }
- flushed = 1;
- goto again_alloc;
- }
+ radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+
+ if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE)
+ fprintf(stderr,"failure to revalidate BOs - badness\n");
+
radeon_bo_map(rmesa->dma.current, 1);
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 19ff2688e6..dcca326c66 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast_setup/swrast_setup.h"
#include "radeon_context.h"
+#include "radeon_mipmap_tree.h"
#include "radeon_ioctl.h"
#include "radeon_state.h"
#include "radeon_tcl.h"
@@ -2043,8 +2044,48 @@ static void update_texturematrix( GLcontext *ctx )
}
}
+static GLboolean r100ValidateBuffers(GLcontext *ctx)
+{
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrb;
+ int i;
+
+ radeon_validate_reset_bos(&rmesa->radeon);
+
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ /* color buffer */
+ if (rrb && rrb->bo) {
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ /* depth buffer */
+ rrb = radeon_get_depthbuffer(&rmesa->radeon);
+ /* color buffer */
+ if (rrb && rrb->bo) {
+ radeon_validate_bo(&rmesa->radeon, rrb->bo,
+ 0, RADEON_GEM_DOMAIN_VRAM);
+ }
-void radeonValidateState( GLcontext *ctx )
+ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
+ radeonTexObj *t;
+
+ if (!ctx->Texture.Unit[i]._ReallyEnabled)
+ continue;
+
+ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
+ if (t->image_override && t->bo)
+ radeon_validate_bo(&rmesa->radeon, t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ else if (t->mt->bo)
+ radeon_validate_bo(&rmesa->radeon, t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ }
+
+ return radeon_revalidate_bos(ctx);
+}
+
+GLboolean radeonValidateState( GLcontext *ctx )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
GLuint new_state = rmesa->radeon.NewGLState;
@@ -2061,6 +2102,10 @@ void radeonValidateState( GLcontext *ctx )
new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
}
+ /* we need to do a space check here */
+ if (!r100ValidateBuffers(ctx))
+ return GL_FALSE;
+
/* Need an event driven matrix update?
*/
if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
@@ -2136,7 +2181,8 @@ static void radeonWrapRunPipeline( GLcontext *ctx )
/* Validate state:
*/
if (rmesa->radeon.NewGLState)
- radeonValidateState( ctx );
+ if (!radeonValidateState( ctx ))
+ FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
has_material = (ctx->Light.Enabled && check_material( ctx ));
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h
index f05fa827d7..a7c8eef32a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.h
+++ b/src/mesa/drivers/dri/radeon/radeon_state.h
@@ -50,7 +50,7 @@ extern void radeonUpdateDrawBuffer( GLcontext *ctx );
extern void radeonUploadTexMatrix( r100ContextPtr rmesa,
int unit, GLboolean swapcols );
-extern void radeonValidateState( GLcontext *ctx );
+extern GLboolean radeonValidateState( GLcontext *ctx );
extern void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode );