예제 #1
0
        protected SwapChain(ref Descriptor desc, Device device, string label) : base(ref desc, device, label)
        {
            Assert.Debug(desc.MaxFramesInFlight > 0, "Invalid in-flight framecount!");
            Assert.Debug(desc.BufferCount > 0, "Invalid backbuffer count!");
            Assert.Debug(desc.AssociatedGraphicsQueue != null, "No graphics queue passed!");
            Assert.Debug(desc.AssociatedGraphicsQueue.Desc.Type == CommandListType.Graphics, "Passed command queue needs to be a graphics queue!");

            var fenceDesc = new Fence.Descriptor {
                InitialValue = 0
            };

            FrameFence = device.Create(ref fenceDesc);
            FrameFence.AddRef();

            Create();

            BackbufferResources = new Resource[desc.BufferCount];
            var resourceDesc = new Resource.Descriptor
            {
                Type          = Resource.Descriptor.Types.Backbuffer,
                DataDimension = Dimension.Texture2D
            };

            for (uint i = 0; i < BackbufferResources.Length; ++i)
            {
                BackbufferResources[i] = device.Create(ref resourceDesc, "Backbuffer");
                BackbufferResources[i].CreateFromSwapChain(this, i);
            }
        }
예제 #2
0
 /// <summary>
 /// Waits until all prepared frames are renderd and the GPU has no more tasks.
 /// Use this method carefully since it will usually come with a huge stall!
 /// </summary>
 public void WaitUntilAllFramesCompleted()
 {
     if (NumCompletedFramesGPU != NumCompletedFramesCPU)
     {
         FrameFence.WaitForCompletion(NumCompletedFramesCPU, TimeSpan.MaxValue);
     }
 }
예제 #3
0
        /// <summary>
        /// Swaps backbuffer. If syncInterval is bigger than zero, this function must wait until the GPU is able to perform the swap. (TODO: Is that correct?)
        /// </summary>
        /// <remarks>
        /// Signals the internal frameFence that is used to determine how many frames are inflight.
        /// Does not call any additional wait function (like WaitForFreeInflightFrame).
        /// </remarks>
        /// <param name="syncInterval">Synchronize presentation after the nth vertical blank. 0 means no synchronization.</param>
        public void EndFrame(uint syncInterval = 1)
        {
            // Present and mark end of frame with fence signal.
            Present(syncInterval);
            ++NumCompletedFramesCPU;
            FrameFence.Signal(NumCompletedFramesCPU);

            activeInFlightFrameIndex = (activeInFlightFrameIndex + 1) % Desc.MaxFramesInFlight;
        }
예제 #4
0
        /// <summary>
        /// Waits until only Desc.MaxFramesInFlight-1 frames are inflight and will then trigger the OnBeginRendering event.
        /// If an application is highly GPU bound, it will wait for the GPU to complete the rendering for this swapChain in this function.
        /// </summary>
        public void BeginFrame()
        {
            // Fullfill the MaxFramesInFlight constraint.
            Assert.Debug(NumFramesInFlight <= Desc.MaxFramesInFlight, "It should be impossible to have more than Desc.MaxFramesInFlight frames in flight.");
            if (NumFramesInFlight == Desc.MaxFramesInFlight)
            {
                FrameFence.WaitForCompletion(NumCompletedFramesGPU + 1, TimeSpan.MaxValue);
            }

            // Anounce frame start to all listeners.
            OnBeginFrame?.Invoke(activeInFlightFrameIndex);
        }
예제 #5
0
        internal override void Destroy()
        {
            WaitUntilAllFramesCompleted();
            FrameFence.RemoveRef();
            FrameFence.Destroy();

            foreach (var resource in BackbufferResources)
            {
                resource.RemoveRef();
                resource.Dispose();
            }
            BackbufferResources = null;


            base.Destroy();
        }