Example #1
0
        public VkEvent(VkEventCreateFlags flags)
        {
            var createInfo = new VkEventCreateInfo
            {
                sType = VkStructureType.EventCreateInfo,
                flags = flags
            };

            Vulkan.vkCreateEvent(Vulkan.device, &createInfo, null, out this).CheckResult();
        }
Example #2
0
        public VkFence(VkFenceCreateFlags flags)
        {
            VkFenceCreateInfo createInfo = new VkFenceCreateInfo
            {
                sType = VkStructureType.FenceCreateInfo,
                flags = flags
            };

            Vulkan.vkCreateFence(Vulkan.device, &createInfo, null, out this).CheckResult();
        }
Example #3
0
        public VkSemaphore(VkSemaphoreCreateFlags flags)
        {
            var semaphoreCreateInfo = new VkSemaphoreCreateInfo
            {
                sType = VkStructureType.SemaphoreCreateInfo,
                flags = flags
            };

            Vulkan.vkCreateSemaphore(Vulkan.device, &semaphoreCreateInfo, null, out this).CheckResult();
        }
Example #4
0
        public static IntPtr GetProcAddr(this VkDevice device, string name)
        {
            int byteCount = Interop.GetMaxByteCount(name);
            var dstPtr    = stackalloc byte[byteCount];

            Interop.StringToPointer(name, dstPtr, byteCount);
            var addr = Vulkan.vkGetDeviceProcAddr(device, dstPtr);

            return(addr);
        }
Example #5
0
        public VkQueryPool(VkQueryType queryType, uint queryCount, VkQueryPipelineStatisticFlags pipelineStatistics = VkQueryPipelineStatisticFlags.None)
        {
            var createInfo = new VkQueryPoolCreateInfo
            {
                sType              = VkStructureType.QueryPoolCreateInfo,
                queryType          = queryType,
                queryCount         = queryCount,
                pipelineStatistics = pipelineStatistics,
            };

            Vulkan.vkCreateQueryPool(Vulkan.device, &createInfo, null, out this).CheckResult();
        }
Example #6
0
 public void Dispose()
 {
     Vulkan.vkDestroySemaphore(Vulkan.device, this, null);
 }
Example #7
0
 public VkQueue(uint queueFamilyIndex, uint queueIndex)
 {
     Vulkan.vkGetDeviceQueue(Vulkan.device, queueFamilyIndex, queueIndex, out this);
 }
Example #8
0
 public void Dispose()
 {
     Vulkan.vkDestroyBufferView(Vulkan.device, this, null);
 }
Example #9
0
        public VkResult GetStatus()
        {
            VkResult result = Vulkan.vkGetFenceStatus(Vulkan.device, this);

            return(result);
        }
Example #10
0
 public void Dispose()
 {
     Vulkan.vkDestroyImageView(Vulkan.device, this, null);
 }
Example #11
0
 public void Reset()
 {
     Vulkan.vkResetEvent(Vulkan.device, this);
 }
Example #12
0
 public void Dispose()
 {
     Vulkan.vkDestroyEvent(Vulkan.device, this, null);
 }
Example #13
0
 public void GetResults(uint firstQuery, uint queryCount, uint dataSize, IntPtr data, ulong stride, VkQueryResultFlags flags = VkQueryResultFlags.None)
 {
     Vulkan.vkGetQueryPoolResults(Vulkan.device, this, firstQuery, queryCount, (UIntPtr)dataSize, (void *)data, stride, flags);
 }
