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 );
        }
Beispiel #4
0
        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 );
        }
Beispiel #6
0
        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>();
        }
Beispiel #7
0
        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();
        }