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(); } }