Example #14
0
        /**
         * Create the swapchain and get it's Images with given width and height
         *
         * @param width Pointer to the width of the swapchain (may be adjusted to fit the requirements of the swapchain)
         * @param height Pointer to the height of the swapchain (may be adjusted to fit the requirements of the swapchain)
         * @param vsync (Optional) Can be used to force vsync'd rendering (by using VK_PRESENT_MODE_FIFO_KHR as presentation mode)
         */
        public unsafe void Create(ref uint width, ref uint height, bool vsync = false)
        {
            VkResult       err;
            VkSwapchainKHR oldSwapchain = swapchain;

            // Get physical Device Surface properties and formats
            VkSurfaceCapabilitiesKHR surfCaps;

            err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Device.PhysicalDevice, Surface, out surfCaps);
            Debug.Assert(err == VkResult.Success);

            // Get available present modes
            uint presentModeCount;

            err = vkGetPhysicalDeviceSurfacePresentModesKHR(Device.PhysicalDevice, Surface, &presentModeCount, null);
            Debug.Assert(err == VkResult.Success);
            Debug.Assert(presentModeCount > 0);

            using (Vector <VkPresentModeKHR> presentModes = new Vector <VkPresentModeKHR>(presentModeCount))
            {
                err = vkGetPhysicalDeviceSurfacePresentModesKHR(Device.PhysicalDevice, Surface, &presentModeCount, (VkPresentModeKHR *)presentModes.Data);
                Debug.Assert(err == VkResult.Success);
                presentModes.Count = presentModeCount;

                // 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))
                {
                    width  = surfCaps.currentExtent.width;
                    height = surfCaps.currentExtent.height;
                }

                extent = new VkExtent3D(width, height, 1);

                // 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.Fifo;

                // 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.Mailbox)
                        {
                            swapchainPresentMode = VkPresentModeKHR.Mailbox;
                            break;
                        }
                        if ((swapchainPresentMode != VkPresentModeKHR.Mailbox) && (presentModes[i] == VkPresentModeKHR.Immediate))
                        {
                            swapchainPresentMode = VkPresentModeKHR.Immediate;
                        }
                    }
                }

                // Determine the number of Images
                uint desiredNumberOfSwapchainImages = IMAGE_COUNT;// surfCaps.minImageCount + 1;
                if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount))
                {
                    Debug.Assert(false);
                    desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
                }

                // Find the transformation of the Surface
                VkSurfaceTransformFlagsKHR preTransform;
                if ((surfCaps.supportedTransforms & VkSurfaceTransformFlagsKHR.Identity) != 0)
                {
                    // We prefer a non-rotated transform
                    preTransform = VkSurfaceTransformFlagsKHR.Identity;
                }
                else
                {
                    preTransform = surfCaps.currentTransform;
                }

                VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR
                {
                    sType                 = VkStructureType.SwapchainCreateInfoKHR,
                    pNext                 = null,
                    surface               = Surface,
                    minImageCount         = desiredNumberOfSwapchainImages,
                    imageFormat           = ColorFormat,
                    imageColorSpace       = ColorSpace,
                    imageExtent           = new VkExtent2D(extent.width, extent.height),
                    imageUsage            = VkImageUsageFlags.ColorAttachment,
                    preTransform          = preTransform,
                    imageArrayLayers      = 1,
                    imageSharingMode      = VkSharingMode.Exclusive,
                    queueFamilyIndexCount = 0,
                    pQueueFamilyIndices   = null,
                    presentMode           = swapchainPresentMode,
                    oldSwapchain          = oldSwapchain,
                    // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area
                    clipped        = true,
                    compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque
                };

                // Set additional usage flag for blitting from the swapchain Images if supported
                Device.GetPhysicalDeviceFormatProperties(ColorFormat, out VkFormatProperties formatProps);

                if ((formatProps.optimalTilingFeatures & VkFormatFeatureFlags.BlitDst) != 0)
                {
                    swapchainCI.imageUsage |= VkImageUsageFlags.TransferSrc;
                }

                swapchain = Device.CreateSwapchainKHR(ref swapchainCI);

                // If an existing swap chain is re-created, destroy the old swap chain
                // This also cleans up all the presentable Images
                if (oldSwapchain.Handle != 0)
                {
                    for (uint i = 0; i < ImageCount; i++)
                    {
                        ImageViews[i].Dispose();
                    }

                    Device.DestroySwapchainKHR(oldSwapchain);
                }

                var vkImages = Vulkan.vkGetSwapchainImagesKHR(Device.Handle, swapchain);
                VkImages.Clear();
                Images     = new Image[vkImages.Length];
                ImageViews = new ImageView[vkImages.Length];
                for (int i = 0; i < vkImages.Length; i++)
                {
                    Images[i] = new Image(vkImages[i])
                    {
                        imageType = VkImageType.Image2D,
                        extent    = extent
                    };
                    ImageViews[i] = ImageView.Create(Images[i], VkImageViewType.Image2D, ColorFormat, VkImageAspectFlags.Color, 0, 1);
                }

                // Get the swap chain Images
                VkImages.Add(vkImages);
            }
        }
