コード例 #1
0
ファイル: ClearView.cs プロジェクト: iwandi/VulkanSharp
        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;
        }
コード例 #2
0
        private void CreateSemaphores()
        {
            var semaphoreInfo = new SemaphoreCreateInfo();

            vkImageAvailableSemaphore = vkDevice.CreateSemaphore(semaphoreInfo);
            vkRenderFinishedSemaphore = vkDevice.CreateSemaphore(semaphoreInfo);
        }
コード例 #3
0
        public Queue(Device myDevice, uint QueueFamilyIndex, uint QueueIndex)
        {
            SemaphoreCreateInfo myInfo = new SemaphoreCreateInfo();

            myQueueSemaphore      = myDevice.CreateSemaphore(myInfo);
            this.QueueFamilyIndex = QueueFamilyIndex;
            this.QueueIndex       = QueueIndex;
            myDevice.GetQueue(this, QueueFamilyIndex, QueueIndex);
        }
コード例 #4
0
        public unsafe Semaphore(Api api)
        {
            _api = api;

            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphoreInfo.SType = StructureType.SemaphoreCreateInfo;

            Util.Verify(_api.Vk.CreateSemaphore(_api.Device.VkDevice, semaphoreInfo, default, out _vkSemaphore), $"{nameof(Semaphore)}: Failed to create semaphore");
コード例 #5
0
        public unsafe Semaphore GetNextPresentSemaphore()
        {
            var createInfo = new SemaphoreCreateInfo {
                StructureType = StructureType.SemaphoreCreateInfo
            };

            presentSemaphore = NativeDevice.CreateSemaphore(ref createInfo);
            Collect(presentSemaphore);
            return(presentSemaphore);
        }
コード例 #6
0
        public SwapchainManager(Device LogicalDevice, SurfaceFormatKHR SelectedSurfaceFormat)
        {
            var compositeAlpha = VulkanRenderer.Surface.SurfaceCapabilities.SupportedCompositeAlpha.HasFlag(CompositeAlphaFlagsKHR.Inherit)
               ? CompositeAlphaFlagsKHR.Inherit
               : CompositeAlphaFlagsKHR.Opaque;
            SemaphoreCreateInfo semaphoreInfo = new SemaphoreCreateInfo();

            SwapchainDrawCompleteSemaphore = LogicalDevice.CreateSemaphore(semaphoreInfo);
            CreateDefaultSwapchainRenderPass(LogicalDevice);
            renderPassBeginInfo = new RenderPassBeginInfo {
                ClearValueCount = 1, ClearValues = new ClearValue[] { new ClearValue {
                                                                          Color = new ClearColorValue(Color.AliceBlue)
                                                                      } }, RenderPass = myBaseRenderPass
            };
            renderPassBeginInfo.RenderArea = new Rect2D {
                Extent = new Extent2D {
                    Width = VulkanRenderer.Surface.SurfaceCapabilities.CurrentExtent.Width, Height = VulkanRenderer.Surface.SurfaceCapabilities.CurrentExtent.Height
                }, Offset = new Offset2D {
                    X = 0, Y = 0
                }
            };
            var swapchainInfo = new SwapchainCreateInfoKHR
            {
                Surface            = VulkanRenderer.Surface,
                MinImageCount      = VulkanRenderer.Surface.SurfaceCapabilities.MinImageCount + 1,
                ImageFormat        = VulkanRenderer.Surface.SelectedSurfaceFormat.Format,
                ImageColorSpace    = VulkanRenderer.Surface.SelectedSurfaceFormat.ColorSpace,
                ImageExtent        = VulkanRenderer.Surface.SurfaceCapabilities.CurrentExtent,
                ImageUsage         = ImageUsageFlags.ColorAttachment,
                PreTransform       = SurfaceTransformFlagsKHR.Identity,
                ImageArrayLayers   = 1,
                ImageSharingMode   = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { VulkanRenderer.ActiveGraphicsFamilyQueueIndex },
                PresentMode        = PresentModeKHR.Fifo,
                CompositeAlpha     = compositeAlpha
            };

            Swapchain            = VulkanRenderer.SelectedLogicalDevice.CreateSwapchainKHR(swapchainInfo);
            Images               = VulkanRenderer.SelectedLogicalDevice.GetSwapchainImagesKHR(Swapchain);
            SwapChainPresentInfo = new PresentInfoKHR
            {
                Swapchains   = new SwapchainKHR[] { Swapchain },
                ImageIndices = new uint[] { VulkanRenderer.SelectedLogicalDevice.AcquireNextImageKHR(Swapchain, ulong.MaxValue, SwapchainDrawCompleteSemaphore) }
            };


            Framebuffers = new SwapChainFrameBuffer[Images.Length]; //Move this to swap chains

            for (int i = 0; i < Images.Length; i++)
            {
                Framebuffers[i] = new SwapChainFrameBuffer(myBaseRenderPass, Images[i], i, VulkanRenderer.Surface.SurfaceCapabilities.CurrentExtent.Width, VulkanRenderer.Surface.SurfaceCapabilities.CurrentExtent.Height, 1);
                Framebuffers[i].Initialize();
            }
        }
コード例 #7
0
ファイル: Tutorial03.cs プロジェクト: Benkei/Crow.Framework
        void CreateSemaphores()
        {
            var semaphore_create_info = new SemaphoreCreateInfo
            {
                sType = StructureType.SemaphoreCreateInfo,
                pNext = IntPtr.Zero,
                flags = 0,
            };

            vk.CreateSemaphore(GetDevice, ref semaphore_create_info, (AllocationCallbacks *)0, out Vulkan.ImageAvailableSemaphore).CheckError();
            vk.CreateSemaphore(GetDevice, ref semaphore_create_info, (AllocationCallbacks *)0, out Vulkan.RenderingFinishedSemaphore).CheckError();
        }
コード例 #8
0
ファイル: GraphicsManager.cs プロジェクト: Ciastex/Prisma
        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);
        }
