From 996de63aec09437c31b256e9d7215d7522b3dce7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 28 Mar 2019 18:31:18 +0200 Subject: lib/igt_fb: Don't use blitter for large buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The blitter stride is limited to <32k. Fall back to gtt mmap or rendercopy if we're about to exceed that. Not quite sure why we're not just using gtt mmap for Y tiling always. But let's keep it like that for now. v2: Use rendercopy as the fallback for Yf v3: Deal with gen4+ tiled stride correctly (Chris) Cc: Chris Wilson Cc: Dhinakaran Pandiyan Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson --- lib/igt_fb.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/igt_fb.c b/lib/igt_fb.c index f5c9a9f1..4210f745 100644 --- a/lib/igt_fb.c +++ b/lib/igt_fb.c @@ -1580,6 +1580,31 @@ struct fb_blit_upload { struct intel_batchbuffer *batch; }; +static int max_blitter_stride(int fd, uint64_t modifier) +{ + int stride = 32768; + + if (intel_gen(intel_get_drm_devid(fd)) >= 4 && + modifier != DRM_FORMAT_MOD_NONE) + stride *= 4; + + return stride; +} + +static bool use_rendercopy(const struct igt_fb *fb) +{ + return is_ccs_modifier(fb->modifier) || + (fb->modifier == I915_FORMAT_MOD_Yf_TILED && + fb->strides[0] >= max_blitter_stride(fb->fd, fb->modifier)); +} + +static bool use_blitter(const struct igt_fb *fb) +{ + return (fb->modifier == I915_FORMAT_MOD_Y_TILED || + fb->modifier == I915_FORMAT_MOD_Yf_TILED) && + fb->strides[0] < max_blitter_stride(fb->fd, fb->modifier); +} + static void init_buf(struct fb_blit_upload *blit, struct igt_buf *buf, const struct igt_fb *fb, @@ -2762,7 +2787,7 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb) blit->base.fd = fd; blit->base.fb = fb; - if (is_ccs_modifier(fb->modifier)) { + if (use_rendercopy(fb)) { blit->base.bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); blit->base.batch = intel_batchbuffer_alloc(blit->base.bufmgr, intel_get_drm_devid(fd)); @@ -2774,9 +2799,7 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb) &blit->shadow_fb); igt_assert(blit->shadow_ptr); - if (fb->modifier == LOCAL_I915_FORMAT_MOD_Y_TILED || - fb->modifier == LOCAL_I915_FORMAT_MOD_Yf_TILED || - is_ccs_modifier(fb->modifier)) { + if (use_rendercopy(fb) || use_blitter(fb)) { setup_linear_mapping(&blit->base); } else { blit->base.linear.fb = *fb; @@ -2856,10 +2879,9 @@ cairo_surface_t *igt_get_cairo_surface(int fd, struct igt_fb *fb) ((f->cairo_id == CAIRO_FORMAT_INVALID) && (f->pixman_id != PIXMAN_invalid))) create_cairo_surface__convert(fd, fb); - else if (is_ccs_modifier(fb->modifier)) + else if (use_rendercopy(fb)) create_cairo_surface__rendercopy(fd, fb); - else if (fb->modifier == LOCAL_I915_FORMAT_MOD_Y_TILED || - fb->modifier == LOCAL_I915_FORMAT_MOD_Yf_TILED) + else if (use_blitter(fb)) create_cairo_surface__blit(fd, fb); else create_cairo_surface__gtt(fd, fb); -- cgit v1.2.3