Beispiel #1
0
        AppGpu AppGpuInit(uint id, PhysicalDevice obj)
        {
            // TODO : Limits

            AppGpu gpu = new AppGpu
            {
                Id          = id,
                Obj         = obj,
                Props       = obj.GetProperties(),
                QueueProps  = obj.GetQueueFamilyProperties(),
                MemoryProps = obj.GetMemoryProperties(),
                Features    = obj.GetFeatures(),
                Limits      = null,
            };

            gpu.QueueReqs = new DeviceQueueCreateInfo[gpu.QueueProps.Length];
            for (uint i = 0; i < gpu.QueueProps.Length; i++)
            {
                uint queueCount = gpu.QueueProps[i].QueueCount;
                DeviceQueueCreateInfo queueReq = new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = i,
                    QueueCount       = queueCount,
                    QueuePriorities  = new float[queueCount],
                };
                gpu.QueueReqs[i] = queueReq;
            }

            gpu.Device = AppDevInit(gpu);
            AppDevInitFormats(gpu.Device);

            return(gpu);
        }
Beispiel #2
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", "VK_KHR_display_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };
            var physicalDevice = devices [0];

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat       = SelectFormat(physicalDevice, surface);

            swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat);
            var images       = device.GetSwapchainImagesKHR(swapchain);
            var renderPass   = CreateRenderPass(surfaceFormat);
            var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass);

            commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities);
            var fenceInfo = new FenceCreateInfo();

            fences = new Fence [] { device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Beispiel #3
0
        static void CreateDevice()
        {
            var queueCreateInfo = new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = 0,
            };

            var deviceEnabledExtensions = new[]
            {
                "VK_KHR_swapchain",
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfoCount  = 1,
                QueueCreateInfos      = queueCreateInfo,
                EnabledExtensionNames = deviceEnabledExtensions,
            };

            device = physicalDevice.CreateDevice(deviceCreateInfo, null);
            Console.WriteLine("[ OK ] Device");

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

            queue = device.GetQueue(0, (uint)queueNodeIndex);
            Console.WriteLine("[ OK ] Queue");
        }
        Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            // Device objects represent logical connections to physical devices. Each device exposes
            // a number of queue families each having one or more queues. All queues in a queue family
            // support the same operations.
            //
            // As described above, a Vulkan application will first query for all physical
            // devices in a system. Each physical device can then be queried for its capabilities,
            // including its queue and queue family properties. Once an acceptable physical device is
            // identified, an application will create a corresponding logical device. An application
            // must create a separate logical device for each physical device it will use. The created
            // logical device is then the primary interface to the physical device.

            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var features = new PhysicalDeviceFeatures();

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

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

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
Beispiel #5
0
        /// <summary>
        /// Initialize the graphic device.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            // - Take presentation and graphic queue
            GraphicQueueIndex = GetSuitableQueues(Physical.Handle, QueueFlags.Graphics).First();
            PresentQueueIndex = GetPresentQueues(Physical.Handle, Physical.DrawingSurface.Handle).First();
            ComputeQueueIndex = GetSuitableQueues(Physical.Handle, QueueFlags.Compute).First();

            var queues = new DeviceQueueCreateInfo[]
            {
                new DeviceQueueCreateInfo {
                    QueueFamilyIndex = GraphicQueueIndex, QueuePriorities = new[] { 1f }
                },
                new DeviceQueueCreateInfo {
                    QueueFamilyIndex = PresentQueueIndex, QueuePriorities = new[] { 1f }
                },
                new DeviceQueueCreateInfo {
                    QueueFamilyIndex = ComputeQueueIndex, QueuePriorities = new[] { 1f }
                }
            };

            // - Create logical device
            Handle = Physical.Handle.CreateDevice(queues, null, new[] { KhrExtensions.Swapchain });

            // - Gets the logical queues
            GraphicQueue = Handle.GetQueue(GraphicQueueIndex, 0);
            PresentQueue = Handle.GetQueue(PresentQueueIndex, 0);
            ComputeQueue = Handle.GetQueue(ComputeQueueIndex, 0);
        }
        private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            var queueCreateInfos = new DeviceQueueCreateInfo[]
            {
                new DeviceQueueCreateInfo()
                {
                    QueueFamilyIndex = (uint)indices.GraphicsFamily,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f },
                }
            };

            var createInfo = new DeviceCreateInfo()
            {
                EnabledExtensionNames = new string[] { "VK_KHR_swapchain" },
                QueueCreateInfos      = queueCreateInfos,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
            };

            vkDevice = vkPhysicalDevice.CreateDevice(createInfo);

            vkGraphicsQueue = vkDevice.GetQueue((uint)indices.GraphicsFamily, 0);
            vkPresentQueue  = vkDevice.GetQueue((uint)indices.PresentFamily, 0);
        }