コード例 #9
0
        public unsafe SemaphoreHolder(Vk api, Device device)
        {
            _api    = api;
            _device = device;

            var semaphoreCreateInfo = new SemaphoreCreateInfo()
            {
                SType = StructureType.SemaphoreCreateInfo
            };

            api.CreateSemaphore(device, in semaphoreCreateInfo, null, out _semaphore).ThrowOnError();

            _referenceCount = 1;
        }
コード例 #10
0
        public unsafe VulkanSemaphorePair(VulkanDevice device)
        {
            _device = device;

            var semaphoreCreateInfo = new SemaphoreCreateInfo {
                SType = StructureType.SemaphoreCreateInfo
            };

            _device.Api.CreateSemaphore(_device.InternalHandle, semaphoreCreateInfo, null, out var semaphore).ThrowOnError();
            ImageAvailableSemaphore = semaphore;

            _device.Api.CreateSemaphore(_device.InternalHandle, semaphoreCreateInfo, null, out semaphore).ThrowOnError();
            RenderFinishedSemaphore = semaphore;
        }
コード例 #11
0
        public unsafe Window(VulkanGraphicsDevice gd, SurfaceKHR surface, PhysicalDevice physicalDevice, Device device)
        {
            _gd             = gd;
            _physicalDevice = physicalDevice;
            _device         = device;
            _surface        = surface;

            CreateSwapchain();

            var semaphoreCreateInfo = new SemaphoreCreateInfo()
            {
                SType = StructureType.SemaphoreCreateInfo
            };

            gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
            gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _renderFinishedSemaphore).ThrowOnError();
        }
コード例 #12
0
ファイル: XLogoView.cs プロジェクト: iwandi/VulkanSharp
        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;
        }
コード例 #13
0
        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;
        }
