From: Marek Olšák <marek.ol...@amd.com> This is controversial, but I don't see a better way out of this.
Tonga has 2 GB of VRAM and 2 GB of GTT. amdgpu is not capable of submitting an IB referencing 1 GB of VRAM and 1 GB of GTT. The CS ioctl never succeeds even though it's far below the limits. Without this, "dEQP-GLES2.functional.color_clear.single_rgb" fails to submit an IB. With this, dEQP throws a framebuffer-incomplete exception and kills the process. IMO, failing the CS ioctl is worse for stability than failing big allocations. --- src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 3 +++ src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 12 +++++++++++- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 3 +++ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 10 +++++++++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 1805ce6..8e3a87a 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -491,6 +491,9 @@ amdgpu_bo_create(struct radeon_winsys *rws, struct amdgpu_winsys_bo *bo; unsigned usage = 0, pb_cache_bucket; + if (size > ws->info.max_alloc_size) + return NULL; + /* Align size to page size. This is the minimum alignment for normal * BOs. Aligning this here helps the cached bufmgr. Especially small BOs, * like constant/uniform buffers, can benefit from better and more reuse. diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index 9a04cbe..44efc2e 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -271,7 +271,17 @@ static bool do_winsys_init(struct amdgpu_winsys *ws, int fd) ws->info.gart_size = gtt.heap_size; ws->info.vram_size = vram.heap_size; /* TODO: the kernel reports vram/gart.max_allocation == 251 MB (bug?) */ - ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size); + + /* TODO: Drop this limitation once buffers don't have to occupy one + * continuous piece of memory. (e.g. split buffers) + * + * At the moment, the memory manager isn't practically capable of finding + * space for a buffer whose size is a half of the heap. Limiting + * max_alloc_size to 1/3 of the largest heap still doesn't guarantee + * successful command submission, but it's the least we can do. + */ + ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size) / 3; + /* convert the shader clock from KHz to MHz */ ws->info.max_shader_clock = ws->amdinfo.max_engine_clk / 1000; ws->info.max_se = ws->amdinfo.num_shader_engines; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 897b536..7e663ee 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -731,6 +731,9 @@ radeon_winsys_bo_create(struct radeon_winsys *rws, if (size > UINT_MAX) return NULL; + if (size > ws->info.max_alloc_size) + return NULL; + /* Align size to page size. This is the minimum alignment for normal * BOs. Aligning this here helps the cached bufmgr. Especially small BOs, * like constant/uniform buffers, can benefit from better and more reuse. diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c index 1b32c37..d19d542 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c @@ -373,7 +373,15 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws) ws->info.gart_size = gem_info.gart_size; ws->info.vram_size = gem_info.vram_size; - ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size); + /* TODO: Drop this limitation once buffers don't have to occupy one + * continuous piece of memory. (e.g. split buffers) + * + * At the moment, the memory manager isn't practically capable of finding + * space for a buffer whose size is a half of the heap. Limiting + * max_alloc_size to 1/3 of the largest heap still doesn't guarantee + * successful command submission, but it's the least we can do. + */ + ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size) / 3; if (ws->info.drm_minor < 40) ws->info.max_alloc_size = MIN2(ws->info.max_alloc_size, 256*1024*1024); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev