Пример #1
0
        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" },
                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();

            fence = device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Пример #2
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;
        }
Пример #3
0
        public static DeviceCreateInfo CreateDeviceCreateInfo(PhysicalDevice physicalDevice, bool createDefaultQueue, IEnumerable <InitRequest> initRequest = null)
        {
            string[] layers;
            string[] extentions;
            if (initRequest != null)
            {
                layers     = GetDeviceExtention(physicalDevice, initRequest);
                extentions = GetDeviceExtention(physicalDevice, initRequest);
            }
            else
            {
                layers     = new string[0];
                extentions = new string[0];
            }

            List <DeviceQueueCreateInfo> queus = new List <DeviceQueueCreateInfo>();

            if (createDefaultQueue)
            {
                uint selectedQueue;
                // TODO : this needs to be a single step in order to correctly partition
                // TODO : on default we should look for a present queue
                if (VulkanInitUtility.TrySelectQueue(physicalDevice, QueueFlags.Compute | QueueFlags.Graphics | QueueFlags.Transfer, true, out selectedQueue))
                {
                    queus.Add(new DeviceQueueCreateInfo
                    {
                        QueueCount       = 1,
                        QueueFamilyIndex = selectedQueue,
                        QueuePriorities  = new float[] { 1.0f },
                    });
                }
                ;
            }

            DeviceCreateInfo deviceCreateInfo = new DeviceCreateInfo
            {
                EnabledLayerNames     = layers,
                EnabledExtensionNames = extentions,
                QueueCreateInfos      = queus.ToArray(),
            };

            return(deviceCreateInfo);
        }
Пример #4
0
    public unsafe void TestWithoutChain()
    {
        // We don't have to use the BaseInStructure() pattern, as we can start with an existing struct
        var createInfo = new DeviceCreateInfo
        {
            Flags = 1U
        };

        // However, note that AddNext will still coerce the SType of createInfo.
        createInfo.AddNext(out PhysicalDeviceFeatures2 features2);
        Assert.Equal((nint)(&features2), (nint)createInfo.PNext);
        Assert.Equal(0, (nint)features2.PNext);

        // Note, even though we didn't use chain, we have still coerced the SType
        Assert.Equal(StructureType.DeviceCreateInfo, createInfo.SType);
        Assert.Equal(StructureType.PhysicalDeviceFeatures2, features2.SType);

        Assert.Equal(1U, createInfo.Flags);
    }
Пример #5
0
        public void PropertiesSet()
        {
            QueueFamilyProperties[] props = PhysicalDevice.GetQueueFamilyProperties();
            int queueFamilyIndex          = props.Length - 1;
            int queueCount       = props[props.Length - 1].QueueCount;
            int queueIndex       = queueCount - 1;
            var deviceCreateInfo = new DeviceCreateInfo(new[]
            {
                new DeviceQueueCreateInfo(queueFamilyIndex, queueCount, Enumerable.Range(0, queueCount).Select(_ => 1.0f).ToArray())
            });

            using (Device device = PhysicalDevice.CreateDevice(deviceCreateInfo))
            {
                Queue queue = device.GetQueue(queueFamilyIndex, queueIndex);

                Assert.Equal(device, queue.Parent);
                Assert.Equal(queueFamilyIndex, queue.FamilyIndex);
                Assert.Equal(queueIndex, queue.Index);
            }
        }
Пример #6
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;
        }
Пример #7
0
        private static Device CreateAbstractDevice(PhysicalDevice physicalDevice)
        {
            var deviceQueueInfo = new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new[] { 1f }
            };

            var deviceInfo = new DeviceCreateInfo
            {
                Flags                 = 0,
                EnabledLayerCount     = 0,
                EnabledLayerNames     = null,
                EnabledExtensionCount = 0,
                EnabledExtensionNames = null,
                QueueCreateInfoCount  = 1,
                QueueCreateInfos      = new[] { deviceQueueInfo }
            };

            return(physicalDevice.CreateDevice(deviceInfo));
        }
