Exemplo n.º 1
0
 internal Queue(Device device, uint family, uint index)
 {
     Device           = device;
     Handle           = device.Handle.GetDeviceQueue(family, index);
     FamilyIndex      = family;
     FamilyProperties = Device.PhysicalDevice.Handle.GetQueueFamilyProperties()[(int)family];
 }
Exemplo n.º 2
0
        private void GetQueueFamilyIndices()
        {
            uint queueFamilyCount = 0;

            vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, ref queueFamilyCount, null);
            VkQueueFamilyProperties[] qfp = new VkQueueFamilyProperties[queueFamilyCount];
            vkGetPhysicalDeviceQueueFamilyProperties(_physicalDevice, ref queueFamilyCount, out qfp[0]);

            bool foundGraphics = false;
            bool foundPresent  = false;

            for (uint i = 0; i < qfp.Length; i++)
            {
                if ((qfp[i].queueFlags & VkQueueFlags.Graphics) != 0)
                {
                    _graphicsQueueIndex = i;
                    foundGraphics       = true;
                }

                vkGetPhysicalDeviceSurfaceSupportKHR(_physicalDevice, i, _surface, out VkBool32 presentSupported);
                if (presentSupported)
                {
                    _presentQueueIndex = i;
                    foundPresent       = true;
                }

                if (foundGraphics && foundPresent)
                {
                    break;
                }
            }
        }
Exemplo n.º 3
0
        public SoftwarePhysicalDevice(SoftwareInstance instance)
        {
            m_Instance = instance;

            m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT));
            m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_COMPUTE_BIT));

            m_ExtensionProperties.Add(VkExtensionProperties.Create(VkExtensionNames.VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1));

            m_PhysicalDeviceMemoryProperties = new VkPhysicalDeviceMemoryProperties();
            m_PhysicalDeviceMemoryProperties.memoryTypeCount = 1;
            m_PhysicalDeviceMemoryProperties.memoryTypes     = new VkMemoryType[]
            {
                new VkMemoryType()
                {
                    heapIndex     = 0,
                    propertyFlags = VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
                }
            };
            m_PhysicalDeviceMemoryProperties.memoryHeapCount = 1;
            m_PhysicalDeviceMemoryProperties.memoryHeaps     = new VkMemoryHeap[]
            {
                new VkMemoryHeap()
                {
                    flags = VkMemoryHeapFlagBits.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, size = 64 * 1024 * 1024
                }
            };
        }
Exemplo n.º 4
0
        public DummyPhysicalDevice(SoftwareInstance instance)
        {
            m_Instance = instance;

            m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT));
            m_QueueFamilyProperties.Add(VkQueueFamilyProperties.Create(1, VkQueueFlagBits.VK_QUEUE_COMPUTE_BIT));

            m_ExtensionProperties.Add(VkExtensionProperties.Create(VkExtensionNames.VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1));
        }
Exemplo n.º 5
0
        internal QueueFamily(VkQueueFamilyProperties prop, PhysicalDevice pDevice, uint index)
        {
            this.pDevice = pDevice;
            this.index   = index;

            Flags                       = prop.queueFlags;
            QueueCount                  = prop.queueCount;
            TimestampValidBits          = prop.timestampValidBits;
            MinImageTransferGranularity = prop.minImageTransferGranularity;
        }
Exemplo n.º 6
0
        public static ReadOnlySpan <VkQueueFamilyProperties> vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice)
        {
            uint queueFamilyPropertyCount = 0;

            vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, null);

            ReadOnlySpan <VkQueueFamilyProperties> queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertyCount];

            fixed(VkQueueFamilyProperties *queueFamilyPropertiesPtr = queueFamilyProperties)
            {
                vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertyCount, queueFamilyPropertiesPtr);
            }

            return(queueFamilyProperties);
        }
