protected virtual void Dispose(bool disposing) { if (mIsDisposed) { return; } for (uint i = 0; i < mImageCount; i++) { mBuffers[i].View.DestroyImageView(mPartition.Device, null); } if (mSwapChain != null) { mSwapChain.DestroySwapchainKHR(mPartition.Device, null); } mIsDisposed = true; }
public void Create(IMgCommandBuffer cmd, UInt32 width, UInt32 height) { mWidth = width; mHeight = height; Result err; IMgSwapchainKHR oldSwapchain = mSwapChain; Setup(); // Get physical device surface properties and formats MgSurfaceCapabilitiesKHR surfCaps; err = mPartition.PhysicalDevice.GetPhysicalDeviceSurfaceCapabilitiesKHR(mLayer.Surface, out surfCaps); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get available present modes MgPresentModeKHR[] presentModes; err = mPartition.PhysicalDevice.GetPhysicalDeviceSurfacePresentModesKHR(mLayer.Surface, out presentModes); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); var swapchainExtent = new MgExtent2D { }; // width and height are either both -1, or both not -1. if ((int)surfCaps.CurrentExtent.Width == -1) { // If the surface size is undefined, the size is set to // the size of the images requested. swapchainExtent.Width = mWidth; swapchainExtent.Height = mHeight; } else { // If the surface size is defined, the swap chain size must match swapchainExtent = surfCaps.CurrentExtent; mWidth = surfCaps.CurrentExtent.Width; mHeight = surfCaps.CurrentExtent.Height; } // Prefer mailbox mode if present, it's the lowest latency non-tearing present mode MgPresentModeKHR swapchainPresentMode = MgPresentModeKHR.FIFO_KHR; for (uint i = 0; i < presentModes.Length; i++) { if (presentModes[i] == MgPresentModeKHR.MAILBOX_KHR) { swapchainPresentMode = MgPresentModeKHR.MAILBOX_KHR; break; } if ((swapchainPresentMode != MgPresentModeKHR.MAILBOX_KHR) && (presentModes[i] == MgPresentModeKHR.IMMEDIATE_KHR)) { swapchainPresentMode = MgPresentModeKHR.IMMEDIATE_KHR; } } // Determine the number of images uint desiredNumberOfSwapchainImages = surfCaps.MinImageCount + 1; if ((surfCaps.MaxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.MaxImageCount)) { desiredNumberOfSwapchainImages = surfCaps.MaxImageCount; } MgSurfaceTransformFlagBitsKHR preTransform; if ((surfCaps.SupportedTransforms & MgSurfaceTransformFlagBitsKHR.IDENTITY_BIT_KHR) != 0) { preTransform = MgSurfaceTransformFlagBitsKHR.IDENTITY_BIT_KHR; } else { preTransform = surfCaps.CurrentTransform; } var swapchainCI = new MgSwapchainCreateInfoKHR { Surface = mLayer.Surface, MinImageCount = desiredNumberOfSwapchainImages, ImageFormat = Format, ImageColorSpace = mColorSpace, ImageExtent = swapchainExtent, ImageUsage = MgImageUsageFlagBits.COLOR_ATTACHMENT_BIT, PreTransform = (MgSurfaceTransformFlagBitsKHR)preTransform, ImageArrayLayers = 1, ImageSharingMode = MgSharingMode.EXCLUSIVE, QueueFamilyIndices = null, PresentMode = swapchainPresentMode, OldSwapchain = oldSwapchain, Clipped = true, CompositeAlpha = MgCompositeAlphaFlagBitsKHR.OPAQUE_BIT_KHR, }; err = mPartition.Device.CreateSwapchainKHR(swapchainCI, null, out mSwapChain); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // If an existing swap chain is re-created, destroy the old swap chain // This also cleans up all the presentable images if (oldSwapchain != null) { for (uint i = 0; i < mImageCount; i++) { mBuffers[i].View.DestroyImageView(mPartition.Device, null); } oldSwapchain.DestroySwapchainKHR(mPartition.Device, null); } // Get the swap chain images err = mPartition.Device.GetSwapchainImagesKHR(mSwapChain, out mImages); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); // Get the swap chain buffers containing the image and imageview mImageCount = (uint)mImages.Length; mBuffers = new MgSwapchainBuffer[mImageCount]; for (uint i = 0; i < mImageCount; i++) { var buffer = new MgSwapchainBuffer(); var colorAttachmentView = new MgImageViewCreateInfo { Format = Format, Components = new MgComponentMapping { R = MgComponentSwizzle.R, G = MgComponentSwizzle.G, B = MgComponentSwizzle.B, A = MgComponentSwizzle.A, }, SubresourceRange = new MgImageSubresourceRange { AspectMask = MgImageAspectFlagBits.COLOR_BIT, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1, }, ViewType = MgImageViewType.TYPE_2D, Flags = 0, }; buffer.Image = mImages[i]; // Transform images from initial (undefined) to present layout mImageTools.SetImageLayout( cmd, buffer.Image, MgImageAspectFlagBits.COLOR_BIT, MgImageLayout.UNDEFINED, MgImageLayout.PRESENT_SRC_KHR); colorAttachmentView.Image = buffer.Image; IMgImageView bufferView; err = mPartition.Device.CreateImageView(colorAttachmentView, null, out bufferView); Debug.Assert(err == Result.SUCCESS, err + " != Result.SUCCESS"); buffer.View = bufferView; mBuffers [i] = buffer; } }