Пример #8
0
        protected Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var enabledExtensions = new[]
            {
                VulkanConstant.KhrSwapchainExtensionName,
            };

            var features = new PhysicalDeviceFeatures();

            features.ShaderClipDistance = true;
            features.ShaderCullDistance = true;

            var queueCreateInfo  = new DeviceQueueCreateInfo(queueFamily, new[] { 0f });
            var deviceCreateInfo = new DeviceCreateInfo(new[] { queueCreateInfo }, enabledLayers, enabledExtensions);

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
Пример #9
0
        protected virtual void CreateDevice()
        {
            uint queuePriorities = 0;
            var queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount = 1,
                QueuePriorities = new IntPtr(&queuePriorities)
            };

            var enabledLayerNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
            };

            try
            {
                fixed (void* enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed (void* enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var enabledFeatures = new PhysicalDeviceFeatures
                    {
                        ShaderClipDistance = true,
                    };

                    var deviceCreateInfo = new DeviceCreateInfo
                    {
                        StructureType = StructureType.DeviceCreateInfo,
                        QueueCreateInfoCount = 1,
                        QueueCreateInfos = new IntPtr(&queueCreateInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                        EnabledFeatures = new IntPtr(&enabledFeatures)
                    };

                    if (validate)
                    {
                        deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    device = physicalDevice.CreateDevice(ref deviceCreateInfo);
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                    Marshal.FreeHGlobal(enabledExtensionName);

                foreach (var enabledLayerName in enabledLayerNames)
                    Marshal.FreeHGlobal(enabledLayerName);
            }

            var queueNodeIndex = physicalDevice.QueueFamilyProperties.
                Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
                Select((properties, index) => index).First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
        }
Пример #10
0
        protected virtual void CreateDevice()
        {
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledLayerNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
            };

            try
            {
                fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var enabledFeatures = new PhysicalDeviceFeatures
                    {
                        ShaderClipDistance = true,
                    };

                    var deviceCreateInfo = new DeviceCreateInfo
                    {
                        StructureType         = StructureType.DeviceCreateInfo,
                        QueueCreateInfoCount  = 1,
                        QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                        EnabledFeatures       = new IntPtr(&enabledFeatures)
                    };

                    if (validate)
                    {
                        deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    device = physicalDevice.CreateDevice(ref deviceCreateInfo);
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

                foreach (var enabledLayerName in enabledLayerNames)
                {
                    Marshal.FreeHGlobal(enabledLayerName);
                }
            }

            var queueNodeIndex = physicalDevice.QueueFamilyProperties.
                                 Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
                                 Select((properties, index) => index).First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
        }
Пример #11
0
        public virtual void Initialize(InstanceCreateData data)
        {
            this.data = data;
            var graphicsQueue = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new float[] { 1.0f },
                QueueFamilyIndex = (uint)data.queueFamilyIndices.GraphicsFamily
            };
            var presentQueue = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new float[] { 1.0f },
                QueueFamilyIndex = (uint)data.queueFamilyIndices.PresentFamily
            };
            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = data.enabledDeviceExtensions,
                EnabledExtensionCount = (uint)data.enabledDeviceExtensions.Length,
                EnabledLayerNames     = data.enabledLayers,
                EnabledLayerCount     = (data.enabledLayers == null ? 0 : (uint)data.enabledLayers.Length),
                QueueCreateInfos      = new DeviceQueueCreateInfo[] { graphicsQueue, presentQueue },
                EnabledFeatures       = new PhysicalDeviceFeatures
                {
                    SamplerAnisotropy = true
                }
            };

            device             = data.physicalDevice.CreateDevice(deviceInfo);
            this.graphicsQueue = device.GetQueue((uint)data.queueFamilyIndices.GraphicsFamily, 0);
            this.presentQueue  = device.GetQueue((uint)data.queueFamilyIndices.PresentFamily, 0);

            CreateSwapChain();
            CreateImageViews();
            CreateRenderPass();
            CreateDescriptorSetLayout();
            CreateGraphicsPipeline();
            CreateFrameBuffers();
            CreateCommandPool();
            CreateBuffers();
            CreateDescriptorPool();
            CreateDescriptorSets();
            CreateCommandBuffers();
            CreateSyncObjects();

            submitInfo = new SubmitInfo
            {
                WaitSemaphoreCount   = 1,
                WaitDstStageMask     = waitStages,
                CommandBufferCount   = 1,
                SignalSemaphoreCount = 1,
            };
            presentInfo = new PresentInfoKhr
            {
                WaitSemaphoreCount = 1,
                SwapchainCount     = 1,
            };

            initialized = running = true;
            _lastFrame  = DateTime.Now;
            Start();

            //data.control.ParentForm.ResizeBegin += ResizeBegin;
            //data.control.ParentForm.ResizeEnd += ResizeEnd;
        }
Пример #12
0
 internal static unsafe extern Result vkCreateDevice(PhysicalDevice physicalDevice, DeviceCreateInfo* createInfo, AllocationCallbacks* allocator, Device* device);
Пример #13
0
        /// <summary>
        ///     Initializes the specified device.
        /// </summary>
        /// <param name="graphicsProfiles">The graphics profiles.</param>
        /// <param name="deviceCreationFlags">The device creation flags.</param>
        /// <param name="windowHandle">The window handle.</param>
        private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle)
        {
            if (nativeDevice != Device.Null)
            {
                // Destroy previous device
                ReleaseDevice();
            }

            rendererName = Adapter.Description;

            PhysicalDeviceProperties physicalDeviceProperties;

            NativePhysicalDevice.GetProperties(out physicalDeviceProperties);
            ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment;

            RequestedProfile = graphicsProfiles.Last();

            var queueProperties = NativePhysicalDevice.QueueFamilyProperties;

            // Command lists are thread-safe and execute deferred
            IsDeferred = true;

            // TODO VULKAN
            // Create Vulkan device based on profile
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledFeature = new PhysicalDeviceFeatures
            {
                FillModeNonSolid   = true,
                ShaderClipDistance = true,
                ShaderCullDistance = true,
                SamplerAnisotropy  = true,
                DepthClamp         = true,
            };

            var extensionProperties     = NativePhysicalDevice.GetDeviceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName));
                var name        = Marshal.PtrToStringAnsi(namePointer);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add("VK_KHR_swapchain");
            if (!availableExtensionNames.Contains("VK_KHR_swapchain"))
            {
                throw new InvalidOperationException();
            }

            if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode)
            {
                desiredExtensionNames.Add("VK_EXT_debug_marker");
                IsProfilingSupported = true;
            }

            var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray();

            try
            {
                var deviceCreateInfo = new DeviceCreateInfo
                {
                    StructureType         = StructureType.DeviceCreateInfo,
                    QueueCreateInfoCount  = 1,
                    QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                    EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                    EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero,
                    EnabledFeatures       = new IntPtr(&enabledFeature)
                };

                nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo);
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }
            }

            NativeCommandQueue = nativeDevice.GetQueue(0, 0);

            //// Prepare copy command list (start it closed, so that every new use start with a Reset)
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                StructureType    = StructureType.CommandPoolCreateInfo,
                QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex
                Flags            = CommandPoolCreateFlags.ResetCommandBuffer
            };

            NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo);

            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                Level              = CommandBufferLevel.Primary,
                CommandPool        = NativeCopyCommandPool,
                CommandBufferCount = 1
            };
            CommandBuffer nativeCommandBuffer;

            NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer);
            NativeCopyCommandBuffer = nativeCommandBuffer;

            DescriptorPools = new HeapPool(this);

            nativeResourceCollector       = new NativeResourceCollector(this);
            graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this);

            EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float);
        }
Пример #14
0
        void CreateDevice()
        {
            PhysicalDevice[] physical_devices = DelegateUtility.EnumerateToArray <PhysicalDevice> (vk.EnumeratePhysicalDevices, (IntPtr)vulkan.Instance);

            if (physical_devices == null)
            {
                //std::cout << "Error occurred during physical devices enumeration!" << std::endl;
                return;
            }

            uint selected_graphics_queue_family_index = uint.MaxValue;
            uint selected_present_queue_family_index  = uint.MaxValue;

            for (int i = 0; i < physical_devices.Length; ++i)
            {
                if (CheckPhysicalDeviceProperties(physical_devices[i],
                                                  out selected_graphics_queue_family_index, out selected_present_queue_family_index))
                {
                    vulkan.PhysicalDevice = physical_devices[i];
                }
            }

            if (vulkan.PhysicalDevice.IsZero ||
                selected_graphics_queue_family_index == uint.MaxValue ||
                selected_present_queue_family_index == uint.MaxValue)
            {
                //std::cout << "Could not select physical device based on the chosen properties!" << std::endl;
                return;
            }

            var    queue_create_infos = stackalloc DeviceQueueCreateInfo[2];
            uint   count            = 1;
            float *queue_priorities = stackalloc float[1];

            queue_priorities[0] = 1.0f;

            queue_create_infos[0] = new DeviceQueueCreateInfo
            {
                sType            = StructureType.DeviceQueueCreateInfo,                  // VkStructureType              sType
                pNext            = IntPtr.Zero,                                          // const void                  *pNext
                flags            = 0,                                                    // VkDeviceQueueCreateFlagBits     flags
                queueFamilyIndex = selected_graphics_queue_family_index,                 // uint32_t                     queueFamilyIndex
                queueCount       = 1,                                                    // uint32_t                     queueCount
                pQueuePriorities = queue_priorities                                      // const float                 *pQueuePriorities
            };

            if (selected_graphics_queue_family_index != selected_present_queue_family_index)
            {
                queue_create_infos[1] = new DeviceQueueCreateInfo
                {
                    sType            = StructureType.DeviceQueueCreateInfo,                     // VkStructureType              sType
                    pNext            = IntPtr.Zero,                                             // const void                  *pNext
                    flags            = 0,                                                       // VkDeviceQueueCreateFlagBits     flags
                    queueFamilyIndex = selected_present_queue_family_index,                     // uint32_t                     queueFamilyIndex
                    queueCount       = 1,                                                       // uint32_t                     queueCount
                    pQueuePriorities = queue_priorities                                         // const float                 *pQueuePriorities
                };
                count++;
            }

            const uint exCount = 1;
            var        exPtr   = MarshalUtility.AllocateString(new string[] { KhrSwapchain.EXTENSION_NAME });

            DeviceCreateInfo device_create_info = new DeviceCreateInfo
            {
                sType = StructureType.DeviceCreateInfo,                        // VkStructureType                    sType
                pNext = IntPtr.Zero,                                           // const void                        *pNext
                flags = 0,                                                     // VkDeviceCreateFlagBits                flags
                queueCreateInfoCount    = count,                               // uint32_t                           queueCreateInfoCount
                pQueueCreateInfos       = queue_create_infos,                  // const VkDeviceQueueCreateInfo     *pQueueCreateInfos
                enabledLayerCount       = 0,                                   // uint32_t                           enabledLayerCount
                ppEnabledLayerNames     = (byte *)0,                           // const char * const                *ppEnabledLayerNames
                enabledExtensionCount   = exCount,                             // uint32_t                           enabledExtensionCount
                ppEnabledExtensionNames = (byte *)exPtr,                       // const char * const                *ppEnabledExtensionNames
                pEnabledFeatures        = (PhysicalDeviceFeatures *)0          // const VkPhysicalDeviceFeatures    *pEnabledFeatures
            };

            vk.CreateDevice(vulkan.PhysicalDevice, ref device_create_info, (AllocationCallbacks *)0, out vulkan.Device).CheckError();

            MarshalUtility.FreeString(exPtr, (int)exCount);
        }
Пример #15
0
        static public MPointArray ComputeData(MPointArray inPos, float angle, float envolope)
        {
            var memorySize = inPos.Count * 4 * sizeof(float);

            float[] ubo = { inPos.Count, angle, envolope };

            // pos to float[]
            float[] allPos = new float[inPos.Count * 4];
            var     i      = 0;

            foreach (var point in inPos)
            {
                allPos[i * 4 + 0] = (float)point.x;
                allPos[i * 4 + 1] = (float)point.y;
                allPos[i * 4 + 2] = (float)point.z;
                allPos[i * 4 + 3] = (float)point.w;
                i++;
            }

            var instance = new Instance(new InstanceCreateInfo {
                ApplicationInfo = new ApplicationInfo {
                    ApplicationName    = "CSharp Vulkan",
                    ApplicationVersion = Vulkan.Version.Make(1, 0, 0),
                    ApiVersion         = Vulkan.Version.Make(1, 0, 0),
                    EngineName         = "CSharp Engine",
                    EngineVersion      = Vulkan.Version.Make(1, 0, 0)
                },
                //EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames     = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            });

            var debugCallback = new Instance.DebugReportCallback(DebugReportCallback);

            instance.EnableDebug(debugCallback, DebugReportFlagsExt.Warning | DebugReportFlagsExt.Error);

            PhysicalDevice physicalDevice = instance.EnumeratePhysicalDevices()[0];

            var queueFamilyIndex = FindBestComputeQueue(physicalDevice);

            DeviceQueueCreateInfo[] deviceQueueCreateInfo =
            {
                new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = queueFamilyIndex,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f }
                }
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfos      = deviceQueueCreateInfo,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
                EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                //EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            };

            var device = physicalDevice.CreateDevice(deviceCreateInfo);

            //var memProperties = physicalDevice.GetMemoryProperties();

            var bufferCreateInfo = new BufferCreateInfo
            {
                Size               = memorySize,
                Usage              = BufferUsageFlags.StorageBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var inBuffer  = device.CreateBuffer(bufferCreateInfo);
            var outBuffer = device.CreateBuffer(bufferCreateInfo);

            var memRequirements = device.GetBufferMemoryRequirements(inBuffer);

            uint memIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);

            var memoryAllocatInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = memIndex
            };

            var memory = device.AllocateMemory(memoryAllocatInfo);

            var dataPtr = device.MapMemory(memory, 0, memorySize);

            Marshal.Copy(allPos, 0, dataPtr, allPos.Length);

            device.UnmapMemory(memory);

            memRequirements = device.GetBufferMemoryRequirements(outBuffer);
            memoryAllocatInfo.MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);
            var outMemory = device.AllocateMemory(memoryAllocatInfo);

            device.BindBufferMemory(inBuffer, memory, 0);
            device.BindBufferMemory(outBuffer, outMemory, 0);

            //var uboSize = Marshal.SizeOf(ubo);
            var uboSize             = 3 * sizeof(float);
            var uboBufferCreateInfo = new BufferCreateInfo
            {
                Size               = uboSize,
                Usage              = BufferUsageFlags.UniformBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var uboBuffer = device.CreateBuffer(uboBufferCreateInfo);

            memRequirements = device.GetBufferMemoryRequirements(uboBuffer);

            var uboMemoryAllocInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent)
            };

            var uboMemory = device.AllocateMemory(uboMemoryAllocInfo);
            var uboPtr    = device.MapMemory(uboMemory, 0, uboSize);

            Marshal.Copy(ubo, 0, uboPtr, ubo.Length);
            device.UnmapMemory(uboMemory);

            device.BindBufferMemory(uboBuffer, uboMemory, 0);

            //string textureName = string.Format("{0}.comp.spv", typeof(VulankCompute).Namespace);
            //Stream stream = typeof(VulankCompute).GetTypeInfo().Assembly.GetManifestResourceStream(textureName);
            string shaderFile = @"E:\coding\CShape\yTwistCSharpVulkan\comp.spv";
            Stream stream     = File.Open(shaderFile, FileMode.Open);

            byte[] shaderCode = new byte[stream.Length];
            stream.Read(shaderCode, 0, (int)stream.Length);
            stream.Close();
            stream.Dispose();
            var shaderModule = device.CreateShaderModule(shaderCode);

            DescriptorSetLayoutBinding[] descriptorSetLayoutBindings =
            {
                new DescriptorSetLayoutBinding
                {
                    Binding         = 0,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 2,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                }
            };

            var descriporSetLayoutCreateinfo = new DescriptorSetLayoutCreateInfo
            {
                Bindings = descriptorSetLayoutBindings
            };

            var descriptorSetLayout = device.CreateDescriptorSetLayout(descriporSetLayoutCreateinfo);

            var descriptorPool = device.CreateDescriptorPool(new DescriptorPoolCreateInfo
            {
                MaxSets   = 1,
                PoolSizes = new DescriptorPoolSize[]
                {
                    new DescriptorPoolSize
                    {
                        DescriptorCount = 3
                    }
                }
            });

            var descriptorSet = device.AllocateDescriptorSets(new DescriptorSetAllocateInfo
            {
                DescriptorPool = descriptorPool,
                SetLayouts     = new DescriptorSetLayout[] { descriptorSetLayout }
            })[0];

            var inBufferInfo = new DescriptorBufferInfo
            {
                Buffer = inBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var outBufferInfo = new DescriptorBufferInfo
            {
                Buffer = outBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var uboBufferInfo = new DescriptorBufferInfo
            {
                Buffer = uboBuffer,
                Offset = 0,
                Range  = uboSize
            };

            WriteDescriptorSet[] writeDescriptorSets =
            {
                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 0,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { inBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 1,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { outBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 2,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { uboBufferInfo }
                }
            };

            device.UpdateDescriptorSets(writeDescriptorSets, null);

            var pipelineLayout = device.CreatePipelineLayout(new PipelineLayoutCreateInfo
            {
                SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout }
            });

            var shaderStage = new PipelineShaderStageCreateInfo
            {
                Stage  = ShaderStageFlags.Compute,
                Module = shaderModule,
                Name   = "main"
            };

            var pipeline = device.CreateComputePipelines(null, new ComputePipelineCreateInfo[]
            {
                new ComputePipelineCreateInfo
                {
                    Stage  = shaderStage,
                    Layout = pipelineLayout
                }
            })[0];

            var commandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                QueueFamilyIndex = queueFamilyIndex
            });

            var cmdBuffer = device.AllocateCommandBuffers(new CommandBufferAllocateInfo
            {
                CommandPool        = commandPool,
                CommandBufferCount = 1,
                Level = CommandBufferLevel.Primary
            })[0];

            cmdBuffer.Begin(new CommandBufferBeginInfo
            {
                Flags = CommandBufferUsageFlags.OneTimeSubmit
            });

            cmdBuffer.CmdBindPipeline(PipelineBindPoint.Compute, pipeline);

            cmdBuffer.CmdBindDescriptorSet(PipelineBindPoint.Compute, pipelineLayout, 0, descriptorSet, null);

            cmdBuffer.CmdDispatch((uint)inPos.Count, 1, 1);

            cmdBuffer.End();

            var queue = device.GetQueue(queueFamilyIndex, 0);

            //var fence = device.CreateFence(new FenceCreateInfo { Flags=0 });
            queue.Submit(new SubmitInfo
            {
                WaitSemaphoreCount = 0,
                CommandBuffers     = new CommandBuffer[] { cmdBuffer },
            });
            queue.WaitIdle();
            //device.WaitForFence(fence, true, UInt64.MaxValue);

            var newDataPtr = device.MapMemory(outMemory, 0, memorySize);

            Marshal.Copy(newDataPtr, allPos, 0, allPos.Length);
            device.UnmapMemory(outMemory);

            var j = 0;

            foreach (var p in inPos)
            {
                p.x = allPos[j * 4 + 0];
                p.y = allPos[j * 4 + 1];
                p.z = allPos[j * 4 + 2];
                p.w = allPos[j * 4 + 3];
                j++;
            }

            //device.DestroyFence(fence);
            device.DestroyShaderModule(shaderModule);
            device.DestroyCommandPool(commandPool);
            device.DestroyDescriptorSetLayout(descriptorSetLayout);
            device.DestroyDescriptorPool(descriptorPool);
            device.DestroyPipelineLayout(pipelineLayout);
            device.DestroyPipeline(pipeline);
            device.DestroyBuffer(inBuffer);
            device.DestroyBuffer(outBuffer);
            device.DestroyBuffer(uboBuffer);
            device.FreeMemory(memory);
            device.FreeMemory(outMemory);
            device.FreeMemory(uboMemory);
            device.Destroy();

            //instance.Destroy();

            return(inPos);
        }
