int mipbias = 4; // 3 is sufficient, but at 4 it loads #endregion Fields #region Constructors public VirtualTexture( D3D10.Device device, VirtualTextureInfo info, int atlassize, int uploadsperframe, string filename ) { this.device = device; this.info = info; this.atlascount = atlassize / info.PageSize; this.uploadsperframe = uploadsperframe; indexer = new PageIndexer( info ); toload = new List<PageCount>( indexer.Count ); Console.Write( "Creating PageAtlas..."); atlas = new TextureAtlas( device, info, atlascount, uploadsperframe ); Console.WriteLine("done."); Console.Write( "Creating PageLoader..." ); loader = new PageLoader( filename + ".cache", indexer, info ); Console.WriteLine("done."); cache = new PageCache( info, atlas, loader, indexer, atlascount ); Console.Write( "Creating PageTable..."); pagetable = new PageTable( device, cache, info, indexer ); Console.WriteLine("done."); }
readonly int[] sizes; // This stores the sizes of various mip levels #endregion Fields #region Constructors public PageIndexer( VirtualTextureInfo info ) { this.info = info; mipcount = MathExtensions.Log2(info.PageTableSize) + 1; sizes = new int[mipcount]; for( int i = 0; i < mipcount; ++i ) sizes[i] = ( info.VirtualTextureSize / info.TileSize ) >> i; offsets = new int[mipcount]; Count = 0; for( int i = 0; i < mipcount; ++i ) { offsets[i] = Count; Count += sizes[i] * sizes[i]; } // Calculate reverse mapping reverse = new Page[Count]; for( int i = 0; i < mipcount; ++i ) { int size = sizes[i]; for( int y = 0; y < size; ++y ) for( int x = 0; x < size; ++x ) { Page page = new Page( x, y, i ); reverse[this[page]] = page; } } }
public TextureAtlas( D3D10.Device device, VirtualTextureInfo info, int count, int uploadsperframe ) { this.device = device; this.info = info; int pagesize = info.PageSize; resource = new Direct3D.Texture( device, count * pagesize, count * pagesize, DXGI.Format.R8G8B8A8_UNorm, D3D10.ResourceUsage.Default, 1 ); staging = new Direct3D.StagingTexturePool( device, pagesize, pagesize, DXGI.Format.R8G8B8A8_UNorm, uploadsperframe, D3D10.CpuAccessFlags.Write ); }
public PageLoader( string filename, PageIndexer indexer, VirtualTextureInfo info ) { this.filename = filename; this.info = info; this.indexer = indexer; file = new TileDataFile( filename, info, FileAccess.Read ); readthread = new ProcessingThread<ReadState>( LoadPage, PageLoadComplete ); }
public TileDataFile( string filename, VirtualTextureInfo info, FileAccess access ) { Debug.Assert( DataOffset >= Marshal.SizeOf(typeof(VirtualTextureInfo)) ); this.info = info; this.size = info.PageSize * info.PageSize * 4; FileMode mode = FileMode.Open; if( access != FileAccess.Read ) mode = FileMode.OpenOrCreate; file = new FileStream( filename, mode, access, FileShare.None, 4096, FileOptions.RandomAccess ); }
int current; // This is used for generating the texture atlas indices before the lru is full #endregion Fields #region Constructors public PageCache( VirtualTextureInfo info, TextureAtlas atlas, PageLoader loader, PageIndexer indexer, int count ) { this.info = info; this.atlas = atlas; this.loader = loader; this.indexer = indexer; this.count = count; lru = new LruCollection<Page,Point>( count * count ); lru.Removed += ( page, point ) => Removed( page, point ); loader.LoadComplete += LoadComplete; loading = new HashSet<Page>(); }
public PageTable( D3D10.Device device, PageCache cache, VirtualTextureInfo info, PageIndexer indexer ) { this.info = info; this.device = device; this.indexer = indexer; quadtree = new Quadtree(new Rectangle(0, 0, info.PageTableSize, info.PageTableSize), MathExtensions.Log2(info.PageTableSize)); int size = info.PageTableSize; texture = new Direct3D.Texture( device, size, size, DXGI.Format.R8G8B8A8_UNorm, D3D10.ResourceUsage.Default, 0 ); staging = new Direct3D.WriteTexture( device, size, size, DXGI.Format.R8G8B8A8_UNorm ); cache.Added += ( Page page, Point pt ) => quadtree.Add( page, pt ); cache.Removed += ( Page page, Point pt ) => quadtree.Remove( page ); SetupDataAndInfo(); }