Beispiel #7
0
        private Device CreateLogicalDevice(out Queue GraphicsQueue, out Queue PresentQueue)
        {
            var   queueInfos    = stackalloc DeviceQueueCreateInfo[2];
            uint  infoCount     = 1;
            float queuePriority = 1f;

            queueInfos[0] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.GraphicsFamily, queueCount: 1, pQueuePriorities: &queuePriority);

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                infoCount = 2;

                queueInfos[1] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.PresentFamily, queueCount: 1, pQueuePriorities: &queuePriority);
            }

            PhysicalDeviceFeatures features = default;

            using var extensionNames = SilkMarshal.StringArrayToMemory(RequiredDeviceExtensions);

            PhysicalDeviceSeparateDepthStencilLayoutsFeatures depthStencilFeature = new PhysicalDeviceSeparateDepthStencilLayoutsFeatures
            {
                SType = StructureType.PhysicalDeviceSeparateDepthStencilLayoutsFeatures,
                SeparateDepthStencilLayouts = true
            };

            DeviceCreateInfo createInfo = new DeviceCreateInfo
            {
                SType = StructureType.DeviceCreateInfo,
                //PNext = &depthStencilFeature,
                QueueCreateInfoCount    = infoCount,
                PQueueCreateInfos       = queueInfos,
                EnabledExtensionCount   = (uint)RequiredDeviceExtensions.Length,
                PpEnabledExtensionNames = (byte **)extensionNames,
                PEnabledFeatures        = &features
            };

            Device device;
            var    res = VkApi.CreateDevice(this.PhysicalDevice, &createInfo, null, &device);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Logical Device Creation Failed!", res);
            }

            Queue queue = default;

            VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.GraphicsFamily, 0, &queue);

            GraphicsQueue = queue;

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                queue = default;
                VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.PresentFamily, 0, &queue);
            }

            PresentQueue = queue;

            return(device);
        }
        public void CreateDevice()
        {
            /*
             * We create the logical device in this function.
             */

            /*
             * When creating the device, we also specify what queues it has.
             */
            // Store memory properties of the physical device.
            PhysicalDeviceMemoryProperties MemoryProperties = physicalDevice.GetMemoryProperties();
            PhysicalDeviceFeatures         Features         = physicalDevice.GetFeatures();
            PhysicalDeviceProperties       Properties       = physicalDevice.GetProperties();

            // Create a logical device.
            var queueCreateInfos = new DeviceQueueCreateInfo[1];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(computeQueueFamilyIndex, 1, 1.0f);

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

            device = physicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            queue = device.GetQueue(computeQueueFamilyIndex);

            // Create command pool(s).
            //commandPool = device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex));
        }
Beispiel #9
0
        public unsafe ReturnSet <bool> InitializeLogicalDevice(VulkanDevice physicalDevice, Logger logger)
        {
            uint queuePriorities = 0;

            var deviceQueueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var physicalDeviceFeatures = new PhysicalDeviceFeatures
            {
                ShaderClipDistance = true,
            };

            var enabledLayerNames = new[]
            {
                ExtensionNames.VK_LAYER_LUNARG_standard_validation.ToIntPtr()
            };

            var enabledExtensionNames = new[]
            {
                ExtensionNames.VK_KHR_swapchain.ToIntPtr()
            };

            fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
            fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
            {
                var deviceCreateInfo = new DeviceCreateInfo
                {
                    StructureType         = StructureType.DeviceCreateInfo,
                    QueueCreateInfoCount  = 1,
                    QueueCreateInfos      = new IntPtr(&deviceQueueCreateInfo),
                    EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                    EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                    EnabledFeatures       = new IntPtr(&physicalDeviceFeatures),
                    EnabledLayerCount     = (uint)enabledLayerNames.Length,
                    EnabledLayerNames     = new IntPtr(enabledLayerNamesPointer)
                };

                physicalDevice.CreateLogicalDevice(deviceCreateInfo);

                logger.AddMessage("Logical Device created successfully");

                _queue = physicalDevice.CreateQueue(_surface);

                logger.AddMessage($"Queue created on {physicalDevice.Name}");

                _form.Show();

                return(new ReturnSet <bool>(true));
            }
        }