Exemplo n.º 7
0
        /// <summary>
        /// To query properties of queues available on a physical device, call:
        /// </summary>
        /// <returns>array of <see cref="VkQueueFamilyProperties"/> structures</returns>
        public VkQueueFamilyProperties[] GetQueueFamilyProperties()
        {
            unsafe
            {
                VkQueueFamilyProperties[] props;
                uint count = 0;
                do
                {
                    props = new VkQueueFamilyProperties[count];

                    fixed(VkQueueFamilyProperties *pptr = props)
                    vkGetPhysicalDeviceQueueFamilyProperties(this, &count, pptr);
                } while (props.Length != count);

                return(props);
            }
        }
Exemplo n.º 8
0
        unsafe void init()
        {
            // Gather physical Device memory properties
            IntPtr tmp = Marshal.AllocHGlobal(Marshal.SizeOf <VkPhysicalDeviceMemoryProperties>());

            vkGetPhysicalDeviceMemoryProperties(phy, tmp);
            memoryProperties = Marshal.PtrToStructure <VkPhysicalDeviceMemoryProperties> (tmp);

            uint queueFamilyCount = 0;

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, IntPtr.Zero);
            QueueFamilies = new VkQueueFamilyProperties[queueFamilyCount];

            if (queueFamilyCount <= 0)
            {
                throw new Exception("No queues found for physical device");
            }

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, QueueFamilies.Pin());
            QueueFamilies.Unpin();

            uint propCount = 0;

            vkEnumerateDeviceExtensionProperties(phy, IntPtr.Zero, out propCount, IntPtr.Zero);

            VkExtensionProperties[] extProps = new VkExtensionProperties[propCount];

            vkEnumerateDeviceExtensionProperties(phy, IntPtr.Zero, out propCount, extProps.Pin());
            extProps.Unpin();

            for (int i = 0; i < extProps.Length; i++)
            {
                fixed(VkExtensionProperties *ep = extProps)
                {
                    IntPtr n = (IntPtr)ep[i].extensionName;

                    switch (Marshal.PtrToStringAnsi(n))
                    {
                    case "VK_KHR_swapchain":
                        HasSwapChainSupport = true;
                        break;
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Gets the queue families available on the passed device.
        /// </summary>
        /// <param name="device">The device to get the queue families on.</param>
        public static VkQueueFamilyProperties[] GetQueueFamilies(VkPhysicalDevice device)
        {
            if (!device)
            {
                throw new ArgumentNullException(nameof(device), "Cannot pass null device or device handle");
            }

            uint famCount;

            device.GetPhysicalDeviceQueueFamilyProperties(&famCount, null);
            var fams = new VkQueueFamilyProperties[famCount];

            fixed(VkQueueFamilyProperties *famPtr = fams)
            {
                device.GetPhysicalDeviceQueueFamilyProperties(&famCount, famPtr);
            }

            return(fams);
        }
Exemplo n.º 10
0
        private QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device)
        {
            QueueFamilyIndices indices = new QueueFamilyIndices();

            int queueFamilyCount = 0;

            Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, null);
            VkQueueFamilyProperties[] queueFamilies = new VkQueueFamilyProperties[queueFamilyCount];
            Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, queueFamilies);

            int i = 0;

            foreach (var queueFamily in queueFamilies)
            {
                if (queueFamily.queueCount > 0 && (queueFamily.queueFlags & VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT) > 0)
                {
                    indices.graphicsFamily = i;
                }

                bool presentSupport = false;
                Vulkan.vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, out presentSupport);

                if (queueFamily.queueCount > 0 && presentSupport)
                {
                    indices.presentFamily = i;
                }

                if (indices.isComplete())
                {
                    break;
                }

                i++;
            }

            return(indices);
        }
