mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 17:58:26 +02:00
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
This commit is contained in:
parent
4170216009
commit
05304d41f2
10 changed files with 148 additions and 91 deletions
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
|
|||
if (radeon) {
|
||||
|
||||
if (radeon->dma.current) {
|
||||
radeonReleaseDmaRegion( radeon );
|
||||
rcommonFlushCmdBuf( radeon, __FUNCTION__ );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
radeon_validate_bo(rmesa, rmesa->dma.current, RADEON_GEM_DOMAIN_GTT, 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;
|
||||
}
|
||||
if (radeon_revalidate_bos(rmesa->glCtx) == GL_FALSE)
|
||||
fprintf(stderr,"failure to revalidate BOs - badness\n");
|
||||
|
||||
radeon_bo_map(rmesa->dma.current, 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
void radeonValidateState( GLcontext *ctx )
|
||||
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);
|
||||
}
|
||||
|
||||
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 ));
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue