public void InitializeVulkan() { var devices = Instance.EnumeratePhysicalDevices(); var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr { Window = aNativeWindow }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new float [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" }, QueueCreateInfos = new DeviceQueueCreateInfo [] { queueInfo } }; var physicalDevice = devices [0]; device = physicalDevice.CreateDevice(deviceInfo); queue = device.GetQueue(0, 0); var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat); var images = device.GetSwapchainImagesKHR(swapchain); var renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass); commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities); var fenceInfo = new FenceCreateInfo(); fences = new Fence [] { device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); semaphore = device.CreateSemaphore(semaphoreInfo); initialized = true; }
/// <summary> /// Initializes a new instance of the <see cref="BindImageMemorySwapchainInfoKhx"/> structure. /// </summary> /// <param name="swapchain">Is <c>null</c> or a <see cref="SwapchainKhr"/> handle.</param> /// <param name="imageIndex">An image index within <see cref="Swapchain"/>.</param> /// <param name="next"> /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure. /// </param> public BindImageMemorySwapchainInfoKhx(SwapchainKhr swapchain, int imageIndex, IntPtr next = default(IntPtr)) { Type = StructureType.BindImageMemorySwapchainInfoKhx; Next = next; Swapchain = swapchain; ImageIndex = imageIndex; }
/// <summary> /// Query the current value of a surface counter. /// <para> /// The requested counters become active when the first presentation command for the /// associated swapchain is processed by the presentation engine. /// </para> /// </summary> /// <param name="swapchain">The swapchain from which to query the counter value.</param> /// <param name="counter">The counter to query.</param> /// <returns>The current value of the counter.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static long GetCounterExt(this SwapchainKhr swapchain, SurfaceCountersExt counter) { long counterValue; Result result = vkGetSwapchainCounterEXT(swapchain.Parent, swapchain, counter, &counterValue); VulkanException.ThrowForInvalidResult(result); return(counterValue); }
/// <summary> /// Obtain the RC duration of the PE's display. /// </summary> /// <param name="swapchain">The swapchain to obtain the refresh duration for.</param> /// <returns>An instance of the <see cref="RefreshCycleDurationGoogle"/> structure.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static RefreshCycleDurationGoogle GetRefreshCycleDurationGoogle(this SwapchainKhr swapchain) { RefreshCycleDurationGoogle properties; Result result = vkGetRefreshCycleDurationGOOGLE(swapchain)(swapchain.Parent, swapchain, &properties); VulkanException.ThrowForInvalidResult(result); return(properties); }
/// <summary> /// Initializes a new instance of the <see cref="AcquireNextImageInfoKhx"/> structure. /// </summary> /// <param name="swapchain"> /// The <see cref="SwapchainKhr"/> from which an image is being acquired. /// </param> /// <param name="timeout"> /// Indicates how long the function waits, in nanoseconds, if no image is available. /// </param> /// <param name="semaphore">A <see cref="Semaphore"/> to signal.</param> /// <param name="fence">A <see cref="Fence"/> to signal.</param> /// <param name="deviceMask"> /// A mask of physical devices for which the swapchain image will be ready to use when the /// semaphore or fence is signaled. /// </param> /// <param name="next"> /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure. /// </param> public AcquireNextImageInfoKhx(SwapchainKhr swapchain, long timeout, Semaphore semaphore = null, Fence fence = null, int deviceMask = 0, IntPtr next = default(IntPtr)) { Type = StructureType.AcquireNextImageInfoKhx; Swapchain = swapchain; Timeout = timeout; Semaphore = semaphore; Fence = fence; DeviceMask = deviceMask; Next = next; }
private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface) { var queueFamilyProperties = physDev.GetQueueFamilyProperties(); uint queueFamilyUsedIndex; for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex) { if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface)) { continue; } if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics)) { break; } } var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new[] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new[] { "VK_KHR_swapchain", }, QueueCreateInfos = new[] { queueInfo } }; _device = physDev.CreateDevice(deviceInfo); _queue = _device.GetQueue(0, 0); _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectSurfaceFormat(physDev, surface); _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat); _images = _device.GetSwapchainImagesKHR(_swapchainKhr); _renderPass = CreateRenderPass(surfaceFormat); _framebuffers = CreateFramebuffers(_images, surfaceFormat); var fenceInfo = new FenceCreateInfo(); _fence = _device.CreateFence(fenceInfo); var semaphoreInfo = new SemaphoreCreateInfo(); _semaphore = _device.CreateSemaphore(semaphoreInfo); _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities); }
private void CreateSwapChain() { var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface); SurfaceFormatKhr surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats); PresentModeKhr presentMode = ChooseSwapPresentMode(swapChainSupport.presentModes); Extent2D extent = ChooseSwapExtent(swapChainSupport.capabilities); uint imageCount = swapChainSupport.capabilities.MinImageCount + 1; if (swapChainSupport.capabilities.MaxImageCount > 0) { imageCount = Math.Min(imageCount, swapChainSupport.capabilities.MaxImageCount); } var createInfo = new SwapchainCreateInfoKhr() { MinImageCount = imageCount, ImageFormat = surfaceFormat.Format, ImageColorSpace = surfaceFormat.ColorSpace, ImageExtent = extent, ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = swapChainSupport.capabilities.CurrentTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, PresentMode = presentMode, Surface = vkSurface, }; var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface); if (indices.GraphicsFamily != indices.PresentFamily) { createInfo.ImageSharingMode = SharingMode.Concurrent; createInfo.QueueFamilyIndices = new[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily, }; } else { createInfo.ImageSharingMode = SharingMode.Exclusive; } vkSwapChain = vkDevice.CreateSwapchainKHR(createInfo); vkSwapChainImages = vkDevice.GetSwapchainImagesKHR(vkSwapChain); vkSwapChainImageFormat = surfaceFormat.Format; vkSwapChainExtent = extent; }
internal void Build() { GraphicsCommandPool?.Reset(); ComputeCommandPool?.Reset(); ImageAvailableSemaphore?.Dispose(); RenderingFinishedSemaphore?.Dispose(); Swapchain?.Dispose(); ImageAvailableSemaphore = ToDispose(Device.CreateSemaphore()); RenderingFinishedSemaphore = ToDispose(Device.CreateSemaphore()); Swapchain = ToDispose(VKHelper.CreateSwapchain(this)); CacheSwapchainImages(); }
/// <summary> /// Obtain timing of a previously-presented image. /// <para> /// The implementation will maintain a limited amount of history of timing information about /// previous presents. /// </para> /// <para> /// Because of the asynchronous nature of the presentation engine, the timing information for /// a given <see cref="QueueExtensions.PresentKhr(Queue, Semaphore, SwapchainKhr, int)"/> /// command will become available some time later. /// </para> /// <para>These time values can be asynchronously queried, and will be returned if available.</para> /// <para> /// All time values are in nanoseconds, relative to a monotonically-increasing clock (e.g. /// `CLOCK_MONOTONIC` (see clock_gettime(2)) on Android and Linux). /// </para> /// </summary> /// <param name="swapchain"> /// The swapchain to obtain presentation timing information duration for. /// </param> /// <returns>An array of <see cref="PastPresentationTimingGoogle"/> structures.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static PastPresentationTimingGoogle[] GetPastPresentationTimingGoogle(this SwapchainKhr swapchain) { int count; Result result = vkGetPastPresentationTimingGOOGLE(swapchain)(swapchain.Parent, swapchain, &count, null); VulkanException.ThrowForInvalidResult(result); var timings = new PastPresentationTimingGoogle[count]; fixed(PastPresentationTimingGoogle *timingsPtr = timings) result = vkGetPastPresentationTimingGOOGLE(swapchain)(swapchain.Parent, swapchain, &count, timingsPtr); VulkanException.ThrowForInvalidResult(result); return(timings); }
protected void CreateSwapChain() { format = ChooseFormat(data.formats); var presentMode = ChoosePresentMode(data.presentModes); extent = ChooseSwapExtent(); var imageCount = data.surfaceCapabilities.MinImageCount + 1; if (data.surfaceCapabilities.MaxImageCount > 0 && imageCount > data.surfaceCapabilities.MaxImageCount) { imageCount = data.surfaceCapabilities.MaxImageCount; } var swapChainInfo = new SwapchainCreateInfoKhr { Surface = data.surface, MinImageCount = imageCount, ImageFormat = format.Format, ImageColorSpace = format.ColorSpace, ImageExtent = extent, ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = data.surfaceCapabilities.CurrentTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, PresentMode = presentMode, Clipped = true }; var indices = data.queueFamilyIndices; var queueFamilyIndices = new uint[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily }; if (indices.PresentFamily != indices.GraphicsFamily) { swapChainInfo.ImageSharingMode = SharingMode.Concurrent; swapChainInfo.QueueFamilyIndexCount = (uint)queueFamilyIndices.Length; swapChainInfo.QueueFamilyIndices = queueFamilyIndices; } else { swapChainInfo.ImageSharingMode = SharingMode.Exclusive; } swapchain = device.CreateSwapchainKHR(swapChainInfo); images = device.GetSwapchainImagesKHR(swapchain); bufferSize = imageCount; }
public void InitializeVulkan() { var devices = Instance.EnumeratePhysicalDevices(); var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr { Window = aNativeWindow }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new float [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" }, QueueCreateInfos = new DeviceQueueCreateInfo [] { queueInfo } }; var physicalDevice = devices [0]; device = physicalDevice.CreateDevice(deviceInfo); queue = device.GetQueue(0, 0); surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); swapchain = CreateSwapchain(surface, surfaceFormat); var images = device.GetSwapchainImagesKHR(swapchain); renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat); var vertexBuffer = CreateBuffer(physicalDevice, Logo.Vertices, BufferUsageFlags.VertexBuffer, typeof(float)); var indexBuffer = CreateBuffer(physicalDevice, Logo.Indexes, BufferUsageFlags.IndexBuffer, typeof(short)); uniformBuffer = CreateUniformBuffer(physicalDevice); descriptorSetLayout = CreateDescriptorSetLayout(); var pipelines = CreatePipelines(); descriptorSets = CreateDescriptorSets(); UpdateDescriptorSets(); commandBuffers = CreateCommandBuffers(images, framebuffers, pipelines [0], vertexBuffer, indexBuffer, (uint)Logo.Indexes.Length); var fenceInfo = new FenceCreateInfo(); fences = new Fence [] { device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); semaphore = device.CreateSemaphore(semaphoreInfo); initialized = true; }
public virtual void Initialize(PhysicalDevice physicalDevice, SurfaceKhr surface) { var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties(); uint queueFamilyUsedIndex; for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex) { if (!physicalDevice.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface)) { continue; } if (queueFamilyProperties [queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics)) { break; } } var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new float [] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new string [] { "VK_KHR_swapchain" }, QueueCreateInfos = new DeviceQueueCreateInfo [] { queueInfo } }; device = physicalDevice.CreateDevice(deviceInfo); queue = device.GetQueue(0, 0); surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); swapchain = CreateSwapchain(surface, surfaceFormat); images = device.GetSwapchainImagesKHR(swapchain); renderPass = CreateRenderPass(surfaceFormat); framebuffers = CreateFramebuffers(images, surfaceFormat); var fenceInfo = new FenceCreateInfo(); fence = device.CreateFence(fenceInfo); var semaphoreInfo = new SemaphoreCreateInfo(); semaphore = device.CreateSemaphore(semaphoreInfo); initialized = true; }
public static bool TryCreateSwapChain(Instance instance, PhysicalDevice physicalDevice, Device device, SurfaceKhr surface, uint queue, ref System.Drawing.Size size, Format format, ColorSpaceKhr colorSpace, PresentModeKhr presentMode, ref SwapchainKhr swapchain) { SwapchainCreateInfoKhr swapChainCreateInfo = new SwapchainCreateInfoKhr { Surface = surface, MinImageCount = 2, ImageFormat = format, ImageColorSpace = colorSpace, ImageExtent = ToExtent2D(size), ImageArrayLayers = 1, ImageUsage = ImageUsageFlags.ColorAttachment, ImageSharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queue }, PreTransform = SurfaceTransformFlagsKhr.Inherit, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, // TODO : set this to Ingerit if it can be fixed in Check PresentMode = presentMode, Clipped = false, OldSwapchain = swapchain, }; if (!CheckSwapchainCreateInfo(physicalDevice, swapChainCreateInfo, true)) { return(false); } size.Width = (int)swapChainCreateInfo.ImageExtent.Width; size.Height = (int)swapChainCreateInfo.ImageExtent.Height; SwapchainKhr newSwapchain = device.CreateSwapchainKHR(swapChainCreateInfo); if (newSwapchain != null) { swapchain = newSwapchain; return(true); } return(false); }
private void InitializeVulkan() { var devices = _instance.EnumeratePhysicalDevices(); var surface = _instance.CreateWin32SurfaceKHR( new Win32SurfaceCreateInfoKhr { Hinstance = Instance, Hwnd = Handle }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new [] { "VK_KHR_swapchain" }, QueueCreateInfos = new [] { queueInfo } }; var physicalDevice = devices [0]; _device = physicalDevice.CreateDevice(deviceInfo); _queue = _device.GetQueue(0, 0); var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); _swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat); var images = _device.GetSwapchainImagesKHR(_swapchain); var renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass); _commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities); var fenceInfo = new FenceCreateInfo(); _fences = new [] { _device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); _semaphore = _device.CreateSemaphore(semaphoreInfo); _initialized = true; }
public bool CreateSwapChain(DrunkSpock spock, int extentX, int extentY) { PhysicalDevice phys = mLogical.Parent; SurfaceKhr surf = spock.GetSurface(); SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf); SurfaceFormatKhr [] surfFormats = phys.GetSurfaceFormatsKhr(surf); PresentModeKhr [] presModes = phys.GetSurfacePresentModesKhr(surf); if (surfFormats.Length <= 0 || presModes.Length <= 0) { Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes..."); return(false); } mSwapExtent = new Extent2D(extentX, extentY); int imageCount = surfCaps.MinImageCount + 1; if (surfCaps.MaxImageCount > 0 && imageCount > surfCaps.MaxImageCount) { imageCount = surfCaps.MaxImageCount; } SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr( surf, Format.B8G8R8A8UNorm, mSwapExtent, imageCount, ColorSpaceKhr.SRgbNonlinear, 1, ImageUsages.ColorAttachment); scci.ImageSharingMode = SharingMode.Exclusive; if (presModes.Contains(PresentModeKhr.Mailbox)) { scci.PresentMode = PresentModeKhr.Mailbox; } mSwapChain = mLogical.CreateSwapchainKhr(scci); if (mSwapChain == null) { Misc.SafeInvoke(eErrorSpam, "Create swap chain failed..."); return(false); } VulkanCore.Image [] chainImages = mSwapChain.GetImages(); mChainImageViews = new ImageView[chainImages.Length]; for (int i = 0; i < chainImages.Length; i++) { ImageSubresourceRange isr = new ImageSubresourceRange( ImageAspects.Color, 0, 1, 0, 1); ImageViewCreateInfo ivci = new ImageViewCreateInfo( mSwapChain.Format, isr); mChainImageViews[i] = chainImages[i].CreateView(ivci); } //descriptor pool stuff DescriptorPoolSize dps = new DescriptorPoolSize( DescriptorType.UniformBuffer, chainImages.Length); DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo(); dpci.PoolSizes = new DescriptorPoolSize[] { dps }; dpci.MaxSets = chainImages.Length; mDPool = mLogical.CreateDescriptorPool(dpci); return(true); }
public void CreateSwapChain(PresentModeKhr presentMode, uint imageCount) { SwapchainKhr oldSwapChain = SwapChain; if (SwapSurface == null) { // == Create Surface for Swap Chain IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module); Win32SurfaceCreateInfoKhr surfaceInfo = new Win32SurfaceCreateInfoKhr() { Hwnd = window.Handle, Flags = 0, Hinstance = hInstance, }; SurfaceKhr surface = Instance.CreateWin32SurfaceKHR(surfaceInfo, null); QueueInfo graphicsQueueInfo = GetQueue(QueueFlags.Graphics); Queue graphicsQueue = Device.GetQueue(graphicsQueueInfo.queueFamilyIndex, graphicsQueueInfo.queueIndex); SwapSurface = surface; } // == Create Swap Chain // TODO : this is bugged in Vulkan-Mono PresentModeKhr can not be called from Marshal.SizeOf /*bool presentModeSupported = false; * PresentModeKhr[] presentModes = Gpu.GetSurfacePresentModesKHR(SwapSurface); * foreach (PresentModeKhr checkMode in presentModes) * { * if(checkMode == presentMode) * { * presentModeSupported = true; * break; * } * } * if(!presentModeSupported ) * { * throw new Exception("PresentMode :" + presentMode + " not supported by gpu."); * }*/ SurfaceCapabilitiesKhr surfaceCapabilities = Gpu.GetSurfaceCapabilitiesKHR(SwapSurface); if (surfaceCapabilities.CurrentExtent.Width == uint.MaxValue) { BackBufferWidth = (uint)window.Width; BackBufferHeight = (uint)window.Height; } else { BackBufferWidth = surfaceCapabilities.CurrentExtent.Width; BackBufferHeight = surfaceCapabilities.CurrentExtent.Height; } uint reqImageCount = surfaceCapabilities.MinImageCount + imageCount; if (reqImageCount > 0 && reqImageCount > surfaceCapabilities.MaxImageCount) { reqImageCount = surfaceCapabilities.MaxImageCount; } SurfaceFormatKhr[] surfaceFormats = Gpu.GetSurfaceFormatsKHR(SwapSurface); Format format = surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined ? Format.B8g8r8a8Unorm : surfaceFormats[0].Format; SurfaceTransformFlagsKhr preTransform = (surfaceCapabilities.SupportedTransforms & SurfaceTransformFlagsKhr.Identity) == SurfaceTransformFlagsKhr.Identity ? SurfaceTransformFlagsKhr.Identity : surfaceCapabilities.CurrentTransform; SwapchainCreateInfoKhr swapChainInfo = new SwapchainCreateInfoKhr { Surface = SwapSurface, MinImageCount = reqImageCount, ImageFormat = format, ImageColorSpace = surfaceFormats[0].ColorSpace, ImageExtent = new Extent2D { Width = BackBufferWidth, Height = BackBufferHeight, }, ImageUsage = (uint)ImageUsageFlags.ColorAttachment, PreTransform = preTransform, CompositeAlpha = CompositeAlphaFlagsKhr.Opaque, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, PresentMode = presentMode, // TODO : Vulkan : we cant assing a null swapChain //OldSwapchain = oldSwapChain != null ? oldSwapChain : null, Clipped = true, }; if (oldSwapChain != null) { // this is a workaround as we cant assing a null one swapChainInfo.OldSwapchain = oldSwapChain; Device.DestroySwapchainKHR(oldSwapChain, null); oldSwapChain = null; } SwapchainKhr swapChain = Device.CreateSwapchainKHR(swapChainInfo, null); // == Create Images Image[] swapImages = Device.GetSwapchainImagesKHR(swapChain); SwapChainBuffer[] buffers = new SwapChainBuffer[swapImages.Length]; for (uint i = 0; i < buffers.Length; i++) { ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo { Format = format, Components = new ComponentMapping { R = ComponentSwizzle.R, G = ComponentSwizzle.G, B = ComponentSwizzle.B, A = ComponentSwizzle.A, }, SubresourceRange = new ImageSubresourceRange { AspectMask = (uint)ImageAspectFlags.Color, BaseMipLevel = 1, BaseArrayLayer = 0, LayerCount = 1, }, ViewType = ImageViewType.View2D, Flags = 0, Image = swapImages[i], }; ImageView view = Device.CreateImageView(imageViewInfo, null); buffers[i] = new SwapChainBuffer { image = swapImages[i], view = view, }; } }
private static vkGetPastPresentationTimingGOOGLEDelegate vkGetPastPresentationTimingGOOGLE(SwapchainKhr swapchain) => GetProc <vkGetPastPresentationTimingGOOGLEDelegate>(swapchain, nameof(vkGetPastPresentationTimingGOOGLE));
private static vkGetRefreshCycleDurationGOOGLEDelegate vkGetRefreshCycleDurationGOOGLE(SwapchainKhr swapchain) => GetProc <vkGetRefreshCycleDurationGOOGLEDelegate>(swapchain, nameof(vkGetRefreshCycleDurationGOOGLE));
private static TDelegate GetProc <TDelegate>(SwapchainKhr swapchain, string name) where TDelegate : class => swapchain.Parent.GetProc <TDelegate>(name);
private static Frame[] GetFrames(Device device, SwapchainKhr swapchain, Extent2D imageSize, RenderPass renderpass) { var images = device.GetSwapchainImagesKHR(swapchain); return(images.Select(image => new Frame(image, device, imageSize, renderpass)).ToArray()); }
private void CreateSwapchain(int swapchainCount) { SurfaceCapabilitiesKhr capabilities = hostDevice.GetCurrentCapabilities(surface); //Clamp the size to within the min and max extends reported by the surface capabilities swapchainSize = nativeWindow.ClientRect.Size.Clamp( new Int2(capabilities.MinImageExtent.Width, capabilities.MinImageExtent.Height), new Int2(capabilities.MaxImageExtent.Width, capabilities.MaxImageExtent.Height)); //Gather info about the swapchain var createInfo = new SwapchainCreateInfoKhr ( surface: surface, minImageCount: swapchainCount, imageFormat: surfaceFormat, imageColorSpace: surfaceColorspace, imageExtent: new Extent2D(swapchainSize.X, swapchainSize.Y), imageArrayLayers: 1, imageUsage: ImageUsages.ColorAttachment, //If the graphics and present queues are different we need to allow sharing the //swapchain images imageSharingMode: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ? SharingMode.Exclusive : SharingMode.Concurrent, queueFamilyIndices: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ? null : new [] { graphicsQueue.FamilyIndex, presentQueue.FamilyIndex }, preTransform: capabilities.CurrentTransform, compositeAlpha: CompositeAlphasKhr.Opaque, presentMode: presentMode, clipped: true ); //Create the swapchain swapchain = logicalDevice.CreateSwapchainKhr(createInfo); var swapchainImages = swapchain.GetImages(); //Verify that we got the amount of images we expected if (swapchainImages.Length != swapchainCount) { throw new Exception( $"[{nameof(Window)}] Incorrect number of swapchain images acquired, expected: {swapchainCount}, got: {swapchainImages.Length}"); } //Create the image targets swapchainTextures = new DeviceTexture[swapchainCount]; for (int i = 0; i < swapchainTextures.Length; i++) { swapchainTextures[i] = DeviceTexture.CreateSwapchainTarget( swapchainSize, surfaceFormat, swapchainImages[i]); } logger?.Log(nameof(Window), $@"Swapchain created: {{ size: {swapchainSize}, texCount: {swapchainTextures.Length}, mode: {presentMode}, format: {surfaceFormat}, colorSpace: {surfaceColorspace} }}"); }
/// <summary> /// Initializes a new instance of the <see cref="ImageSwapchainCreateInfoKhx"/> structure. /// </summary> /// <param name="swapchain"> /// Is <c>null</c> or a handle of an <see cref="SwapchainKhr"/> that the image will be bound to. /// </param> /// <param name="next"> /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure. /// </param> public ImageSwapchainCreateInfoKhx(SwapchainKhr swapchain, IntPtr next = default(IntPtr)) { Type = StructureType.ImageSwapchainCreateInfoKhx; Next = next; Swapchain = swapchain; }
private static vkGetSwapchainCounterEXTDelegate vkGetSwapchainCounterEXT(SwapchainKhr swapchain) => swapchain.Parent.GetProc <vkGetSwapchainCounterEXTDelegate>(nameof(vkGetSwapchainCounterEXT));
internal static unsafe extern Result vkAcquireNextImageKHR(Device device, SwapchainKhr swapchain, UInt64 timeout, Semaphore semaphore, Fence fence, out UInt32 *ImageIndex);
internal static unsafe extern Result vkGetSwapchainImagesKHR(Device device, SwapchainKhr swapchain, out UInt32 *SwapchainImageCount, out IntPtr pSwapchainImages);
internal static unsafe extern void vkDestroySwapchainKHR(Device device, SwapchainKhr swapchain, AllocationCallbacks *Allocator);
void InitSwapChain() { surface = VulkanInitUtility.CreateSurface(instance, window); // TODO : try to use a linear format // TODO : dount just guest the queue surfaceFormat = Format.B8G8R8A8Unorm; surfaceSize = window.Size; if (!VulkanInitUtility.TryCreateSwapChain(instance, physicalDevice, device, surface, (uint)0, ref surfaceSize, surfaceFormat, ColorSpaceKhr.SrgbNonlinear, PresentModeKhr.Fifo, ref swapChain)) { throw new Exception("Failed to create swap chain"); } swapChainSemphore = device.CreateSemaphore(new SemaphoreCreateInfo { }); // create Images and Image Views swapchainImages = device.GetSwapchainImagesKHR(swapChain); swapchainImageViews = new ImageView[swapchainImages.Length]; int i = 0; foreach (Image image in swapchainImages) { ImageView view = device.CreateImageView(new ImageViewCreateInfo { Image = image, Format = surfaceFormat, ViewType = ImageViewType.View2D, Components = new ComponentMapping { R = ComponentSwizzle.Identity, G = ComponentSwizzle.Identity, B = ComponentSwizzle.Identity, A = ComponentSwizzle.Identity, }, SubresourceRange = new ImageSubresourceRange { AspectMask = ImageAspectFlags.Color, LayerCount = 1, LevelCount = 1, BaseMipLevel = 0, BaseArrayLayer = 0, }, }); swapchainImageViews[i] = view; i++; } cleanupStack.Push(() => { foreach (ImageView imageView in swapchainImageViews) { device.DestroyImageView(imageView); } device.DestroySemaphore(swapChainSemphore); swapChainSemphore = null; device.DestroySwapchainKHR(swapChain); swapChain = null; instance.DestroySurfaceKHR(surface); surface = null; }); }
/// <summary> /// Create multiple swapchains that share presentable images. /// <para> /// Is similar to <see cref="CreateSwapchainKhr"/>, except that it takes an array of <see /// cref="SwapchainCreateInfoKhr"/> structures, and returns an array of swapchain objects. /// </para> /// <para> /// The swapchain creation parameters that affect the properties and number of presentable /// images must match between all the swapchains.If the displays used by any of the /// swapchains do not use the same presentable image layout or are incompatible in a way that /// prevents sharing images, swapchain creation will fail with the result code <see /// cref="Result.ErrorIncompatibleDisplayKhr"/>. If any error occurs, no swapchains will be /// created. Images presented to multiple swapchains must be re-acquired from all of them /// before transitioning away from <see cref="ImageLayout.PresentSrcKhr"/>. After destroying /// one or more of the swapchains, the remaining swapchains and the presentable images can /// continue to be used. /// </para> /// </summary> /// <param name="device">The device to create the swapchains for.</param> /// <param name="createInfos">Structures specifying the parameters of the created swapchains.</param> /// <param name="allocator"> /// The allocator used for host memory allocated for the swapchain objects when there is no /// more specific allocator available. /// </param> /// <returns>The created swapchain objects.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static SwapchainKhr[] CreateSharedSwapchainsKhr(this Device device, SwapchainCreateInfoKhr[] createInfos, AllocationCallbacks?allocator = null) { return(SwapchainKhr.CreateSharedKhr(device, createInfos, ref allocator)); }
public void Create(CommandBuffer commandBuffer) { var surfaceCapabilities = PhysicalDevice.GetSurfaceCapabilitiesKHR(Surface); Extent2D swapChainExtend = new Extent2D { Width = surfaceCapabilities.CurrentExtent.Width, Height = surfaceCapabilities.CurrentExtent.Height }; var presentModes = PhysicalDevice.GetSurfacePresentModesKHR(Surface); PresentModeKhr presentMode = GetBestPresentMode(presentModes); var desiredImages = surfaceCapabilities.MinImageCount + 1; if (surfaceCapabilities.MaxImageCount > 0 && desiredImages > surfaceCapabilities.MaxImageCount) { desiredImages = surfaceCapabilities.MaxImageCount; } var preTransform = surfaceCapabilities.CurrentTransform; if (surfaceCapabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKhr.Identity)) { preTransform = SurfaceTransformFlagsKhr.Identity; } var oldSwapChain = Swapchain; var swapChainCreateInfo = new SwapchainCreateInfoKhr { Surface = Surface, MinImageCount = desiredImages, ImageFormat = ColorFormat, ImageColorSpace = ColorSpace, ImageExtent = swapChainExtend, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = preTransform, ImageArrayLayers = 1, ImageSharingMode = SharingMode.Exclusive, QueueFamilyIndexCount = 0, QueueFamilyIndices = null, PresentMode = presentMode, Clipped = true, // Alpha on the window surface should be opaque: // If it was not we could create transparent regions of our window which // would require support from the Window compositor. You can totally do // that if you wanted though ;) CompositeAlpha = CompositeAlphaFlagsKhr.Opaque }; Swapchain = Device.CreateSwapchainKHR(swapChainCreateInfo); if (oldSwapChain != null) { Device.DestroySwapchainKHR(oldSwapChain); } Images = Device.GetSwapchainImagesKHR(Swapchain).ToList(); // Create the image views for the swap chain. They will all be single // layer, 2D images, with no mipmaps. // Check the VkImageViewCreateInfo structure to see other views you // can potentially create. for (var i = 0; i < Images.Count; i++) { var buffer = new SwapChainBuffer(); var colorAttachmentView = new ImageViewCreateInfo { Format = ColorFormat, Components = new ComponentMapping { R = ComponentSwizzle.R, G = ComponentSwizzle.G, B = ComponentSwizzle.B, A = ComponentSwizzle.A }, SubresourceRange = new ImageSubresourceRange { AspectMask = ImageAspectFlags.Color, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1 }, ViewType = ImageViewType.View2D }; buffer.Image = Images[i]; SetImageLayout(commandBuffer, buffer.Image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSrcKhr); buffer.View = Device.CreateImageView(colorAttachmentView); Buffers.Add(buffer); } }