Exemplo n.º 11
0
        internal PhysicalDevice(IntPtr vkPhy)
        {
            phy = vkPhy;

            // Gather physical Device memory properties
            IntPtr tmp = Marshal.AllocHGlobal(Marshal.SizeOf <VkPhysicalDeviceMemoryProperties> ());

            vkGetPhysicalDeviceMemoryProperties(phy, tmp);
            memoryProperties = Marshal.PtrToStructure <VkPhysicalDeviceMemoryProperties> (tmp);
            Marshal.FreeHGlobal(tmp);

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out uint queueFamilyCount, IntPtr.Zero);
            QueueFamilies = new VkQueueFamilyProperties [queueFamilyCount];

            if (queueFamilyCount <= 0)
            {
                throw new Exception("No queues found for physical device");
            }

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, QueueFamilies.Pin());
            QueueFamilies.Unpin();

            HasSwapChainSupport = GetDeviceExtensionSupported(Ext.D.VK_KHR_swapchain);
        }
Exemplo n.º 12
0
        static VkPhysicalDevice PickPhysicalDevice(VkInstance instance, VkSurfaceKHR surface, out uint queueFamilyIndex)
        {
            queueFamilyIndex = 0;
            uint deviceCount = 0;

            vkEnumeratePhysicalDevices(instance, &deviceCount, null);
            Console.WriteLine($"There are {deviceCount} devices available.");
            VkPhysicalDevice[] devices = new VkPhysicalDevice[deviceCount];
            if (deviceCount <= 0)
                return(VkPhysicalDevice.Null);

            fixed(VkPhysicalDevice *ptr = &devices[0])
            vkEnumeratePhysicalDevices(instance, &deviceCount, ptr);

            VkPhysicalDeviceProperties props = new VkPhysicalDeviceProperties();


            for (int i = 0; i < deviceCount; i++)
            {
                bool badGpu           = true;
                bool onlyPickDiscrete = true;

                vkGetPhysicalDeviceProperties(devices[i], &props);

                uint familyQueueCount = 0;
                vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &familyQueueCount, null);
                VkQueueFamilyProperties[] famProps = new VkQueueFamilyProperties[familyQueueCount];

                fixed(VkQueueFamilyProperties *ptr = famProps)
                vkGetPhysicalDeviceQueueFamilyProperties(devices[i], &familyQueueCount, ptr);

                VkPhysicalDeviceFeatures deviceFeatures;
                vkGetPhysicalDeviceFeatures(devices[i], &deviceFeatures);
                if (deviceFeatures.samplerAnisotropy == VkBool32.False)
                {
                    continue;
                }

                for (uint k = 0; k < familyQueueCount; k++)
                {
                    if ((int)(famProps[k].queueFlags & VkQueueFlags.Graphics) <= 0)
                    {
                        continue;
                    }
                    VkBool32 supported = VkBool32.False;
                    Assert(vkGetPhysicalDeviceSurfaceSupportKHR(devices[i], k, surface, &supported));
                    if (supported == VkBool32.False)
                    {
                        continue;
                    }

                    /*fixed (VkPhysicalDevice* ptr = &(devices[i]))
                     *  if (!GLFW.Vulkan.GetPhysicalDevicePresentationSupport((IntPtr)(&instance), (IntPtr)ptr, k))//Throws exception
                     *  {
                     *      continue;
                     *  }*/
                    if (onlyPickDiscrete && !(props.deviceType == VkPhysicalDeviceType.DiscreteGpu))
                    {
                        continue;
                    }

                    queueFamilyIndex = k;
                    badGpu           = false;
                }



                //Here we pick if its acceptable
                if (badGpu)
                {
                    continue;
                }


                Console.WriteLine($"Picking GPU: {Marshal.PtrToStringUTF8((IntPtr)props.deviceName)}");
                return(devices[i]);
            }

            throw new System.Exception("There was no GPU that filled our needs.");
        }
