Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        public override void LoadAttachments(IEnumerable <Resource.IDescriptor> resources)
        {
            // - Skip buffer creation if no resources to load
            if (resources.Count() <= 0)
            {
                return;
            }

            // - Creates a command buffer for data transfer
            var commands = GraphicDevice.Handle.AllocateCommandBuffer(Commands[0], CommandBufferLevel.Primary);

            commands.Begin(CommandBufferUsageFlags.OneTimeSubmit);

            foreach (Resource.IDescriptor res in resources)
            {
                switch (res)
                {
                case Shape.Descriptor shape:

                    // - Loads the geometry
                    Geometry pointer = GeometryDispatcher.Load(shape);

                    // - Set resource loaded in the source thread
                    shape.SourceScheduler.Add(() =>
                    {
                        shape.SetResource(pointer);
                        shape.SetState(Resource.State.Loaded);
                    });

                    break;

                default:
                    throw new Exception($"Resource {res.GetType().Name} does not has a loader.");
                }
            }

            {
                // - Upload invalidated vertexs
                VertexManager.Upload(commands, 1000);

                // - Upload invalidated indexes
                IndexManager.Upload(commands, 1000);
            }
            commands.End();

            // - Perform all attachment operations
            GraphicDevice.GraphicQueue.Submit
            (
                new SubmitInfo
            {
                CommandBuffers = new[] { commands }
            },
                null
            );

            // - Free attachment command buffer
            Commands[0].FreeCommandBuffers(commands);

            // - Wait the GPU (we must operate only when GPU is idle)
            GraphicDevice.Handle.WaitIdle();
        }