• Daniel Vetter's avatar
    drm/i915: Track frontbuffer invalidation/flushing · f99d7069
    Daniel Vetter authored
    So these are the guts of the new beast. This tracks when a frontbuffer
    gets invalidated (due to frontbuffer rendering) and hence should be
    constantly scaned out, and when it's flushed again and can be
    compressed/one-shot-upload.
    
    Rules for flushing are simple: The frontbuffer needs one more full
    upload starting from the next vblank. Which means that the flushing
    can _only_ be called once the frontbuffer update has been latched.
    
    But this poses a problem for pageflips: We can't just delay the
    flushing until the pageflip is latched, since that would pose the risk
    that we override frontbuffer rendering that has been scheduled
    in-between the pageflip ioctl and the actual latching.
    
    To handle this track asynchronous invalidations (and also pageflip)
    state per-ring and delay any in-between flushing until the rendering
    has completed. And also cancel any delayed flushing if we get a new
    invalidation request (whether delayed or not).
    
    Also call intel_mark_fb_busy in both cases in all cases to make sure
    that we keep the screen at the highest refresh rate both on flips,
    synchronous plane updates and for frontbuffer rendering.
    
    v2: Lots of improvements
    
    Suggestions from Chris:
    - Move invalidate/flush in flush_*_domain and set_to_*_domain.
    - Drop the flush in busy_ioctl since it's redundant. Was a leftover
      from an earlier concept to track flips/delayed flushes.
    - Don't forget about the initial modeset enable/final disable.
      Suggested by Chris.
    
    Track flips accurately, too. Since flips complete independently of
    rendering we need to track pending flips in a separate mask. Again if
    an invalidate happens we need to cancel the evenutal flush to avoid
    races.
    
    v3:
    Provide correct header declarations for flip functions. Currently not
    needed outside of intel_display.c, but part of the proper interface.
    
    v4: Add proper domain management to fbcon so that the fbcon buffer is
    also tracked correctly.
    
    v5: Fixup locking around the fbcon set_to_gtt_domain call.
    
    v6: More comments from Chris:
    - Split out fbcon changes.
    - Drop superflous checks for potential scanout before calling intel_fb
      functions - we can micro-optimize this later.
    - s/intel_fb_/intel_fb_obj_/ to make it clear that this deals in gem
      object. We already have precedence for fb_obj in the pin_and_fence
      functions.
    
    v7: Clarify the semantics of the flip flush handling by renaming
    things a bit:
    - Don't go through a gem object but take the relevant frontbuffer bits
      directly. These functions center on the plane, the actual object is
      irrelevant - even a flip to the same object as already active should
      cause a flush.
    - Add a new intel_frontbuffer_flip for synchronous plane updates. It
      currently just calls intel_frontbuffer_flush since the implemenation
      differs.
    
    This way we achieve a clear split between one-shot update events on
    one side and frontbuffer rendering with potentially a very long delay
    between the invalidate and flush.
    
    Chris and I also had some discussions about mark_busy and whether it
    is appropriate to call from flush. But mark busy is a state which
    should be derived from the 3 events (invalidate, flush, flip) we now
    have by the users, like psr does by tracking relevant information in
    psr.busy_frontbuffer_bits. DRRS (the only real use of mark_busy for
    frontbuffer) needs to have similar logic. With that the overall
    mark_busy in the core could be removed.
    
    v8: Only when retiring gpu buffers only flush frontbuffer bits we
    actually invalidated in a batch. Just for safety since before any
    additional usage/invalidate we should always retire current rendering.
    Suggested by Chris Wilson.
    
    v9: Actually use intel_frontbuffer_flip in all appropriate places.
    Spotted by Chris.
    
    v10: Address more comments from Chris:
    - Don't call _flip in set_base when the crtc is inactive, avoids redunancy
      in the modeset case with the initial enabling of all planes.
    - Add comments explaining that the initial/final plane enable/disable
      still has work left to do before it's fully generic.
    
    v11: Only invalidate for gtt/cpu access when writing. Spotted by Chris.
    
    v12: s/_flush/_flip/ in intel_overlay.c per Chris' comment.
    
    Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
    Cc: Chris Wilson <chris@chris-wilson.co.uk>
    Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
    f99d7069
i915_drv.h 84 KB