Exemple #1
0
        /// <summary>
        /// Translates virtual texture address to physical rectangle in physical texture.
        /// </summary>
        /// <param name="address"></param>
        /// <param name="rectangle"></param>
        /// <returns>False if address is not presented in cache</returns>
        public bool TranslateAddress(VTAddress address, VTTile tile, out Rectangle rectangle)
        {
            Page page;

            if (cache.TryGetValue(address, out page))
            {
                var pa   = page.Address;
                var ppc  = pageCount;
                var size = VTConfig.PageSizeBordered;
                int x    = (pa % ppc) * size;
                int y    = (pa / ppc) * size;
                int w    = size;
                int h    = size;
                rectangle = new Rectangle(x, y, w, h);

                page.Tile = tile;

                return(true);
            }
            else
            {
                rectangle = new Rectangle();
                return(false);
            }
        }
Exemple #2
0
 /// <summary>
 /// Request texture loading
 /// </summary>
 /// <param name="address"></param>
 public void RequestTile(VTAddress address)
 {
                 #if USE_PRIORITY_QUEUE
     requestQueue.Enqueue(address.MipLevel, address);
                 #else
     requestQueue.Enqueue(address);
                 #endif
 }
Exemple #3
0
        /// <summary>
        /// Clears cache
        /// </summary>
        public void Purge()
        {
            cache = new LRUCache <VTAddress, Page>(capacity);

            //	fill cache with dummy pages :
            for (int i = 0; i < capacity; i++)
            {
                var va   = VTAddress.CreateBadAddress(i);
                var page = new Page(va, i, pageCount, physTexSize);
                cache.Add(va, page);
            }
        }
Exemple #4
0
            public Page(VTAddress va, int pa, int physPageCount, int physicalTexSize)
            {
                this.VA      = va;
                this.Address = pa;

                var physTexSize = (float)physicalTexSize;
                var border      = VTConfig.PageBorderWidth;
                var pageSize    = VTConfig.PageSizeBordered;

                this.X = ((pa % physPageCount) * pageSize + border) / physTexSize;
                this.Y = ((pa / physPageCount) * pageSize + border) / physTexSize;
            }
