This follows on from the previous post to discuss an implementation of
the memory manager for managing only AGP memory.

Right now, I'm primarily concerned with unified memory chipsets, like
i915 and via. This memory manager would be suitable for managing the
AGP memory on non-unified chipsets, but a different implementation
would be needed for the on-card video ram, based more on dma and
copying than map/unmapping as will be seen below.

In the past there has been talk about mapping user memory into the GTT
aperture as a mechanism to avoid copy-based uploading.  What I'm
proposing is that this type of mapping becomes the only or at least
primary way of getting data and memory into the GART aperture.

In the simplest case, the API functions would have approximately the
following implementations:


    CreateBuffer(GLuint size)

        - Allocate size bytes of virtual memory.

    BufferData(void *ptr)
    BufferSubData(...)

        - Simplest implementation:  MapBuffer(), memcpy, UnmapBuffer()
        - May be possible to do better, but get something working first.
        
    ValidateBuffer()

         - Recall that this is the function called by the driver
           inside LOCK_HARDWARE() to indicate it wants to use the
           buffer.  So this will trigger the "upload", which in this
           implementation is always handled by mapping the data into
           the GART table.

         - Search the agp address space for contiguous unused range
           matching buffer size.  If none available, attempt to
           rearrange and evict buffers to free space.

         - Mlock buffer pages.
         - Map buffer pages into GART.
         - Perhaps take some steps to ensure they aren't accessed
           except through the gart.

    MapBuffer()

        - If the buffer is mlocked and mapped into the GART, unmap it.
        - Return a virtual address space pointer to the buffer.

    UnmapBuffer()

        - Could be a noop.  But perhaps take some steps to ensure
          the pointer above is invalidated.

    DestroyBuffer()

        - If buffer is mlocked and mapped to GART, unmap it.
        - Free the virtual memory allocated above.

The idea of a fixed pool of AGP memory sitting there whether in use or
not is something I'd like to move away from, and this ties in very
well with some of the questions that an AGP memory manager raises:

1) When buffers are evicted from AGP memory, how are the contents of
   the buffers preserved?

    - The naive answer is that we must allocate memory somewhere and
      then back-copy from AGP to that allocated memory.  This is
      deadly slow and would probably mean that any such design would
      actually be slower than the current memory manager under texture
      swapping.

    - My proposal is that because the buffer is simply user memory
      that has been mapped into AGP, the way to free up AGP memory is
      to just unmap that buffer. There is no need to copy any data as
      the client process still holds the pages.

    - Note that in this proposal AGP memory isn't a constrained
      resource, because "AGP memory" is really just mlocked client
      memory which has been mapped into the GART.  The constraints are
      1) mlocked client memory (not our problem) and 2) the AGP address
      space.


2) What happens when free space becomes fragmented?

    - The naive answer is that you use the blitter to copy data within
      the static AGP memory pool to reduce fragmentation.

    - My proposal is that you never attempt to rearrange memory in
      that way, because doing so would remove the data from the pages
      the client allocated to hold it - you'd then have to tell the
      client that the data had moved to a new bunch of pages and it
      would have to somehow map them into its memory.  A big hassle.

    - Instead you have two options:

        1) Unmap buffers from their old AGP addresses and re-map them
           into new contiguous addresses starting.

        2) Alternately, just unmap the offending buffers and let the
           client re-map them when they are next required.


3) What about back and depth buffers?

    - These are buffer objects just like any other, no special
      treatment is required.  The X server on initialization simply
      creates a buffer of this size.  The physical memory won't be
      allocated, let alone mapped into the GART, until the first time
      a client does ValidateBuffer( backbuffer ).

4) What about the front buffer?

    - OK, you got me there.  There needs to be some way of tagging
      this buffer as special so it doesn't get moved or evicted except
      by the X server (eg. during rotate events).


What does all this mean?

1) I think this is the first solution for memory management that I can
   imagine implementing.  Also it's one which gives reasonable
   performance when data is being evicted from the GART.

2) We need to understand mapping and unmapping from the GART a lot
   better.  There was a simple patch posted to xorg-devel for i915 X
   image upload using this recently.

3) We need to understand how this usage can be made to fit into the
   existing agpgart kernel infrastructure.

Keith


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to