Пример #16
0
        public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount)
        {
            if (queueCount > QueuesCount)
            {
                queueCount = QueuesCount;
            }

            float *queuePriorities = stackalloc float[(int)queueCount];

            for (int i = 0; i < queueCount; i++)
            {
                queuePriorities[i] = 1f;
            }

            var queueCreateInfo = new DeviceQueueCreateInfo()
            {
                SType            = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = queueFamilyIndex,
                QueueCount       = queueCount,
                PQueuePriorities = queuePriorities
            };

            var features = new PhysicalDeviceFeatures()
            {
                DepthBiasClamp           = true,
                DepthClamp               = true,
                DualSrcBlend             = true,
                FragmentStoresAndAtomics = true,
                GeometryShader           = true,
                ImageCubeArray           = true,
                IndependentBlend         = true,
                LogicOp                   = true,
                MultiViewport             = true,
                PipelineStatisticsQuery   = true,
                SamplerAnisotropy         = true,
                ShaderClipDistance        = true,
                ShaderImageGatherExtended = true,
                // ShaderStorageImageReadWithoutFormat = true,
                // ShaderStorageImageWriteWithoutFormat = true,
                VertexPipelineStoresAndAtomics = true
            };

            var featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
                IndexTypeUint8 = supportedExtensions.Contains("VK_EXT_index_type_uint8")
            };

            var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
            {
                SType             = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
                PNext             = &featuresIndexU8,
                TransformFeedback = true
            };

            var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceRobustness2FeaturesExt,
                PNext          = &featuresTransformFeedback,
                NullDescriptor = true
            };

            var featuresVk12 = new PhysicalDeviceVulkan12Features()
            {
                SType             = StructureType.PhysicalDeviceVulkan12Features,
                PNext             = &featuresRobustness2,
                DrawIndirectCount = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName)
            };

            var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray();

            IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
            }

            var deviceCreateInfo = new DeviceCreateInfo()
            {
                SType = StructureType.DeviceCreateInfo,
                PNext = &featuresVk12,
                QueueCreateInfoCount    = 1,
                PQueueCreateInfos       = &queueCreateInfo,
                PpEnabledExtensionNames = (byte **)ppEnabledExtensions,
                EnabledExtensionCount   = (uint)enabledExtensions.Length,
                PEnabledFeatures        = &features
            };

            api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                Marshal.FreeHGlobal(ppEnabledExtensions[i]);
            }

            return(device);
        }