Example #15
0
 public void Dispose()
 {
     Vulkan.vkDestroyShaderModule(Vulkan.device, this, null);
 }
 protected override void Destroy(bool disposing)
 {
     Vulkan.vkDestroyDebugReportCallbackEXT(Parent, handle, null);
     _callback = null;
 }
Example #17
0
 public void Dispose()
 {
     Vulkan.vkDestroySampler(Vulkan.device, this, null);
 }
Example #18
0
 public void Dispose()
 {
     Vulkan.vkDestroyFramebuffer(Vulkan.device, this, null);
 }
Example #19
0
 public void Reset()
 {
     Vulkan.vkResetFences(Vulkan.device, this);
 }
Example #20
0
 public void Dispose()
 {
     Vulkan.vkDestroyFence(Vulkan.device, this, null);
 }
Example #21
0
 public void Wait(ulong timeout = ~0ul)
 {
     Vulkan.vkWaitForFences(Vulkan.device, this, false, timeout);
 }
Example #22
0
 public void Dispose()
 {
     Vulkan.vkDestroyPipeline(Vulkan.device, this, null);
 }
Example #23
0
        static VkDevice CreateLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, CStringList enabledExtensions,
                                            bool useSwapChain = true, VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.Compute | VkQueueFlags.Transfer)
        {
            using Vector <VkDeviceQueueCreateInfo> queueCreateInfos = new Vector <VkDeviceQueueCreateInfo>();
            float defaultQueuePriority = 0.0f;

            // Graphics queue
            if ((requestedQueueTypes & VkQueueFlags.Graphics) != 0)
            {
                QFGraphics = GetQueueFamilyIndex(VkQueueFlags.Graphics);
                var queueInfo = new VkDeviceQueueCreateInfo
                {
                    sType            = VkStructureType.DeviceQueueCreateInfo,
                    queueFamilyIndex = QFGraphics,
                    queueCount       = 1,
                    pQueuePriorities = &defaultQueuePriority
                };
                queueCreateInfos.Add(queueInfo);
            }
            else
            {
                QFGraphics = (uint)IntPtr.Zero;
            }

            // Dedicated compute queue
            if ((requestedQueueTypes & VkQueueFlags.Compute) != 0)
            {
                QFCompute = GetQueueFamilyIndex(VkQueueFlags.Compute);
                if (QFCompute != QFGraphics)
                {
                    // If compute family index differs, we need an additional queue create info for the compute queue
                    var queueInfo = new VkDeviceQueueCreateInfo
                    {
                        sType            = VkStructureType.DeviceQueueCreateInfo,
                        queueFamilyIndex = QFCompute,
                        queueCount       = 1,
                        pQueuePriorities = &defaultQueuePriority
                    };
                    queueCreateInfos.Add(queueInfo);
                }
            }
            else
            {
                // Else we use the same queue
                QFCompute = QFGraphics;
            }

            // Dedicated transfer queue
            if ((requestedQueueTypes & VkQueueFlags.Transfer) != 0)
            {
                QFTransfer = GetQueueFamilyIndex(VkQueueFlags.Transfer);
                if (QFTransfer != QFGraphics && QFTransfer != QFCompute)
                {
                    // If compute family index differs, we need an additional queue create info for the transfer queue
                    var queueInfo = new VkDeviceQueueCreateInfo
                    {
                        sType            = VkStructureType.DeviceQueueCreateInfo,
                        queueFamilyIndex = QFTransfer,
                        queueCount       = 1,
                        pQueuePriorities = &defaultQueuePriority
                    };
                    queueCreateInfos.Add(queueInfo);
                }
            }
            else
            {
                // Else we use the same queue
                QFTransfer = QFGraphics;
            }

            // Create the logical device representation
            using CStringList deviceExtensions = new CStringList(enabledExtensions);
            if (useSwapChain)
            {
                // If the device will be used for presenting to a display via a swapchain we need to request the swapchain extension
                deviceExtensions.Add(Vulkan.KHRSwapchainExtensionName);
            }

            var deviceCreateInfo = new VkDeviceCreateInfo
            {
                sType = VkStructureType.DeviceCreateInfo,
                queueCreateInfoCount = queueCreateInfos.Count,
                pQueueCreateInfos    = queueCreateInfos.DataPtr,
                pEnabledFeatures     = &enabledFeatures
            };

            if (deviceExtensions.Count > 0)
            {
                deviceCreateInfo.enabledExtensionCount   = deviceExtensions.Count;
                deviceCreateInfo.ppEnabledExtensionNames = (byte **)deviceExtensions.Data;
            }

            return(Vulkan.CreateDevice(PhysicalDevice, &deviceCreateInfo));
        }
Example #24
0
 public void Dispose()
 {
     Vulkan.vkDestroyQueryPool(Vulkan.device, this, null);
 }
Example #25
0
        public static VkDevice Create(Settings settings, VkPhysicalDeviceFeatures enabledFeatures, CStringList enabledExtensions,
                                      VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.Compute | VkQueueFlags.Transfer)
        {
            instanceExtensions.Add(Vulkan.KHRSurfaceExtensionName);
            instanceExtensions.Add(Vulkan.KHRGetPhysicalDeviceProperties2ExtensionName);

            enabledExtensions.Add(Vulkan.KHRMaintenance1ExtensionName);
            enabledExtensions.Add(Vulkan.EXTInlineUniformBlockExtensionName);

            //enabledExtensions.Add(Strings.VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT);

            CreateInstance(settings);

            // Physical Device
            var physicalDevices = Vulkan.vkEnumeratePhysicalDevices(VkInstance);

            // TODO: Implement arg parsing, etc.
            int selectedDevice = 0;

            PhysicalDevice = physicalDevices[selectedDevice];
            Debug.Assert(PhysicalDevice.Handle != IntPtr.Zero);

            vkGetPhysicalDeviceProperties(PhysicalDevice, out VkPhysicalDeviceProperties properties);
            Properties = properties;

            vkGetPhysicalDeviceFeatures(PhysicalDevice, out VkPhysicalDeviceFeatures features);
            Features = features;

            if (features.tessellationShader)
            {
                enabledFeatures.tessellationShader = true;
            }

            if (features.multiDrawIndirect)
            {
                enabledFeatures.multiDrawIndirect = true;
            }
            // Enable anisotropic filtering if supported
            if (features.samplerAnisotropy)
            {
                enabledFeatures.samplerAnisotropy = true;
            }
            // Enable texture compression
            if (features.textureCompressionBC)
            {
                enabledFeatures.textureCompressionBC = true;
            }
            else if (features.textureCompressionASTC_LDR)
            {
                enabledFeatures.textureCompressionASTC_LDR = true;
            }
            else if (features.textureCompressionETC2)
            {
                enabledFeatures.textureCompressionETC2 = true;
            }

            if (features.sparseBinding && features.sparseResidencyImage2D)
            {
                enabledFeatures.shaderResourceResidency = true;
                enabledFeatures.shaderResourceMinLod    = true;
                enabledFeatures.sparseBinding           = true;
                enabledFeatures.sparseResidencyImage2D  = true;
            }
            else
            {
                Log.Warn("Sparse binding not supported");
            }

            // Memory properties are used regularly for creating all kinds of buffers
            VkPhysicalDeviceMemoryProperties memoryProperties;

            vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, out memoryProperties);
            MemoryProperties = memoryProperties;

            var qf = Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice);

            QueueFamilyProperties.Add(qf);

            var extensions = Vulkan.vkEnumerateDeviceExtensionProperties(PhysicalDevice);

            foreach (var ext in extensions)
            {
                string strExt = UTF8String.FromPointer(ext.extensionName);
                //enabledExtensions.Add((IntPtr)ext.extensionName);
                supportedExtensions.Add(strExt);
            }

            device = CreateLogicalDevice(Features, enabledExtensions, true, requestedQueueTypes);

            if (device != VkDevice.Null)
            {
                VkPipelineCacheCreateInfo pipelineCacheCreateInfo = new VkPipelineCacheCreateInfo()
                {
                    sType = VkStructureType.PipelineCacheCreateInfo
                };

                VulkanUtil.CheckResult(vkCreatePipelineCache(device, &pipelineCacheCreateInfo, null, out pipelineCache));
            }

            return(device);
        }
Example #26
0
 public void Set()
 {
     Vulkan.vkSetEvent(Vulkan.device, this);
 }
Example #27
0
 public void Dispose()
 {
     Vulkan.vkDestroyRenderPass(Vulkan.device, this, null);
 }