コード例 #14
0
        void OnRenderCallback(Queue queue, CommandBuffer[] cmdBuffer, SwapchainData swapchainData)
        {
            var semaphoreCreateInfo = new SemaphoreCreateInfo();
            var presentSemaphore    = device.CreateSemaphore(semaphoreCreateInfo);

            semaphoreCreateInfo.Dispose();

            var currentBufferIndex = (int)device.AcquireNextImageKHR(swapchainData.Swapchain, ulong.MaxValue, presentSemaphore, null);

            SubmitForExecution(queue, presentSemaphore, cmdBuffer[currentBufferIndex]);

            // Present the image (display it on the screen)
            var presentInfo = new PresentInfoKHR(new[] { swapchainData.Swapchain }, new[] { (uint)currentBufferIndex });

            queue.PresentKHR(presentInfo);
            presentInfo.Dispose();

            queue.WaitIdle(); // wait for execution to finish

            device.DestroySemaphore(presentSemaphore);
        }
コード例 #15
0
        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;
        }
コード例 #16
0
        //static int i;

        void OnRenderCallback(Queue queue, CommandBuffer[] cmdBuffer, SwapchainData swapchainData, UniformData uniformData, Transform transform)
        {
            //transform.model *= OpenTK.Matrix4.CreateRotationX(i++);
            //CopyUBO(transform, uniformData);

            var semaphoreCreateInfo = new SemaphoreCreateInfo();
            var presentSemaphore    = device.CreateSemaphore(semaphoreCreateInfo);

            semaphoreCreateInfo.Dispose();

            var currentBufferIndex = (int)device.AcquireNextImageKHR(swapchainData.Swapchain, ulong.MaxValue, presentSemaphore, null);

            SubmitForExecution(queue, presentSemaphore, cmdBuffer[currentBufferIndex]);

            var presentInfo = new PresentInfoKHR(new[] { swapchainData.Swapchain }, new[] { (uint)currentBufferIndex });

            queue.PresentKHR(presentInfo);
            presentInfo.Dispose();

            queue.WaitIdle();

            device.DestroySemaphore(presentSemaphore);
        }
コード例 #17
0
ファイル: Frame.cs プロジェクト: MatijaBrown/SilkyNvg
        public unsafe Frame(uint graphicsQueueFamily, Device device, Vk vk)
        {
            _device = device;
            _vk     = vk;

            FenceCreateInfo     fenceCreateInfo     = VkInit.FenceCreateInfo(true);
            SemaphoreCreateInfo semaphoreCreateInfo = VkInit.SemaphoreCreateInfo();

            VkUtil.AssertVulkan(vk.CreateFence(_device, fenceCreateInfo, null, out Fence renderFence));
            VkUtil.AssertVulkan(vk.CreateSemaphore(_device, semaphoreCreateInfo, null, out Semaphore renderSemaphore));
            VkUtil.AssertVulkan(vk.CreateSemaphore(_device, semaphoreCreateInfo, null, out Semaphore presentSemaphore));
            RenderSemaphore  = renderSemaphore;
            PresentSemaphore = presentSemaphore;
            RenderFence      = renderFence;

            CommandPoolCreateInfo commandPoolCreateInfo = VkInit.CommandPoolCreateInfo(graphicsQueueFamily, 0);

            VkUtil.AssertVulkan(_vk.CreateCommandPool(_device, commandPoolCreateInfo, null, out _commandPool));

            CreateCommandBuffers();

            _commandBufferIndex = 0;
        }
コード例 #18
0
ファイル: Functions.cs プロジェクト: jwollen/SharpVulkan
 internal static unsafe extern Result vkCreateSemaphore(Device device, SemaphoreCreateInfo* createInfo, AllocationCallbacks* allocator, Semaphore* semaphore);
コード例 #19
0
ファイル: Functions.cs プロジェクト: jwollen/SharpVulkan
 public unsafe Semaphore CreateSemaphore(ref SemaphoreCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     Semaphore semaphore;
     fixed (SemaphoreCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateSemaphore(this, __createInfo__, allocator, &semaphore).CheckError();
     }
     return semaphore;
 }
