Exemplo n.º 1
0
        public void Submit(VkSemaphore waitSemaphore, VkPipelineStageFlags waitDstStageMask,
                           VkCommandBuffer commandBuffer, VkSemaphore signalSemaphore, VkFence fence = default)
        {
            VkCommandBuffer commandBufferHandle = commandBuffer;

            var nativeSubmit = new VkSubmitInfo
            {
                sType = VkStructureType.SubmitInfo
            };

            if (waitSemaphore != default)
            {
                nativeSubmit.waitSemaphoreCount = 1;
                nativeSubmit.pWaitSemaphores    = &waitSemaphore;
                nativeSubmit.pWaitDstStageMask  = &waitDstStageMask;
            }

            if (commandBuffer != null)
            {
                nativeSubmit.commandBufferCount = 1;
                nativeSubmit.pCommandBuffers    = &commandBufferHandle;
            }

            if (signalSemaphore != default)
            {
                nativeSubmit.signalSemaphoreCount = 1;
                nativeSubmit.pSignalSemaphores    = &signalSemaphore;
            }

            VulkanUtil.CheckResult(vkQueueSubmit(this, 1, &nativeSubmit, fence));
        }
Exemplo n.º 2
0
        public Graphics(Settings settings)
        {
#if DEBUG
            //settings.Validation = true;
#else
            settings.Validation = false;
#endif
            Settings = settings;

            enabledFeatures.samplerAnisotropy = true;
            enabledFeatures.depthClamp        = true;
            enabledFeatures.shaderStorageImageExtendedFormats = true;

            Device.Create(settings, enabledFeatures, EnabledExtensions);

            // Get a graphics queue from the Device
            GraphicsQueue = new VkQueue(Device.QFGraphics, 0);
            WorkQueue     = new VkQueue(Device.QFGraphics, 0);
            ComputeQueue  = new VkQueue(Device.QFCompute, 0);
            TransferQueue = new VkQueue(Device.QFTransfer, 0);

            DepthFormat = Device.GetSupportedDepthFormat();

            primaryCmdPool = new CommandBufferPool(Device.QFGraphics, VkCommandPoolCreateFlags.ResetCommandBuffer);

            DescriptorPoolManager = new DescriptorPoolManager();

            acquireSemaphore = new VkSemaphore(VkSemaphoreCreateFlags.None);
        }
Exemplo n.º 3
0
        public static VkResult vkCreateSemaphore(VkDevice device, out VkSemaphore semaphore)
        {
            VkSemaphoreCreateInfo createInfo = new VkSemaphoreCreateInfo
            {
                sType = VkStructureType.SemaphoreCreateInfo,
                pNext = null,
                flags = VkSemaphoreCreateFlags.None
            };

            return(vkCreateSemaphore(device, &createInfo, null, out semaphore));
        }
Exemplo n.º 4
0
        public RenderContext(int id = -1)
        {
            this.id = id;

            acquireSemaphore = new VkSemaphore(VkSemaphoreCreateFlags.None);

            for (int i = 0; i < (int)SubmitQueue.MaxCount; i++)
            {
                submitQueue[i] = new SubmitQueueData
                {
                    cmdBuffer          = pools[i].AllocateCommandBuffer(VkCommandBufferLevel.Primary),
                    submitFence        = new VkFence(VkFenceCreateFlags.Signaled),
                    semaphore          = new VkSemaphore(VkSemaphoreCreateFlags.None),
                    pipelineStageFlags = (i == (int)SubmitQueue.Compute ? VkPipelineStageFlags.ComputeShader : VkPipelineStageFlags.FragmentShader)
                };
            }
        }
Exemplo n.º 5
0
        private VkResult AcquireNextImage(out uint imageIndex)
        {
            VkSemaphore acquireSemaphore;

            if (_recycledSemaphores.Count == 0)
            {
                vkCreateSemaphore(VkDevice, out acquireSemaphore).CheckResult();
            }
            else
            {
                acquireSemaphore = _recycledSemaphores[_recycledSemaphores.Count - 1];
                _recycledSemaphores.RemoveAt(_recycledSemaphores.Count - 1);
            }

            VkResult result = vkAcquireNextImageKHR(VkDevice, Swapchain.Handle, ulong.MaxValue, acquireSemaphore, VkFence.Null, out imageIndex);

            if (result != VkResult.Success)
            {
                _recycledSemaphores.Add(acquireSemaphore);
                return(result);
            }

            if (_perFrame[imageIndex].QueueSubmitFence != VkFence.Null)
            {
                vkWaitForFences(VkDevice, _perFrame[imageIndex].QueueSubmitFence, true, ulong.MaxValue);
                vkResetFences(VkDevice, _perFrame[imageIndex].QueueSubmitFence);
            }

            if (_perFrame[imageIndex].PrimaryCommandPool != VkCommandPool.Null)
            {
                vkResetCommandPool(VkDevice, _perFrame[imageIndex].PrimaryCommandPool, VkCommandPoolResetFlags.None);
            }

            // Recycle the old semaphore back into the semaphore manager.
            VkSemaphore old_semaphore = _perFrame[imageIndex].SwapchainAcquireSemaphore;

            if (old_semaphore != VkSemaphore.Null)
            {
                _recycledSemaphores.Add(old_semaphore);
            }

            _perFrame[imageIndex].SwapchainAcquireSemaphore = acquireSemaphore;

            return(VkResult.Success);
        }
Exemplo n.º 6
0
        public unsafe void QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = default)
        {
            var sc          = swapchain;
            var presentInfo = new VkPresentInfoKHR
            {
                sType          = VkStructureType.PresentInfoKHR,
                pNext          = null,
                swapchainCount = 1,
                pSwapchains    = &sc,
                pImageIndices  = &imageIndex
            };

            // Check if a wait semaphore has been specified to wait for before presenting the image
            if (waitSemaphore != VkSampler.Null)
            {
                presentInfo.pWaitSemaphores    = (VkSemaphore *)Unsafe.AsPointer(ref waitSemaphore);
                presentInfo.waitSemaphoreCount = 1;
            }

            VulkanUtil.CheckResult(vkQueuePresentKHR(queue, &presentInfo));
        }
Exemplo n.º 7
0
        public static VkResult vkQueuePresentKHR(VkQueue queue, VkSemaphore waitSemaphore, VkSwapchainKHR swapchain, uint imageIndex)
        {
            var presentInfo = new VkPresentInfoKHR
            {
                sType = VkStructureType.PresentInfoKHR,
                pNext = null
            };

            if (waitSemaphore != VkSemaphore.Null)
            {
                presentInfo.waitSemaphoreCount = 1u;
                presentInfo.pWaitSemaphores    = &waitSemaphore;
            }

            if (swapchain != VkSwapchainKHR.Null)
            {
                presentInfo.swapchainCount = 1u;
                presentInfo.pSwapchains    = &swapchain;
                presentInfo.pImageIndices  = &imageIndex;
            }

            return(vkQueuePresentKHR(queue, &presentInfo));
        }
Exemplo n.º 8
0
        public bool AcquireNextImage(VkSemaphore presentCompleteSemaphore, out int imageIndex)
        {
            VkResult res = Device.AcquireNextImageKHR(swapchain, ulong.MaxValue, presentCompleteSemaphore, new VkFence(), out uint nextImageIndex);

            if (res == VkResult.ErrorOutOfDateKHR)
            {
                Log.Error(res.ToString());
                //uint w = 0, h = 0;
                //Create(ref w, ref h, false);
            }
            else if (res == VkResult.SuboptimalKHR)
            {
                Log.Info(res.ToString());
            }
            else if (res != VkResult.Success)
            {
                Log.Info(res.ToString());
                imageIndex = 0;
                return(false);
            }

            imageIndex = (int)nextImageIndex;
            return(true);
        }
