/// <summary> /// Render a set of asssets on the screen. /// </summary> public override void Render(Asset[] assets) { base.Render(assets); CommandBuffers[CurrentFrame] = GraphicDevice.Handle.AllocateCommandBuffers(Commands[CurrentFrame], CommandBufferLevel.Primary, (uint)Swapchain.Images.Count()); for (int index = 0; index < Swapchain.Images.Count(); index++) { var commandBuffer = CommandBuffers[CurrentFrame][index]; commandBuffer.Begin(CommandBufferUsageFlags.SimultaneousUse); commandBuffer.BeginRenderPass(DefaultRenderPass.Handle, Swapchain.VideoBuffers[index].Handler, new Rect2D(Swapchain.SurfaceSize), (ClearValue)(0F, 1F, 0F, 1F), SubpassContents.Inline); if (assets != null) { foreach (Asset asset in assets) { // - Gets the mesh from the mesh store var mesh = GeometryDispatcher.Get(asset.Mesh); VertexManager.Bind(commandBuffer); IndexManager.Bind(commandBuffer, (int)mesh.Indexes.Offset); commandBuffer.BindPipeline(PipelineBindPoint.Graphics, Pipeline.PipelineInstance); commandBuffer.DrawIndexed((uint)mesh.Indexes.Count, (uint)mesh.Indexes.Count / 3, 0, 0, 0); } } commandBuffer.EndRenderPass(); commandBuffer.End(); } uint nextImage = Swapchain.Handle.AcquireNextImage(uint.MaxValue, ImageAvailableSemaphores[CurrentFrame], null); if (ImagesInFlight[(int)nextImage] != null) { GraphicDevice.Handle.WaitForFences(ImagesInFlight[(int)nextImage], true, UInt64.MaxValue); } // - Mark the image as now being in use by this frame ImagesInFlight[(int)nextImage] = InFlightFences[CurrentFrame]; try { GraphicDevice.Handle.ResetFences(InFlightFences[CurrentFrame]); GraphicDevice.GraphicQueue.Submit ( new SubmitInfo { CommandBuffers = new[] { CommandBuffers[CurrentFrame][nextImage] }, SignalSemaphores = new[] { RenderFinishedSemaphores[CurrentFrame] }, WaitDestinationStageMask = new[] { PipelineStageFlags.ColorAttachmentOutput }, WaitSemaphores = new[] { ImageAvailableSemaphores[CurrentFrame] } }, InFlightFences[CurrentFrame] ); } catch (DeviceLostException) { InvalidateDevice(); } try { var present = GraphicDevice.PresentQueue.Present(RenderFinishedSemaphores[CurrentFrame], Swapchain.Handle, nextImage, new Result[1]); switch (present) { case Result.Suboptimal: InvalidateGraphics(); break; } if (present == Result.Success) { GraphicDevice.Handle.WaitForFences(InFlightFences[CurrentFrame], true, UInt64.MaxValue); Commands[(CurrentFrame + 1) % MaxFrameInFlight].FreeCommandBuffers(CommandBuffers[(CurrentFrame + 1) % MaxFrameInFlight]); CommandBuffers[(CurrentFrame + 1) % MaxFrameInFlight] = null; } } catch { InvalidateGraphics(); } finally { } CurrentFrame = (CurrentFrame + 1) % MaxFrameInFlight; }