Exemplo n.º 13
0
        public unsafe void InitSurface(IntPtr sdlWindow)
        {
            VkResult err;
            // Create the os-specific Surface
            VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR();

            surfaceCreateInfo.sType = Win32SurfaceCreateInfoKHR;
            var processHandle = Process.GetCurrentProcess().Handle;//.SafeHandle.DangerousGetHandle();

            surfaceCreateInfo.hinstance = processHandle;
            surfaceCreateInfo.hwnd      = sdlWindow;
            VkSurfaceKHR surface;

            err     = vkCreateWin32SurfaceKHR(Instance, &surfaceCreateInfo, null, &surface);
            Surface = surface;

            // Get available queue family properties
            uint queueCount;

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null);
            Debug.Assert(queueCount >= 1);

            var queueProps = new VkQueueFamilyProperties[queueCount];

            fixed(VkQueueFamilyProperties *pointer = queueProps)
            {
                vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, pointer);
            }

            // 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 & VkQueueFlagBits.Graphics) != 0)
                {
                    if (graphicsQueueNodeIndex == uint.MaxValue)
                    {
                        graphicsQueueNodeIndex = i;
                    }

                    if (supportsPresent[i] == true)
                    {
                        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] == true)
                    {
                        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!");
            }

            QueueNodeIndex = graphicsQueueNodeIndex;

            // Get list of supported Surface formats
            uint formatCount;

            err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null);
            Debug.Assert(err == VkResult.Success);
            Debug.Assert(formatCount > 0);

            var surfaceFormats = new VkSurfaceFormatKHR[formatCount];

            fixed(VkSurfaceFormatKHR *pointer = surfaceFormats)
            {
                err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, pointer);
                Debug.Assert(err == VkResult.Success);
            }

            // 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))
            {
                ColorFormat = 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;
                foreach (var surfaceFormat in surfaceFormats)
                {
                    if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm)
                    {
                        ColorFormat          = 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)
                {
                    ColorFormat = surfaceFormats[0].format;
                    ColorSpace  = surfaceFormats[0].colorSpace;
                }
            }
        }
Exemplo n.º 14
0
        static void Main(string[] args)
        {
            VkInstance inst;

            using (VkApplicationInfo ai = new VkApplicationInfo()) {
                using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo {
                    pApplicationInfo = ai
                }){
                    CheckResult(vkCreateInstance(ci, IntPtr.Zero, out inst));
                }
            }

            Vk.LoadInstanceFunctionPointers(inst);

            if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.DiscreteGpu, out VkPhysicalDevice phy))
            {
                if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.IntegratedGpu, out phy))
                {
                    if (!TryGetPhysicalDevice(inst, VkPhysicalDeviceType.Cpu, out phy))
                    {
                        throw new Exception("no suitable physical device found");
                    }
                }
            }

            foreach (VkPhysicalDeviceToolPropertiesEXT toolProp in GetToolProperties(phy))
            {
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine($"Enabled Tool: {toolProp.name}({toolProp.version})");
                Console.ResetColor();
            }

            vkGetPhysicalDeviceQueueFamilyProperties(phy, out uint queueFamilyCount, IntPtr.Zero);
            VkQueueFamilyProperties[] qFamProps = new VkQueueFamilyProperties[queueFamilyCount];
            vkGetPhysicalDeviceQueueFamilyProperties(phy, out queueFamilyCount, qFamProps.Pin());
            qFamProps.Unpin();
            Console.WriteLine($"Queues:");
            for (int i = 0; i < queueFamilyCount; i++)
            {
                Console.WriteLine($"\t{i}: {qFamProps[i].queueFlags,-60} ({qFamProps[i].queueCount})");
            }

            uint qFamIndex = (uint)qFamProps.Select((qFam, index) => (qFam, index))
                             .First(qfp => qfp.qFam.queueFlags.HasFlag(VkQueueFlags.Graphics)).index;

            VkDevice dev = default;

            float[] priorities = { 0 };
            using (VkDeviceQueueCreateInfo qInfo = new VkDeviceQueueCreateInfo(qFamIndex, 1, priorities)) {
                using (VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo()
                {
                    pQueueCreateInfos = qInfo
                }) {
                    CheckResult(vkCreateDevice(phy, deviceCreateInfo, IntPtr.Zero, out dev));
                }
            }
            vkGetDeviceQueue(dev, qFamIndex, 0, out VkQueue gQ);

            vkDestroyDevice(dev, IntPtr.Zero);

            vkDestroyInstance(inst, IntPtr.Zero);
        }