Exemplo n.º 9
0
 public static VkResult AcquireNextImageKHR(VkSwapchainKHR swapchain, ulong timeout, VkSemaphore semaphore, VkFence fence, out uint pImageIndex)
 {
     return(vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, out pImageIndex));
 }
Exemplo n.º 10
0
        public static VkResult vkCreateTypedSemaphore(VkDevice device, VkSemaphoreType type, ulong initialValue, out VkSemaphore semaphore)
        {
            VkSemaphoreTypeCreateInfo typeCreateiInfo = new VkSemaphoreTypeCreateInfo
            {
                sType         = VkStructureType.SemaphoreTypeCreateInfo,
                pNext         = null,
                semaphoreType = type,
                initialValue  = initialValue
            };

            VkSemaphoreCreateInfo createInfo = new VkSemaphoreCreateInfo
            {
                sType = VkStructureType.SemaphoreCreateInfo,
                pNext = &typeCreateiInfo,
                flags = VkSemaphoreCreateFlags.None
            };

            return(vkCreateSemaphore(device, &createInfo, null, out semaphore));
        }
Exemplo n.º 11
0
        public void RenderFrame(Action <VkCommandBuffer, VkFramebuffer, VkExtent2D> draw, [CallerMemberName] string?frameName = null)
        {
            VkResult result = AcquireNextImage(out uint swapchainIndex);

            // Handle outdated error in acquire.
            if (result == VkResult.SuboptimalKHR || result == VkResult.ErrorOutOfDateKHR)
            {
                //Resize(context.swapchain_dimensions.width, context.swapchain_dimensions.height);
                result = AcquireNextImage(out swapchainIndex);
            }

            if (result != VkResult.Success)
            {
                vkDeviceWaitIdle(VkDevice);
                return;
            }

            // Begin command recording
            VkCommandBuffer cmd = _perFrame[swapchainIndex].PrimaryCommandBuffer;

            VkCommandBufferBeginInfo beginInfo = new VkCommandBufferBeginInfo
            {
                sType = VkStructureType.CommandBufferBeginInfo,
                flags = VkCommandBufferUsageFlags.OneTimeSubmit
            };

            vkBeginCommandBuffer(cmd, &beginInfo).CheckResult();

            draw(cmd, Swapchain.Framebuffers[swapchainIndex], Swapchain.Extent);

            // Complete the command buffer.
            vkEndCommandBuffer(cmd).CheckResult();

            if (_perFrame[swapchainIndex].SwapchainReleaseSemaphore == VkSemaphore.Null)
            {
                vkCreateSemaphore(VkDevice, out _perFrame[swapchainIndex].SwapchainReleaseSemaphore).CheckResult();
            }

            VkPipelineStageFlags wait_stage      = VkPipelineStageFlags.ColorAttachmentOutput;
            VkSemaphore          waitSemaphore   = _perFrame[swapchainIndex].SwapchainAcquireSemaphore;
            VkSemaphore          signalSemaphore = _perFrame[swapchainIndex].SwapchainReleaseSemaphore;

            VkSubmitInfo submitInfo = new VkSubmitInfo
            {
                sType = VkStructureType.SubmitInfo,
                commandBufferCount   = 1u,
                pCommandBuffers      = &cmd,
                waitSemaphoreCount   = 1u,
                pWaitSemaphores      = &waitSemaphore,
                pWaitDstStageMask    = &wait_stage,
                signalSemaphoreCount = 1u,
                pSignalSemaphores    = &signalSemaphore
            };

            // Submit command buffer to graphics queue
            vkQueueSubmit(GraphicsQueue, submitInfo, _perFrame[swapchainIndex].QueueSubmitFence);

            result = PresentImage(swapchainIndex);

            // Handle Outdated error in present.
            if (result == VkResult.SuboptimalKHR || result == VkResult.ErrorOutOfDateKHR)
            {
                //Resize(context.swapchain_dimensions.width, context.swapchain_dimensions.height);
            }
            else if (result != VkResult.Success)
            {
                Log.Error("Failed to present swapchain image.");
            }
        }