From 9f41b5829b1511ed731b3f7b2a8808c7d472a182 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 25 Jan 2020 00:57:07 +0100 Subject: [PATCH] comments, move initVulkan in Run() --- addons/Directory.Build.props | 2 +- appveyor.yml | 19 ++++++++ samples/Directory.Build.props | 6 +-- vke.net.sln | 44 ++++++++++++++---- vke/netfx.props | 1 - vke/src/VkWindow.cs | 88 +++++++++++++++++++++++++++-------- vke/src/base/Activable.cs | 6 +-- vke/src/base/Instance.cs | 2 +- 8 files changed, 130 insertions(+), 38 deletions(-) create mode 100644 appveyor.yml delete mode 120000 vke/netfx.props diff --git a/addons/Directory.Build.props b/addons/Directory.Build.props index 9f566b4..81a78f6 100644 --- a/addons/Directory.Build.props +++ b/addons/Directory.Build.props @@ -34,7 +34,7 @@ - + diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..3f45e42 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,19 @@ +version: 1.0.{build} +image: Visual Studio 2019 + +environment: + VULKAN_SDK: C:/VulkanSDK/1.1.130.0 + APPVEYOR_SAVE_CACHE_ON_ERROR: true + +cache: + - VulkanSDK.exe + - c:\VulkanSDK\ + +install: + - if not exist VulkanSDK.exe curl -L --silent --show-error --output VulkanSDK.exe https://vulkan.lunarg.com/sdk/download/1.1.130.0/windows/VulkanSDK-1.1.130.0-Installer.exe?Human=true && VulkanSDK.exe /S + +before_build: + - nuget restore + +build: + verbosity: minimal diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props index f6d8442..0f2b9a8 100644 --- a/samples/Directory.Build.props +++ b/samples/Directory.Build.props @@ -10,8 +10,8 @@ Jean-Philippe Bruyère $(SolutionDir)build\$(Configuration)\ - Exe - true + Exe + false $(MSBuildThisFileDirectory)common\shaders @@ -33,7 +33,7 @@ - + diff --git a/vke.net.sln b/vke.net.sln index 4d856a0..fd98d3c 100644 --- a/vke.net.sln +++ b/vke.net.sln @@ -1,10 +1,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "addons", "addons", "{4AA67AB0-C331-4CB2-9C00-B74F5DE31658}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpirVTasks", "SpirVTasks\SpirVTasks.csproj", "{7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vke", "vke\vke.csproj", "{642726F4-0592-4846-8EAF-A5D1964C85A7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "addons", "addons", "{4AA67AB0-C331-4CB2-9C00-B74F5DE31658}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvironmentPipeline", "addons\EnvironmentPipeline\EnvironmentPipeline.csproj", "{F04C3F79-2E08-4D35-A804-43039DCB7F5E}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistanceFieldFont", "addons\DistanceFieldFont\DistanceFieldFont.csproj", "{FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gltfLoader", "addons\gltfLoader\gltfLoader.csproj", "{F3BBF67D-7E63-48F3-8156-ADC014D268BB}" @@ -13,26 +17,26 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VkvgPipeline", "addons\Vkvg EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{16439374-B8DB-4643-8116-EB3358B49A12}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle", "samples\Triangle\Triangle.csproj", "{124152F8-FAE6-4D4B-87B9-6074DD365E9B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Textured", "samples\Textured\Textured.csproj", "{1B2DF710-E500-49E5-8802-EBA71A05E827}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "compute", "samples\compute\compute.csproj", "{5000CDE2-99B9-47EA-B4D9-EA1631F0E14A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistanceFieldFontTest", "samples\DistanceFieldFontTest\DistanceFieldFontTest.csproj", "{77437C6D-28B5-4798-96CA-68F987770D65}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "samples\Model\Model.csproj", "{A7D3FB7F-769B-4F36-9E3E-3FB71F24D306}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Textured", "samples\Textured\Textured.csproj", "{1B2DF710-E500-49E5-8802-EBA71A05E827}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TexturedCube", "samples\TexturedCube\TexturedCube.csproj", "{8185163E-A67C-4C0E-8548-67E2A9F16309}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpirVTasks", "SpirVTasks\SpirVTasks.csproj", "{7B05B5A7-49E2-4D05-BEF8-734F70CDBF17}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvironmentPipeline", "addons\EnvironmentPipeline\EnvironmentPipeline.csproj", "{F04C3F79-2E08-4D35-A804-43039DCB7F5E}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "deferred", "samples\deferred\deferred.csproj", "{D9A41382-444E-44ED-B638-3D8F06F2FBC2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle", "samples\Triangle\Triangle.csproj", "{124152F8-FAE6-4D4B-87B9-6074DD365E9B}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pbr", "samples\pbr\pbr.csproj", "{7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vkeEditor", "samples\vkeEditor\vkeEditor.csproj", "{81619805-9E6F-404A-BC0D-A2C25DDA2EDC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tests", "samples\tests\tests.csproj", "{F9117397-E105-44DD-A9BD-F6F8DC641095}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -146,6 +150,26 @@ Global {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.Release|Any CPU.Build.0 = Release|Any CPU {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.Release|Any CPU.Build.0 = Release|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC}.BuildPackages|Any CPU.Build.0 = Release|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.Release|Any CPU.Build.0 = Release|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU + {F9117397-E105-44DD-A9BD-F6F8DC641095}.BuildPackages|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E} = {4AA67AB0-C331-4CB2-9C00-B74F5DE31658} @@ -160,6 +184,8 @@ Global {D9A41382-444E-44ED-B638-3D8F06F2FBC2} = {16439374-B8DB-4643-8116-EB3358B49A12} {124152F8-FAE6-4D4B-87B9-6074DD365E9B} = {16439374-B8DB-4643-8116-EB3358B49A12} {7EB2430B-6BC0-4AE9-B1FA-57C3DB2AE1C5} = {16439374-B8DB-4643-8116-EB3358B49A12} + {81619805-9E6F-404A-BC0D-A2C25DDA2EDC} = {16439374-B8DB-4643-8116-EB3358B49A12} + {F9117397-E105-44DD-A9BD-F6F8DC641095} = {16439374-B8DB-4643-8116-EB3358B49A12} EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution Policies = $0 diff --git a/vke/netfx.props b/vke/netfx.props deleted file mode 120000 index 728e74b..0000000 --- a/vke/netfx.props +++ /dev/null @@ -1 +0,0 @@ -../netfx.props \ No newline at end of file diff --git a/vke/src/VkWindow.cs b/vke/src/VkWindow.cs index fab1325..ecb6ac2 100644 --- a/vke/src/VkWindow.cs +++ b/vke/src/VkWindow.cs @@ -16,15 +16,19 @@ namespace vke { /// Provide default swapchain with its command pool and buffers per image and the main present queue /// public abstract class VkWindow : IDisposable { - static Dictionary windows = new Dictionary(); + /** GLFW callback may return a custom pointer, this list makes the link between the GLFW window pointer and the + manage VkWindow instance. */ + static Dictionary windows = new Dictionary(); + /** GLFW window native pointer. */ IntPtr hWin; /**Vulkan Surface */ protected VkSurfaceKHR hSurf; /**vke Instance encapsulating a VkInstance. */ protected Instance instance; /**vke Physical device associated with this window*/ - protected PhysicalDevice phy; + protected PhysicalDevice phy; + /**vke logical device */ protected Device dev; protected PresentQueue presentQueue; protected SwapChain swapChain; @@ -33,14 +37,14 @@ namespace vke { protected VkSemaphore[] drawComplete; protected VkFence drawFence; - protected uint fps; + protected uint fps { get; private set; } protected bool updateViewRequested = true; - protected double lastMouseX, lastMouseY; + protected double lastMouseX { get; private set; } + protected double lastMouseY { get; private set; } protected bool[] MouseButton => buttons; - /// - /// default camera - /// + + /**Default camera initialized with a Field of view of 40° and and aspect ratio of 1. */ protected Camera camera = new Camera (Utils.DegreesToRadians (45f), 1f); bool[] buttons = new bool[10]; @@ -66,16 +70,24 @@ namespace vke { public uint Width { get; private set; } public uint Height { get; private set; } + public bool VSync { get; private set; } public string Title { set { Glfw3.SetWindowTitle (hWin, value); } } - + /// + /// Create a new vulkan enabled window with GLFW. + /// + /// Caption of the window + /// Width. + /// Height. + /// Vertical synchronisation status for creating the swapchain. public VkWindow (string name = "VkWindow", uint _width = 800, uint _height = 600, bool vSync = false) { Width = _width; Height = _height; + VSync = vSync; Glfw3.Init (); @@ -95,22 +107,39 @@ namespace vke { Glfw3.SetCharCallback (hWin, HandleCharDelegate); windows.Add (hWin, this); - - initVulkan (vSync); } - + /// + /// Set current mouse cursor in the GLFW window. + /// + /// New mouse cursor to set. public void SetCursor (CursorShape cursor) { if (currentCursor != IntPtr.Zero) Glfw3.DestroyCursor (currentCursor); currentCursor = Glfw3.CreateStandardCursor (cursor); Glfw3.SetCursor (hWin, currentCursor); } + /// + /// Ask GLFW to close the native window. + /// public void Close () { Glfw3.SetWindowShouldClose (hWin, 1); } - - void initVulkan (bool vSync) { + /// + /// Create the minimum vulkan objects to quickly start a new application. The folowing objects are created: + /// - Vulkan Instance with extensions present in the `EnabledInstanceExtensions` property. + /// - Vulkan Surface for the GLFW native window. + /// - Vulkan device for the selected physical one with configured enabledFeatures and extensions present in `EnabledDeviceExtensions` list. Selection of the default physical device + /// may be replaced by the `selectPhysicalDevice` method override. + /// - Create a default Graphic Queue with presentable support. The default queue creation may be customized by overriding the `createQueues` method. + /// - Default vulkan Swapchain creation. Some swapchain's parameters are controled through static fields of the `SwapChain` class (ex: `SwapChain.PREFERED_FORMAT`). + /// - Create a default command pool for the `presentQueue` family index. + /// - Create an empty command buffer collection (`cmds`). + /// - Create one unsignaled vulkan semaphore (named `drawComplete` per swapchain image used to control presentation submission to the graphic queue. + /// - Create a signaled vulkan fence (`drawFence`). (TODO: improve this. + /// With all these objects, vulkan application programming startup is reduced to the minimal. + /// + protected virtual void initVulkan () { List instExts = new List (Glfw3.GetRequiredInstanceExtensions ()); if (EnabledInstanceExtensions != null) instExts.AddRange (EnabledInstanceExtensions); @@ -119,14 +148,14 @@ namespace vke { hSurf = instance.CreateSurface (hWin); - phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.HasSwapChainSupport); + selectPhysicalDevice (); VkPhysicalDeviceFeatures enabledFeatures = default; configureEnabledFeatures (phy.Features, ref enabledFeatures); //First create the c# device class dev = new Device (phy); - dev.debugUtilsEnabled = instance.debugUtilsEnabled; + dev.debugUtilsEnabled = instance.debugUtilsEnabled;//store a boolean to prevent testing against the extension string presence. //create queue class createQueues (); @@ -135,7 +164,7 @@ namespace vke { dev.Activate (enabledFeatures, EnabledDeviceExtensions); swapChain = new SwapChain (presentQueue as PresentQueue, Width, Height, SwapChain.PREFERED_FORMAT, - vSync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.MailboxKHR); + VSync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.MailboxKHR); swapChain.Create (); Width = swapChain.Width; @@ -156,12 +185,19 @@ namespace vke { } /// /// Override this method to modify enabled features before device creation. Feature availability is given by the first argument. + /// By default, no features is selected. /// /// Available features for the selected vulkan physical device associated with this window /// Set boolean fileds of this structure to true to enable features. protected virtual void configureEnabledFeatures (VkPhysicalDeviceFeatures available_features, ref VkPhysicalDeviceFeatures enabled_features) { } /// + /// Override this method to select another device than the first one with a swapchain support. + /// + protected virtual void selectPhysicalDevice () { + phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.HasSwapChainSupport); + } + /// /// Override this method to create additional queue. Dedicated queue of the requested type will be selected first, created queues may excess /// available physical queues. /// @@ -279,9 +315,20 @@ namespace vke { #endregion /// - /// main window loop, exits on GLFW3 exit event + /// main window loop, exits on GLFW3 exit event. Before entering the rendering loop, the following methods are called: + /// - initVulkan (device, queues and swapchain creations). + /// - OnResize (create there your frame buffers couple to the swapchain and trigger the recording of your command buffers for the presentation. + /// - UpdateView (generaly used when the camera setup has changed to update MVP matrices) + /// The rendering loop consist of the following steps: + /// - render (the default one will submit the default command buffers to the presentQueue and trigger a queue present for each swapchain images. + /// - if the `updateViewRequested` field is set to 'true', call the `UpdateView` method. + /// - frame counting and chrono. + /// - if elapsed time reached `UpdateFrequency` value, the `Update` method is called and the elapsed time chrono is reseet. + /// - GLFW events are polled at the end of the loop. /// public virtual void Run () { + initVulkan (); + OnResize (); UpdateView (); @@ -314,20 +361,21 @@ namespace vke { } /// /// Suitable for updating the matrices, called at least once before the rendering loop just - /// after 'OnResize'. Then, triggered each time 'updateViewRequested' is true in the render loop, don't forget to + /// after 'OnResize'. Then, triggered in the render loop each time the 'updateViewRequested' field is set to 'true', don't forget to /// reset 'updateViewRequested' to 'false' or call the 'base.UpdateView()' which will reset this boolean. /// public virtual void UpdateView () { updateViewRequested = false; } /// - /// custom update method called at UpdateFrequency, base method is empty. + /// custom update method called controled by the `UpdateFrequency` field, base method is empty. /// public virtual void Update () { } /// /// Called when swapchain has been resized, override this method to resize your framebuffers coupled to the swapchain. - /// The base method will update Window 'Width' and 'Height' properties with new swapchain's dimensions. + /// The base method will update Window 'Width' and 'Height' properties with new swapchain's dimensions. This method is guarantied to + /// be called once just after `initVulkan` and before the first render. /// protected virtual void OnResize () { Width = swapChain.Width; diff --git a/vke/src/base/Activable.cs b/vke/src/base/Activable.cs index 6e60f8d..5fc2a99 100644 --- a/vke/src/base/Activable.cs +++ b/vke/src/base/Activable.cs @@ -8,7 +8,7 @@ using static Vulkan.Vk; namespace vke { /// - /// Tristate status of activables, reflecting vulkan openrations + /// Tristate status of activables, reflecting vulkan operations /// public enum ActivableState { /// @@ -38,10 +38,10 @@ namespace vke { [XmlIgnore] protected uint references; //keep track of the current state of activation. protected ActivableState state; - //With the debug marker extension, setting name to vulkan's object ease the debugging. + //With the debug utils extension, setting name to vulkan's object ease the debugging. protected string name; /// - /// This property has to be implemented in every vulkan object. It should return the correct debug marker info. + /// This property has to be implemented in every vulkan object. It must return the correct debug marker info. /// /// The debug marker info. protected abstract VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo { get; } diff --git a/vke/src/base/Instance.cs b/vke/src/base/Instance.cs index beb415a..b4fdc70 100644 --- a/vke/src/base/Instance.cs +++ b/vke/src/base/Instance.cs @@ -91,7 +91,7 @@ namespace vke { Vk.LoadInstanceFunctionPointers (inst); } } - + public string[] SupportedExtensions () => SupportedExtensions (IntPtr.Zero); public string[] SupportedExtensions (IntPtr layer) { Utils.CheckResult (vkEnumerateInstanceExtensionProperties (layer, out uint count, IntPtr.Zero)); -- 2.47.3