sna: Align upload buffers to 128

This seems to be a restriction (observed on 965gm at least) that we
have incoherent sampler cache if we write within 128 bytes of a busy
buffer. This is either due to a restriction on neighbouring cachelines
(like the earlier BLT limitations) or an effect of sampler prefetch.

Reported-by: Zdenek Kabelac <zkabelac@redhat.com>
References: https://bugs.freedesktop.org/show_bug.cgi?id=50477
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-06-18 23:43:00 +01:00
parent 39e5c74915
commit 291b3c4367
1 changed files with 12 additions and 5 deletions

View File

@ -71,6 +71,13 @@ search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
#define DBG(x) ErrorF x
#endif
/* Worst case seems to be 965gm where we cannot write within a cacheline that
* is being simultaneously being read by the GPU, or within the sampler
* prefetch. In general, the chipsets seem to have a requirement that sampler
* offsets be aligned to a cacheline (64 bytes).
*/
#define UPLOAD_ALIGNMENT 128
#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE)
#define NUM_PAGES(x) (((x) + PAGE_SIZE-1) / PAGE_SIZE)
@ -1134,7 +1141,7 @@ static void _kgem_bo_delete_partial(struct kgem *kgem, struct kgem_bo *bo)
DBG(("%s: size=%d, offset=%d, parent used=%d\n",
__FUNCTION__, bo->size.bytes, bo->delta, io->used));
if (ALIGN(bo->delta + bo->size.bytes, 64) == io->used)
if (ALIGN(bo->delta + bo->size.bytes, UPLOAD_ALIGNMENT) == io->used)
io->used = bo->delta;
}
@ -3619,9 +3626,9 @@ static struct kgem_partial_bo *partial_bo_alloc(int num_pages)
{
struct kgem_partial_bo *bo;
bo = malloc(sizeof(*bo) + 128 + num_pages * PAGE_SIZE);
bo = malloc(sizeof(*bo) + 2*UPLOAD_ALIGNMENT + num_pages * PAGE_SIZE);
if (bo) {
bo->mem = (void *)ALIGN((uintptr_t)bo + sizeof(*bo), 64);
bo->mem = (void *)ALIGN((uintptr_t)bo + sizeof(*bo), UPLOAD_ALIGNMENT);
bo->mmapped = false;
}
@ -4005,7 +4012,7 @@ init:
__FUNCTION__, alloc, bo->base.handle));
done:
bo->used = ALIGN(bo->used, 64);
bo->used = ALIGN(bo->used, UPLOAD_ALIGNMENT);
assert(bo->mem);
*ret = (char *)bo->mem + offset;
return kgem_create_proxy(kgem, &bo->base, offset, size);
@ -4052,7 +4059,7 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem,
* that it can be allocated to other pixmaps.
*/
min = bo->delta + height * stride;
min = ALIGN(min, 64);
min = ALIGN(min, UPLOAD_ALIGNMENT);
if (io->used != min) {
DBG(("%s: trimming partial buffer from %d to %d\n",
__FUNCTION__, io->used, min));