Exemple #5
0
        /// <summary>
        /// Adds new page to cache.
        ///
        ///	If page exists:
        ///		- LFU index of existing page is shifted.
        ///		- returns FALSE
        ///
        /// If page with given address does not exist:
        ///		- page added to cache.
        ///		- some pages could be evicted
        ///		- return TRUE
        ///
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public bool Add(VTAddress virtualAddress, out int physicalAddress)
        {
            Page page;

            if (dictionary.TryGetValue(virtualAddress, out page))
            {
                page.LfuIndex |= (byte)0x1;

                physicalAddress = page.Address;

                return(false);
            }
            else
            {
                if (GetFreePhysicalAddress(out physicalAddress))
                {
                    page = new Page(virtualAddress, physicalAddress, VTConfig.PhysicalPageCount);

                    table[physicalAddress] = page;
                    dictionary.Add(virtualAddress, page);

                    return(true);
                }
                else
                {
                    page = GetPageToDiscard();

                    physicalAddress = page.Address;
                    dictionary.Remove(page.VA);

                    page = new Page(virtualAddress, physicalAddress, VTConfig.PhysicalPageCount);

                    table[physicalAddress] = page;
                    dictionary.Add(virtualAddress, page);

                    return(true);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Adds new page to cache.
        ///
        ///	If page exists:
        ///		- LFU index of existing page is shifted.
        ///		- returns FALSE
        ///
        /// If page with given address does not exist:
        ///		- page added to cache.
        ///		- some pages could be evicted
        ///		- return TRUE
        ///
        /// </summary>
        /// <param name="address"></param>
        /// <returns>False if page is already exist</returns>
        public bool Add(VTAddress virtualAddress, out int physicalAddress)
        {
            Page page;

            if (cache.TryGetValue(virtualAddress, out page))
            {
                physicalAddress = page.Address;

                return(false);
            }
            else
            {
                cache.Discard(out page);

                var newPage = new Page(virtualAddress, page.Address, pageCount, physTexSize);

                cache.Add(virtualAddress, newPage);

                physicalAddress = newPage.Address;

                return(true);
            }
        }
Exemple #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="depthBuffer"></param>
        /// <param name="hdrTarget"></param>
        /// <param name="diffuse"></param>
        /// <param name="specular"></param>
        /// <param name="normals"></param>
        internal void RenderGBuffer(GameTime gameTime, StereoEye stereoEye, Camera camera, HdrFrame frame, RenderWorld rw, bool staticOnly)
        {
            using (new PixEvent("RenderGBuffer")) {
                if (surfaceShader == null)
                {
                    return;
                }

                if (rs.SkipSceneRendering)
                {
                    return;
                }

                var device = Game.GraphicsDevice;

                var view         = camera.GetViewMatrix(stereoEye);
                var projection   = camera.GetProjectionMatrix(stereoEye);
                var viewPosition = camera.GetCameraPosition4(stereoEye);

                var cbData       = new CBMeshInstanceData();
                var cbDataSubset = new CBSubsetData();

                var hdr      = frame.HdrBuffer.Surface;
                var depth    = frame.DepthBuffer.Surface;
                var gbuffer0 = frame.GBuffer0.Surface;
                var gbuffer1 = frame.GBuffer1.Surface;
                var feedback = frame.FeedbackBuffer.Surface;

                device.ResetStates();

                device.SetTargets(depth, hdr, gbuffer0, gbuffer1, feedback);
                device.PixelShaderSamplers[0] = SamplerState.LinearPointClamp;
                device.PixelShaderSamplers[1] = SamplerState.PointClamp;
                device.PixelShaderSamplers[2] = SamplerState.AnisotropicClamp;

                var instances = rw.Instances;

                if (instances.Any())
                {
                    device.PixelShaderResources[1] = rs.VTSystem.PageTable;
                    device.PixelShaderResources[2] = rs.VTSystem.PhysicalPages0;
                    device.PixelShaderResources[3] = rs.VTSystem.PhysicalPages1;
                    device.PixelShaderResources[4] = rs.VTSystem.PhysicalPages2;
                }

                //#warning INSTANSING!
                foreach (var instance in instances)
                {
                    if (!instance.Visible)
                    {
                        continue;
                    }

                    if (staticOnly && !instance.Static)
                    {
                        continue;
                    }

                    cbData.View           = view;
                    cbData.Projection     = projection;
                    cbData.World          = instance.World;
                    cbData.ViewPos        = viewPosition;
                    cbData.Color          = instance.Color;
                    cbData.ViewBounds     = new Vector4(hdr.Width, hdr.Height, hdr.Width, hdr.Height);
                    cbData.VTPageScaleRCP = rs.VTSystem.PageScaleRCP;

                    constBuffer.SetData(cbData);

                    device.PixelShaderConstants[0]  = constBuffer;
                    device.VertexShaderConstants[0] = constBuffer;
                    device.PixelShaderConstants[1]  = constBufferSubset;

                    device.SetupVertexInput(instance.vb, instance.ib);

                    if (instance.IsSkinned)
                    {
                        constBufferBones.SetData(instance.BoneTransforms);
                        device.VertexShaderConstants[3] = constBufferBones;
                    }

                    try {
                        device.PipelineState = factory[(int)(SurfaceFlags.GBUFFER | SurfaceFlags.RIGID)];


                        foreach (var subset in instance.Subsets)
                        {
                            var vt   = rw.VirtualTexture;
                            var rect = vt.GetTexturePosition(subset.Name);

                            cbDataSubset.Rectangle = new Vector4(rect.X, rect.Y, rect.Width, rect.Height);

                            constBufferSubset.SetData(cbDataSubset);
                            device.PixelShaderConstants[1] = constBufferSubset;

                            device.DrawIndexed(subset.PrimitiveCount * 3, subset.StartPrimitive * 3, 0);
                        }

                        rs.Counters.SceneDIPs++;
                    } catch (UbershaderException e) {
                        Log.Warning(e.Message);
                        ExceptionDialog.Show(e);
                    }
                }


                //
                //	downsample feedback buffer and readback it to virtual texture :
                //
                rs.Filter.StretchRect(frame.FeedbackBufferRB.Surface, frame.FeedbackBuffer, SamplerState.PointClamp);

                var feedbackBuffer = new VTAddress[HdrFrame.FeedbackBufferWidth * HdrFrame.FeedbackBufferHeight];
                frame.FeedbackBufferRB.GetFeedback(feedbackBuffer);
                rs.VTSystem.Update(feedbackBuffer, gameTime);
            }
        }
Exemple #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        public void Update(VTAddress[] data, GameTime gameTime)
        {
            var feedback = data.Distinct().Where(p => p.Dummy != 0).ToArray();

            ApplyVTState();

            List <VTAddress> feedbackTree = new List <VTAddress>();

            //
            //	Build tree :
            //
            foreach (var addr in feedback)
            {
                var paddr = addr;

                feedbackTree.Add(paddr);

                while (paddr.MipLevel < VTConfig.MaxMipLevel)
                {
                    paddr = VTAddress.FromChild(paddr);
                    feedbackTree.Add(paddr);
                }
            }

            //
            //	Distinct :
            //
            feedbackTree = feedbackTree
                           //	.Where( p0 => cache.Contains(p0) )
                           .Distinct()
                           .OrderBy(p1 => p1.MipLevel)
                           .ToList();     //*/


            //
            //	Detect thrashing and prevention
            //	Get highest mip, remove them, repeat until no thrashing occur.
            //
            while (feedbackTree.Count >= tileCache.Capacity / 2)
            {
                int minMip = feedbackTree.Min(va => va.MipLevel);
                feedbackTree.RemoveAll(va => va.MipLevel == minMip);
            }


            if (LockTiles)
            {
                feedbackTree.Clear();
            }


            if (tileCache != null)
            {
            }

            //
            //	Put into cache :
            //
            if (tileCache != null && tileLoader != null)
            {
                foreach (var addr in feedbackTree)
                {
                    int physAddr;

                    if (tileCache.Add(addr, out physAddr))
                    {
                        //Log.Message("...vt tile cache: {0} --> {1}", addr, physAddr );

                        tileLoader.RequestTile(addr);
                    }
                }
            }

            //
            //	update table :
            //
            if (tileLoader != null && tileCache != null)
            {
                for (int i = 0; i < MaxPPF; i++)
                {
                    VTTile tile;

                    if (tileLoader.TryGetTile(out tile))
                    {
                        Rectangle rect;

                        if (tileCache.TranslateAddress(tile.VirtualAddress, tile, out rect))
                        {
                            var sz = VTConfig.PageSizeBordered;

                            if (RandomColor)
                            {
                                tile.FillRandomColor();
                            }

                            if (ShowTileCheckers)
                            {
                                tile.DrawChecker();
                            }

                            if (ShowTileAddress)
                            {
                                tile.DrawText(fontImage, 16, 16, tile.VirtualAddress.ToString());
                                tile.DrawText(fontImage, 16, 32, string.Format("{0} {1}", rect.X / sz, rect.Y / sz));
                                tile.DrawText(fontImage, 16, 48, Math.Floor(stopwatch.Elapsed.TotalMilliseconds).ToString());
                            }

                            if (ShowTileBorder)
                            {
                                tile.DrawBorder();
                            }

                            //PhysicalPages.SetData( 0, rect, tile.Data, 0, tile.Data.Length );
                            tileStamper?.Add(tile, rect);
                        }
                    }
                }


                //	emboss tiles to physical texture
                tileStamper?.Update(this, gameTime.ElapsedSec);

                //	update page table :
                UpdatePageTable();
            }
        }