Пример #17
0
        AppDev AppDevInit(AppGpu gpu)
        {
            DeviceCreateInfo info = new DeviceCreateInfo
            {
                QueueCreateInfoCount = 0, // TODO : this sould not be
                QueueCreateInfos     = new DeviceQueueCreateInfo[0],
                EnabledLayerCount    = 0,
                EnabledLayerNames    = new string[0],
            };

            // Scan layers
            List <LayerExtensionList> layers = new List <LayerExtensionList>();

            LayerProperties[] layerProperties = gpu.Obj.EnumerateDeviceLayerProperties();
            if (layerProperties != null)
            {
                foreach (LayerProperties layer in layerProperties)
                {
                    LayerExtensionList layerExtList = new LayerExtensionList
                    {
                        LayerProperties     = layer,
                        ExtensionProperties = gpu.Obj.EnumerateDeviceExtensionProperties(layer.LayerName),
                    };
                    if (layerExtList.ExtensionProperties == null)
                    {
                        layerExtList.ExtensionProperties = new ExtensionProperties[0];
                    }
                    layers.Add(layerExtList);
                }
            }

            ExtensionProperties[] extensions = gpu.Obj.EnumerateDeviceExtensionProperties("");

            foreach (string knownExtName in KnownDeviceExtensions)
            {
                bool extensionFound = false;
                foreach (ExtensionProperties extention in extensions)
                {
                    if (extention.ExtensionName == knownExtName)
                    {
                        extensionFound = true;
                        break;
                    }
                }

                if (!extensionFound)
                {
                    throw new Exception("Cannot find extension: " + knownExtName);
                }
            }

            gpu.DeviceLayers     = layers.ToArray();
            gpu.DeviceExtensions = extensions;

            info.QueueCreateInfoCount = (uint)gpu.QueueReqs.Length;
            info.QueueCreateInfos     = gpu.QueueReqs;

            info.EnabledExtensionNames = KnownDeviceExtensions;
            info.EnabledExtensionCount = (uint)KnownDeviceExtensions.Length;

            Device device = gpu.Obj.CreateDevice(info, null);

            return(new AppDev
            {
                Gpu = gpu,
                Obj = device,
            });
        }
Пример #18
0
 public unsafe Device CreateDevice(ref DeviceCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     Device device;
     fixed (DeviceCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateDevice(this, __createInfo__, allocator, &device).CheckError();
     }
     return device;
 }