コード例 #20
0
ファイル: Sample.cs プロジェクト: jcapellman/SharpVulkan
        protected virtual unsafe void Draw()
        {
            var semaphoreCreateInfo = new SemaphoreCreateInfo {
                StructureType = StructureType.SemaphoreCreateInfo
            };
            var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);

            try
            {
                // Get the index of the next available swapchain image
                currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
            }
            catch (SharpVulkanException e) when(e.Result == Result.ErrorOutOfDate)
            {
                // TODO: Handle resize and retry draw
                throw new NotImplementedException();
            }

            // Record drawing command buffer
            var beginInfo = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo
            };

            commandBuffer.Begin(ref beginInfo);
            DrawInternal();
            commandBuffer.End();

            // Submit
            var drawCommandBuffer  = commandBuffer;
            var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
            var submitInfo         = new SubmitInfo
            {
                StructureType      = StructureType.SubmitInfo,
                WaitSemaphoreCount = 1,
                WaitSemaphores     = new IntPtr(&presentCompleteSemaphore),
                WaitDstStageMask   = new IntPtr(&pipelineStageFlags),
                CommandBufferCount = 1,
                CommandBuffers     = new IntPtr(&drawCommandBuffer),
            };

            queue.Submit(1, &submitInfo, Fence.Null);

            // Present
            var swapchain = this.swapchain;
            var currentBackBufferIndexCopy = currentBackBufferIndex;
            var presentInfo = new PresentInfo
            {
                StructureType  = StructureType.PresentInfo,
                SwapchainCount = 1,
                Swapchains     = new IntPtr(&swapchain),
                ImageIndices   = new IntPtr(&currentBackBufferIndexCopy)
            };

            queue.Present(ref presentInfo);

            // Wait
            queue.WaitIdle();

            device.ResetDescriptorPool(descriptorPool, DescriptorPoolResetFlags.None);

            // Cleanup
            device.DestroySemaphore(presentCompleteSemaphore);
        }
コード例 #21
0
ファイル: Sample.cs プロジェクト: jwollen/SharpVulkan
        protected unsafe virtual void Draw()
        {
            var semaphoreCreateInfo = new SemaphoreCreateInfo { StructureType = StructureType.SemaphoreCreateInfo };
            var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);

            try
            {
                // Get the index of the next available swapchain image
                currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
            }
            catch (SharpVulkanException e) when (e.Result == Result.ErrorOutOfDate)
            {
                // TODO: Handle resize and retry draw
                throw new NotImplementedException();
            }

            // Record drawing command buffer
            var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
            commandBuffer.Begin(ref beginInfo);
            DrawInternal();
            commandBuffer.End();

            // Submit
            var drawCommandBuffer = commandBuffer;
            var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
            var submitInfo = new SubmitInfo
            {
                StructureType = StructureType.SubmitInfo,
                WaitSemaphoreCount = 1,
                WaitSemaphores = new IntPtr(&presentCompleteSemaphore),
                WaitDstStageMask = new IntPtr(&pipelineStageFlags),
                CommandBufferCount = 1,
                CommandBuffers = new IntPtr(&drawCommandBuffer),
            };
            queue.Submit(1, &submitInfo, Fence.Null);

            // Present
            var swapchain = this.swapchain;
            var currentBackBufferIndexCopy = currentBackBufferIndex;
            var presentInfo = new PresentInfo
            {
                StructureType = StructureType.PresentInfo,
                SwapchainCount = 1,
                Swapchains = new IntPtr(&swapchain),
                ImageIndices = new IntPtr(&currentBackBufferIndexCopy)
            };
            queue.Present(ref presentInfo);

            // Wait
            queue.WaitIdle();

            device.ResetDescriptorPool(descriptorPool, DescriptorPoolResetFlags.None);

            // Cleanup
            device.DestroySemaphore(presentCompleteSemaphore);
        }