/// <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 }