Пример #19
0
        public Context(GameWindow window)
        {
            Window              = window;
            Instance            = ToDispose(VKHelper.CreateInstance());
            DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance));
            Surface             = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle));

            foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (GraphicsQueueFamilyIndex == -1)
                        {
                            GraphicsQueueFamilyIndex = i;
                        }
                        if (ComputeQueueFamilyIndex == -1)
                        {
                            ComputeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, Surface) &&
                            VKHelper.GetPresentationSupport(physicalDevice, i))
                        {
                            PresentQueueFamilyIndex = i;
                        }

                        if (GraphicsQueueFamilyIndex != -1 &&
                            ComputeQueueFamilyIndex != -1 &&
                            PresentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            GenerateDepthStencilFormat();

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex);
            ComputeQueue  = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(ComputeQueueFamilyIndex);
            PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(PresentQueueFamilyIndex);

            Content = new Content(this);

            GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer)));
            ComputeCommandPool  = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex)));

            Graphics = ToDispose(new Graphics(this));

            Build();
        }
Пример #20
0
        public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount)
        {
            if (queueCount > QueuesCount)
            {
                queueCount = QueuesCount;
            }

            float *queuePriorities = stackalloc float[(int)queueCount];

            for (int i = 0; i < queueCount; i++)
            {
                queuePriorities[i] = 1f;
            }

            var queueCreateInfo = new DeviceQueueCreateInfo()
            {
                SType            = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = queueFamilyIndex,
                QueueCount       = queueCount,
                PQueuePriorities = queuePriorities
            };

            api.GetPhysicalDeviceProperties(physicalDevice, out var properties);
            bool useRobustBufferAccess = VendorUtils.FromId(properties.VendorID) == Vendor.Nvidia;

            var supportedFeatures = api.GetPhysicalDeviceFeature(physicalDevice);

            var features = new PhysicalDeviceFeatures()
            {
                DepthBiasClamp           = true,
                DepthClamp               = true,
                DualSrcBlend             = true,
                FragmentStoresAndAtomics = true,
                GeometryShader           = true,
                ImageCubeArray           = true,
                IndependentBlend         = true,
                LogicOp                   = true,
                MultiViewport             = true,
                PipelineStatisticsQuery   = true,
                SamplerAnisotropy         = true,
                ShaderClipDistance        = true,
                ShaderFloat64             = supportedFeatures.ShaderFloat64,
                ShaderImageGatherExtended = true,
                // ShaderStorageImageReadWithoutFormat = true,
                // ShaderStorageImageWriteWithoutFormat = true,
                TessellationShader             = true,
                VertexPipelineStoresAndAtomics = true,
                RobustBufferAccess             = useRobustBufferAccess
            };

            void *pExtendedFeatures = null;

            var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
            {
                SType             = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
                PNext             = pExtendedFeatures,
                TransformFeedback = true
            };

            pExtendedFeatures = &featuresTransformFeedback;

            var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
            {
                SType          = StructureType.PhysicalDeviceRobustness2FeaturesExt,
                PNext          = pExtendedFeatures,
                NullDescriptor = true
            };

            pExtendedFeatures = &featuresRobustness2;

            var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT()
            {
                SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
                PNext = pExtendedFeatures,
                ExtendedDynamicState = supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName)
            };

            pExtendedFeatures = &featuresExtendedDynamicState;

            var featuresVk11 = new PhysicalDeviceVulkan11Features()
            {
                SType = StructureType.PhysicalDeviceVulkan11Features,
                PNext = pExtendedFeatures,
                ShaderDrawParameters = true
            };

            pExtendedFeatures = &featuresVk11;

            var featuresVk12 = new PhysicalDeviceVulkan12Features()
            {
                SType = StructureType.PhysicalDeviceVulkan12Features,
                PNext = pExtendedFeatures,
                DescriptorIndexing = supportedExtensions.Contains("VK_EXT_descriptor_indexing"),
                DrawIndirectCount  = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName)
            };

            pExtendedFeatures = &featuresVk12;

            PhysicalDeviceIndexTypeUint8FeaturesEXT featuresIndexU8;

            if (supportedExtensions.Contains("VK_EXT_index_type_uint8"))
            {
                featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
                {
                    SType          = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
                    PNext          = pExtendedFeatures,
                    IndexTypeUint8 = true
                };

                pExtendedFeatures = &featuresIndexU8;
            }

            PhysicalDeviceFragmentShaderInterlockFeaturesEXT featuresFragmentShaderInterlock;

            if (supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"))
            {
                featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT()
                {
                    SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
                    PNext = pExtendedFeatures,
                    FragmentShaderPixelInterlock = true
                };

                pExtendedFeatures = &featuresFragmentShaderInterlock;
            }

            PhysicalDeviceSubgroupSizeControlFeaturesEXT featuresSubgroupSizeControl;

            if (supportedExtensions.Contains("VK_EXT_subgroup_size_control"))
            {
                featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT()
                {
                    SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
                    PNext = pExtendedFeatures,
                    SubgroupSizeControl = true
                };

                pExtendedFeatures = &featuresSubgroupSizeControl;
            }

            var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray();

            IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
            }

            var deviceCreateInfo = new DeviceCreateInfo()
            {
                SType = StructureType.DeviceCreateInfo,
                PNext = pExtendedFeatures,
                QueueCreateInfoCount    = 1,
                PQueueCreateInfos       = &queueCreateInfo,
                PpEnabledExtensionNames = (byte **)ppEnabledExtensions,
                EnabledExtensionCount   = (uint)enabledExtensions.Length,
                PEnabledFeatures        = &features
            };

            api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();

            for (int i = 0; i < enabledExtensions.Length; i++)
            {
                Marshal.FreeHGlobal(ppEnabledExtensions[i]);
            }

            return(device);
        }
