Example #1
0
        public ReturnSet <bool> Initialize(Logger logger)
        {
            try
            {
                var instanceCreationResult = VulkanInstance.Create();

                if (instanceCreationResult.IsError)
                {
                    throw instanceCreationResult.Error;
                }

                _instance = instanceCreationResult.Value;

                logger.AddMessage("Instance created successfully");

                var surfaceCreationResult = VulkanSurface.Create(_instance, _form);

                if (surfaceCreationResult.IsError)
                {
                    throw surfaceCreationResult.Error;
                }

                _surface = surfaceCreationResult.Value;

                logger.AddMessage("Surface created successfully");

                return(new ReturnSet <bool>(true));
            }
            catch (Exception ex)
            {
                return(new ReturnSet <bool>(ex));
            }
        }
Example #2
0
        internal GraphicsManager(Game game, IntPtr sdlRendererHandle)
        {
            _log  = LogManager.GetForCurrentAssembly();
            _game = game;

            SdlRendererHandle = sdlRendererHandle;

            CreateVulkanInstance();

            SDL2.SDL_Vulkan_CreateSurface(
                _game.Window.SdlWindowHandle,
                VulkanInstanceHandle,
                out var surfacePtr
                );

            SdlVulkanSurfaceHandle = new UIntPtr(surfacePtr);
            SdlVulkanSurface       = (SurfaceKhr)typeof(SurfaceKhr).GetConstructor(
                BindingFlags.NonPublic | BindingFlags.Instance,
                null, Type.EmptyTypes, null
                ).Invoke(null);
            typeof(SurfaceKhr).GetField("m", BindingFlags.Instance | BindingFlags.NonPublic)
            .SetValue(SdlVulkanSurface, surfacePtr
                      );

            var physDevs = VulkanInstance.EnumeratePhysicalDevices();

            InitializeVulkan(physDevs[0], SdlVulkanSurface);

            RenderContext = new RenderContext(game);
        }
Example #3
0
        public unsafe SurfaceKHR CreateSurface(VulkanInstance instance)
        {
            if (OperatingSystem.IsWindows())
            {
                if (instance.Api.TryGetInstanceExtension(new Instance(instance.Handle), out KhrWin32Surface surfaceExtension))
                {
                    var createInfo = new Win32SurfaceCreateInfoKHR()
                    {
                        Hinstance = 0, Hwnd = Handle, SType = StructureType.Win32SurfaceCreateInfoKhr
                    };

                    surfaceExtension.CreateWin32Surface(new Instance(instance.Handle), createInfo, null, out var surface).ThrowOnError();

                    return(surface);
                }
            }
            else if (OperatingSystem.IsLinux())
            {
                if (instance.Api.TryGetInstanceExtension(new Instance(instance.Handle), out KhrXlibSurface surfaceExtension))
                {
                    var createInfo = new XlibSurfaceCreateInfoKHR()
                    {
                        SType  = StructureType.XlibSurfaceCreateInfoKhr,
                        Dpy    = (nint *)Display,
                        Window = Handle
                    };

                    surfaceExtension.CreateXlibSurface(new Instance(instance.Handle), createInfo, null, out var surface).ThrowOnError();

                    return(surface);
                }
            }

            throw new PlatformNotSupportedException("The current platform does not support surface creation.");
        }