Beispiel #10
0
        private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface)
        {
            var  queueFamilyProperties = physDev.GetQueueFamilyProperties();
            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new[] { 1.0f },
                QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_swapchain",
                },
                QueueCreateInfos = new[] { queueInfo }
            };

            _device = physDev.CreateDevice(deviceInfo);

            _queue = _device.GetQueue(0, 0);
            _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectSurfaceFormat(physDev, surface);

            _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat);
            _images       = _device.GetSwapchainImagesKHR(_swapchainKhr);
            _renderPass   = CreateRenderPass(surfaceFormat);
            _framebuffers = CreateFramebuffers(_images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            _fence = _device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore      = _device.CreateSemaphore(semaphoreInfo);
            _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities);
        }
Beispiel #11
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", "VK_KHR_display_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };
            var physicalDevice = devices [0];

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain = CreateSwapchain(surface, surfaceFormat);
            var images = device.GetSwapchainImagesKHR(swapchain);

            renderPass = CreateRenderPass(surfaceFormat);

            var framebuffers = CreateFramebuffers(images, surfaceFormat);
            var vertexBuffer = CreateBuffer(physicalDevice, Logo.Vertices, BufferUsageFlags.VertexBuffer, typeof(float));
            var indexBuffer  = CreateBuffer(physicalDevice, Logo.Indexes, BufferUsageFlags.IndexBuffer, typeof(short));

            uniformBuffer       = CreateUniformBuffer(physicalDevice);
            descriptorSetLayout = CreateDescriptorSetLayout();
            var pipelines = CreatePipelines();

            descriptorSets = CreateDescriptorSets();
            UpdateDescriptorSets();

            commandBuffers = CreateCommandBuffers(images, framebuffers, pipelines [0], vertexBuffer, indexBuffer, (uint)Logo.Indexes.Length);
            var fenceInfo = new FenceCreateInfo();

            fences = new Fence [] { device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Beispiel #12
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;
        }
Beispiel #13
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;
        }
Beispiel #14
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));
        }
Beispiel #15
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));
        }
Beispiel #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);
        }
        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);
            }
        }
Beispiel #18
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();
        }
Beispiel #19
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);
        }
Beispiel #20
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);
        }
Beispiel #21
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;
        }
