#include "pan_util.h"
 #include "pandecode/decode.h"
 
-static void
+void
 panfrost_drm_mmap_bo(struct panfrost_screen *screen, struct panfrost_bo *bo)
 {
         struct drm_panfrost_mmap_bo mmap_bo = { .handle = bo->gem_handle };
          * never map since we don't care about their contents; they're purely
          * for GPU-internal use. */
 
-        if (!(flags & PAN_ALLOCATE_INVISIBLE))
+        if (!(flags & (PAN_ALLOCATE_INVISIBLE | PAN_ALLOCATE_DELAY_MMAP)))
                 panfrost_drm_mmap_bo(screen, bo);
 
         pipe_reference_init(&bo->reference, 1);
 
         size_t bo_size;
 
         panfrost_setup_slices(pres, &bo_size);
-        pres->bo = panfrost_drm_create_bo(screen, bo_size, 0);
+
+        /* We create a BO immediately but don't bother mapping, since we don't
+         * care to map e.g. FBOs which the CPU probably won't touch */
+        pres->bo = panfrost_drm_create_bo(screen, bo_size, PAN_ALLOCATE_DELAY_MMAP);
 }
 
 static struct pipe_resource *
 
         *out_transfer = &transfer->base;
 
+        /* If we haven't already mmaped, now's the time */
+
+        if (!bo->cpu) {
+                struct panfrost_screen *screen = pan_screen(pctx->screen);
+                panfrost_drm_mmap_bo(screen, bo);
+        }
+
         /* Check if we're bound for rendering and this is a read pixels. If so,
          * we need to flush */
 
 
 panfrost_drm_create_bo(struct panfrost_screen *screen, size_t size,
                        uint32_t flags);
 void
+panfrost_drm_mmap_bo(struct panfrost_screen *screen, struct panfrost_bo *bo);
+void
 panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo);
 struct panfrost_bo *
 panfrost_drm_import_bo(struct panfrost_screen *screen, int fd);