// Initializes the various graphics resources found throughout the library internal void InitializeResources() { // Scratch command pool var pci = new Vk.CommandPoolCreateInfo(Queues.Graphics.FamilyIndex, Vk.CommandPoolCreateFlags.Transient | Vk.CommandPoolCreateFlags.ResetCommandBuffer); _scratchPool = VkDevice.CreateCommandPool(pci); _scratchAllocInfo = new Vk.CommandBufferAllocateInfo(Vk.CommandBufferLevel.Primary, 1); _scratchBeginInfo = new Vk.CommandBufferBeginInfo(Vk.CommandBufferUsages.OneTimeSubmit, null); _scratchFence = VkDevice.CreateFence(); // Resources throughout the library TransferBuffer.CreateResources(); }
public Swapchain(GraphicsDevice gdevice, Vk.Instance instance, Vk.PhysicalDevice pDevice, Vk.Device device) { Device = gdevice; _window = gdevice.Application.Window; _vkInstance = instance; _vkPhysicalDevice = pDevice; _vkDevice = device; // Create the surface long surfHandle = Glfw.CreateWindowSurface(instance, _window.Handle); Vk.AllocationCallbacks?acb = null; Surface = new VkKhr.SurfaceKhr(instance, ref acb, surfHandle); if (VkKhr.PhysicalDeviceExtensions.GetSurfaceSupportKhr(pDevice, gdevice.Queues.Graphics.FamilyIndex, Surface) == Vk.Constant.False) { LFATAL($"The physical device '{gdevice.Info.Name}' does not support surface presentation."); throw new PlatformNotSupportedException("Physical device does not support surface presentation."); } LINFO("Created Vulkan presentation surface."); // Check the surface for swapchain support levels var sFmts = VkKhr.PhysicalDeviceExtensions.GetSurfaceFormatsKhr(pDevice, Surface); var pModes = VkKhr.PhysicalDeviceExtensions.GetSurfacePresentModesKhr(pDevice, Surface); if (sFmts.Length == 0) { throw new PlatformNotSupportedException("The chosen device does not support any presentation formats."); } if (pModes.Length == 0) { throw new PlatformNotSupportedException("The chosen device does not support any presentation modes."); } // Choose the best available surface format if (sFmts.Length == 1 && sFmts[0].Format == Vk.Format.Undefined) // We are allowed to pick! { _surfaceFormat = PREFERRED_SURFACE_FORMATS[0]; } else // Check if one of the preferred formats is available, otherwise just use the first format given { var sfmt = PREFERRED_SURFACE_FORMATS.FirstOrDefault(fmt => sFmts.Contains(fmt)); if (sfmt.Format == 0 && sfmt.ColorSpace == 0) { _surfaceFormat = sFmts[0]; } else { _surfaceFormat = sfmt; } } // Choose the presentation mode (prefer mailbox -> fifo -> imm) _presentMode = pModes.Contains(VkKhr.PresentModeKhr.Mailbox) ? VkKhr.PresentModeKhr.Mailbox : pModes.Contains(VkKhr.PresentModeKhr.Fifo) ? VkKhr.PresentModeKhr.Fifo : VkKhr.PresentModeKhr.Immediate; // Prepare the synchronization objects _syncObjects.ImageAvailable = new Vk.Semaphore[MAX_INFLIGHT_FRAMES]; _syncObjects.BlitComplete = new Vk.Semaphore[MAX_INFLIGHT_FRAMES]; for (int i = 0; i < MAX_INFLIGHT_FRAMES; ++i) { _syncObjects.ImageAvailable[i] = device.CreateSemaphore(); _syncObjects.BlitComplete[i] = device.CreateSemaphore(); } // Setup the command buffers var cpci = new Vk.CommandPoolCreateInfo(_presentQueue.FamilyIndex, Vk.CommandPoolCreateFlags.Transient | Vk.CommandPoolCreateFlags.ResetCommandBuffer); _commandPool = device.CreateCommandPool(cpci); var cbai = new Vk.CommandBufferAllocateInfo(Vk.CommandBufferLevel.Primary, 1); _commandBuffer = _commandPool.AllocateBuffers(cbai)[0]; _blitFence = device.CreateFence(); // Do NOT start this signalled, as it is needed in rebuildSwapchain() below _rtTransferBarrier = new Vk.ImageMemoryBarrier( null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.ColorAttachmentWrite, Vk.Accesses.TransferRead, Vk.ImageLayout.ColorAttachmentOptimal, Vk.ImageLayout.TransferSrcOptimal ); _rtAttachBarrier = new Vk.ImageMemoryBarrier( null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1), Vk.Accesses.TransferRead, Vk.Accesses.ColorAttachmentWrite, Vk.ImageLayout.TransferSrcOptimal, Vk.ImageLayout.ColorAttachmentOptimal ); // Build the swapchain rebuildSwapchain(); }