public IEnumerable <IRenderable> UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables) { var c = (VeldridRendererContext)context; var gd = c.GraphicsDevice; if (!(renderables.FirstOrDefault() is SkyboxRenderable skybox)) { yield break; } ITextureManager textureManager = Resolve <ITextureManager>(); IDeviceObjectManager objectManager = Resolve <IDeviceObjectManager>(); textureManager?.PrepareTexture(skybox.Texture, context); TextureView textureView = (TextureView)textureManager?.GetTexture(skybox.Texture); var resourceSet = objectManager.Get <ResourceSet>((skybox, textureView)); if (resourceSet == null) { resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription( _resourceLayout, gd.PointSampler, textureView, _uniformBuffer)); resourceSet.Name = $"RS_Sky:{skybox.Texture.Name}"; PerfTracker.IncrementFrameCounter("Create ResourceSet"); objectManager.Set((skybox, textureView), resourceSet); } yield return(skybox); }
public IEnumerable <IRenderable> UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneContext sc, IEnumerable <IRenderable> renderables) { ITextureManager textureManager = Resolve <ITextureManager>(); IDeviceObjectManager dom = Resolve <IDeviceObjectManager>(); foreach (var sprite in renderables.OfType <MultiSprite>()) { if (sprite.ActiveInstances == 0) { continue; } uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize; var buffer = dom.Prepare((sprite, sprite), () => { var newBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer)); newBuffer.Name = $"B_SpriteInst:{sprite.Name}"; PerfTracker.IncrementFrameCounter("Create InstanceBuffer"); return(newBuffer); }, existing => existing.SizeInBytes != bufferSize); if (sprite.InstancesDirty) { cl.UpdateBuffer(buffer, 0, sprite.Instances); PerfTracker.IncrementFrameCounter("Update InstanceBuffers"); } textureManager?.PrepareTexture(sprite.Key.Texture, gd); TextureView textureView = textureManager?.GetTexture(sprite.Key.Texture); dom.Prepare((sprite, textureView), () => { var resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription( _perSpriteResourceLayout, gd.PointSampler, textureView, _uniformBuffer)); resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}"; PerfTracker.IncrementFrameCounter("Create ResourceSet"); return(resourceSet); }, _ => false ); sprite.InstancesDirty = false; yield return(sprite); } Resolve <ISpriteManager>().Cleanup(); }
public IEnumerable <IRenderable> UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables) { var c = (VeldridRendererContext)context; var cl = c.CommandList; var gd = c.GraphicsDevice; var sc = c.SceneContext; ITextureManager textureManager = Resolve <ITextureManager>(); IDeviceObjectManager objectManager = Resolve <IDeviceObjectManager>(); EngineFlags engineFlags = Resolve <IEngineSettings>().Flags; foreach (var renderable in renderables) { var sprite = (MultiSprite)renderable; if (sprite.ActiveInstances == 0) { continue; } var shaderKey = new SpriteShaderKey(sprite, engineFlags); if (!_pipelines.ContainsKey(shaderKey)) { _pipelines.Add(shaderKey, BuildPipeline(gd, sc, shaderKey)); } uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize; var buffer = objectManager.Get <DeviceBuffer>((sprite, sprite)); if (buffer?.SizeInBytes != bufferSize) { buffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer)); buffer.Name = $"B_SpriteInst:{sprite.Name}"; PerfTracker.IncrementFrameCounter("Create InstanceBuffer"); objectManager.Set((sprite, sprite), buffer); } if (sprite.InstancesDirty) { cl.UpdateBuffer(buffer, 0, sprite.Instances); PerfTracker.IncrementFrameCounter("Update InstanceBuffers"); } textureManager?.PrepareTexture(sprite.Key.Texture, context); TextureView textureView = (TextureView)textureManager?.GetTexture(sprite.Key.Texture); var resourceSet = objectManager.Get <ResourceSet>((sprite, textureView)); if (resourceSet == null) { resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription( _perSpriteResourceLayout, gd.PointSampler, textureView, _uniformBuffer)); resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}"; PerfTracker.IncrementFrameCounter("Create ResourceSet"); objectManager.Set((sprite, textureView), resourceSet); } sprite.InstancesDirty = false; yield return(sprite); } Resolve <ISpriteManager>().Cleanup(); }
public void UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables, IList <IRenderable> results) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (renderables == null) { throw new ArgumentNullException(nameof(renderables)); } if (results == null) { throw new ArgumentNullException(nameof(results)); } var c = (VeldridRendererContext)context; var cl = c.CommandList; var gd = c.GraphicsDevice; var textureManager = Resolve <ITextureManager>(); var objectManager = Resolve <IDeviceObjectManager>(); var engineFlags = Resolve <IEngineSettings>().Flags; foreach (var renderable in renderables) { var sprite = (MultiSprite)renderable; if (sprite.ActiveInstances == 0) { continue; } cl.PushDebugGroup(sprite.Name); var shaderKey = new SpriteShaderKey(sprite, engineFlags); if (!_pipelines.ContainsKey(shaderKey)) { _pipelines.Add(shaderKey, BuildPipeline(gd, c.SceneContext, shaderKey)); } uint bufferSize = (uint)sprite.Instances.Length * SpriteInstanceData.StructSize; var buffer = objectManager.GetDeviceObject <DeviceBuffer>((sprite, sprite, "InstanceBuffer")); if (buffer?.SizeInBytes != bufferSize) { buffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(bufferSize, BufferUsage.VertexBuffer)); buffer.Name = $"B_Inst:{sprite.Name}"; PerfTracker.IncrementFrameCounter("Create InstanceBuffer"); objectManager.SetDeviceObject((sprite, sprite, "InstanceBuffer"), buffer); sprite.InstancesDirty = true; } if (sprite.InstancesDirty) { var instances = sprite.Instances; VeldridUtil.UpdateBufferSpan(cl, buffer, instances); PerfTracker.IncrementFrameCounter("Update InstanceBuffers"); } textureManager?.PrepareTexture(sprite.Key.Texture, context); TextureView textureView = (TextureView)textureManager?.GetTexture(sprite.Key.Texture); var uniformBuffer = objectManager.GetDeviceObject <DeviceBuffer>((sprite, textureView, "UniformBuffer")); if (uniformBuffer == null) { uniformBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <SpriteUniformInfo>(), BufferUsage.UniformBuffer)); uniformBuffer.Name = $"B_SpriteUniform:{sprite.Name}"; PerfTracker.IncrementFrameCounter("Create sprite uniform buffer"); objectManager.SetDeviceObject((sprite, textureView, "UniformBuffer"), uniformBuffer); var uniformInfo = new SpriteUniformInfo { Flags = sprite.Key.Flags, TextureWidth = textureView?.Target.Width ?? 1, TextureHeight = textureView?.Target.Height ?? 1 }; cl.UpdateBuffer(uniformBuffer, 0, uniformInfo); } var resourceSet = objectManager.GetDeviceObject <ResourceSet>((sprite, textureView, "ResourceSet")); if (resourceSet == null) { resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription( _perSpriteResourceLayout, textureView, gd.PointSampler, uniformBuffer)); resourceSet.Name = $"RS_Sprite:{sprite.Key.Texture.Name}"; PerfTracker.IncrementFrameCounter("Create ResourceSet"); objectManager.SetDeviceObject((sprite, textureView, "ResourceSet"), resourceSet); } sprite.InstancesDirty = false; results.Add(sprite); cl.PopDebugGroup(); } Resolve <ISpriteManager>().Cleanup(); }
public void UpdatePerFrameResources(IRendererContext context, IEnumerable <IRenderable> renderables, IList <IRenderable> results) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (renderables == null) { throw new ArgumentNullException(nameof(renderables)); } if (results == null) { throw new ArgumentNullException(nameof(results)); } var c = (VeldridRendererContext)context; var cl = c.CommandList; var gd = c.GraphicsDevice; var objectManager = Resolve <IDeviceObjectManager>(); foreach (var renderable in renderables) { var overlay = (InfoOverlay)renderable; // Only render if an overlay is being shown if (overlay.ExamineOpacity + overlay.ManipulateOpacity + overlay.TalkOpacity + overlay.TakeOpacity <= 0) { continue; } cl.PushDebugGroup("Info Overlay"); var tiles = overlay.Tiles; var buffer = objectManager.GetDeviceObject <DeviceBuffer>((overlay, overlay, "Tiles")); if (buffer?.SizeInBytes != tiles.Length) { var size = 16 * (((uint)tiles.Length + 15) / 16); buffer = gd.ResourceFactory.CreateBuffer(new BufferDescription(size, BufferUsage.StructuredBufferReadOnly, 4)); buffer.Name = "B_InfoOverlayTiles"; objectManager.SetDeviceObject((overlay, overlay, "Tiles"), buffer); overlay.BufferDirty = true; } if (overlay.BufferDirty) { VeldridUtil.UpdateBufferSpan(cl, buffer, tiles); PerfTracker.IncrementFrameCounter("Update InstanceBuffers"); } var uniformBuffer = objectManager.GetDeviceObject <DeviceBuffer>((overlay, overlay, "UniformBuffer")); if (uniformBuffer == null) { uniformBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription( (uint)Unsafe.SizeOf <InfoOverlayUniforms>(), BufferUsage.UniformBuffer)); uniformBuffer.Name = "InfoOverlayUniformBuffer"; PerfTracker.IncrementFrameCounter("Create info overlay uniform buffer"); objectManager.SetDeviceObject((overlay, overlay, "UniformBuffer"), uniformBuffer); } var uniformInfo = new InfoOverlayUniforms { Examine = overlay.ExamineOpacity, Manipulate = overlay.ManipulateOpacity, Talk = overlay.TalkOpacity, Take = overlay.TakeOpacity, Width = overlay.Width, Height = overlay.Height, TileWidth = overlay.TileWidth, TileHeight = overlay.TileHeight, }; cl.UpdateBuffer(uniformBuffer, 0, uniformInfo); var resourceSet = objectManager.GetDeviceObject <ResourceSet>((overlay, overlay, "ResourceSet")); if (resourceSet == null) { resourceSet = gd.ResourceFactory.CreateResourceSet(new ResourceSetDescription( _perSpriteResourceLayout, buffer, uniformBuffer)); resourceSet.Name = "RS_InfoOverlay"; PerfTracker.IncrementFrameCounter("Create ResourceSet"); objectManager.SetDeviceObject((overlay, overlay, "ResourceSet"), resourceSet); } results.Add(overlay); overlay.BufferDirty = false; cl.PopDebugGroup(); } }