Example #4
0
        public VulkanInitializer(String WindowName, RendererWindow WindowHandle, GraphicsSettings mySettings, IPreferredGraphicsDeviceFilter myGraphicsDeviceFilter = null, IPreferredComputeDeviceFilter myComputeDeviceFilter = null)
        {
            var Window       = new VulkanInstance(WindowName, WindowHandle.WindowHandle);
            var Surface      = new SurfaceKHR(Window);
            var myDeviceList = new VulkanSupportedDevices(Window, Surface, myGraphicsDeviceFilter, myComputeDeviceFilter);

            var SelectedPhysicalGraphicsDevice = myDeviceList.GetBestGraphicsDevice();
            var SelectedLogicalGraphicsDevice  = new VulkanLogicalDevice(SelectedPhysicalGraphicsDevice);

            DescriptorSetPoolManager myDescriptorPoolGraphicsManager;
            DescriptorSetPoolManager myDescriptorPoolComputeManager;

            Renderer.Vulkan.Queue myGraphicsQueue = null;
            Renderer.Vulkan.Queue myComputeQueue  = null;

            var SelectedPhysicalComputeDevice = myDeviceList.GetNextComputeDevice();
            VulkanLogicalDevice SelectedLogicalComputeDevice;

            if (myDeviceList.Count == 1)
            {
                //Compute and Renderer will share a device.
                SelectedLogicalComputeDevice    = new VulkanLogicalDevice(SelectedPhysicalGraphicsDevice);
                myDescriptorPoolGraphicsManager = new DescriptorSetPoolManager(SelectedLogicalGraphicsDevice);
                myDescriptorPoolComputeManager  = myDescriptorPoolGraphicsManager;
                myGraphicsQueue = SelectedLogicalGraphicsDevice.QueueManager.GetQueue(QueueFlags.Graphics);
                myComputeQueue  = SelectedLogicalGraphicsDevice.QueueManager.GetQueue(QueueFlags.Compute);
            }
            else
            {
                //TODO: iterate through queue to find next best device for compute
                SelectedLogicalComputeDevice    = new VulkanLogicalDevice(SelectedPhysicalComputeDevice);
                myDescriptorPoolGraphicsManager = new DescriptorSetPoolManager(SelectedLogicalGraphicsDevice);
                myDescriptorPoolComputeManager  = new DescriptorSetPoolManager(SelectedLogicalComputeDevice);
                myGraphicsQueue = SelectedLogicalGraphicsDevice.QueueManager.GetQueue(QueueFlags.Graphics);
                myComputeQueue  = SelectedLogicalComputeDevice.QueueManager.GetQueue(QueueFlags.Compute);
            }


            myLightingManager = new LightingManager();

            var Renderer = new VulkanRenderer(myLightingManager, Surface, Window, SelectedLogicalGraphicsDevice, myDescriptorPoolGraphicsManager, SelectedPhysicalGraphicsDevice, myGraphicsQueue, mySettings);
            var Compute  = new VulkanCompute(SelectedLogicalComputeDevice, myDescriptorPoolComputeManager, SelectedPhysicalComputeDevice, myComputeQueue);

            RenderingManager = Renderer;
            //Make sure they know about eachother's fences so they don't draw or do compute shaders at the same time!
            Renderer.SetComputeFence(Compute.GetFinishedFence());//Semaphore or fence?
            Compute.SetRendererFence(Renderer.GetFinshedFence());
            ComputeManager = Compute;
        }
 public VulkanSupportedDevices(VulkanInstance myWindow, SurfaceKHR mySurface, IPreferredGraphicsDeviceFilter CustomGraphicFilter = null, IPreferredComputeDeviceFilter CustomComputeFilter = null)
 {
     if (CustomGraphicFilter != null)
     {
         GraphicsDevicePreferences = CustomGraphicFilter;
     }
     if (CustomComputeFilter != null)
     {
         ComputeDevicePreferences = CustomComputeFilter;
     }
     foreach (var A in myWindow.EnumeratePhysicalDevices())
     {
         VulkanPhysicalDevice myPhysicalDevice = (VulkanPhysicalDevice)A;
         myDevices.Add(new Support(A, GraphicsDevicePreferences.Score(A, mySurface), ComputeDevicePreferences.Score(A)));
     }
 }
