intel/fake_bufmgr: Attempt to restrict references to objects in a batchbuffer > aperture size.
So with compiz on Intel hw with fake bufmgr, opening 4 firefox windows at 1680x1050 and hitting alt-tab, could cause the batchbuffer to try and reference more than the 32MB of RAM allocated. Fix 1: Fix 1 is to pre-verify the list of buffers against the current batchbuffer and if it can't possibly fit in the aperture to flush the batchbuffer to the hardware and try again. If the buffers still can't fit well then you are hosed as I'm not sure there is a nice way to tell anyone. Fix 2: Next problem was that even with a simple check for total < aperture, we ran into fragmentation issues, this meant that half way down a set of buffers, we would fail as no blocks were available. Fix this by nuking the memory manager from orbit and letting it start again and relayout the blocks in a manner that fits. Fix 3: Finally the initial problem we were seeing was a memcpy to a NULL backing store. We seem to end up with a texture at some point that never gets mapped but ends up with data in it. compiz al-tab icons have this property. So I created a card dirty bit that memcpy's any buffer that is !static and is written to back to memory. This probably is wrong but it makes compiz work for now. Caveats: 965 support is still fail.
This commit is contained in:
@@ -142,10 +142,10 @@ dri_bufmgr_destroy(dri_bufmgr *bufmgr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
||||||
GLuint offset, dri_bo *target_buf)
|
GLuint offset, dri_bo *target_buf)
|
||||||
{
|
{
|
||||||
reloc_buf->bufmgr->emit_reloc(reloc_buf, flags, delta, offset, target_buf);
|
return reloc_buf->bufmgr->emit_reloc(reloc_buf, flags, delta, offset, target_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dri_process_relocs(dri_bo *batch_buf, GLuint *count)
|
void *dri_process_relocs(dri_bo *batch_buf, GLuint *count)
|
||||||
@@ -163,3 +163,9 @@ dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug)
|
|||||||
{
|
{
|
||||||
bufmgr->debug = enable_debug;
|
bufmgr->debug = enable_debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dri_bufmgr_check_aperture_space(dri_bo *bo)
|
||||||
|
{
|
||||||
|
return bo->bufmgr->check_aperture_space(bo);
|
||||||
|
}
|
||||||
|
@@ -156,7 +156,7 @@ struct _dri_bufmgr {
|
|||||||
* \param target Buffer whose offset should be written into the relocation
|
* \param target Buffer whose offset should be written into the relocation
|
||||||
* entry.
|
* entry.
|
||||||
*/
|
*/
|
||||||
void (*emit_reloc)(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
int (*emit_reloc)(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
||||||
GLuint offset, dri_bo *target);
|
GLuint offset, dri_bo *target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,6 +176,7 @@ struct _dri_bufmgr {
|
|||||||
|
|
||||||
void (*post_submit)(dri_bo *batch_buf, dri_fence **fence);
|
void (*post_submit)(dri_bo *batch_buf, dri_fence **fence);
|
||||||
|
|
||||||
|
int (*check_aperture_space)(dri_bo *bo);
|
||||||
GLboolean debug; /**< Enables verbose debugging printouts */
|
GLboolean debug; /**< Enables verbose debugging printouts */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,9 +212,11 @@ void dri_bo_fake_disable_backing_store(dri_bo *bo,
|
|||||||
void *ptr);
|
void *ptr);
|
||||||
void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
|
void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
|
||||||
|
|
||||||
void dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
int dri_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
||||||
GLuint offset, dri_bo *target_buf);
|
GLuint offset, dri_bo *target_buf);
|
||||||
void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count);
|
void *dri_process_relocs(dri_bo *batch_buf, uint32_t *count);
|
||||||
void dri_post_process_relocs(dri_bo *batch_buf);
|
void dri_post_process_relocs(dri_bo *batch_buf);
|
||||||
void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence);
|
void dri_post_submit(dri_bo *batch_buf, dri_fence **last_fence);
|
||||||
|
int dri_bufmgr_check_aperture_space(dri_bo *bo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -133,6 +133,9 @@ typedef struct _bufmgr_fake {
|
|||||||
GLboolean debug;
|
GLboolean debug;
|
||||||
|
|
||||||
GLboolean performed_rendering;
|
GLboolean performed_rendering;
|
||||||
|
|
||||||
|
/* keep track of the current total size of objects we have relocs for */
|
||||||
|
unsigned long current_total_size;
|
||||||
} dri_bufmgr_fake;
|
} dri_bufmgr_fake;
|
||||||
|
|
||||||
typedef struct _dri_bo_fake {
|
typedef struct _dri_bo_fake {
|
||||||
@@ -142,6 +145,8 @@ typedef struct _dri_bo_fake {
|
|||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
unsigned dirty:1;
|
unsigned dirty:1;
|
||||||
|
unsigned size_accounted:1; /*this buffers size has been accounted against the aperture */
|
||||||
|
unsigned card_dirty:1; /* has the card written to this buffer - we make need to copy it back */
|
||||||
unsigned int refcount;
|
unsigned int refcount;
|
||||||
/* Flags may consist of any of the DRM_BO flags, plus
|
/* Flags may consist of any of the DRM_BO flags, plus
|
||||||
* DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two
|
* DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two
|
||||||
@@ -177,6 +182,8 @@ typedef struct _dri_fence_fake {
|
|||||||
static int clear_fenced(dri_bufmgr_fake *bufmgr_fake,
|
static int clear_fenced(dri_bufmgr_fake *bufmgr_fake,
|
||||||
unsigned int fence_cookie);
|
unsigned int fence_cookie);
|
||||||
|
|
||||||
|
static int dri_fake_check_aperture_space(dri_bo *bo);
|
||||||
|
|
||||||
#define MAXFENCE 0x7fffffff
|
#define MAXFENCE 0x7fffffff
|
||||||
|
|
||||||
static GLboolean FENCE_LTE( unsigned a, unsigned b )
|
static GLboolean FENCE_LTE( unsigned a, unsigned b )
|
||||||
@@ -264,11 +271,19 @@ alloc_block(dri_bo *bo)
|
|||||||
*/
|
*/
|
||||||
static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block)
|
static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block)
|
||||||
{
|
{
|
||||||
|
dri_bo_fake *bo_fake;
|
||||||
DBG("free block %p\n", block);
|
DBG("free block %p\n", block);
|
||||||
|
|
||||||
if (!block)
|
if (!block)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bo_fake = (dri_bo_fake *)block->bo;
|
||||||
|
if (bo_fake->card_dirty == GL_TRUE) {
|
||||||
|
memcpy(bo_fake->backing_store, block->virtual, block->bo->size);
|
||||||
|
bo_fake->card_dirty = GL_FALSE;
|
||||||
|
bo_fake->dirty = GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (block->on_hardware) {
|
if (block->on_hardware) {
|
||||||
block->bo = NULL;
|
block->bo = NULL;
|
||||||
}
|
}
|
||||||
@@ -287,11 +302,15 @@ static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block)
|
|||||||
static void
|
static void
|
||||||
alloc_backing_store(dri_bo *bo)
|
alloc_backing_store(dri_bo *bo)
|
||||||
{
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
assert(!bo_fake->backing_store);
|
assert(!bo_fake->backing_store);
|
||||||
assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE)));
|
assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE)));
|
||||||
|
|
||||||
bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64);
|
bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64);
|
||||||
|
|
||||||
|
DBG("alloc_backing - buf %d %p %d\n", bo_fake->id, bo_fake->backing_store, bo->size);
|
||||||
|
assert(bo_fake->backing_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -495,9 +514,6 @@ static GLboolean evict_and_alloc_block(dri_bo *bo)
|
|||||||
|
|
||||||
DBG("%s 0x%x bytes failed\n", __FUNCTION__, bo->size);
|
DBG("%s 0x%x bytes failed\n", __FUNCTION__, bo->size);
|
||||||
|
|
||||||
assert(is_empty_list(&bufmgr_fake->on_hardware));
|
|
||||||
assert(is_empty_list(&bufmgr_fake->fenced));
|
|
||||||
|
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,6 +800,26 @@ dri_fake_bo_unmap(dri_bo *bo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_fake_kick_all(dri_bufmgr_fake *bufmgr_fake)
|
||||||
|
{
|
||||||
|
struct block *block, *tmp;
|
||||||
|
|
||||||
|
bufmgr_fake->performed_rendering = GL_FALSE;
|
||||||
|
/* okay for ever BO that is on the HW kick it off.
|
||||||
|
seriously not afraid of the POLICE right now */
|
||||||
|
foreach_s(block, tmp, &bufmgr_fake->on_hardware) {
|
||||||
|
dri_bo_fake *bo_fake = (dri_bo_fake *)block->bo;
|
||||||
|
|
||||||
|
block->on_hardware = 0;
|
||||||
|
free_block(bufmgr_fake, block);
|
||||||
|
bo_fake->block = NULL;
|
||||||
|
bo_fake->validated = GL_FALSE;
|
||||||
|
bo_fake->dirty = GL_TRUE;
|
||||||
|
block->bo->offset = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dri_fake_bo_validate(dri_bo *bo, uint64_t flags)
|
dri_fake_bo_validate(dri_bo *bo, uint64_t flags)
|
||||||
{
|
{
|
||||||
@@ -810,6 +846,9 @@ dri_fake_bo_validate(dri_bo *bo, uint64_t flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reset size accounted */
|
||||||
|
bo_fake->size_accounted = 0;
|
||||||
|
|
||||||
/* Allocate the card memory */
|
/* Allocate the card memory */
|
||||||
if (!bo_fake->block && !evict_and_alloc_block(bo)) {
|
if (!bo_fake->block && !evict_and_alloc_block(bo)) {
|
||||||
bufmgr_fake->fail = 1;
|
bufmgr_fake->fail = 1;
|
||||||
@@ -836,7 +875,13 @@ dri_fake_bo_validate(dri_bo *bo, uint64_t flags)
|
|||||||
*/
|
*/
|
||||||
dri_bufmgr_fake_wait_idle(bufmgr_fake);
|
dri_bufmgr_fake_wait_idle(bufmgr_fake);
|
||||||
|
|
||||||
memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size);
|
/* we may never have mapped this BO so it might not have any backing store */
|
||||||
|
/* if this happens it should be rare, but 0 the card memory in any case */
|
||||||
|
if (bo_fake->backing_store)
|
||||||
|
memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size);
|
||||||
|
else
|
||||||
|
memset(bo_fake->block->virtual, 0, bo->size);
|
||||||
|
|
||||||
bo_fake->dirty = 0;
|
bo_fake->dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,17 +962,25 @@ dri_fake_destroy(dri_bufmgr *bufmgr)
|
|||||||
free(bufmgr);
|
free(bufmgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
dri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
dri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
||||||
GLuint offset, dri_bo *target_buf)
|
GLuint offset, dri_bo *target_buf)
|
||||||
{
|
{
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)reloc_buf->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)reloc_buf->bufmgr;
|
||||||
struct fake_buffer_reloc *r;
|
struct fake_buffer_reloc *r;
|
||||||
dri_bo_fake *reloc_fake = (dri_bo_fake *)reloc_buf;
|
dri_bo_fake *reloc_fake = (dri_bo_fake *)reloc_buf;
|
||||||
int i;
|
dri_bo_fake *target_fake = (dri_bo_fake *)target_buf;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
assert(reloc_buf);
|
assert(reloc_buf);
|
||||||
assert(target_buf);
|
assert(target_buf);
|
||||||
|
|
||||||
|
if (!target_fake->is_static && !target_fake->size_accounted) {
|
||||||
|
ret = dri_fake_check_aperture_space(target_buf);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (reloc_fake->relocs == NULL) {
|
if (reloc_fake->relocs == NULL) {
|
||||||
reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) *
|
reloc_fake->relocs = malloc(sizeof(struct fake_buffer_reloc) *
|
||||||
MAX_RELOCS);
|
MAX_RELOCS);
|
||||||
@@ -954,7 +1007,7 @@ dri_fake_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1008,8 +1061,11 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)
|
|||||||
/* Validate the target buffer if that hasn't been done. */
|
/* Validate the target buffer if that hasn't been done. */
|
||||||
if (!target_fake->validated) {
|
if (!target_fake->validated) {
|
||||||
ret = dri_fake_reloc_and_validate_buffer(r->target_buf);
|
ret = dri_fake_reloc_and_validate_buffer(r->target_buf);
|
||||||
if (ret != 0)
|
if (ret != 0) {
|
||||||
|
if (bo->virtual != NULL)
|
||||||
|
dri_bo_unmap(bo);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the value of the relocation entry. */
|
/* Calculate the value of the relocation entry. */
|
||||||
@@ -1028,8 +1084,15 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)
|
|||||||
if (bo->virtual != NULL)
|
if (bo->virtual != NULL)
|
||||||
dri_bo_unmap(bo);
|
dri_bo_unmap(bo);
|
||||||
|
|
||||||
if (bo_fake->validate_flags & DRM_BO_FLAG_WRITE)
|
if (bo_fake->validate_flags & DRM_BO_FLAG_WRITE) {
|
||||||
|
if (!(bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED))) {
|
||||||
|
if (bo_fake->backing_store == 0)
|
||||||
|
alloc_backing_store(bo);
|
||||||
|
|
||||||
|
bo_fake->card_dirty = GL_TRUE;
|
||||||
|
}
|
||||||
bufmgr_fake->performed_rendering = GL_TRUE;
|
bufmgr_fake->performed_rendering = GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return dri_fake_bo_validate(bo, bo_fake->validate_flags);
|
return dri_fake_bo_validate(bo, bo_fake->validate_flags);
|
||||||
}
|
}
|
||||||
@@ -1040,17 +1103,30 @@ dri_fake_process_relocs(dri_bo *batch_buf, GLuint *count_p)
|
|||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr;
|
||||||
dri_bo_fake *batch_fake = (dri_bo_fake *)batch_buf;
|
dri_bo_fake *batch_fake = (dri_bo_fake *)batch_buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
int retry_count = 0;
|
||||||
|
|
||||||
bufmgr_fake->performed_rendering = GL_FALSE;
|
bufmgr_fake->performed_rendering = GL_FALSE;
|
||||||
|
|
||||||
dri_fake_calculate_validate_flags(batch_buf);
|
dri_fake_calculate_validate_flags(batch_buf);
|
||||||
|
|
||||||
batch_fake->validate_flags = DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ;
|
batch_fake->validate_flags = DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ;
|
||||||
|
|
||||||
|
/* we've ran out of RAM so blow the whole lot away and retry */
|
||||||
|
restart:
|
||||||
ret = dri_fake_reloc_and_validate_buffer(batch_buf);
|
ret = dri_fake_reloc_and_validate_buffer(batch_buf);
|
||||||
|
if (bufmgr_fake->fail == 1) {
|
||||||
|
if (retry_count == 0) {
|
||||||
|
retry_count++;
|
||||||
|
dri_fake_kick_all(bufmgr_fake);
|
||||||
|
bufmgr_fake->fail = 0;
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
}
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
|
|
||||||
*count_p = 0; /* junk */
|
*count_p = 0; /* junk */
|
||||||
|
|
||||||
|
bufmgr_fake->current_total_size = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1097,6 +1173,29 @@ dri_fake_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
|
|||||||
dri_bo_fake_post_submit(batch_buf);
|
dri_bo_fake_post_submit(batch_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dri_fake_check_aperture_space(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
GLuint sz;
|
||||||
|
|
||||||
|
sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1);
|
||||||
|
|
||||||
|
if (bo_fake->size_accounted || bo_fake->is_static)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (bufmgr_fake->current_total_size + sz > bufmgr_fake->size) {
|
||||||
|
DBG("check_space: bo %d %d overflowed bufmgr\n", bo_fake->id, sz);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufmgr_fake->current_total_size += sz;
|
||||||
|
bo_fake->size_accounted = 1;
|
||||||
|
DBG("check_space: bo %d %d %d\n", bo_fake->id, bo->size, bufmgr_fake->current_total_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
dri_bufmgr *
|
dri_bufmgr *
|
||||||
dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
|
dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
@@ -1132,7 +1231,8 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
|
|||||||
bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
|
bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
|
||||||
bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;
|
bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;
|
||||||
bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit;
|
bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit;
|
||||||
bufmgr_fake->bufmgr.debug = GL_FALSE;
|
bufmgr_fake->bufmgr.check_aperture_space = dri_fake_check_aperture_space;
|
||||||
|
bufmgr_fake->bufmgr.debug = GL_TRUE;
|
||||||
|
|
||||||
bufmgr_fake->fence_emit = fence_emit;
|
bufmgr_fake->fence_emit = fence_emit;
|
||||||
bufmgr_fake->fence_wait = fence_wait;
|
bufmgr_fake->fence_wait = fence_wait;
|
||||||
@@ -1140,3 +1240,4 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
|
|||||||
|
|
||||||
return &bufmgr_fake->bufmgr;
|
return &bufmgr_fake->bufmgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -295,6 +295,7 @@ i915_emit_state(struct intel_context *intel)
|
|||||||
struct i915_context *i915 = i915_context(&intel->ctx);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
struct i915_hw_state *state = i915->current;
|
struct i915_hw_state *state = i915->current;
|
||||||
int i;
|
int i;
|
||||||
|
int ret, count;
|
||||||
GLuint dirty;
|
GLuint dirty;
|
||||||
BATCH_LOCALS;
|
BATCH_LOCALS;
|
||||||
|
|
||||||
@@ -311,7 +312,37 @@ i915_emit_state(struct intel_context *intel)
|
|||||||
*/
|
*/
|
||||||
intel_batchbuffer_require_space(intel->batch, get_state_size(state) + 8,
|
intel_batchbuffer_require_space(intel->batch, get_state_size(state) + 8,
|
||||||
LOOP_CLIPRECTS);
|
LOOP_CLIPRECTS);
|
||||||
|
count = 0;
|
||||||
|
again:
|
||||||
|
dirty = get_dirty(state);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if (dirty & I915_UPLOAD_BUFFERS) {
|
||||||
|
ret |= dri_bufmgr_check_aperture_space(state->draw_region->buffer);
|
||||||
|
ret |= dri_bufmgr_check_aperture_space(state->depth_region->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty & I915_UPLOAD_TEX_ALL) {
|
||||||
|
for (i = 0; i < I915_TEX_UNITS; i++)
|
||||||
|
if (dirty & I915_UPLOAD_TEX(i)) {
|
||||||
|
if (state->tex_buffer[i]) {
|
||||||
|
ret |= dri_bufmgr_check_aperture_space(state->tex_buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret) {
|
||||||
|
if (count == 0) {
|
||||||
|
count++;
|
||||||
|
intel_batchbuffer_flush(intel->batch);
|
||||||
|
goto again;
|
||||||
|
} else {
|
||||||
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state");
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* work out list of buffers to emit */
|
||||||
|
|
||||||
/* Do this here as we may have flushed the batchbuffer above,
|
/* Do this here as we may have flushed the batchbuffer above,
|
||||||
* causing more state to be dirty!
|
* causing more state to be dirty!
|
||||||
*/
|
*/
|
||||||
|
@@ -87,6 +87,10 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
|
|||||||
batch->ptr = batch->map;
|
batch->ptr = batch->map;
|
||||||
batch->dirty_state = ~0;
|
batch->dirty_state = ~0;
|
||||||
batch->cliprect_mode = IGNORE_CLIPRECTS;
|
batch->cliprect_mode = IGNORE_CLIPRECTS;
|
||||||
|
|
||||||
|
/* account batchbuffer in aperture */
|
||||||
|
dri_bufmgr_check_aperture_space(batch->buf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct intel_batchbuffer *
|
struct intel_batchbuffer *
|
||||||
@@ -264,7 +268,11 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
|
|||||||
dri_bo *buffer,
|
dri_bo *buffer,
|
||||||
GLuint flags, GLuint delta)
|
GLuint flags, GLuint delta)
|
||||||
{
|
{
|
||||||
dri_emit_reloc(batch->buf, flags, delta, batch->ptr - batch->map, buffer);
|
int ret;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
ret = dri_emit_reloc(batch->buf, flags, delta, batch->ptr - batch->map, buffer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Using the old buffer offset, write in what the right data would be, in case
|
* Using the old buffer offset, write in what the right data would be, in case
|
||||||
* the buffer doesn't move and we can short-circuit the relocation processing
|
* the buffer doesn't move and we can short-circuit the relocation processing
|
||||||
|
@@ -54,6 +54,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
|
|||||||
|
|
||||||
struct intel_context *intel;
|
struct intel_context *intel;
|
||||||
const intelScreenPrivate *intelScreen;
|
const intelScreenPrivate *intelScreen;
|
||||||
|
int ret;
|
||||||
|
|
||||||
DBG("%s\n", __FUNCTION__);
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
@@ -123,6 +124,15 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
again:
|
||||||
|
ret = dri_bufmgr_check_aperture_space(dst->buffer);
|
||||||
|
ret |= dri_bufmgr_check_aperture_space(src->buffer);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
intel_batchbuffer_flush(intel->batch);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nbox; i++, pbox++) {
|
for (i = 0; i < nbox; i++, pbox++) {
|
||||||
drm_clip_rect_t box = *pbox;
|
drm_clip_rect_t box = *pbox;
|
||||||
|
|
||||||
|
@@ -817,7 +817,7 @@ dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
|
|||||||
* the relocation entry write when the buffer hasn't moved from the
|
* the relocation entry write when the buffer hasn't moved from the
|
||||||
* last known offset in target_buf.
|
* last known offset in target_buf.
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
dri_ttm_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
dri_ttm_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
||||||
GLuint offset, dri_bo *target_buf)
|
GLuint offset, dri_bo *target_buf)
|
||||||
{
|
{
|
||||||
@@ -851,6 +851,7 @@ dri_ttm_emit_reloc(dri_bo *reloc_buf, uint64_t flags, GLuint delta,
|
|||||||
reloc_buf_ttm->reloc_buf_data[0]++; /* Increment relocation count */
|
reloc_buf_ttm->reloc_buf_data[0]++; /* Increment relocation count */
|
||||||
/* Check wraparound */
|
/* Check wraparound */
|
||||||
assert(reloc_buf_ttm->reloc_buf_data[0] != 0);
|
assert(reloc_buf_ttm->reloc_buf_data[0] != 0);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1039,6 +1040,15 @@ intel_ttm_enable_bo_reuse(dri_bufmgr *bufmgr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
dri_ttm_check_aperture_space(dri_bo *bo)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the TTM buffer manager, which uses the kernel to allocate, map,
|
* Initializes the TTM buffer manager, which uses the kernel to allocate, map,
|
||||||
* and manage map buffer objections.
|
* and manage map buffer objections.
|
||||||
@@ -1082,7 +1092,7 @@ intel_bufmgr_ttm_init(int fd, unsigned int fence_type,
|
|||||||
bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
|
bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
|
||||||
bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;
|
bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;
|
||||||
bufmgr_ttm->bufmgr.debug = GL_FALSE;
|
bufmgr_ttm->bufmgr.debug = GL_FALSE;
|
||||||
|
bufmgr_ttm->bufmgr.check_aperture_space = dri_ttm_check_aperture_space;
|
||||||
/* Initialize the linked lists for BO reuse cache. */
|
/* Initialize the linked lists for BO reuse cache. */
|
||||||
for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++)
|
for (i = 0; i < INTEL_TTM_BO_BUCKETS; i++)
|
||||||
bufmgr_ttm->cache_bucket[i].tail = &bufmgr_ttm->cache_bucket[i].head;
|
bufmgr_ttm->cache_bucket[i].tail = &bufmgr_ttm->cache_bucket[i].head;
|
||||||
|
Reference in New Issue
Block a user