public static VkSurfaceFormatKHR Create(VkFormat format, VkColorSpaceKHR colorSpace) { return(new VkSurfaceFormatKHR() { format = format, colorSpace = colorSpace }); }
private SoftwareImage(SoftwareDevice device, VkFormat format, VkExtent3D imageExtent, VkColorSpaceKHR colorSpace, out VkResult result) { this.m_device = device; this.m_imageFormat = format; this.m_imageExtent = imageExtent; this.m_imageColorSpace = colorSpace; Initialize(out result); }
private SoftwareImage(SoftwareDevice device, VkSwapchainCreateInfoKHR createInfo, out VkResult result) { this.m_device = device; this.m_imageFormat = createInfo.imageFormat; this.m_imageExtent = VkExtent3D.Create(createInfo.imageExtent.width, createInfo.imageExtent.height, 1); this.m_imageColorSpace = createInfo.imageColorSpace; Initialize(out result); }
private SoftwareImage(SoftwareDevice device, VkImageCreateInfo pCreateInfo, out VkResult result) { this.m_device = device; this.m_createInfo = pCreateInfo; this.m_imageFormat = pCreateInfo.format; this.m_imageExtent = pCreateInfo.extent; this.m_imageColorSpace = VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; Initialize(out result); }
/// <summary> /// Initializes a new instance of the <see cref="VkSurfaceFormatKHR"/> struct. /// </summary> /// <param name="format">Is the <see cref="VkFormat"/> that is compatible with the specified surface.</param> /// <param name="colorSpace">Is a presentation <see cref="VkColorSpaceKHR"/> that is compatible with the surface.</param> public VkSurfaceFormatKHR(VkFormat format, VkColorSpaceKHR colorSpace) { this.format = format; this.colorSpace = colorSpace; }
public SwapchainKHR(SurfaceKHR surface, Device device, uint minImageCount, uint layerCount, VkImageUsageFlag usageFlag, VkFormat imageFormat, VkColorSpaceKHR colorSpace, VkExtent2D dimensions, VkCompositeAlphaFlagBitsKHR compositeAlpha, VkPresentModeKHR presentMode, bool clipped = true, VkSurfaceTransformFlagBitsKHR transform = VkSurfaceTransformFlagBitsKHR.IdentityBitKhr, VkSharingMode sharing = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null, SwapchainKHR oldSwapchain = null) { SurfaceKHR = surface; Device = device; { var surfSupported = false; foreach (var family in Device.Queues.Select(x => x.FamilyIndex).Distinct()) { if (PhysicalDevice.Handle.GetPhysicalDeviceSurfaceSupportKHR(family, SurfaceKHR.Handle)) { surfSupported = true; break; } } if (!surfSupported) { throw new NotSupportedException($"No queues on device support the surface"); } } _sharingQueueInfo = sharedQueueFamily; unsafe { if (sharing == VkSharingMode.Concurrent) { Debug.Assert(sharedQueueFamily != null); } var hasPinnedSharedQueue = sharedQueueFamily != null && sharedQueueFamily.Length > 0; var pinnedSharedQueueFamily = hasPinnedSharedQueue ? GCHandle.Alloc(sharedQueueFamily, GCHandleType.Pinned) : default(GCHandle); try { var info = new VkSwapchainCreateInfoKHR() { SType = VkStructureType.SwapchainCreateInfoKhr, PNext = IntPtr.Zero, Flags = 0, // reserved VkSwapchainCreateFlagBitsKHR Surface = surface.Handle, MinImageCount = minImageCount, ImageFormat = imageFormat, ImageColorSpace = colorSpace, ImageExtent = dimensions, ImageArrayLayers = layerCount, ImageUsage = usageFlag, ImageSharingMode = sharing, QueueFamilyIndexCount = (uint)(sharedQueueFamily?.Length ?? 0), PQueueFamilyIndices = hasPinnedSharedQueue ? (uint *)Marshal.UnsafeAddrOfPinnedArrayElement(sharedQueueFamily, 0).ToPointer() : (uint *)0, PreTransform = transform, CompositeAlpha = compositeAlpha, PresentMode = presentMode, Clipped = clipped, OldSwapchain = oldSwapchain?.Handle ?? VkSwapchainKHR.Null }; _info = info; Handle = Device.Handle.CreateSwapchainKHR(&info, Instance.AllocationCallbacks); if (oldSwapchain != null) { foreach (var img in oldSwapchain._swapchainImages) { img.Dispose(); } oldSwapchain.Dispose(); } } finally { if (hasPinnedSharedQueue) { pinnedSharedQueueFamily.Free(); } } } var images = Device.Handle.GetSwapchainImagesKHR(Handle); _swapchainImages.Clear(); _swapchainImages.Capacity = images.Length; foreach (var img in images) { _swapchainImages.Add(new SwapchainImage(this, img)); } }
public SwapchainKHRBuilder RequiredFormats(VkColorSpaceKHR colorSpace, params VkFormat[] formats) { _requiredFormats.Add(new KeyValuePair <VkColorSpaceKHR, VkFormat[]>(colorSpace, formats)); return(this); }
public void CreateSwapChain() { var PhysicalDevice = NativeDevice.NativeAdapter.NativePhysicalDevice; var width = Parameters.BackBufferWidth; var height = Parameters.BackBufferHeight; var vsync = Parameters.Settings.VSync; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount]; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps); // Iterate over each queue to learn whether it supports presenting: // Find a queue with present support // Will be used to present the swap chain Images to the windowing system VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount]; for (uint i = 0; i < queueCount; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, Surface, &supportsPresent[i]); } // Search for a graphics and a present queue in the array of queue // families, try to find one that supports both uint graphicsQueueNodeIndex = uint.MaxValue; uint presentQueueNodeIndex = uint.MaxValue; for (uint i = 0; i < queueCount; i++) { if ((queueProps[i].queueFlags & VkQueueFlags.Graphics) != 0) { if (graphicsQueueNodeIndex == uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == 1) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex == uint.MaxValue) { // If there's no queue that supports both present and graphics // try to find a separate present queue for (uint i = 0; i < queueCount; ++i) { if (supportsPresent[i] == 1) { presentQueueNodeIndex = i; break; } } } // Exit if either a graphics or a presenting queue hasn't been found if (graphicsQueueNodeIndex == uint.MaxValue || presentQueueNodeIndex == uint.MaxValue) { throw new InvalidOperationException("Could not find a graphics and/or presenting queue!"); } // todo : Add support for separate graphics and presenting queue if (graphicsQueueNodeIndex != presentQueueNodeIndex) { throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!"); } // Get list of supported Surface formats uint formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null); VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, surfaceFormats); // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED, // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM if ((formatCount == 1) && (surfaceFormats[0].format == VkFormat.Undefined)) { VkColorFormat = VkFormat.B8g8r8a8Unorm; ColorSpace = surfaceFormats[0].colorSpace; } else { // iterate over the list of available Surface format and // check for the presence of VK_FORMAT_B8G8R8A8_UNORM bool found_B8G8R8A8_UNORM = false; List <VkSurfaceFormatKHR> Formats = new List <VkSurfaceFormatKHR>(); for (int i = 0; i < formatCount; i++) { Formats.Add(surfaceFormats[i]); } foreach (var surfaceFormat in Formats) { if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm) { VkColorFormat = surfaceFormat.format; ColorSpace = surfaceFormat.colorSpace; found_B8G8R8A8_UNORM = true; break; } } // in case VK_FORMAT_B8G8R8A8_UNORM is not available // select the first available color format if (!found_B8G8R8A8_UNORM) { VkColorFormat = surfaceFormats[0].format; ColorSpace = surfaceFormats[0].colorSpace; } } // Get physical Device Surface properties and formats VkSurfaceCapabilitiesKHR surfCaps; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PhysicalDevice, Surface, &surfCaps); // Get available present modes uint presentModeCount; vkGetPhysicalDeviceSurfacePresentModesKHR(PhysicalDevice, Surface, &presentModeCount, null); VkPresentModeKHR *presentModes = stackalloc VkPresentModeKHR[(int)presentModeCount]; vkGetPhysicalDeviceSurfacePresentModesKHR(PhysicalDevice, Surface, &presentModeCount, (VkPresentModeKHR *)presentModes); VkExtent2D swapchainExtent; // If width (and height) equals the special value 0xFFFFFFFF, the size of the Surface will be set by the swapchain if (surfCaps.currentExtent.width == unchecked ((uint)-1)) { // If the Surface size is undefined, the size is set to // the size of the Images requested. swapchainExtent.width = (uint)width; swapchainExtent.height = (uint)height; } else { // If the Surface size is defined, the swap chain size must match swapchainExtent = surfCaps.currentExtent; width = (int)surfCaps.currentExtent.width; height = (int)surfCaps.currentExtent.height; } // Select a present mode for the swapchain // The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec // This mode waits for the vertical blank ("v-sync") VkPresentModeKHR swapchainPresentMode = VkPresentModeKHR.FifoKHR; // If v-sync is not requested, try to find a mailbox mode // It's the lowest latency non-tearing present mode available if (!vsync) { for (uint i = 0; i < presentModeCount; i++) { if (presentModes[i] == VkPresentModeKHR.MailboxKHR) { swapchainPresentMode = VkPresentModeKHR.MailboxKHR; break; } if ((swapchainPresentMode != VkPresentModeKHR.MailboxKHR) && (presentModes[i] == VkPresentModeKHR.ImmediateKHR)) { swapchainPresentMode = VkPresentModeKHR.ImmediateKHR; } } } // Determine the number of Images uint desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1; if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount)) { desiredNumberOfSwapchainImages = surfCaps.maxImageCount; } // Find the transformation of the Surface VkSurfaceTransformFlagsKHR preTransform; if ((surfCaps.supportedTransforms & VkSurfaceTransformFlagsKHR.IdentityKHR) != 0) { // We prefer a non-rotated transform preTransform = VkSurfaceTransformFlagsKHR.IdentityKHR; } else { preTransform = surfCaps.currentTransform; } VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.SwapchainCreateInfoKHR, pNext = null, surface = Surface, minImageCount = desiredNumberOfSwapchainImages, imageFormat = VkColorFormat, imageColorSpace = ColorSpace, imageExtent = new VkExtent2D() { width = swapchainExtent.width, height = swapchainExtent.height }, imageUsage = VkImageUsageFlags.ColorAttachment, preTransform = preTransform, imageArrayLayers = 1, imageSharingMode = VkSharingMode.Exclusive, queueFamilyIndexCount = 0, pQueueFamilyIndices = null, presentMode = swapchainPresentMode, oldSwapchain = SwapChain, // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area clipped = True, compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR, }; // Set additional usage flag for blitting from the swapchain Images if supported VkFormatProperties formatProps; vkGetPhysicalDeviceFormatProperties(PhysicalDevice, VkColorFormat, out formatProps); if ((formatProps.optimalTilingFeatures & VkFormatFeatureFlags.BlitDst) != 0) { swapchainCI.imageUsage |= VkImageUsageFlags.TransferSrc; } VkSwapchainKHR swapChain; vkCreateSwapchainKHR(NativeDevice.Device, &swapchainCI, null, &swapChain); SwapChain = swapChain; //vkDestroySwapchainKHR(NativeDevice.Device, SwapChain, null); uint imageCount; vkGetSwapchainImagesKHR(NativeDevice.Device, SwapChain, &imageCount, null); VkImage *VkImages = stackalloc VkImage[(int)imageCount]; vkGetSwapchainImagesKHR(NativeDevice.Device, swapChain, &imageCount, VkImages); Images = new List <VkImage>(); for (int i = 0; i < imageCount; i++) { Images.Add(VkImages[i]); } }
public void CreateSwapChain() { VkPhysicalDevice PhysicalDevice = NativeDevice.NativeAdapter.handle; int width = Parameters.Width; int height = Parameters.Height; bool vsync = false; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount]; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps); // Iterate over each queue to learn whether it supports presenting: // Find a queue with present support // Will be used to present the swap chain Images to the windowing system VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount]; for (uint i = 0; i < queueCount; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, surface, out supportsPresent[i]); } // Search for a graphics and a present queue in the array of queue // families, try to find one that supports both uint graphicsQueueNodeIndex = uint.MaxValue; uint presentQueueNodeIndex = uint.MaxValue; for (uint i = 0; i < queueCount; i++) { if ((queueProps[i].queueFlags & VkQueueFlags.Graphics) != 0) { if (graphicsQueueNodeIndex is uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == true) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex is uint.MaxValue) { // If there's no queue that supports both present and graphics // try to find a separate present queue for (uint i = 0; i < queueCount; ++i) { if (supportsPresent[i] == true) { presentQueueNodeIndex = i; break; } } } // Exit if either a graphics or a presenting queue hasn't been found if (graphicsQueueNodeIndex is uint.MaxValue || presentQueueNodeIndex is uint.MaxValue) { throw new InvalidOperationException("Could not find a graphics and/or presenting queue!"); } // TODO : Add support for separate graphics and presenting queue if (graphicsQueueNodeIndex != presentQueueNodeIndex) { throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!"); } // Get list of supported Surface formats uint formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, null); VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, surfaceFormats); // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED, // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM if ((formatCount is 1) && (surfaceFormats[0].format is VkFormat.Undefined)) { color_format = VkFormat.B8G8R8A8UNorm; color_space = surfaceFormats[0].colorSpace; }