What follows is my understanding of the texture management system in the
DRI.  This is all based on the Radeon driver in the 11-Feb-2002 CVS of the
mesa-4-0-branch.  While it is based on the Radeon code, all drivers except
gamma and tdfx seem to use the same scheme (and virtually identical code).
If there are any drivers that differ in any significant way, could
knowledgeable parties please comment?

- Excluding the texture backing store, which is managed by Mesa, texture
  data is tracked in two places.  The per-screen (card) SAREA divides each
  type of texturable memory (on-card, AGP, etc.) into an array of fixed
  sized chunks (RADEONSAREAPriv.texList in
  programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h).  The number of
  these chunks is a compile-time constant, and it cannot be changed without
  destroying the universe.  That is, any changes here will present major
  compatability issues.  Currently, this constant is 64.  So, for the new
  128MB Radeon 8500 cards, each block of memory will likely be 1MB or more.
  This is not as bad as it may first seem, see below.  The usage of each
  type of memory is also tracked per-context. 

- The per-context memory tracking is done using a memHeap_t.  Allocations
  from the memHeap_t (see lib/GL/mesa/src/drv/common/mm.c) are done at byte
  granularity.  When a context needs a block of texture memory, it is
  allocated from the memHeap_t.  This results in very little memory
  fragmentation (within a context).  After the allocation is made, the map
  of allocated memory in the SAREA is updated (radeonUpdateTexLRU in
  lib/GL/mesa/src/drv/radeon/radeon_texmem.c).  Basically, each block of
  memory in texList that corresponds to an allocated region (in the
  per-context memHeap_t) is marked as allocated.

- The texList isn't just an array of blocks.  It's also a priority queue
  (linked list).  As each texture is accessed, the blocks that it occupies
  are moved to the head of the queue.  In the Radeon code, each time a
  texture is uploaded or bound to a texture unit, the blocks of memory (in
  AGP space or on-card) are moved to the head of the texList queue.

- If an allocation (via the memHeap_t) fails when texture space is allocated
  (radeonUploadTexImages in lib/GL/mesa/src/drv/radeon/radeon_texmem.c),
  blocks at the end of the texList queue are freed until the allocation can
  succeed.  This may be an area where the algorithm could be improved.  For
  example, it might be better to find the largest free block (in the
  memHeap_t) and release memory around that block in LRU or least-often-used
  fashion until the allocation can succeed.  This may be too difficult to get
  right or too slow when done right.  Someone would have to try it and see.

- Each time a direct-client detects that another client has held the
  per-screen lock, radeonGetLock is called.  This synchronizes the
  per-context vision of the hardware state.  Part of this synchronization is
  synchronizing the view of texture memory.  In addition to the texList, the
  SAREA holds a texAge array.  This array stores the generation number of
  each of the texture heaps.  If a client detects that the generation number
  of a heap has changed in radeonGetLock, it calls radeonAgeTextures for
  that heap.  radeonAgeTextures runs through the texList looking for blocks
  with a more recent generation number.  Each block that has a newer
  generation is passed to radeonTexturesGone.

- radeonTexturesGone searches the per-context memHeap_t for an allocated
  region matching the block with the updated generation.  When a matching
  region is found, it is freed, and if the region was for a texture in the
  local context, the local state of that texture is updated.  If the updated
  block (from the global context) is "in-use" (i.e., some other context has
  stolen that block from the current context), the block is re-allocated and
  marked as in-use by another context.

- It seems that about 2 years ago a few people (from the CVS log) had taken
  a stab at factoring the common code out and put it in
  shared_texture_lru.[ch] in lib/GL/mesa/src/drv/common.  This code looks
  like a pretty reasonable start, but it isn't used and hasn't been touched
  (at least not in CVS) since 4-April-2000.

-- 
Tell that to the Marines!

_______________________________________________
Dri-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to