Пример #21
0
        private unsafe void CreateLogicalDevice()
        {
            QueueFamilyIndices indices = FindQueueFamilies(_physicalDevice);

            uint[] uniqueQueueFamilies = new[] { indices.GraphicsFamily.Value, indices.PresentFamily.Value };
            var    queueCreateInfos    = stackalloc DeviceQueueCreateInfo[uniqueQueueFamilies.Length];

            float queuePriority = 1.0f;

            for (int i = 0; i < uniqueQueueFamilies.Length; i++)
            {
                uint queueFamily     = uniqueQueueFamilies[i];
                var  queueCreateInfo = new DeviceQueueCreateInfo
                {
                    SType            = StructureType.DeviceQueueCreateInfo,
                    QueueFamilyIndex = queueFamily,
                    QueueCount       = 1,
                    PQueuePriorities = &queuePriority
                };
                queueCreateInfos[i] = queueCreateInfo;
            }

            var deviceFeatures = new PhysicalDeviceFeatures();

            var createInfo = new DeviceCreateInfo
            {
                SType                 = StructureType.DeviceCreateInfo,
                PQueueCreateInfos     = queueCreateInfos,
                QueueCreateInfoCount  = (uint)uniqueQueueFamilies.Length,
                PEnabledFeatures      = &deviceFeatures,
                EnabledExtensionCount = 0
            };

            if (EnableValidationLayers)
            {
                createInfo.EnabledLayerCount   = (uint)_validationLayers.Length;
                createInfo.PpEnabledLayerNames = (byte **)SilkMarshal.MarshalStringArrayToPtr(_validationLayers);
            }
            else
            {
                createInfo.EnabledLayerCount = 0;
            }

            fixed(Device *device = &_device)
            {
                Result result = _vk.CreateDevice(_physicalDevice, &createInfo, (AllocationCallbacks *)null, device);

                if (result != Result.Success)
                {
                    throw new Exception("Failed to create logical device!");
                }
            }

            fixed(Queue *graphicsQueue = &_graphicsQueue)
            {
                _vk.GetDeviceQueue(_device, indices.GraphicsFamily.Value, 0, graphicsQueue);
            }

            fixed(Queue *presentQueue = &_presentQueue)
            {
                _vk.GetDeviceQueue(_device, indices.PresentFamily.Value, 0, presentQueue);
            }
        }
Пример #22
0
        public VulkanContext(Instance instance, SurfaceKhr surface, Platform platform)
        {
            // Find graphics and presentation capable physical device(s) that support
            // the provided surface for platform.
            int graphicsQueueFamilyIndex = -1;
            int computeQueueFamilyIndex  = -1;
            int presentQueueFamilyIndex  = -1;

            foreach (PhysicalDevice physicalDevice in instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (graphicsQueueFamilyIndex == -1)
                        {
                            graphicsQueueFamilyIndex = i;
                        }
                        if (computeQueueFamilyIndex == -1)
                        {
                            computeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, surface) &&
                            GetPresentationSupport(physicalDevice, i))
                        {
                            presentQueueFamilyIndex = i;
                        }

                        if (graphicsQueueFamilyIndex != -1 &&
                            computeQueueFamilyIndex != -1 &&
                            presentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            bool GetPresentationSupport(PhysicalDevice physicalDevice, int queueFamilyIndex)
            {
                switch (platform)
                {
                case Platform.Android:
                    return(true);

                case Platform.Win32:
                    return(physicalDevice.GetWin32PresentationSupportKhr(queueFamilyIndex));

                default:
                    throw new NotImplementedException();
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = graphicsQueueFamilyIndex == presentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(graphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(presentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(graphicsQueueFamilyIndex);
            ComputeQueue  = computeQueueFamilyIndex == graphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(computeQueueFamilyIndex);
            PresentQueue = presentQueueFamilyIndex == graphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(presentQueueFamilyIndex);

            // Create command pool(s).
            GraphicsCommandPool = Device.CreateCommandPool(new CommandPoolCreateInfo(graphicsQueueFamilyIndex));
            ComputeCommandPool  = Device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex));
        }
Пример #23
0
 public unsafe void CreateLogicalDevice(DeviceCreateInfo deviceCreateInfo)
 {
     _device = _physicalDevice.CreateDevice(ref deviceCreateInfo);
 }