Example #6
0
        public unsafe VulkanDebugMessenger(VulkanInstance instance) : base(instance.VK)
        {
            _DebugUtils = instance.GetInstanceExtension <ExtDebugUtils>();

            DebugUtilsMessengerCreateInfoEXT createInfo = new DebugUtilsMessengerCreateInfo(StructureType.DebugUtilsMessengerCreateInfoExt, null, 0u,
                                                                                            _MESSAGE_SEVERITY_IMPORTANT,
                                                                                            DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt
                                                                                            | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt
                                                                                            | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt,
                                                                                            &DebugCallback
                                                                                            );

            Result result = _DebugUtils.CreateDebugUtilsMessenger(instance, &createInfo, (AllocationCallbacks *)null !, out _Messenger);

            if (result is not Result.Success)
            {
                throw new VulkanException(result, "Failed to create debug messenger,");
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="LogicalDevice"></param>
        /// <param name="DescriptorPoolManager">Since it's possible for one device to support both the compute and the rendering, the VulkanInitializer will decide and send it to us. </param>
        /// <param name="PhysicalDevice"></param>
        /// <param name="MainGraphicsQueue"></param>
        /// <param name="mySettings"></param>
        public VulkanRenderer(LightingManager myManager, SurfaceKHR Surface, VulkanInstance myInstance, VulkanLogicalDevice LogicalDevice, DescriptorSetPoolManager DescriptorPoolManager, VulkanPhysicalDevice PhysicalDevice, Engine.Renderer.Vulkan.Queue MainGraphicsQueue, GraphicsSettings mySettings)
        {
            #region Variables from Initializer, Fences, Semaphores
            GlobalLightingManager  = myManager;
            VulkanRenderer.Surface = Surface;
            VulkanRenderer.Window  = myInstance;
            VulkanRenderer.SelectedLogicalDevice  = LogicalDevice;
            VulkanRenderer.SelectedPhysicalDevice = PhysicalDevice;
            //For now we'll only support one main Graphics Queue that may or may not be used in other places like the Compute Shader. Depends on graphics card.
            GraphicsQueue = MainGraphicsQueue;
            ActiveGraphicsFamilyQueueIndex = GraphicsQueue.QueueFamilyIndex;
            //Creates Debug Camera

            this.ActiveCamera = new CameraComponent(); //TODO: Remove after debug phase is finally over.

            VulkanRenderer.Viewport = new Viewport
            {
                Width    = mySettings.SCREEN_WIDTH,
                Height   = mySettings.SCREEN_HEIGHT,
                MinDepth = 0,
                MaxDepth = 1.0f,
            };
            FenceCreateInfo fenceInfo = new FenceCreateInfo();
            DrawingFence = VulkanRenderer.SelectedLogicalDevice.CreateFence(fenceInfo);
            OffscreenRenderFinishedSemaphore = VulkanRenderer.SelectedLogicalDevice.CreateSemaphore(new SemaphoreCreateInfo());
            #endregion
            #region Vulkan Pools and Queues Initialization
            myDescriptorPoolManager = DescriptorPoolManager;
            myShaderManager         = new ShaderManager(myDescriptorPoolManager);
            myFramebufferManager    = new FrameBufferManager(mySettings.SCREEN_WIDTH, mySettings.SCREEN_HEIGHT);//TODO: Needed?
            myModelResourceManager  = new ResourceSetManager();
            mySwapchain             = new SwapchainManager(LogicalDevice, Surface.SelectedSurfaceFormat);
            PrimaryCommandPool      = new PrimaryCommandBufferPool(LogicalDevice, GraphicsQueue.QueueFamilyIndex, 1);
            int Count = LogicalDevice.QueueManager.GetFreeQueueCount(QueueFlags.Graphics);
            for (int i = 0; i < Count; i++)
            {
                myDeferredPassesCommandPoolQueue.Enqueue(new SecondaryCommandBufferPool(LogicalDevice, GraphicsQueue.QueueFamilyIndex, 30));
            }
            #endregion
            #region GBuffer, Subpass Initialization
            GeometryBuffer myGeometryBuffer = new GeometryBuffer();


            mySubpasses = GetSubpassesFromGraphics(mySettings);
            uint starting = 1;
            uint ending   = 2;
            for (int i = 0; i < mySubpasses.Length; i++)
            {
                mySubpasses[i].SetSubpassStart(starting + 1);
                if (i + 1 >= mySubpasses.Length)
                {
                    mySubpasses[i].SetSubpassEnd(UInt32.MaxValue);
                }
                ending++;
                starting++;
            }

            var OffscreenRenderPass = new RenderPass(myGeometryBuffer, mySubpasses);

            GeometryPass = new GeometryPass(myGeometryBuffer, OffscreenRenderPass, myDeferredPassesCommandPoolQueue.Dequeue(), myShaderManager);

            #endregion

            #region Final Composition Render Setup
            OnScreenRenderPass = new RenderPass();                                                                                                                                       // this.CreateFinalRenderPass(LogicalDevice);
            var Result = myShaderManager.CreatePipeline(OnScreenRenderPass, new String[] { "OffscreenToOnScreenVert", "OffscreenToOnScreenFrag" }, out myDeferredRendererDescriptorSet); //TODO: create method that returns resource set for shader of a given type.
            DeferredRendererOutputPipe       = Result.Item2;
            DeferredRendererOutputPipeLayout = Result.Item1;
            Tuple <String, DescriptorImageInfo>[] myDescriptorInfo = GeometryPass.GetGBufferDescriptorImageInfo();
            if (mySubpasses.Length != 0)
            {
                foreach (var A in myDescriptorInfo)
                {
                    foreach (SubPass B in mySubpasses)
                    {
                        //ResourceSet mySet = B.GetResourceSet();
                        // mySet.Write(A.Item1, A.Item2);
                    }
                }
            }
            //Tell our deferred renderer that we can
            foreach (var A in myDescriptorInfo)
            {
                myDeferredRendererDescriptorSet.Write(A.Item1, A.Item2);
            }
            CreateFinalQuadRenderingSpace();
            #endregion
        }