Beispiel #22
0
 /// <summary>
 /// Construct a Graphics object belonging to a window
 /// </summary>
 /// <param name="window"></param>
 public Graphics(WyvernWindow window)
 {
     // Argument checks
     if (window is null)
     {
         throw new ArgumentNullException(nameof(window));
     }
     // Initialize the static part of Graphics if necessary
     InitializeStatic();
     // Store window
     Window = window;
     // Create window surface
     {
         AllocationCallbacks?allocationCallbacks = null;
         Surface = new SurfaceKhr(
             Instance,
             ref allocationCallbacks,
             VkGLFW3.VkGlfw.CreateWindowSurface(Instance.Handle, Window, IntPtr.Zero)
             );
         Surface.PrintDebug();
     }
     // Choose a physical device
     {
         PhysicalDevice = Instance.EnumeratePhysicalDevices()
                          .Where(e => GetDeviceMeetsRequirements(e, Surface))
                          .OrderByDescending(GetDeviceScore)
                          .FirstOrDefault();
         if (PhysicalDevice is null)
         {
             throw new InvalidOperationException("No physical device found that meets the requirements for the application");
         }
         MemoryProperties = PhysicalDevice.GetMemoryProperties();
     }
     // Create default queue families
     {
         ComputeQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(ComputeQueueFamily)}", this, QueueFamily.QueueType.Compute, 2,
             true, ComputeCommandPoolFlags
             );
         GraphicsQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(GraphicsQueueFamily)}", this, QueueFamily.QueueType.Graphics, 2,
             true, GraphicsCommandPoolFlags
             );
         TransferQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(TransferQueueFamily)}", this, QueueFamily.QueueType.Transfer, 2,
             true, TransferCommandPoolFlags
             );
         PresentQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(PresentQueueFamily)}", this, QueueFamily.QueueType.Present, 1,
             false
             );
     }
     // Create a logical device
     {
         // Generate queue create info structs
         var queueCreateInfos = QueueFamilies.Select(queueFamily =>
         {
             // Generate queue priorities
             var priorities = new float[queueFamily.Count];
             for (var i = 0; i < priorities.Length; i++)
             {
                 priorities[i] = 1f - (i / (float)(priorities.Length - 1));
             }
             // Create create info
             var createInfo = new DeviceQueueCreateInfo()
             {
                 QueueFamilyIndex = queueFamily.Index,
                 QueueCount       = queueFamily.Count,
                 QueuePriorities  = priorities
             };
             return(createInfo);
         });
         // Merge multiple queue families' queue create infos
         {
             var alreadyHave       = new List <int>();
             var uniqueCreateInfos = new List <DeviceQueueCreateInfo>();
             foreach (var createInfo in queueCreateInfos.OrderByDescending(e => e.QueueCount))
             {
                 if (!alreadyHave.Contains(createInfo.QueueFamilyIndex))
                 {
                     alreadyHave.Add(createInfo.QueueFamilyIndex);
                     uniqueCreateInfos.Add(createInfo);
                 }
             }
             queueCreateInfos = uniqueCreateInfos;
             foreach (var createInfo in queueCreateInfos)
             {
                 createInfo.PrintDebug();
             }
         }
         // Create device
         Device = PhysicalDevice.CreateDevice(new DeviceCreateInfo()
         {
             EnabledExtensionNames = EnabledDeviceExtensions.ToArray(),
             QueueCreateInfos      = queueCreateInfos.ToArray(),
             EnabledFeatures       = EnabledPhysicalDeviceFeatures
         });
         // Set the queues in the queue families, using those created with the device
         foreach (var family in QueueFamilies)
         {
             var queues = new Queue[family.Count];
             for (var i = 0; i < queues.Length; i++)
             {
                 queues[i] = Device.GetQueue(family.Index, i);
             }
             family.SetQueues(queues);
         }
         // Create and set the command pools in the queue families
         foreach (var family in QueueFamilies)
         {
             // Skip family that shouldn't have a command pool
             if (!family.HasCommandPool)
             {
                 continue;
             }
             // Create command pool
             var commandPool = Device.CreateCommandPool(new CommandPoolCreateInfo()
             {
                 QueueFamilyIndex = family.Index,
                 Flags            = family.CommandPoolFlags
             });
             family.SetCommandPool(commandPool);
         }
     }
     // Create swapchain
     {
         // Query supported capabilities and formats
         var surfaceCapabilities = SurfaceCapabilities;
         var surfaceFormats      = SurfaceFormats;
         var surfacePresentModes = SurfacePresentModes;
         surfaceCapabilities.PrintDebug();
         // Choose the best image format and color space
         {
             var imageFormat = Array.Find(
                 PreferredSwapchainFormats,
                 preferred => surfaceFormats.Any(available => available.Format == preferred)
                 );
             if (imageFormat == Format.Undefined)
             {
                 imageFormat = surfaceFormats.FirstOrDefault().Format;
             }
             if (imageFormat == Format.Undefined)
             {
                 throw new InvalidOperationException("Surface somehow does not support any known image formats");
             }
             SwapchainImageFormat = imageFormat;
             SwapchainColorSpace  = surfaceFormats.First(e => e.Format == SwapchainImageFormat).ColorSpace;
         }
         // Choose the best present mode
         {
             var presentMode = Array.Find(
                 PreferredPresentModes,
                 preferred => surfacePresentModes.Any(available => available == preferred)
                 );
             SwapchainPresentMode = presentMode;
         }
         // Create the swapchain
         SwapchainExtent = surfaceCapabilities.CurrentExtent;
         Swapchain       = Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr(
                                                         surface: Surface,
                                                         imageFormat: SwapchainImageFormat,
                                                         imageExtent: SwapchainExtent,
                                                         preTransform: surfaceCapabilities.CurrentTransform,
                                                         presentMode: SwapchainPresentMode,
                                                         minImageCount: SurfaceCapabilities.MinImageCount,
                                                         imageArrayLayers: SurfaceCapabilities.MaxImageArrayLayers,
                                                         imageSharingMode: SharingMode.Exclusive,
                                                         imageColorSpace: SwapchainColorSpace
                                                         ));
         SwapchainAttachmentImages = Swapchain.GetImages().Select(
             e => new VKImage(
                 e, SwapchainImageFormat,
                 SwapchainExtent,
                 new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1)
                 )
             ).ToArray();
         Swapchain.PrintDebug();
     }
     // Create semaphores & fences
     {
         // Image available semaphore
         ImageAvailableSemaphore = Device.CreateSemaphore();
         ReadyToPresentSemaphore = Device.CreateSemaphore();
         // Swapchain image rendering fences
         RenderToImageFences = new Fence[SwapchainAttachmentImages.Length];
         for (var i = 0; i < RenderToImageFences.Length; i++)
         {
             RenderToImageFences[i] = Device.CreateFence(new FenceCreateInfo(flags: FenceCreateFlags.Signaled));
         }
     }
     // Create content collection
     {
         Content = new ContentCollection(this);
     }
     // Misc
     Stopwatch   = Stopwatch.StartNew();
     CurrentTime = 0.0;
 }
Beispiel #23
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);
        }
Beispiel #24
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);
        }
        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));
        }
Beispiel #26
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);
        }