]> O.S.I.I.S - jp/vke.net.git/commitdiff
Fence as activable + Fence collection, split glfw bindings in glfw-sharp external...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 2 Feb 2020 16:17:42 +0000 (17:17 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 2 Feb 2020 16:17:42 +0000 (17:17 +0100)
50 files changed:
README.md
addons/DistanceFieldFont/DistanceFieldFont.csproj
addons/EnvironmentPipeline/EnvironmentPipeline.csproj
addons/VkvgPipeline/VkvgPipeline.csproj
addons/gltfLoader/gltfLoader.csproj
samples/ClearScreen/ClearScreen.csproj [new file with mode: 0644]
samples/ClearScreen/README.md [new file with mode: 0644]
samples/ClearScreen/main.cs [new file with mode: 0644]
samples/Textured/README.md [new file with mode: 0644]
samples/Textured/Textured.csproj
samples/Textured/main.cs
samples/Triangle/README.md
samples/Triangle/main.cs
samples/Triangle/shaders/main.vert
samples/screenShots/ClearScreen.png [new file with mode: 0644]
samples/screenShots/Textured.png [new file with mode: 0644]
samples/screenShots/Triangle.png [new file with mode: 0644]
vke.net.sln
vke/src/VkWindow.cs
vke/src/base/Activable.cs
vke/src/base/Buffer.cs
vke/src/base/CommandBuffer.cs
vke/src/base/DescriptorPool.cs
vke/src/base/DescriptorSet.cs
vke/src/base/Device.cs
vke/src/base/Fence.cs [new file with mode: 0644]
vke/src/base/FrameBuffer.cs
vke/src/base/GPUBuffer.cs
vke/src/base/GraphicPipeline.cs
vke/src/base/HostBuffer.cs
vke/src/base/Image.cs
vke/src/base/Queue.cs
vke/src/base/RenderPass.cs
vke/src/base/Resource.cs
vke/src/base/SwapChain.cs
vke/src/glfw/CodePoint.cs [deleted file]
vke/src/glfw/Delegates.cs [deleted file]
vke/src/glfw/ErrorCode.cs [deleted file]
vke/src/glfw/Glfw3.cs [deleted file]
vke/src/glfw/InputAction.cs [deleted file]
vke/src/glfw/Key.cs [deleted file]
vke/src/glfw/Modifier.cs [deleted file]
vke/src/glfw/MonitorEvent.cs [deleted file]
vke/src/glfw/MonitorHandle.cs [deleted file]
vke/src/glfw/MouseButton.cs [deleted file]
vke/src/glfw/NativeString.cs [deleted file]
vke/src/glfw/VideoMode.cs [deleted file]
vke/src/glfw/VideoModePointer.cs [deleted file]
vke/src/glfw/WindowAttribute.cs [deleted file]
vke/vke.csproj

index f214c62f2867ec41dfaf82c01e13b41211c22867..aad23150b7b858d4188a1d6033dad63307d4f507 100644 (file)
--- a/README.md
+++ b/README.md
@@ -24,9 +24,9 @@
    <br>adaptation of the gltf PBR sample from Sacha Willems</br>
 </p>
 
-**vke.net** (_vulkan engine for .net_) is composed of high level classes encapsulating [vulkan]() objects with `IDispose` model and **reference counting**. [GLFW](https://www.glfw.org/)  handles the windowing system.
-
+**vke.net** (_vulkan engine for .net_) is composed of high level classes encapsulating [vulkan]() objects and commands with `IDispose` model and **reference counting**. [GLFW](https://www.glfw.org/)  handles the windowing system.
 
+Vke use autogenerated [vk.net](https://github.com/jpbruyere/vk.net) library for low level binding to vulkan.
 
 Use the 'download_datas.sh' script for downloading sample's datas.
 
@@ -36,6 +36,39 @@ Use the 'download_datas.sh' script for downloading sample's datas.
 - [Vulkan Sdk](https://www.lunarg.com/vulkan-sdk/), **glslc** has to be in the path.
 - optionaly for ui, you will need [vkvg](https://github.com/jpbruyere/vkvg).
 
+### Quick Start
+
+Create a new dotnet console project, and add the [vje nuget package](https://www.nuget.org/packages/vke) to it.
+
+```xml
+<Project Sdk="Microsoft.NET.Sdk">
+    <TargetFrameworks>net472</TargetFrameworks>
+    <OutputType>Exe</OutputType>
+    
+    <ItemGroup>
+           <PackageReference Include="vke" />
+    </ItemGroup>
+</Project>
+```
+For automatic shader compilation to SpirV, add also the [SpirVTasks nuget package](https://www.nuget.org/packages/SpirVTasks/0.1.41-beta). For documentation about this module, follow [this link](SpirVTasks/README.md).
+
+```xml
+    <ItemGroup>    
+               <PackageReference Include="SpirVTasks" />
+        <GLSLShader Include="shaders\*.*" />           
+    </ItemGroup>
+
+```
+### Samples
+
+|                Title                 |                    Screen shots                    |
+| :----------------------------------: | :------------------------------------------------: |
+| [ClearScreen](ClearScreen/README.md) | ![screenshot](samples/screenShots/ClearScreen.png) |
+|    [Triangle](Triangle/README.md)    |  ![screenshot](samples/screenShots/Triangle.png)   |
+|    [Textured](Textured/README.md)    |  ![screenshot](samples/screenShots/Textured.png)   |
+
+
+
 ### Features
 
 - physicaly based rendering, direct and deferred
index 93faa2745fb6cc028b269dc3d53ddf0870382360..357c696d9e12383c154ecef4b321ab1c1a1c030f 100644 (file)
@@ -3,10 +3,10 @@
   <PropertyGroup>
     <AssemblyName>DistanceFieldFont</AssemblyName>
     <PackageId>vke.DistanceFieldFont</PackageId>
-    <AssemblyVersion>0.1.0</AssemblyVersion>
+    <AssemblyVersion>$(VkeReleaseVersion)</AssemblyVersion>
     <Description>vke.net signed distance field font addons, BMFont file format</Description>
     <PackageTags>vulkan C# vke.net gltf</PackageTags>    
-    <PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
+    <PackageVersion>$(VkePackageVersion)</PackageVersion>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
     <PackageProjectUrl>https://github.com/jpbruyere/vke.net/blob/master/README.md</PackageProjectUrl>
index 1344f296b62d204a307591c8e2e7ef6b9de90cd4..c93c847b863282a4890d480d40bb58cb310096b8 100644 (file)
@@ -3,10 +3,10 @@
   <PropertyGroup>
     <AssemblyName>EnvironmentPipeline</AssemblyName>
     <PackageId>vke.EnvironmentPipeline</PackageId>
-    <AssemblyVersion>0.1.2</AssemblyVersion>
+    <AssemblyVersion>$(VkeReleaseVersion)</AssemblyVersion>
     <Description>vke.net Environment cube pipeline</Description>
     <PackageTags>vulkan c# vke.net</PackageTags>    
-    <PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
+    <PackageVersion>$(VkePackageVersion)</PackageVersion>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
     <PackageProjectUrl>https://github.com/jpbruyere/vke.net/blob/master/README.md</PackageProjectUrl>
index 16c1daa39fcb367964f3a9c71184212654f5227e..d010f020765096305bc51b6fc4e538019f30d564 100644 (file)
@@ -3,10 +3,10 @@
   <PropertyGroup>
     <AssemblyName>vke.vkvgPipeline</AssemblyName>
     <PackageId>vke.vkvgPipeline</PackageId>
-    <AssemblyVersion>0.1.0</AssemblyVersion>
+    <AssemblyVersion>$(VkeReleaseVersion)</AssemblyVersion>
     <Description>CVKL vkvg addons, vectorial drawing with cairo like api.</Description>
     <PackageTags>vulkan c# vke.net gltf</PackageTags>    
-    <PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
+    <PackageVersion>$(AssemblyVersion)</PackageVersion>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
     <PackageProjectUrl>https://github.com/jpbruyere/vk.net/blob/master/README.md</PackageProjectUrl>
index a9474c46e0d42bbc5fc00c3161d14f7a4823f7a3..b7940e5ebfae1855f85c34ac9a1cc4dbe91bbcbe 100644 (file)
@@ -3,10 +3,10 @@
   <PropertyGroup>
     <AssemblyName>vke.gltfLoader</AssemblyName>
     <PackageId>vke.gltfLoader</PackageId>
-    <AssemblyVersion>0.1.8</AssemblyVersion>
+    <AssemblyVersion>$(VkeReleaseVersion)</AssemblyVersion>
     <Description>vke.net gltf addons</Description>
     <PackageTags>C# vulkan CVKL gltf</PackageTags>    
-    <PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
+    <PackageVersion>$(AssemblyVersion)</PackageVersion>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
     <PackageProjectUrl>https://github.com/jpbruyere/vke.net/blob/master/README.md</PackageProjectUrl>
diff --git a/samples/ClearScreen/ClearScreen.csproj b/samples/ClearScreen/ClearScreen.csproj
new file mode 100644 (file)
index 0000000..3cf0386
--- /dev/null
@@ -0,0 +1,5 @@
+<Project Sdk="Microsoft.NET.Sdk">  
+  <PropertyGroup>              
+    <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems>
+  </PropertyGroup>  
+</Project>
diff --git a/samples/ClearScreen/README.md b/samples/ClearScreen/README.md
new file mode 100644 (file)
index 0000000..dc9f101
--- /dev/null
@@ -0,0 +1,91 @@
+### The Project File.
+
+To build a minimal vulkan application, add the [vke](https://www.nuget.org/packages/vke/) nuget package, and to enable automatic shader compilation, add the [SpirVTasks](https://www.nuget.org/packages/SpirVTasks/) package and a generic **GLSLShader** item globing a full directory.
+
+```xml
+<Project Sdk="Microsoft.NET.Sdk">
+    <TargetFrameworks>net472</TargetFrameworks>
+    <OutputType>Exe</OutputType>
+    <ItemGroup>    
+        <GLSLShader Include="shaders\*.*" />           
+    </ItemGroup>
+    <ItemGroup>
+        <PackageReference Include="SpirVTasks" />
+        <PackageReference Include="vke" />
+    </ItemGroup>
+</Project>
+
+```
+
+### VkWindow class
+
+**vke** use [GLFW](https://www.glfw.org/) to interface with the windowing system of the OS. Derive your application from the `VkWindow` base class to start with a vulkan enabled window. **Validation** and **RenderDoc** layers loading may be control at startup with public static boolean properties from the `Instance`class.
+
+```csharp
+class Program : VkWindow {
+       static void Main (string[] args) {
+               using (Program vke = new Program ()) {
+                       vke.Run ();
+               }
+       }
+}
+```
+
+### Vulkan Initialization
+
+`init_vulkan` is the first method called by the 'Run' method. Default initialization will provide a vulkan window, a default swap chain bound to it, and a draw and present semaphore to sync the rendering.
+```csharp
+protected override void initVulkan () {
+    base.initVulkan ();
+```
+There are several method to clear the screen with vulkan. One is to use the renderpass CLEAR load operation so that attachment layout transitioning is handled automatically by the render pass.
+```csharp
+    renderPass = new RenderPass (dev, swapChain.ColorFormat);
+    renderPass.ClearValues[0] = new VkClearValue (0.1f, 0.2f, 1);
+    renderPass.Activate ();
+    
+    cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+}
+```
+
+Note that because we only reset the command buffers when rebuilding these, we need to preallocate them during the initialization.
+
+### Frame buffer creation
+
+The resize method is called at least once before any rendering, so it's a safe place to initialize output size related vulkan objects like the frame buffers. vke provide a FrameBuffer collection object to ease handling of multiple related buffers like those used for a swap chain for example..
+```csharp
+FrameBuffers frameBuffers;
+
+protected override void OnResize () {
+       base.OnResize ();
+
+       frameBuffers?.Dispose();
+       frameBuffers = renderPass.CreateFrameBuffers(swapChain);
+       
+       buildCommandBuffers ();
+}
+```
+It's common to rebuild the command buffers targeting the swap chain images after a resize so that the drawing is scaled. So it's a good idea to build/rebuild your commands here.
+
+
+
+### The command buffers
+
+The `VkWindow` class has a default array of command buffers, one for each swap chain image. But it's up to you to allocate and populate them. 
+Here we simply record a begin/end render pass to clear the screen with the load operation of it.
+
+```csharp
+void buildCommandBuffers() {
+       cmdPool.Reset (VkCommandPoolResetFlags.ReleaseResources);
+
+       for (int i = 0; i < swapChain.ImageCount; ++i) {
+               cmds[i].Start ();
+
+               renderPass.Begin (cmds[i], frameBuffers[i]);
+
+               renderPass.End (cmds[i]);
+
+               cmds[i].End ();
+       }
+}
+```
diff --git a/samples/ClearScreen/main.cs b/samples/ClearScreen/main.cs
new file mode 100644 (file)
index 0000000..3e11384
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using vke;
+using Vulkan;
+
+//Most simple example of the `VkWindow` class usage to output something on screen.
+namespace ClearScreen {
+       class Program : VkWindow {
+               //excutable entry point
+               static void Main (string[] args) {
+                       //the base constructor will create the window with GLFW
+                       using (Program vke = new Program ()) {
+                               vke.Run ();
+                       }
+               }
+
+               //frame buffer collection to handle on fb per swapchain image.
+               FrameBuffers frameBuffers;
+               RenderPass renderPass;
+
+               //Vulkan initialization is the first method called by the 'Run' method.
+               //Default initialization will provide a vulkan window, a default swapchain
+               //bound to it, and a draw and present semaphore to sync the rendering.
+               protected override void initVulkan () {
+                       base.initVulkan ();
+
+                       //there are several method to clear the screen with vulkan. One is to
+                       //use the renderpass CLEAR load operation so that attachment layout transitioning
+                       //is handled automatically by the render pass.
+                       renderPass = new RenderPass (dev, swapChain.ColorFormat);
+                       //default clear values are automatically added for each attacments
+                       renderPass.ClearValues[0] = new VkClearValue (0.1f, 0.2f, 1);
+                       //bound to a pipeline, renderpasses are automatically activated, here we use
+                       //a stand alone renderpass just to clear the screen, so we have to
+                       //activate it manually
+                       renderPass.Activate ();
+
+                       //allocate default cmd buffers of the VkWindow class.
+                       cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+               }
+
+               void buildCommandBuffers() {
+                       cmdPool.Reset ();
+
+                       for (int i = 0; i < swapChain.ImageCount; ++i) {
+                               FrameBuffer fb = frameBuffers[i];
+                               cmds[i].Start ();
+
+                               renderPass.Begin (cmds[i], fb);
+                               renderPass.End (cmds[i]);
+
+                               cmds[i].End ();
+                       }
+               }
+
+               //The resize method is called at least once before any rendering, so it's
+               //a safe place to initialize output size related vulkan objects like the 
+               //frame buffers.
+               protected override void OnResize () {
+                       base.OnResize ();
+
+                       frameBuffers?.Dispose();
+                       frameBuffers = renderPass.CreateFrameBuffers(swapChain);
+
+                       buildCommandBuffers ();
+               }
+               //clean up
+               protected override void Dispose (bool disposing) {              
+                       dev.WaitIdle ();
+
+                       renderPass.Dispose ();
+                       frameBuffers?.Dispose();
+
+                       base.Dispose (disposing);
+               }
+       }
+}
diff --git a/samples/Textured/README.md b/samples/Textured/README.md
new file mode 100644 (file)
index 0000000..331e752
--- /dev/null
@@ -0,0 +1,25 @@
+### Enabling extensions
+
+The `VkWindow` class provides two properties that you may override to enable additional extensions.
+
+### Enabling features
+
+Override the `configureEnabledFeatures` method of `VkWindow` to enable features.
+```csharp
+protected override void configureEnabledFeatures (
+             VkPhysicalDeviceFeatures available_features,
+             ref VkPhysicalDeviceFeatures enabled_features) 
+{    
+       enabled_features.samplerAnisotropy = available_features.samplerAnisotropy;
+}
+```
+### Creating queues
+
+To create queues, override the `createQueues` method of `VkWindow`. This function is called before the logical device creation and will take care of physically available queues, creating duplicates if count exceed availability. The `base` method will create a default presentable queue.
+
+```csharp
+protected override void createQueues () {
+       base.createQueues ();
+       transferQ = new Queue (dev, VkQueueFlags.Transfer);
+}
+```
\ No newline at end of file
index bd178d8f7d7a215723d442637568ad8a01bf968d..35e3d8428b7cfcc172d63391c605ca228f0e4703 100644 (file)
@@ -1,6 +1,2 @@
 <Project Sdk="Microsoft.NET.Sdk">
-  <ItemGroup>
-    <PackageReference Include="glTF2Loader" Version="1.1.3-alpha" />
-  </ItemGroup>        
-  
 </Project>
index fb671bb4aa3a2c8097e5d6b7c8e675d46e6c7ad3..78da38764c9a6398dc42287c28cdf6afacfa6daf 100644 (file)
@@ -13,7 +13,6 @@ namespace Textured {
                static void Main (string[] args) {
 #if DEBUG
                        Instance.VALIDATION = true;
-                       Instance.RENDER_DOC_CAPTURE = true;
 #endif
                        using (Program vke = new Program ()) {
                                vke.Run ();
@@ -234,9 +233,10 @@ namespace Textured {
                }       
 
                protected override void Dispose (bool disposing) {
+                       dev.WaitIdle ();
+
                        if (disposing) {
                                if (!isDisposed) {
-                                       dev.WaitIdle ();
                                        pipeline.Dispose ();
                                        dsLayout.Dispose ();
                                        frameBuffers.Dispose();
index 07c2895e017200b966b0c99535f97e04063d1a89..436391f6bb30606ad77e309a8280a3b39c860374 100644 (file)
@@ -1,92 +1,60 @@
-### The Project File.
+### Creating buffers
 
-To build a minimal vulkan application, add the [vke](https://www.nuget.org/packages/vke/) nuget package, and to enable automatic shader compilation, add the [SpirVTasks](https://www.nuget.org/packages/SpirVTasks/) package and a generic **GLSLShader** item globing a full directory.
-
-```xml
-<Project Sdk="Microsoft.NET.Sdk">
-    <TargetFrameworks>net472</TargetFrameworks>
-    <OutputType>Exe</OutputType>
-    <ItemGroup>    
-        <GLSLShader Include="shaders\*.*" />           
-    </ItemGroup>
-    <ItemGroup>
-        <PackageReference Include="SpirVTasks" />
-        <PackageReference Include="vke" />
-    </ItemGroup>
-</Project>
+Vke has two classes to handle buffers. Mappable [`HostBuffer`](../../wiki/api/HostBuffer) and device only [`GPUBuffer`](../../wiki/api/GPUBuffer). 
+For this first simple example, we will only use host mappable buffers. Those classes can handle a Generic argument of a blittable type to handle arrays. Resources like buffers or images are automatically activated, so they need to be explicitly disposed on cleanup. Create them in the `initVulkan` override.
 
+```csharp
+       //the vertex buffer
+       vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
+       //the index buffer
+       ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);    
+       //a permanantly mapped buffer for the mvp matrice
+       uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true);
 ```
 
-### VkWindow class
-
-**vke** use [GLFW](https://www.glfw.org/) to interface with the windowing system of the OS. Derive your application from the `VkWindow` base class to start with a vulkan enabled window. **Validation** and **RenderDoc** layers loading may be control at startup with public static boolean properties from the `Instance`class.
-
+To be able to access the mvp matrix in a shader, we need a descriptor. This implies to create a descriptor  pool to allocate it from and configure the triangle pipeline layout with a corresponding descriptor layout for our matrix.
 ```csharp
-class Program : VkWindow {
-       static void Main (string[] args) {
-               Instance.VALIDATION = true;             
-               using (Program vke = new Program ()) {
-                       vke.Run ();
-               }
-       }
-}
+       descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
 ```
-### Vulkan Initialization
-
-Default vulkan initialization of the VkWindow class will provide the minimal for running and present simple command buffers. For further initialization steps, override the `init_vulkan`method.
-
+Graphic pipeline configuration are predefined by the [`GraphicPipelineConfig`](../../wiki/api/GraphicPipelineConfig) class, which ease sharing configs for several pipelines having lots in common. The pipeline layout will be automatically activated on pipeline creation, so that sharing layout among different pipelines will benefit from the reference counting to automatically dispose unused layout on pipeline clean up. It's the same for [`DescriptorSetLayout`](../../wiki/api/DescriptorSetLayout).
 ```csharp
-protected override void initVulkan () {
-   base.initVulkan ();
-   vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
-   ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
-   uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices);   
-   ...
+GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (
+      VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false);
+      
+cfg.Layout = new PipelineLayout (dev,
+  new DescriptorSetLayout (dev,
+     new VkDescriptorSetLayoutBinding (
+       0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
 ```
-### Enabling extensions
-
-The `VkWindow` class provides two properties that you may override to enable additional extensions. The `Ext` static class of the vulkan package provides up to date lists of existing vulkan extensions for convenience.
-
+Next we configure a default [`RenderPass`](../../wiki/api/RenderPass) with just a color attachment for the swap chain image, a default sub-pass is automatically created and the render pass activation will follow the pipeline life cycle and will be automatically disposed when no longer in use.
 ```csharp
-public virtual string[] EnabledInstanceExtensions => null;
-public virtual string[] EnabledDeviceExtensions =>
-    new string[] { Ext.D.VK_KHR_swapchain };
+       cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
 ```
-
-### Enabling features
-
-Override the `configureEnabledFeatures` method of `VkWindow` to enable features. Available features queried from the selected physical device are provided as argument.
+Configuration of vertex bindings and attributes
 ```csharp
-protected override void configureEnabledFeatures (
-    VkPhysicalDeviceFeatures available_features,
-    ref VkPhysicalDeviceFeatures enabled_features) {
-    
-       enabled_features.samplerAnisotropy = available_features.samplerAnisotropy;    
-}
+       cfg.AddVertexBinding<Vertex> (0);
+       cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat,   //position
+                                   VkFormat.R32g32b32Sfloat);//color
 ```
-### Creating queues
-
-To create queues, override the `createQueues` method of `VkWindow`. This function is called before the logical device creation and will take care of physically available queues, creating duplicates if count exceed availability. The `base` method will create a default presentable queue.
-
+shader are automatically compiled by [`SpirVTacks`](../../SpirVTasks/README.md) if added to the project. The resulting shaders are automatically embedded in the assembly. To specifiy that the shader path is a resource name, put the **'#'** prefix. Else the path will be search on disk.
 ```csharp
-protected override void createQueues () {
-       base.createQueues ();
-       transferQ = new Queue (dev, VkQueueFlags.Transfer);
-}
+       cfg.AddShader (VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
+       cfg.AddShader (VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");
 ```
-### Rendering
-
-VkWindow will provide the default swapchain, but it's up to you to create the frame buffers. For the triangle example, create them in the `OnResize` override. The `RenderPass` class has the ability to create a framebuffer collection for a given swapchain. The `OnResize` method is guarantied to be called once before entering the rendering loop, so that it is a safe place to call the building of your command buffers.
+Once the pipeline configuration is complete, we use it to effectively create and activate a graphic pipeline. Activables used by the pipeline (like the RenderPass, or the PipelineLayout) are referenced in the newly created managed pipeline. So the Configuration object doesn't need cleanup.
 ```csharp
-FrameBuffers frameBuffers;
-
-protected override void OnResize () {
-       base.OnResize ();
-
-       frameBuffers?.Dispose();
-       frameBuffers = pipeline.RenderPass.CreateFrameBuffers(swapChain);
-
-    buildCommandBuffers ();
-}
+       pipeline = new GraphicPipeline (cfg);
+```
+Because descriptor layouts used for a pipeline are only activated on pipeline activation, descriptor sets must not be allocated before, except if the layout has been manually activated, but in this case, layouts will also need to be explicitly disposed.
+```csharp
+       descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
 ```
+The descriptor update is a two step operation. First we create a [`DescriptorSetWrites`](../../wiki/api/DescriptorSetWrites) object defining the layout(s), than we write the descriptor(s).
+The `Descriptor` property of the mvp HostBuffer will return a default descriptor with no offset of the full size of the buffer.
 
+```csharp
+       DescriptorSetWrites uboUpdate =
+         new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
+         
+       uboUpdate.Write (dev, uboMats.Descriptor);
+```
index e9b19961bdd9fb688938d36721060cf538ca0435..70d771c932e124f664b896499a8bd2ebb1831b8f 100644 (file)
@@ -1,14 +1,12 @@
 // Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.IO;
 using System.Numerics;
 using System.Runtime.InteropServices;
-using System.Xml.Serialization;
 using vke;
 using Vulkan;
 
+//the traditional triangle sample
 namespace Triangle {
        class Program : VkWindow {
                static void Main (string[] args) {
@@ -18,15 +16,9 @@ namespace Triangle {
                }
 
                const float rotSpeed = 0.01f, zoomSpeed = 0.01f;
-               float rotX, rotY, rotZ = 0f, zoom = 1f;
-
-               [StructLayout (LayoutKind.Sequential)]
-               struct Matrices {
-                       public Matrix4x4 projection;
-                       public Matrix4x4 view;
-                       public Matrix4x4 model;
-               }
+               float rotX, rotY, zoom = 1f;
 
+               //vertex structure
                [StructLayout(LayoutKind.Sequential)]
                struct Vertex {
                        Vector3 position;
@@ -38,18 +30,19 @@ namespace Triangle {
                        }
                }
 
-               Matrices matrices;
+               Matrix4x4 mvp;      //the model view projection matrix
 
-               HostBuffer ibo;
-               HostBuffer vbo;
-               HostBuffer uboMats;
+               HostBuffer ibo;     //a host mappable buffer to hold the indices.
+               HostBuffer vbo;     //a host mappable buffer to hold vertices.
+               HostBuffer uboMats; //a host mappable buffer for mvp matrice.
 
                DescriptorPool descriptorPool;
-               DescriptorSet descriptorSet;
+               DescriptorSet descriptorSet;//descriptor set for the mvp matrice.
 
-               FrameBuffers frameBuffers;
-               GraphicPipeline pipeline;
+               FrameBuffers frameBuffers;      //the frame buffer collection coupled to the swapchain images
+               GraphicPipeline pipeline;   //the triangle rendering pipeline
 
+               //triangle vertices (position + color per vertex) and indices.
                Vertex[] vertices = {
                        new Vertex (-1.0f, -1.0f, 0.0f ,  1.0f, 0.0f, 0.0f),
                        new Vertex ( 1.0f, -1.0f, 0.0f ,  0.0f, 1.0f, 0.0f),
@@ -57,57 +50,63 @@ namespace Triangle {
                };
                ushort[] indices = new ushort[] { 0, 1, 2 };
 
-               Program () : base () {}
-
                protected override void initVulkan () {
                        base.initVulkan ();
 
+                       //first create the needed buffers
                        vbo = new HostBuffer<Vertex> (dev, VkBufferUsageFlags.VertexBuffer, vertices);
                        ibo = new HostBuffer<ushort> (dev, VkBufferUsageFlags.IndexBuffer, indices);
-                       uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, matrices);
+                       //because mvp matrice may be updated by mouse move, we keep it mapped after creation.
+                       uboMats = new HostBuffer (dev, VkBufferUsageFlags.UniformBuffer, mvp, true);
 
+                       //a descriptor pool to allocate the mvp matrice descriptor from.
                        descriptorPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.UniformBuffer));
 
+                       //Graphic pipeline configuration are predefined by the GraphicPipelineConfig class, which ease sharing config for several pipelines having lots in common.
                        GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false);
-
+                       //Create the pipeline layout, it will be automatically activated on pipeline creation, so that sharing layout among different pipelines will benefit
+                       //from the reference counting to automatically dispose unused layout on pipeline clean up. It's the same for DescriptorSetLayout.
                        cfg.Layout = new PipelineLayout (dev,
-                               new DescriptorSetLayout (dev,
-                                       new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer)));
-
+                               new DescriptorSetLayout (dev, new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer)));
+                       //create a default renderpass with just a color attachment for the swapchain image, a default subpass is automatically created and the renderpass activation
+                       //will follow the pipeline life cicle and will be automatically disposed when no longuer used.
                        cfg.RenderPass = new RenderPass (dev, swapChain.ColorFormat, cfg.Samples);
+                       //configuration of vertex bindings and attributes
                        cfg.AddVertexBinding<Vertex> (0);
-                       cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);
+                       cfg.AddVertexAttributes (0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat);//position + color
 
+                       //shader are automatically compiled by SpirVTacks if added to the project. The resulting shaders are automatically embedded in the assembly.
+                       //To specifiy that the shader path is a resource name, put the '#' prefix. Else the path will be search on disk.
                        cfg.AddShader (VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
                        cfg.AddShader (VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");
 
+                       //create and activate the pipeline with the configuration we've just done.
                        pipeline = new GraphicPipeline (cfg);
 
-                       //note that descriptor set is allocated after the pipeline creation that use this layout, layout is activated
-                       //automaticaly on pipeline creation, and will be disposed automatically when no longuer in use.
+                       //because descriptor layout used for a pipeline are only activated on pipeline activation, descriptor set must not be allocated before, except if the layout has been manually activated, 
+                       //but in this case, layout will need also to be explicitly disposed.
                        descriptorSet = descriptorPool.Allocate (pipeline.Layout.DescriptorSetLayouts[0]);
 
+                       //Write the content of the descriptor, the mvp matrice.
                        DescriptorSetWrites uboUpdate = new DescriptorSetWrites (descriptorSet, pipeline.Layout.DescriptorSetLayouts[0]);
+                       //Descriptor property of the mvp buffer will return a default descriptor with no offset of the full size of the buffer.
                        uboUpdate.Write (dev, uboMats.Descriptor);
 
-                       uboMats.Map ();
-
+                       //allocate the default VkWindow buffers, one per swapchain image. Their will be only reset when rebuilding and not reallocated.
                        cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
                }
 
+               //view update override, see base method for more informations.
                public override void UpdateView () {
-                       matrices.projection = Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f),
-                               (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
-                       matrices.view = 
-                               Matrix4x4.CreateFromAxisAngle (Vector3.UnitZ, rotZ) *
+                       mvp =
                                Matrix4x4.CreateFromAxisAngle (Vector3.UnitY, rotY) *
                                Matrix4x4.CreateFromAxisAngle (Vector3.UnitX, rotX) *
-                               Matrix4x4.CreateTranslation (0, 0, -3f * zoom);
-                       matrices.model = Matrix4x4.Identity;
-                       uboMats.Update (matrices, (uint)Marshal.SizeOf<Matrices> ());
-                       updateViewRequested = false;
-               }
+                               Matrix4x4.CreateTranslation (0, 0, -3f * zoom) *
+                               Utils.CreatePerspectiveFieldOfView (Utils.DegreesToRadians (45f), (float)swapChain.Width / (float)swapChain.Height, 0.1f, 256.0f);
 
+                       uboMats.Update (mvp, (uint)Marshal.SizeOf<Matrix4x4> ());
+                       base.UpdateView ();
+               }
                protected override void onMouseMove (double xPos, double yPos) {
                        double diffX = lastMouseX - xPos;
                        double diffY = lastMouseY - yPos;
@@ -118,6 +117,8 @@ namespace Triangle {
                                zoom += zoomSpeed * (float)diffY;
                        } else
                                return;
+                       //VkWindow has a boolean for requesting a call to 'UpdateView', it will be
+                       //reset by the 'UpdateView' base method or the custom override.
                        updateViewRequested = true;
                }
 
@@ -156,15 +157,18 @@ namespace Triangle {
 
                        buildCommandBuffers ();
                }
-
+               //clean up
                protected override void Dispose (bool disposing) {              
                        dev.WaitIdle ();
                        if (disposing) {
                                if (!isDisposed) {
+                                       //pipeline clean up will dispose PipelineLayout, DescriptorSet layouts and render pass automatically. If their reference count is zero, their handles will be destroyed.
                                        pipeline.Dispose ();
-
+                                       //frame buffers are automatically activated on creation as for resources, so it requests an explicit call to dispose.
                                        frameBuffers?.Dispose();
+                                       //the descriptor pool
                                        descriptorPool.Dispose ();
+                                       //resources have to be explicityly disposed.
                                        vbo.Dispose ();
                                        ibo.Dispose ();
                                        uboMats.Dispose ();
index 542d015af29a64ff1167cc9b81dc8375a910249c..0997ca9a68fbde500ac5d2f5c953260f0ea44876 100644 (file)
@@ -8,10 +8,8 @@ layout (location = 1) in vec3 inColor;
 
 layout (binding = 0) uniform UBO 
 {
-       mat4 projectionMatrix;
-    mat4 viewMatrix;
-       mat4 modelMatrix;
-} ubo;
+       mat4 mvp;
+};
 
 layout (location = 0) out vec3 outColor;
 
@@ -24,7 +22,5 @@ out gl_PerVertex
 void main() 
 {
        outColor = inColor;
-       gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0);
-       //gl_Position.y = -gl_Position.y;
-       //gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
+       gl_Position = mvp * vec4(inPos.xyz, 1.0);
 }
diff --git a/samples/screenShots/ClearScreen.png b/samples/screenShots/ClearScreen.png
new file mode 100644 (file)
index 0000000..c80d070
Binary files /dev/null and b/samples/screenShots/ClearScreen.png differ
diff --git a/samples/screenShots/Textured.png b/samples/screenShots/Textured.png
new file mode 100644 (file)
index 0000000..871f353
Binary files /dev/null and b/samples/screenShots/Textured.png differ
diff --git a/samples/screenShots/Triangle.png b/samples/screenShots/Triangle.png
new file mode 100644 (file)
index 0000000..0340b56
Binary files /dev/null and b/samples/screenShots/Triangle.png differ
index 1ce579ea48ac2dc3b1c0511990d85b412a7a2591..f8baa1e7ee5d7d8126c243cbce2c55ab17e38f08 100644 (file)
@@ -8,11 +8,12 @@ EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "global", "global", "{7285454A-930F-4536-AB84-C076B44C0C80}"
        ProjectSection(SolutionItems) = preProject
                Directory.Build.props = Directory.Build.props
+               README.md = README.md
        EndProjectSection
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "addons", "addons", "{4AA67AB0-C331-4CB2-9C00-B74F5DE31658}"
        ProjectSection(SolutionItems) = preProject
-               addons/Directory.Build.props = "Directory.Build.props"
+               addons\Directory.Build.props = addons\Directory.Build.props
        EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvironmentPipeline", "addons\EnvironmentPipeline\EnvironmentPipeline.csproj", "{F04C3F79-2E08-4D35-A804-43039DCB7F5E}"
@@ -25,9 +26,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VkvgPipeline", "addons\Vkvg
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{16439374-B8DB-4643-8116-EB3358B49A12}"
        ProjectSection(SolutionItems) = preProject
-               samples/Directory.Build.props = "Directory.Build.props"
+               samples\Directory.Build.props = samples\Directory.Build.props
        EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClearScreen", "samples\ClearScreen\ClearScreen.csproj", "{1D2A1968-8F04-4BE0-B03A-573F1F68AB66}"
+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}"
@@ -159,6 +162,16 @@ 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
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.Release|Any CPU.Build.0 = Release|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.DebugCrow|Any CPU.ActiveCfg = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.DebugCrow|Any CPU.Build.0 = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|Any CPU.ActiveCfg = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.ReleaseSpirVTasks|Any CPU.Build.0 = Debug|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|Any CPU.ActiveCfg = Release|Any CPU
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66}.BuildPackages|Any CPU.Build.0 = Release|Any CPU
        EndGlobalSection
        GlobalSection(NestedProjects) = preSolution
                {FEF3AF30-5B88-4D3C-8BD7-8734200E0D1E} = {4AA67AB0-C331-4CB2-9C00-B74F5DE31658}
@@ -173,6 +186,7 @@ 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}
+               {1D2A1968-8F04-4BE0-B03A-573F1F68AB66} = {16439374-B8DB-4643-8116-EB3358B49A12}
        EndGlobalSection
        GlobalSection(MonoDevelopProperties) = preSolution
                Policies = $0
index e2e2fb492dee319e3690aab9c3f02127cf30f5e8..acb23eb9848c13da31ee3fc7351c51ddfa6cd831 100644 (file)
@@ -35,7 +35,7 @@ namespace vke {
                protected CommandPool cmdPool;
                protected CommandBuffer[] cmds;
                protected VkSemaphore[] drawComplete;
-               protected VkFence drawFence;
+               protected Fence drawFence;
 
                protected uint fps { get; private set; }
                protected bool updateViewRequested = true;
@@ -173,7 +173,7 @@ namespace vke {
 
                        cmds = new CommandBuffer[swapChain.ImageCount];
                        drawComplete = new VkSemaphore[swapChain.ImageCount];
-                       drawFence = dev.CreateFence (true);
+                       drawFence = new Fence (dev, true, "draw fence");
 
                        for (int i = 0; i < swapChain.ImageCount; i++) {
                                drawComplete[i] = dev.CreateSemaphore ();
@@ -218,8 +218,8 @@ namespace vke {
                        if (cmds[idx] == null)
                                return;
 
-                       dev.WaitForFence (drawFence);
-                       dev.ResetFence (drawFence);
+                       drawFence.Wait ();
+                       drawFence.Reset ();
 
                        presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence);
                        presentQueue.Present (swapChain, drawComplete[idx]);
@@ -393,8 +393,7 @@ namespace vke {
                                        dev.DestroySemaphore (drawComplete[i]);
                                        cmds[i].Free ();
                                }
-                               dev.DestroyFence (drawFence);
-
+                               drawFence.Dispose ();
                                swapChain.Dispose ();
 
                                vkDestroySurfaceKHR (instance.Handle, hSurf, IntPtr.Zero);
index 5fc2a99b4365fd0515acabc47fa8da12c836b920..2f7edf52ca56bcd80ed985470a76308e02f09e3d 100644 (file)
@@ -41,7 +41,8 @@ namespace vke {
                //With the debug utils extension, setting name to vulkan's object ease the debugging.
                protected string name;
                /// <summary>
-               /// This property has to be implemented in every vulkan object. It must return the correct debug marker info.
+               /// This property has to be implemented in every vulkan object. It must return the correct debug marker info to use
+               /// if VK_EXT_debug_utils extension is enabled.
                /// </summary>
                /// <value>The debug marker info.</value>
                protected abstract VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo { get; }
@@ -52,11 +53,11 @@ namespace vke {
 
                #region CTOR
                protected Activable (Device dev) {
-                       this.Dev = dev;
-                       this.name = GetType ().Name;
+                       Dev = dev;
+                       name = GetType ().Name;
                }
                protected Activable (Device dev, string name) {
-                       this.Dev = dev;
+                       Dev = dev;
                        this.name = name;
                }
                #endregion
@@ -76,7 +77,7 @@ namespace vke {
                        name.Unpin ();                  
                }
                /// <summary>
-               /// Activation of the object, the reference count is incremented.
+               /// Activation of the object, the reference count is incremented and if Debug utils is enabled, name is set.
                /// </summary>
                public virtual void Activate () {
                        references++;
index 9a86f14fa9f75746604079b3c8b607f7ff02fb0b..aa250041a7b71b01d58ce08b3776fd38390e1071 100644 (file)
@@ -7,33 +7,45 @@ using static Vulkan.Vk;
 
 namespace vke {
 
-    /// <summary>
-    /// Base class for HostBuffer and GPUBuffer
-    /// </summary>
-    public class Buffer : Resource {
-        internal VkBuffer handle;
+       /// <summary>
+       /// Base class for managed vulkan buffer objects
+       /// </summary>
+       public class Buffer : Resource {
+               internal VkBuffer handle;
                protected VkBufferCreateInfo createInfo = VkBufferCreateInfo.New ();
-
-               public VkDescriptorBufferInfo Descriptor;
+               /// <summary>Native handle of this vulkan buffer.</summary>
+               /// <value>The handle.</value>
                public VkBuffer Handle => handle;
                public VkBufferCreateInfo Infos => createInfo;
+               /// <summary>Buffer memory is always linear.</summary>
                public override bool IsLinar => true;
 
                protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
                                        => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Buffer, handle.Handle);
                #region CTORS
-               public Buffer (Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size)
-        : base (device, _memoryPropertyFlags) {
-
-            createInfo.size = size;
-            createInfo.usage = usage;
-            createInfo.sharingMode = VkSharingMode.Exclusive;
-
-            Activate ();//DONT OVERRIDE Activate in derived classes!!!!
-        }
+               /// <summary>
+               /// Create a vulkan buffer and automatically activate it. Automatic activation on startup implies to explicitly dispose the buffer.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">a bitmask specifying allowed usages of the buffer</param>
+               /// <param name="_memoryPropertyFlags">Memory property flags.</param>
+               /// <param name="size">Desired size in byte of the buffer to be created.</param>
+               /// <param name="sharingMode">value specifying the sharing mode of the buffer when it will be accessed by multiple queue familie</param>
+               public Buffer (Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
+               : base (device, _memoryPropertyFlags) {
+
+                       createInfo.size = size;
+                       createInfo.usage = usage;
+                       createInfo.sharingMode = VkSharingMode.Exclusive;
+
+                       Activate ();
+               }
                #endregion
 
-        public override void Activate () {
+               /// <summary>
+               /// Activate this vulkan buffer. Note that buffers are automatically activated on creation.
+               /// </summary>
+               public sealed override void Activate () {
                        if (state != ActivableState.Activated) {
                                Utils.CheckResult (vkCreateBuffer (Dev.VkDev, ref createInfo, IntPtr.Zero, out handle));
 #if MEMORY_POOLS
@@ -43,11 +55,11 @@ namespace vke {
                                allocateMemory ();
                                bindMemory ();
 #endif
-                               SetupDescriptor ();
                        }
                        base.Activate ();
-        }
+               }
 
+               #region Implement abstract members of the Resource abstract class.
                internal override void updateMemoryRequirements () {
                        vkGetBufferMemoryRequirements (Dev.VkDev, handle, out memReqs);
                }
@@ -59,49 +71,84 @@ namespace vke {
                        Utils.CheckResult (vkBindBufferMemory (Dev.VkDev, handle, vkMemory, 0));
 #endif
                }
+               #endregion
 
-               public void SetupDescriptor (ulong size = WholeSize, ulong offset = 0) {
-            Descriptor.buffer = handle;
-            Descriptor.range = size;
-            Descriptor.offset = offset;
-        }
-
-        public void CopyTo (CommandBuffer cmd, Image img, VkImageLayout finalLayout = VkImageLayout.ShaderReadOnlyOptimal) {
-            img.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal);
-
-            VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy {
-                imageExtent = img.CreateInfo.extent,
-                imageSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color)
-            };
-
-            vkCmdCopyBufferToImage (cmd.Handle, handle, img.handle, VkImageLayout.TransferDstOptimal, 1, ref bufferCopyRegion);
+               /// <summary>
+               /// Get a default buffer descriptor for the full size with no offset.
+               /// </summary>
+               /// <value>the vulkan buffer descriptor</value>
+               public VkDescriptorBufferInfo Descriptor { get => GetDescriptor (); }
+               /// <summary>
+               /// Get a buffer descriptor.
+               /// </summary>
+               /// <returns>a vulkan buffer descriptor</returns>
+               /// <param name="size">Size in byte of the buffer view</param>
+               /// <param name="offset">an offset in the buffer memory at which point this descriptor.</param>
+               public VkDescriptorBufferInfo GetDescriptor (ulong size = WholeSize, ulong offset = 0) =>
+                       new VkDescriptorBufferInfo { buffer = handle, range = size, offset = offset };
+
+               /// <summary>
+               /// Copy a vulkan buffer to an Image.
+               /// </summary>
+               /// <param name="cmd">a command buffer to handle the operation.</param>
+               /// <param name="img">The Image to copy the buffer to.</param>
+               /// <param name="finalLayout">The final layout to setup for the destination image.</param>
+               public void CopyTo (CommandBuffer cmd, Image img, VkImageLayout finalLayout = VkImageLayout.ShaderReadOnlyOptimal) {
+                       img.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal);
+
+                       VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy {
+                               imageExtent = img.CreateInfo.extent,
+                               imageSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color)
+                       };
+
+                       vkCmdCopyBufferToImage (cmd.Handle, handle, img.handle, VkImageLayout.TransferDstOptimal, 1, ref bufferCopyRegion);
 
                        img.SetLayout (cmd, VkImageAspectFlags.Color, finalLayout);
                }
-        public void CopyTo (CommandBuffer cmd, Buffer buff, ulong size = 0, ulong srcOffset = 0, ulong dstOffset = 0) {
-            VkBufferCopy bufferCopy = new VkBufferCopy {
-                size = (size == 0) ? AllocatedDeviceMemorySize : size,
-                srcOffset = srcOffset,
-                dstOffset = dstOffset
-            };
-            vkCmdCopyBuffer (cmd.Handle, handle, buff.handle, 1, ref bufferCopy);
-        }
+               /// <summary>
+               /// Copy a vulkan buffer to another buffer.
+               /// </summary>
+               /// <param name="cmd">a command buffer to handle the operation.</param>
+               /// <param name="buff">the destination buffer.</param>
+               /// <param name="size">size of the copy operation in byte.</param>
+               /// <param name="srcOffset">a source offset for the copy operation.</param>
+               /// <param name="dstOffset">an offset in the destination buffer for the copy operation.</param>
+               public void CopyTo (CommandBuffer cmd, Buffer buff, ulong size = 0, ulong srcOffset = 0, ulong dstOffset = 0) {
+                       VkBufferCopy bufferCopy = new VkBufferCopy {
+                               size = (size == 0) ? AllocatedDeviceMemorySize : size,
+                               srcOffset = srcOffset,
+                               dstOffset = dstOffset
+                       };
+                       vkCmdCopyBuffer (cmd.Handle, handle, buff.handle, 1, ref bufferCopy);
+               }
+               /// <summary>
+               /// Fill a vulkan buffer memory with an unsinged integer value.
+               /// </summary>
+               /// <param name="cmd">a command buffer to handle the operation.</param>
+               /// <param name="data">an unsigned integer to fill the buffer with.</param>
+               /// <param name="size">size in byte to fill.</param>
+               /// <param name="offset">an offset in byte in the buffer for the fill operation.</param>
                public void Fill (CommandBuffer cmd, uint data, ulong size = 0, ulong offset = 0) {
                        vkCmdFillBuffer (cmd.Handle, handle, offset, (size == 0) ? AllocatedDeviceMemorySize : size, data);
                }
 
                public override string ToString () {
-                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]");
+                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString ("x")}]");
                }
 
-#region IDisposable Support
+               #region IDisposable Support
+               /// <summary>
+               /// Destroy the native handle and set the Activable's state to `Disposed`.
+               /// </summary>
+               /// <remarks>Note that Buffers have to be always explicitly disposed on cleanup.</remarks>
+               /// <param name="disposing">If set to <c>true</c>, this object is currently disposed by the user, not the finalizer.</param>
                protected override void Dispose (bool disposing) {
                        if (state == ActivableState.Activated) {
                                base.Dispose (disposing);
                                vkDestroyBuffer (Dev.VkDev, handle, IntPtr.Zero);
                        }
                        state = ActivableState.Disposed;
-        }
-#endregion
+               }
+               #endregion
        }
 }
index 9c65dc1b27ef87566ee05161dac3db2809c1203d..ef858674c0cecc5b67bcaf3278a8ab4f7c08bd37 100644 (file)
@@ -33,8 +33,14 @@ namespace vke {
                        //State = States.Init;
         }
 
-
-        public void Submit (VkQueue queue, VkSemaphore wait = default(VkSemaphore), VkSemaphore signal = default (VkSemaphore), VkFence fence = default(VkFence)) {
+               /// <summary>
+               /// Submit an executable command buffer with optional wait and signal semaphores, and an optional fence to be signaled when the commands have been completed.
+               /// </summary>
+               /// <param name="queue">Queue.</param>
+               /// <param name="wait">Wait.</param>
+               /// <param name="signal">Signal.</param>
+               /// <param name="fence">Fence.</param>
+        public void Submit (VkQueue queue, VkSemaphore wait = default, VkSemaphore signal = default, Fence fence = null) {
             VkSubmitInfo submit_info = VkSubmitInfo.New();
 
                        IntPtr dstStageMask = Marshal.AllocHGlobal (sizeof(uint));
@@ -58,10 +64,17 @@ namespace vke {
                        }
                        Marshal.FreeHGlobal (dstStageMask);
         }
+               /// <summary>
+               /// Put the command buffer in the recording state.
+               /// </summary>
+               /// <param name="usage">optional command buffer usage flags.</param>
         public void Start (VkCommandBufferUsageFlags usage = 0) {
             VkCommandBufferBeginInfo cmdBufInfo = new VkCommandBufferBeginInfo (usage);
             Utils.CheckResult (vkBeginCommandBuffer (handle, ref cmdBufInfo));
         }
+               /// <summary>
+               /// Put the command buffer in the executable state if no errors are present in the recording.
+               /// </summary>
         public void End () {
             Utils.CheckResult (vkEndCommandBuffer (handle));
         }
index 26339f58a4bd6ce829c823be57f5693723504d05..2970257d1d5f88e8150f7c4b1df5de681cc13d00 100644 (file)
@@ -3,7 +3,6 @@
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
 using System.Collections.Generic;
-using System.Xml.Serialization;
 using Vulkan;
 using static Vulkan.Vk;
 
@@ -11,20 +10,28 @@ namespace vke {
        [Serializable]
     public sealed class DescriptorPool : Activable {        
         internal VkDescriptorPool handle;
-               [XmlAttribute]
                public uint MaxSets;
-               [XmlArrayItem("PoolSize")]
-
-               public List<VkDescriptorPoolSize> PoolSizes = new List<VkDescriptorPoolSize> ();
+               public List<VkDescriptorPoolSize> PoolSizes { get; private set; } = new List<VkDescriptorPoolSize> ();
 
                protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
                                        => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.DescriptorPool, handle.Handle);
 
                #region CTORS
                DescriptorPool () : base (null) {}
+               /// <summary>
+               /// Create a new managed descriptor pool that will be manualy activated after the pool sizes had been populated.
+               /// </summary>
+               /// <param name="device">the logical device that create the pool.</param>
+               /// <param name="maxSets">maximum number of descriptor sets that can be allocated from the pool</param>
                public DescriptorPool (Device device, uint maxSets = 1) : base (device) {            
             MaxSets = maxSets;
         }
+               /// <summary>
+               /// Create and automatically activate a new Descriptor pool with the supplied pool sizes.
+               /// </summary>
+               /// <param name="device">the logical device that create the pool.</param>
+               /// <param name="maxSets">maximum number of descriptor sets that can be allocated from the pool</param>
+               /// <param name="poolSizes">an array of pool sizes describing descriptor types and counts</param>
         public DescriptorPool (Device device, uint maxSets = 1, params VkDescriptorPoolSize[] poolSizes)
             : this (device, maxSets) {
 
@@ -34,7 +41,7 @@ namespace vke {
         }
                #endregion
 
-               public override void Activate () {
+               public sealed override void Activate () {
                        if (state != ActivableState.Activated) {            
                                VkDescriptorPoolCreateInfo info = VkDescriptorPoolCreateInfo.New();
                    info.poolSizeCount = (uint)PoolSizes.Count;
@@ -46,11 +53,12 @@ namespace vke {
                        }
                        base.Activate ();
                }
-
-        /// <summary>
-        /// Create and allocate a new DescriptorSet
-        /// </summary>
-        public DescriptorSet Allocate (params DescriptorSetLayout[] layouts) {
+               /// <summary>
+               /// Allocate a new DescriptorSet from this pool.
+               /// </summary>
+               /// <returns>A managed descriptor set.</returns>
+               /// <param name="layouts">a variable sized array of descriptor layout(s) to allocate the descriptor for.</param>
+               public DescriptorSet Allocate (params DescriptorSetLayout[] layouts) {
             DescriptorSet ds = new DescriptorSet (this, layouts);
             Allocate (ds);
             return ds;
index 80c583dd0da6025a8204d525865b42d6c9d66fd7..8df8be5d752590f54a650e0b78ccf836de9f4a9e 100644 (file)
@@ -3,7 +3,7 @@
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System.Collections.Generic;
 using Vulkan;
-
+//TODO:
 namespace vke {
        public class DescriptorSet {
         internal VkDescriptorSet handle;
index 56e38feb7eec3851639904f5d739b86951f94d3f..65aff0f02ac247e35d9925f119237d58ef11ba4b 100644 (file)
@@ -97,7 +97,10 @@ namespace vke {
                        resourceManager = new ResourceManager (this);
 #endif
                }
-
+               /// <summary>
+               /// Creates a new semaphore.
+               /// </summary>
+               /// <returns>The semaphore native handle</returns>
                public VkSemaphore CreateSemaphore () {
                        VkSemaphore tmp;
                        VkSemaphoreCreateInfo info = VkSemaphoreCreateInfo.New ();
@@ -108,38 +111,14 @@ namespace vke {
                        vkDestroySemaphore (dev, semaphore, IntPtr.Zero);
                        semaphore = 0;
                }
-               public VkFence CreateFence (bool signaled = false) {
-                       VkFence tmp;
-                       VkFenceCreateInfo info = VkFenceCreateInfo.New ();
-                       info.flags = signaled ? VkFenceCreateFlags.Signaled : 0;
-                       Utils.CheckResult (vkCreateFence (dev, ref info, IntPtr.Zero, out tmp));
-                       return tmp;
-               }
-               /// <summary>Destroy the fence.</summary>
-               /// <param name="fence">A valid fence handle.</param>
-               public void DestroyFence (VkFence fence) {
-                       vkDestroyFence (dev, fence, IntPtr.Zero);
-                       fence = 0;
-               }
-               public void WaitForFence (VkFence fence, ulong timeOut = UInt64.MaxValue) {
-                       vkWaitForFences (dev, 1, ref fence, 1, timeOut);
-               }
-               public void ResetFence (VkFence fence) {
-                       vkResetFences (dev, 1, ref fence);
-               }
-               public void WaitForFences (VkFence[] fences, ulong timeOut = UInt64.MaxValue) {
-                       vkWaitForFences (dev, (uint)fences.Length, fences.Pin(), 1, timeOut);
-                       fences.Unpin ();
-               }
-               public void ResetFences (params VkFence[] fences) {
-                       vkResetFences (dev, (uint)fences.Length, fences.Pin());
-                       fences.Unpin ();
-               }
 
                public void DestroyShaderModule (VkShaderModule module) {
                        vkDestroyShaderModule (VkDev, module, IntPtr.Zero);
                        module = 0;
                }
+               /// <summary>
+               /// Wait for this logical device to enter the idle state.
+               /// </summary>
                public void WaitIdle () {
                        Utils.CheckResult (vkDeviceWaitIdle (dev));
                }
@@ -148,27 +127,8 @@ namespace vke {
                        Utils.CheckResult (vkCreateRenderPass (dev, ref info, IntPtr.Zero, out renderPass));
                        return renderPass;
                }
-               internal VkSwapchainKHR CreateSwapChain (VkSwapchainCreateInfoKHR infos) {
-                       VkSwapchainKHR newSwapChain;
-                       Utils.CheckResult (vkCreateSwapchainKHR (dev, ref infos, IntPtr.Zero, out newSwapChain));
-                       return newSwapChain;
-               }
-               internal void DestroySwapChain (VkSwapchainKHR swapChain) {
-                       vkDestroySwapchainKHR (dev, swapChain, IntPtr.Zero);
-               }
-               unsafe public VkImage[] GetSwapChainImages (VkSwapchainKHR swapchain) {
-                       uint imageCount = 0;
-                       Utils.CheckResult (vkGetSwapchainImagesKHR (dev, swapchain, out imageCount, IntPtr.Zero));
-                       if (imageCount == 0)
-                               throw new Exception ("Swapchain image count is 0.");
-                       VkImage[] imgs = new VkImage[imageCount];
-
-                       Utils.CheckResult (vkGetSwapchainImagesKHR (dev, swapchain, out imageCount, imgs.Pin ()));
-                       imgs.Unpin ();
 
-                       return imgs;
-               }
-               unsafe public VkImageView CreateImageView (VkImage image, VkFormat format, VkImageViewType viewType = VkImageViewType.ImageView2D, VkImageAspectFlags aspectFlags = VkImageAspectFlags.Color) {
+               public VkImageView CreateImageView (VkImage image, VkFormat format, VkImageViewType viewType = VkImageViewType.ImageView2D, VkImageAspectFlags aspectFlags = VkImageAspectFlags.Color) {
                        VkImageView view;
                        VkImageViewCreateInfo infos = VkImageViewCreateInfo.New ();
                        infos.image = image;
diff --git a/vke/src/base/Fence.cs b/vke/src/base/Fence.cs
new file mode 100644 (file)
index 0000000..0eb031a
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (c) 2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Vulkan;
+using static Vulkan.Vk;
+
+namespace vke {
+       /// <summary>
+       /// Managed activable fence.
+       /// </summary>
+       public class Fence : Activable {
+               internal VkFence handle;
+               VkFenceCreateInfo info = VkFenceCreateInfo.New ();
+
+               public Fence (Device dev, bool signaled = false, string name = "fence") : base (dev, name) {
+                       info.flags = signaled ? VkFenceCreateFlags.Signaled : 0;
+                       Activate ();
+               }       
+
+               protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
+                       => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Framebuffer, handle.Handle);
+
+               public sealed override void Activate () {
+                       if (state != ActivableState.Activated) {
+                               Utils.CheckResult (vkCreateFence (Dev.VkDev, ref info, IntPtr.Zero, out handle));
+                       }
+                       base.Activate ();
+               }
+               /// <summary>
+               /// Wait this fence to become signaled.
+               /// </summary>
+               /// <param name="timeOut">Time out before cancelling the wait.</param>
+               public void Wait (ulong timeOut = UInt64.MaxValue) {
+                       vkWaitForFences (Dev.VkDev, 1, ref handle, 1, timeOut);
+               }
+               /// <summary>
+               /// put this fence in the unsignaled state.
+               /// </summary>
+               public void Reset () {
+                       vkResetFences (Dev.VkDev, 1, ref handle);
+               }
+
+               public override string ToString () {
+                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString ("x")}]");
+               }
+
+               public static implicit operator VkFence (Fence f) => f == null ? 0 : f.handle;
+
+               #region IDisposable Support
+               protected override void Dispose (bool disposing) {
+                       if (state == ActivableState.Activated)
+                               vkDestroyFence (Dev.VkDev, handle, IntPtr.Zero);
+                       if (!disposing)
+                               System.Diagnostics.Debug.WriteLine ("VKE Activable object disposed by finalizer");
+                       base.Dispose (disposing);
+               }
+               #endregion
+       }
+
+
+       public class Fences : Collection<Fence>, IDisposable {
+               public void Wait (ulong timeOut = UInt64.MaxValue) {
+                       VkFence[] fences = Items.Cast<VkFence> ().ToArray ();
+                       vkWaitForFences (Items[0].Dev.VkDev, (uint)Count, fences.Pin (), 1, timeOut);
+                       fences.Unpin ();
+               }
+               public void Reset () {
+                       VkFence[] fences = Items.Cast<VkFence> ().ToArray ();
+                       vkResetFences (Items[0].Dev.VkDev, (uint)Count, fences.Pin ());
+                       fences.Unpin ();
+               }
+
+               public void Dispose () {
+                       foreach (Fence f in Items)
+                               f.Dispose ();
+                       ClearItems ();
+               }
+       }
+}
index 94a69b95b4d834e6965e1f45ca6303d67503377f..82f214e1950df2cfac265adf2a1499466c7a1fe4 100644 (file)
@@ -10,27 +10,30 @@ using static Vulkan.Vk;
 
 namespace vke {
 
-    public class FrameBuffer : Activable {
-        internal VkFramebuffer handle;
-        RenderPass renderPass;
-        
+       /// <summary>
+       /// Managed activable for one Frame buffer
+       /// </summary>
+       public class FrameBuffer : Activable {
+               internal VkFramebuffer handle;
+               RenderPass renderPass;
+
                public List<Image> attachments = new List<Image> ();
-        VkFramebufferCreateInfo createInfo = VkFramebufferCreateInfo.New();
+               VkFramebufferCreateInfo createInfo = VkFramebufferCreateInfo.New ();
 
-        public uint Width => createInfo.width;
-        public uint Height => createInfo.height;
-        public uint Layers => createInfo.layers;
+               public uint Width => createInfo.width;
+               public uint Height => createInfo.height;
+               public uint Layers => createInfo.layers;
 
                protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
                                        => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Framebuffer, handle.Handle);
                #region CTORS
-               public FrameBuffer (RenderPass _renderPass, uint _width, uint _height, uint _layers = 1) : base(_renderPass.Dev) {
-            renderPass = _renderPass;
-            createInfo.width = _width;
-            createInfo.height = _height;
-            createInfo.layers = _layers;
-            createInfo.renderPass = renderPass.handle;
-        }
+               public FrameBuffer (RenderPass _renderPass, uint _width, uint _height, uint _layers = 1) : base (_renderPass.Dev) {
+                       renderPass = _renderPass;
+                       createInfo.width = _width;
+                       createInfo.height = _height;
+                       createInfo.layers = _layers;
+                       createInfo.renderPass = renderPass.handle;
+               }
                /// <summary>
                /// Create and Activate a new frabuffer for the supplied RenderPass.
                /// </summary>
@@ -39,7 +42,7 @@ namespace vke {
                /// <param name="_height">Height.</param>
                /// <param name="views">Views.</param>
                public FrameBuffer (RenderPass _renderPass, uint _width, uint _height, params Image[] views)
-        : this (_renderPass, _width, _height) {
+               : this (_renderPass, _width, _height) {
                        for (int i = 0; i < views.Length; i++) {
                                Image v = views[i];
                                if (v == null) {
@@ -61,13 +64,13 @@ namespace vke {
                                } else
                                        v.Activate ();//increase ref and create handle if not already activated
 
-                attachments.Add (v);
+                               attachments.Add (v);
                        }
-            Activate ();
+                       Activate ();
                }
                #endregion
 
-               public override void Activate () {
+               public sealed override void Activate () {
                        if (state != ActivableState.Activated) {
                                VkImageView[] views = attachments.Select (a => a.Descriptor.imageView).ToArray ();
                                createInfo.attachmentCount = (uint)views.Length;
@@ -78,26 +81,26 @@ namespace vke {
                                views.Unpin ();
                        }
                        base.Activate ();
-        }
+               }
 
 
                public override string ToString () {
-                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]");
+                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString ("x")}]");
                }
 
-#region IDisposable Support
+               #region IDisposable Support
                protected override void Dispose (bool disposing) {
                        if (state == ActivableState.Activated)
                                Dev.DestroyFramebuffer (handle);
                        if (disposing) {
-                               foreach (Image img in attachments) 
-                                       img.Dispose();
-                       }else
+                               foreach (Image img in attachments)
+                                       img.Dispose ();
+                       } else
                                System.Diagnostics.Debug.WriteLine ("VKE Activable object disposed by finalizer");
-                               
+
                        base.Dispose (disposing);
                }
-#endregion
+               #endregion
 
        }
 }
index 50280bad5f22e37f19b022beb4a346885f39fa71..d5e1c7ca754bb06b9eb2e9af90b91ede024f7d21 100644 (file)
@@ -16,17 +16,32 @@ namespace vke {
         }
     }
        /// <summary>
-       /// Device local Buffer
+       /// Device local Buffer for an array of elements of type T.
        /// </summary>
        public class GPUBuffer<T> : GPUBuffer {
-
+               /// <summary>
+               /// return the current element count of this buffer.
+               /// </summary>
                public int ElementCount { get; private set; }
 
+               /// <summary>
+               /// Create an empty new device local buffer with the size needed to store the specified item count of type T.
+               /// </summary>
+               /// <param name="device">the logical device that will create this buffer.</param>
+               /// <param name="usage">bitmask of the intended usages for this buffer</param>
+               /// <param name="elementCount">Element count of type T to reserve the space for.</param>
                public GPUBuffer (Device device, VkBufferUsageFlags usage, int elementCount)
             : base (device, usage, (ulong)(Marshal.SizeOf<T> () * elementCount)) {
                        ElementCount = elementCount;
         }
-        public GPUBuffer (Queue staggingQ, CommandPool staggingCmdPool, VkBufferUsageFlags usage, T[] elements)
+               /// <summary>
+               /// Create and polulate by copy a new device local buffer.
+               /// </summary>
+               /// <param name="staggingQ">The managed queue that will be used for the copy of the elements from a temporary stagging buffer to the final device buffer.</param>
+               /// <param name="staggingCmdPool">A command pool for the supplied queue.</param>
+               /// <param name="usage">bitmask of the intended usages for this buffer</param>
+               /// <param name="elements">an array of elements of type T to populate the new device buffer with.</param>
+               public GPUBuffer (Queue staggingQ, CommandPool staggingCmdPool, VkBufferUsageFlags usage, T[] elements)
             : base (staggingQ.Dev, usage | VkBufferUsageFlags.TransferDst, (ulong)(Marshal.SizeOf<T> () * elements.Length)) {
                        using (HostBuffer<T> stagging = new HostBuffer<T> (Dev, VkBufferUsageFlags.TransferSrc, elements)) { 
                                CommandBuffer cmd = staggingCmdPool.AllocateCommandBuffer ();
index c538501c86d21240b6c9eb85e4cdb550c40a08d0..6658cc11bd71330e72d09cd6b840053bfff6c192 100644 (file)
@@ -8,20 +8,25 @@ using System.Linq;
 using static Vulkan.Vk;
 
 namespace vke {
-    public class GraphicPipeline : Pipeline {
+       public class GraphicPipeline : Pipeline {
 
                public readonly RenderPass RenderPass;
                public VkSampleCountFlags Samples => RenderPass.Samples;
 
                #region CTORS
-               protected GraphicPipeline (RenderPass renderPass, PipelineCache cache = null, string name = "graphic pipeline") : base(renderPass.Dev, cache, name) { 
+               /// <summary>
+               /// Create and activate a new pipeline for supplied render pass.
+               /// </summary>
+               /// <param name="renderPass">a managed Render pass that will be activated (if not already) during the pipeline creation.</param>
+               /// <param name="cache">an optional pipeline cache to speed up pipeline creation.</param>
+               /// <param name="name">an optionnal name that will be used by the debug utils extension if enabled.</param>
+               protected GraphicPipeline (RenderPass renderPass, PipelineCache cache = null, string name = "graphic pipeline") : base (renderPass.Dev, cache, name) {
                        RenderPass = renderPass;
                }
                /// <summary>
                /// Create a new Pipeline with supplied RenderPass
                /// </summary>
-               public GraphicPipeline (GraphicPipelineConfig cfg, string name = "graphic pipeline") : this (cfg.RenderPass, cfg.Cache, name)
-               {
+               public GraphicPipeline (GraphicPipelineConfig cfg, string name = "graphic pipeline") : this (cfg.RenderPass, cfg.Cache, name) {
                        layout = cfg.Layout;
 
                        init (cfg);
@@ -46,8 +51,7 @@ namespace vke {
                                        VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New ();
                                        colorBlendInfo.logicOpEnable = cfg.ColorBlendLogicOpEnable;
                                        colorBlendInfo.logicOp = cfg.ColorBlendLogicOp;
-                                       unsafe
-                                       {
+                                       unsafe {
                                                colorBlendInfo.blendConstants[0] = cfg.ColorBlendConstants.X;
                                                colorBlendInfo.blendConstants[1] = cfg.ColorBlendConstants.Y;
                                                colorBlendInfo.blendConstants[2] = cfg.ColorBlendConstants.Z;
@@ -58,7 +62,7 @@ namespace vke {
 
                                        VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New ();
                                        dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count;
-                                       dynStatesInfo.pDynamicStates = cfg.dynamicStates.Cast<int>().ToArray().Pin (pctx);
+                                       dynStatesInfo.pDynamicStates = cfg.dynamicStates.Cast<int> ().ToArray ().Pin (pctx);
 
                                        VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New ();
                                        vertInputInfo.vertexBindingDescriptionCount = (uint)cfg.vertexBindings.Count;
@@ -97,7 +101,7 @@ namespace vke {
                                        Utils.CheckResult (vkCreateGraphicsPipelines (Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
 
                                        for (int i = 0; i < cfg.shaders.Count; i++)
-                                               Dev.DestroyShaderModule (shaderStages [i].module);
+                                               Dev.DestroyShaderModule (shaderStages[i].module);
                                }
                        }
                        base.Activate ();
@@ -112,9 +116,9 @@ namespace vke {
 
                protected override void Dispose (bool disposing) {
                        if (disposing) {
-                               if (state == ActivableState.Activated) 
+                               if (state == ActivableState.Activated)
                                        RenderPass.Dispose ();
-                       }else
+                       } else
                                System.Diagnostics.Debug.WriteLine ("GraphicPipeline disposed by finalizer");
 
                        base.Dispose (disposing);
index 2ce0094d9c52af60eeb42f10364ee326cca1195b..f61cb845f7ccaa23e3a85dbf06afb1dde5b5911b 100644 (file)
@@ -8,80 +8,144 @@ using Vulkan;
 using static Vulkan.Vk;
 
 namespace vke {
-       
+       /// <summary>
+       /// Host visible mappable buffer to handle array of blittable type T
+       /// </summary>
        public class HostBuffer<T> : HostBuffer {
-        int TSize;
-
+               int TSize;
+               /// <summary>
+               /// Create an empty mappable vulkan buffer for elements of type T whith specified size.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="arrayElementCount">Array element count.</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
                public HostBuffer (Device device, VkBufferUsageFlags usage, uint arrayElementCount, bool keepMapped = false, bool coherentMem = true)
-            : base (device, usage, (ulong)(Marshal.SizeOf<T> () * arrayElementCount), keepMapped, coherentMem) {
-            TSize = Marshal.SizeOf<T>();
-        }
+                       : base (device, usage, (ulong)(Marshal.SizeOf<T> () * arrayElementCount), keepMapped, coherentMem) {
+                       TSize = Marshal.SizeOf<T> ();
+               }
+               /// <summary>
+               /// Create and populate a mappable vulkan buffer.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="data">a list of T implementing the IList interface which will be used to populate the buffer.</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
                public HostBuffer (Device device, VkBufferUsageFlags usage, IList<T> data, bool keepMapped = false, bool coherentMem = true)
-            : base (device, usage, (ulong)(Marshal.SizeOf<T> () * data.Count), keepMapped, coherentMem) {
-            TSize = Marshal.SizeOf<T>();
-            Map();
-            Update (data, createInfo.size);
+                       : base (device, usage, (ulong)(Marshal.SizeOf<T> () * data.Count), keepMapped, coherentMem) {
+                       TSize = Marshal.SizeOf<T> ();
+                       Map ();
+                       Update (data, createInfo.size);
                        if (!keepMapped)
-               Unmap ();
-        }
-        public HostBuffer (Device device, VkBufferUsageFlags usage, T[] data, bool keepMapped = false, bool coherentMem = true)
-            : base (device, usage, (ulong)(Marshal.SizeOf<T> () * data.Length), keepMapped, coherentMem) {
-            TSize = Marshal.SizeOf<T>();
-            Map();
-            Update (data, createInfo.size);
+                               Unmap ();
+               }
+               /// <summary>
+               /// Create and populate a mappable vulkan buffer.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="data">an array  of T which will be used to populate the buffer.</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
+               public HostBuffer (Device device, VkBufferUsageFlags usage, T[] data, bool keepMapped = false, bool coherentMem = true)
+                       : base (device, usage, (ulong)(Marshal.SizeOf<T> () * data.Length), keepMapped, coherentMem) {
+                       TSize = Marshal.SizeOf<T> ();
+                       Map ();
+                       Update (data, createInfo.size);
                        if (!keepMapped)
-               Unmap ();
-        }
+                               Unmap ();
+               }
+               /// <summary>
+               /// Update content of the buffer with array of given length with no offset.
+               /// </summary>
+               /// <param name="data">Data.</param>
                public void Update (T[] data) {
                        Update (data, (ulong)(TSize * data.Length));
                }
-        public void Update (uint index, T data) {
-            GCHandle ptr = GCHandle.Alloc(data, GCHandleType.Pinned);
-            unsafe {
-                System.Buffer.MemoryCopy(ptr.AddrOfPinnedObject().ToPointer(), (mappedData + (int)(TSize*index)).ToPointer(), TSize, TSize);
-            }
-            ptr.Free();
-        }
-        public void Flush (uint startIndex, uint endIndex) {
-            VkMappedMemoryRange mr = new VkMappedMemoryRange
-            {
-                sType = VkStructureType.MappedMemoryRange,
+               /// <summary>
+               /// Update a single T element in the buffer at specified index.
+               /// </summary>
+               /// <param name="index">0 based index of the T element in the array.</param>
+               /// <param name="data">new value for T to set in the buffer.</param>
+               public void Update (uint index, T data) {
+                       GCHandle ptr = GCHandle.Alloc (data, GCHandleType.Pinned);
+                       unsafe {
+                               System.Buffer.MemoryCopy (ptr.AddrOfPinnedObject ().ToPointer (), (mappedData + (int)(TSize * index)).ToPointer (), TSize, TSize);
+                       }
+                       ptr.Free ();
+               }
+               /// <summary>
+               /// Flush memory, note that coherent memory desn't need it.
+               /// </summary>
+               /// <param name="startIndex">index of the first T element to flush</param>
+               /// <param name="endIndex">index of the last T element to flush</param>
+               public void Flush (uint startIndex, uint endIndex) {
+                       //TODO: vulkan has some alignement constrains on flushing!
+                       VkMappedMemoryRange mr = new VkMappedMemoryRange {
+                               sType = VkStructureType.MappedMemoryRange,
 #if MEMORY_POOLS
                                memory = memoryPool.vkMemory,
-                offset = poolOffset + (ulong)(startIndex * TSize),
+                               offset = poolOffset + (ulong)(startIndex * TSize),
 #else
                                memory = vkMemory,
                                offset = (ulong)(startIndex * TSize),
 #endif
-                size = (ulong)((endIndex - startIndex) * TSize)
-            };
-            vkFlushMappedMemoryRanges(Dev.VkDev, 1, ref mr);
-        }
-    }
+                               size = (ulong)((endIndex - startIndex) * TSize)
+                       };
+                       vkFlushMappedMemoryRanges (Dev.VkDev, 1, ref mr);
+               }
+       }
        /// <summary>
        /// Mappable Buffer with HostVisble and HostCoherent memory flags
        /// </summary>
        public class HostBuffer : Buffer {
-        public HostBuffer (Device device, VkBufferUsageFlags usage, UInt64 size, bool keepMapped = false, bool coherentMem = true)
-                    : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, size) {
-            if (keepMapped)
-                Map();
-        }
-        public HostBuffer (Device device, VkBufferUsageFlags usage, object data, bool keepMapped = false, bool coherentMem = true)
-            : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, (ulong)Marshal.SizeOf(data)) {
-            Map ();
-            Update (data, createInfo.size);
+               /// <summary>
+               /// Create an empty mappable vulkan buffer whith specified size in byte.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="size">buffer memory size in byte</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
+               public HostBuffer (Device device, VkBufferUsageFlags usage, UInt64 size, bool keepMapped = false, bool coherentMem = true)
+                                       : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, size) {
+                       if (keepMapped)
+                               Map ();
+               }
+               /// <summary>
+               /// Create a mappable vulkan buffer whith the supplied object.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="data">Object to set as content of the buffer. It must be blittable to be able to compute size automatically.</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
+               public HostBuffer (Device device, VkBufferUsageFlags usage, object data, bool keepMapped = false, bool coherentMem = true)
+                       : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, (ulong)Marshal.SizeOf (data)) {
+                       Map ();
+                       Update (data, createInfo.size);
                        if (!keepMapped)
-               Unmap ();
-        }
-        public HostBuffer (Device device, VkBufferUsageFlags usage, UInt64 size, IntPtr data, bool keepMapped = false, bool coherentMem = true)
-            : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, size) {
-            Map ();
-            unsafe {
-                System.Buffer.MemoryCopy (data.ToPointer (), mappedData.ToPointer (), size, size);
-            }
+                               Unmap ();
+               }
+               /// <summary>
+               /// Create a mappable vulkan buffer of specified size whith a data pointer.
+               /// </summary>
+               /// <param name="device">Logical Device.</param>
+               /// <param name="usage">Buffer Usage.</param>
+               /// <param name="size">Size in byte of the datas supplied with the pointer.</param>
+               /// <param name="data">Managed pointer which point to the data to copy in the buffer at startup.</param>
+               /// <param name="keepMapped">If set to <c>true</c>, buffer will stay mapped after the constructor.</param>
+               /// <param name="coherentMem">If set to <c>true</c> vulkan memory with have the coherent flag.</param>
+               public HostBuffer (Device device, VkBufferUsageFlags usage, UInt64 size, IntPtr data, bool keepMapped = false, bool coherentMem = true)
+                       : base (device, usage, coherentMem ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.HostVisible, size) {
+                       Map ();
+                       unsafe {
+                               System.Buffer.MemoryCopy (data.ToPointer (), mappedData.ToPointer (), size, size);
+                       }
                        if (!keepMapped)
-               Unmap ();
-        }
-    }  
+                               Unmap ();
+               }
+       }
 }
index 9c1cb8e653ee71ad7fed7c28767409d6982774ba..b2ae336043882703b07137701d61bf108397259e 100644 (file)
@@ -14,59 +14,92 @@ namespace vke {
        /// such imported image will not be disposed with the sampler and the view.
        /// </summary>
        public class Image : Resource {
+               /// <summary>Default format to use if not defined by constructor parameters.</summary>
                public static VkFormat DefaultTextureFormat = VkFormat.R8g8b8a8Unorm;
 
-               internal VkImage handle; 
-        VkImageCreateInfo info = VkImageCreateInfo.New();
+               internal VkImage handle;
+               VkImageCreateInfo info = VkImageCreateInfo.New ();
+               uint[] queueFalillies;
 
                /// <summary>
                /// if true, the vkImage handle will not be destroyed on dispose, useful to create image for swapchain
                /// </summary>
-        bool imported;
-
-        public VkDescriptorImageInfo Descriptor;
-        public VkImageCreateInfo CreateInfo => info;
-        public VkExtent3D Extent => info.extent;
-        public VkFormat Format => info.format;
+               bool imported;
+
+               public VkDescriptorImageInfo Descriptor;
+               /// <summary>Get the create info structure used for creating this image.</summary>
+               public VkImageCreateInfo CreateInfo => info;
+               /// <summary>Get the dimensions in pixel for this image</summary>
+               public VkExtent3D Extent => info.extent;
+               /// <summary>Get image format</summary>
+               public VkFormat Format => info.format;
+               /// <summary>Native vulkan handle for the image.</summary>
                public VkImage Handle => handle;
+               /// <summary>Width in pixel of the image.</summary>
                public uint Width => CreateInfo.extent.width;
+               /// <summary>Height in pixel of the image.</summary>
                public uint Height => CreateInfo.extent.height;
+               /// <summary>Boolean indicating if memory allocated for this image has linear or optimal tiling.</summary>
                public override bool IsLinar => CreateInfo.tiling == VkImageTiling.Linear;
-
+               /// <summary>
+               /// May be used to query the last known layout. It is set when commands explicitly secify the final layout of the image.
+               /// </summary>
+               /// <remarks>Due to the automatic layout trasitions handled by several vulkan commands, use this property with caution, it's value
+               /// may not be the actual layout of the image.</remarks>
                public VkImageLayout lastKnownLayout { get; private set; }
 
                protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
                                        => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.Image, handle.Handle);
 
                #region CTORS
+               /// <summary>
+               /// Create a new Image.
+               /// </summary>
+               /// <remarks>Initial layout will be automatically set to Undefined if tiling is optimal and Preinitialized if tiling is linear.</remarks>
+               /// <param name="device">The logical device that create the image.</param>
+               /// <param name="format">format and type of the texel blocks that will be contained in the image</param>
+               /// <param name="usage">bitmask describing the intended usage of the image.</param>
+               /// <param name="_memoryPropertyFlags">Memory property flags.</param>
+               /// <param name="width">number of data in the X dimension of the image.</param>
+               /// <param name="height">number of data in the Y dimension of the image.</param>
+               /// <param name="type">value specifying the basic dimensionality of the image. Layers in array textures do not count as a dimension for the purposes of the image type.</param>
+               /// <param name="samples">number of sample per texel.</param>
+               /// <param name="tiling">tiling arrangement of the texel blocks in memory.</param>
+               /// <param name="mipsLevels">describes the number of levels of detail available for minified sampling of the image.</param>
+               /// <param name="layers">number of layers in the image.</param>
+               /// <param name="depth">number of data in the Z dimension of the image</param>
+               /// <param name="createFlags">bitmask describing additional parameters of the image.</param>
+               /// <param name="sharingMode">value specifying the sharing mode of the image when it will be accessed by multiple queue families.</param>
+               /// <param name="queuesFamillies">list of queue families that will access this image (ignored if sharingMode is not CONCURRENT).</param>
                public Image (Device device, VkFormat format, VkImageUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags,
-            uint width, uint height,
-            VkImageType type = VkImageType.Image2D, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1,
-            VkImageTiling tiling = VkImageTiling.Optimal, uint mipsLevels = 1, uint layers = 1, uint depth = 1,
-                       VkImageCreateFlags createFlags = 0)
-            : base (device, _memoryPropertyFlags) {
-
-            info.imageType = type;
-            info.format = format;
-            info.extent.width = width;
-            info.extent.height = height;
-            info.extent.depth = depth;
-            info.mipLevels = mipsLevels;
-            info.arrayLayers = layers;
-            info.samples = samples;
-            info.tiling = tiling;
-            info.usage = usage;
-            info.initialLayout = (tiling == VkImageTiling.Optimal) ? VkImageLayout.Undefined : VkImageLayout.Preinitialized;
-            info.sharingMode = VkSharingMode.Exclusive;
+                       uint width, uint height,
+                       VkImageType type = VkImageType.Image2D, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1,
+                       VkImageTiling tiling = VkImageTiling.Optimal, uint mipsLevels = 1, uint layers = 1, uint depth = 1,
+                       VkImageCreateFlags createFlags = 0, VkSharingMode sharingMode = VkSharingMode.Exclusive, params uint[] queuesFamillies)
+                       : base (device, _memoryPropertyFlags) {
+
+                       info.imageType = type;
+                       info.format = format;
+                       info.extent.width = width;
+                       info.extent.height = height;
+                       info.extent.depth = depth;
+                       info.mipLevels = mipsLevels;
+                       info.arrayLayers = layers;
+                       info.samples = samples;
+                       info.tiling = tiling;
+                       info.usage = usage;
+                       info.initialLayout = (tiling == VkImageTiling.Optimal) ? VkImageLayout.Undefined : VkImageLayout.Preinitialized;
+                       info.sharingMode = sharingMode;
                        info.flags = createFlags;
 
+                       this.queueFalillies = queuesFamillies;
                        lastKnownLayout = info.initialLayout;
 
-            Activate ();//DONT OVERRIDE Activate in derived classes!!!!
-        }
+                       Activate ();
+               }
 
                /// <summary>
-               /// Import vkImage handle into a new Image class, handle will be preserve on destruction.
+               /// Import vkImage handle into a new Image class, native handle will be preserve on destruction.
                /// </summary>
                public Image (Device device, VkImage vkHandle, VkFormat format, VkImageUsageFlags usage, uint width, uint height)
                : base (device, VkMemoryPropertyFlags.DeviceLocal) {
@@ -85,13 +118,19 @@ namespace vke {
                        imported = true;
 
                        state = ActivableState.Activated;
-                       references++;//increment ref because it is bound to swapchain
+                       references++;
                }
                #endregion
 
-               public static uint ComputeMipLevels(uint size) => (uint)Math.Floor (Math.Log (size)) + 1;
-               public static uint ComputeMipLevels (int width, int height) =>  (uint)Math.Floor (Math.Log (Math.Max (width, height))) + 1;
+               public static uint ComputeMipLevels (uint size) => (uint)Math.Floor (Math.Log (size)) + 1;
+               public static uint ComputeMipLevels (int width, int height) => (uint)Math.Floor (Math.Log (Math.Max (width, height))) + 1;
 
+               /// <summary>
+               /// Check if specified image usage is supported for the given physical image format.
+               /// </summary>
+               /// <returns><c>true</c>, if usage is supported</returns>
+               /// <param name="usage">bitmask of intend usage for an image.</param>
+               /// <param name="phyFormatSupport">Physical format feature bitmask as returned by `GetFormatProperties` of PhysicalDevice</param>
                public static bool CheckFormatIsSupported (VkImageUsageFlags usage, VkFormatFeatureFlags phyFormatSupport) {
                        if (usage.HasFlag (VkImageUsageFlags.TransferSrc) & !phyFormatSupport.HasFlag (VkFormatFeatureFlags.TransferSrc))
                                return false;
@@ -214,7 +253,7 @@ namespace vke {
 
                                return img;
                        }
-        }
+               }
                /// <summary>
                /// create host visible linear image without command from byte array
                /// </summary>
@@ -293,9 +332,9 @@ namespace vke {
 
                #endregion
 
-               internal override void updateMemoryRequirements () {            
-            vkGetImageMemoryRequirements (Dev.VkDev, handle, out memReqs);            
-        }
+               internal override void updateMemoryRequirements () {
+                       vkGetImageMemoryRequirements (Dev.VkDev, handle, out memReqs);
+               }
                internal override void bindMemory () {
 #if MEMORY_POOLS
                        Utils.CheckResult (vkBindImageMemory (Dev.VkDev, handle, memoryPool.vkMemory, poolOffset));
@@ -303,9 +342,15 @@ namespace vke {
                        Utils.CheckResult (vkBindImageMemory (Dev.VkDev, handle, vkMemory, 0));
 #endif
                }
-        public override void Activate () {
+               public sealed override void Activate () {
                        if (state != ActivableState.Activated) {
-                               Utils.CheckResult (vkCreateImage (Dev.VkDev, ref info, IntPtr.Zero, out handle));
+                               if (info.sharingMode == VkSharingMode.Concurrent && queueFalillies?.Length > 0) {
+                                       info.queueFamilyIndexCount = (uint)queueFalillies.Length;
+                                       info.pQueueFamilyIndices = queueFalillies.Pin ();
+                                       Utils.CheckResult (vkCreateImage (Dev.VkDev, ref info, IntPtr.Zero, out handle));
+                                       queueFalillies.Unpin ();
+                               } else
+                                       Utils.CheckResult (vkCreateImage (Dev.VkDev, ref info, IntPtr.Zero, out handle));
 #if MEMORY_POOLS
                                Dev.resourceManager.Add (this);
 #else
@@ -315,70 +360,78 @@ namespace vke {
 #endif
 
                        }
-            base.Activate ();
-        }
+                       base.Activate ();
+               }
 
                public void CreateView (VkImageViewType type = VkImageViewType.ImageView2D, VkImageAspectFlags aspectFlags = VkImageAspectFlags.Color,
-                       uint layerCount = 1,
-            uint baseMipLevel = 0, int levelCount = -1, uint baseArrayLayer = 0,
+                       uint layerCount = 1, uint baseMipLevel = 0, int levelCount = -1, uint baseArrayLayer = 0,
                        VkComponentSwizzle r = VkComponentSwizzle.R,
                        VkComponentSwizzle g = VkComponentSwizzle.G,
                        VkComponentSwizzle b = VkComponentSwizzle.B,
                        VkComponentSwizzle a = VkComponentSwizzle.A) {
 
-            VkImageView view = default(VkImageView);
-            VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.New();
-            viewInfo.image = handle;
-            viewInfo.viewType = type;
-            viewInfo.format = Format;
-            viewInfo.components.r = r;
-            viewInfo.components.g = g;
-            viewInfo.components.b = b;
-            viewInfo.components.a = a;
-            viewInfo.subresourceRange.aspectMask = aspectFlags;
+                       VkImageView view = default (VkImageView);
+                       VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo.New ();
+                       viewInfo.image = handle;
+                       viewInfo.viewType = type;
+                       viewInfo.format = Format;
+                       viewInfo.components.r = r;
+                       viewInfo.components.g = g;
+                       viewInfo.components.b = b;
+                       viewInfo.components.a = a;
+                       viewInfo.subresourceRange.aspectMask = aspectFlags;
                        viewInfo.subresourceRange.baseMipLevel = baseMipLevel;
                        viewInfo.subresourceRange.levelCount = levelCount < 0 ? info.mipLevels : (uint)levelCount;
                        viewInfo.subresourceRange.baseArrayLayer = baseArrayLayer;
                        viewInfo.subresourceRange.layerCount = layerCount;
 
-            Utils.CheckResult (vkCreateImageView (Dev.VkDev, ref viewInfo, IntPtr.Zero, out view));
+                       Utils.CheckResult (vkCreateImageView (Dev.VkDev, ref viewInfo, IntPtr.Zero, out view));
 
-            if (Descriptor.imageView.Handle != 0)
-                Dev.DestroyImageView (Descriptor.imageView);
-            Descriptor.imageView = view;
-        }
+                       if (Descriptor.imageView.Handle != 0)
+                               Dev.DestroyImageView (Descriptor.imageView);
+                       Descriptor.imageView = view;
+               }
 
                public void CreateSampler (VkSamplerAddressMode addressMode, VkFilter minFilter = VkFilter.Linear,
                                VkFilter magFilter = VkFilter.Linear, VkSamplerMipmapMode mipmapMode = VkSamplerMipmapMode.Linear,
                                float maxAnisotropy = 1.0f, float minLod = 0.0f, float maxLod = -1f) {
                        CreateSampler (minFilter, magFilter, mipmapMode, addressMode, maxAnisotropy, minLod, maxLod);
                }
-
+               /// <summary>
+               /// Create a Sampler and store it into the Descriptor structure of this image.
+               /// </summary>
+               /// <param name="minFilter">Minimum filter.</param>
+               /// <param name="magFilter">Mag filter.</param>
+               /// <param name="mipmapMode">Mipmap mode.</param>
+               /// <param name="addressMode">Address mode.</param>
+               /// <param name="maxAnisotropy">Max anisotropy.</param>
+               /// <param name="minLod">Minimum lod.</param>
+               /// <param name="maxLod">Max lod.</param>
                public void CreateSampler (VkFilter minFilter = VkFilter.Linear, VkFilter magFilter = VkFilter.Linear,
-                               VkSamplerMipmapMode mipmapMode = VkSamplerMipmapMode.Linear, VkSamplerAddressMode addressMode = VkSamplerAddressMode.Repeat,
-            float maxAnisotropy = 1.0f, float minLod = 0.0f, float maxLod = -1f) {
-            VkSampler sampler;
-            VkSamplerCreateInfo sampInfo = VkSamplerCreateInfo.New();
-            sampInfo.maxAnisotropy = maxAnisotropy;
+                                                          VkSamplerMipmapMode mipmapMode = VkSamplerMipmapMode.Linear, VkSamplerAddressMode addressMode = VkSamplerAddressMode.Repeat,
+                       float maxAnisotropy = 1.0f, float minLod = 0.0f, float maxLod = -1f) {
+                       VkSampler sampler;
+                       VkSamplerCreateInfo sampInfo = VkSamplerCreateInfo.New ();
+                       sampInfo.maxAnisotropy = maxAnisotropy;
                        sampInfo.maxAnisotropy = 1.0f;// device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f;
-                       //samplerInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy;
+                                                                                 //samplerInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy;
                        sampInfo.addressModeU = addressMode;
-            sampInfo.addressModeV = addressMode;
-            sampInfo.addressModeW = addressMode;
-            sampInfo.magFilter = magFilter;
-            sampInfo.minFilter = minFilter;
-            sampInfo.mipmapMode = mipmapMode;
-            sampInfo.minLod = minLod;
-            sampInfo.maxLod = maxLod < 0f ? info.mipLevels > 1 ? info.mipLevels : 0 : maxLod;
+                       sampInfo.addressModeV = addressMode;
+                       sampInfo.addressModeW = addressMode;
+                       sampInfo.magFilter = magFilter;
+                       sampInfo.minFilter = minFilter;
+                       sampInfo.mipmapMode = mipmapMode;
+                       sampInfo.minLod = minLod;
+                       sampInfo.maxLod = maxLod < 0f ? info.mipLevels > 1 ? info.mipLevels : 0 : maxLod;
                        sampInfo.compareOp = VkCompareOp.Never;
                        sampInfo.borderColor = VkBorderColor.FloatOpaqueWhite;
 
-            Utils.CheckResult (vkCreateSampler (Dev.VkDev, ref sampInfo, IntPtr.Zero, out sampler));
+                       Utils.CheckResult (vkCreateSampler (Dev.VkDev, ref sampInfo, IntPtr.Zero, out sampler));
 
-            if (Descriptor.sampler.Handle != 0)
-                Dev.DestroySampler (Descriptor.sampler);
-            Descriptor.sampler = sampler;
-        }
+                       if (Descriptor.sampler.Handle != 0)
+                               Dev.DestroySampler (Descriptor.sampler);
+                       Descriptor.sampler = sampler;
+               }
 
                public void SetLayout (CommandBuffer cmdbuffer,
                        VkImageAspectFlags aspectMask,
@@ -387,25 +440,25 @@ namespace vke {
                }
                public void SetLayout (CommandBuffer cmdbuffer,
                        VkImageAspectFlags aspectMask,
-            VkImageLayout oldImageLayout,
+                       VkImageLayout oldImageLayout,
                        VkImageLayout newImageLayout) {
                        SetLayout (cmdbuffer, aspectMask, oldImageLayout, newImageLayout, oldImageLayout.GetDefaultStage (), newImageLayout.GetDefaultStage ());
                }
                public void SetLayout (
-            CommandBuffer cmdbuffer,
-            VkImageAspectFlags aspectMask,
-            VkImageLayout oldImageLayout,
-            VkImageLayout newImageLayout,
-            VkPipelineStageFlags srcStageMask,
-            VkPipelineStageFlags dstStageMask) {
-            VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange {
-                aspectMask = aspectMask,
-                baseMipLevel = 0,
-                levelCount = CreateInfo.mipLevels,
-                layerCount = CreateInfo.arrayLayers,
-            };
-            SetLayout (cmdbuffer, oldImageLayout, newImageLayout, subresourceRange, srcStageMask, dstStageMask);
-        }
+                       CommandBuffer cmdbuffer,
+                       VkImageAspectFlags aspectMask,
+                       VkImageLayout oldImageLayout,
+                       VkImageLayout newImageLayout,
+                       VkPipelineStageFlags srcStageMask,
+                       VkPipelineStageFlags dstStageMask) {
+                       VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange {
+                               aspectMask = aspectMask,
+                               baseMipLevel = 0,
+                               levelCount = CreateInfo.mipLevels,
+                               layerCount = CreateInfo.arrayLayers,
+                       };
+                       SetLayout (cmdbuffer, oldImageLayout, newImageLayout, subresourceRange, srcStageMask, dstStageMask);
+               }
                public void SetLayout (
                        CommandBuffer cmdbuffer,
                        VkImageAspectFlags aspectMask,
@@ -416,8 +469,7 @@ namespace vke {
                        VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
                        VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands,
                        uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored,
-                       uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored)
-               {
+                       uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) {
                        VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange {
                                aspectMask = aspectMask,
                                baseMipLevel = 0,
@@ -437,8 +489,7 @@ namespace vke {
                        VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
                        VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands,
                        uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored,
-                       uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored)
-               {
+                       uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) {
 
                        VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New ();
                        imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
@@ -464,123 +515,123 @@ namespace vke {
                // an image and put it into an active command buffer
                // See chapter 11.4 "Image Layout" for details
                public void SetLayout (
-            CommandBuffer cmdbuffer,            
-            VkImageLayout oldImageLayout,
-            VkImageLayout newImageLayout,
-            VkImageSubresourceRange subresourceRange,
-            VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
-            VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands,
+                       CommandBuffer cmdbuffer,
+                       VkImageLayout oldImageLayout,
+                       VkImageLayout newImageLayout,
+                       VkImageSubresourceRange subresourceRange,
+                       VkPipelineStageFlags srcStageMask = VkPipelineStageFlags.AllCommands,
+                       VkPipelineStageFlags dstStageMask = VkPipelineStageFlags.AllCommands,
                        uint srcQueueFamilyIndex = Vk.QueueFamilyIgnored,
                        uint dstQueueFamilyIndex = Vk.QueueFamilyIgnored) {
-            // Create an image barrier object
-            VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();
-            imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
-            imageMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
-            imageMemoryBarrier.oldLayout = oldImageLayout;
-            imageMemoryBarrier.newLayout = newImageLayout;
-            imageMemoryBarrier.image = handle;
-            imageMemoryBarrier.subresourceRange = subresourceRange;
-
-            // Source layouts (old)
-            // Source access mask controls actions that have to be finished on the old layout
-            // before it will be transitioned to the new layout
-            switch (oldImageLayout) {
-                case VkImageLayout.Undefined:
-                    // Image layout is undefined (or does not matter)
-                    // Only valid as initial layout
-                    // No flags required, listed only for completeness
-                    imageMemoryBarrier.srcAccessMask = 0;
-                    break;
-
-                case VkImageLayout.Preinitialized:
-                    // Image is preinitialized
-                    // Only valid as initial layout for linear images, preserves memory contents
-                    // Make sure host writes have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite;
-                    break;
-
-                case VkImageLayout.ColorAttachmentOptimal:
-                    // Image is a color attachment
-                    // Make sure any writes to the color buffer have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.ColorAttachmentWrite;
-                    break;
-
-                case VkImageLayout.DepthStencilAttachmentOptimal:
-                    // Image is a depth/stencil attachment
-                    // Make sure any writes to the depth/stencil buffer have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.DepthStencilAttachmentWrite;
-                    break;
-
-                case VkImageLayout.TransferSrcOptimal:
-                    // Image is a transfer source 
-                    // Make sure any reads from the image have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
-                    break;
-
-                case VkImageLayout.TransferDstOptimal:
-                    // Image is a transfer destination
-                    // Make sure any writes to the image have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
-                    break;
-
-                case VkImageLayout.ShaderReadOnlyOptimal:
-                    // Image is read by a shader
-                    // Make sure any shader reads from the image have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.ShaderRead;
-                    break;
-            }
-
-            // Target layouts (new)
-            // Destination access mask controls the dependency for the new image layout
-            switch (newImageLayout) {
-                case VkImageLayout.TransferDstOptimal:
-                    // Image will be used as a transfer destination
-                    // Make sure any writes to the image have been finished
-                    imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite;
-                    break;
-
-                case VkImageLayout.TransferSrcOptimal:
-                    // Image will be used as a transfer source
-                    // Make sure any reads from and writes to the image have been finished
-                    //imageMemoryBarrier.srcAccessMask |= VkAccessFlags.TransferRead;
-                    imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
-                    break;
-
-                case VkImageLayout.ColorAttachmentOptimal:
-                    // Image will be used as a color attachment
-                    // Make sure any writes to the color buffer have been finished
-                    imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
-                    imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentWrite;
-                    break;
-
-                case VkImageLayout.DepthStencilAttachmentOptimal:
-                    // Image layout will be used as a depth/stencil attachment
-                    // Make sure any writes to depth/stencil buffer have been finished
-                    imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlags.DepthStencilAttachmentWrite;
-                    break;
-
-                case VkImageLayout.ShaderReadOnlyOptimal:
-                    // Image will be read in a shader (sampler, input attachment)
-                    // Make sure any writes to the image have been finished
-                    if (imageMemoryBarrier.srcAccessMask == 0) {
-                        imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite | VkAccessFlags.TransferWrite;
-                    }
-                    imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
-                    break;
-            }
-
-            // Put barrier inside setup command buffer
-            Vk.vkCmdPipelineBarrier (
-                cmdbuffer.Handle,
-                srcStageMask,
-                dstStageMask,
-                0,
-                0,IntPtr.Zero,
-                0, IntPtr.Zero,
-                1, ref imageMemoryBarrier);
+                       // Create an image barrier object
+                       VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New ();
+                       imageMemoryBarrier.srcQueueFamilyIndex = srcQueueFamilyIndex;
+                       imageMemoryBarrier.dstQueueFamilyIndex = dstQueueFamilyIndex;
+                       imageMemoryBarrier.oldLayout = oldImageLayout;
+                       imageMemoryBarrier.newLayout = newImageLayout;
+                       imageMemoryBarrier.image = handle;
+                       imageMemoryBarrier.subresourceRange = subresourceRange;
+
+                       // Source layouts (old)
+                       // Source access mask controls actions that have to be finished on the old layout
+                       // before it will be transitioned to the new layout
+                       switch (oldImageLayout) {
+                       case VkImageLayout.Undefined:
+                               // Image layout is undefined (or does not matter)
+                               // Only valid as initial layout
+                               // No flags required, listed only for completeness
+                               imageMemoryBarrier.srcAccessMask = 0;
+                               break;
+
+                       case VkImageLayout.Preinitialized:
+                               // Image is preinitialized
+                               // Only valid as initial layout for linear images, preserves memory contents
+                               // Make sure host writes have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite;
+                               break;
+
+                       case VkImageLayout.ColorAttachmentOptimal:
+                               // Image is a color attachment
+                               // Make sure any writes to the color buffer have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.ColorAttachmentWrite;
+                               break;
+
+                       case VkImageLayout.DepthStencilAttachmentOptimal:
+                               // Image is a depth/stencil attachment
+                               // Make sure any writes to the depth/stencil buffer have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.DepthStencilAttachmentWrite;
+                               break;
+
+                       case VkImageLayout.TransferSrcOptimal:
+                               // Image is a transfer source 
+                               // Make sure any reads from the image have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
+                               break;
+
+                       case VkImageLayout.TransferDstOptimal:
+                               // Image is a transfer destination
+                               // Make sure any writes to the image have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferWrite;
+                               break;
+
+                       case VkImageLayout.ShaderReadOnlyOptimal:
+                               // Image is read by a shader
+                               // Make sure any shader reads from the image have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.ShaderRead;
+                               break;
+                       }
+
+                       // Target layouts (new)
+                       // Destination access mask controls the dependency for the new image layout
+                       switch (newImageLayout) {
+                       case VkImageLayout.TransferDstOptimal:
+                               // Image will be used as a transfer destination
+                               // Make sure any writes to the image have been finished
+                               imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferWrite;
+                               break;
+
+                       case VkImageLayout.TransferSrcOptimal:
+                               // Image will be used as a transfer source
+                               // Make sure any reads from and writes to the image have been finished
+                               //imageMemoryBarrier.srcAccessMask |= VkAccessFlags.TransferRead;
+                               imageMemoryBarrier.dstAccessMask = VkAccessFlags.TransferRead;
+                               break;
+
+                       case VkImageLayout.ColorAttachmentOptimal:
+                               // Image will be used as a color attachment
+                               // Make sure any writes to the color buffer have been finished
+                               imageMemoryBarrier.srcAccessMask = VkAccessFlags.TransferRead;
+                               imageMemoryBarrier.dstAccessMask = VkAccessFlags.ColorAttachmentWrite;
+                               break;
+
+                       case VkImageLayout.DepthStencilAttachmentOptimal:
+                               // Image layout will be used as a depth/stencil attachment
+                               // Make sure any writes to depth/stencil buffer have been finished
+                               imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlags.DepthStencilAttachmentWrite;
+                               break;
+
+                       case VkImageLayout.ShaderReadOnlyOptimal:
+                               // Image will be read in a shader (sampler, input attachment)
+                               // Make sure any writes to the image have been finished
+                               if (imageMemoryBarrier.srcAccessMask == 0) {
+                                       imageMemoryBarrier.srcAccessMask = VkAccessFlags.HostWrite | VkAccessFlags.TransferWrite;
+                               }
+                               imageMemoryBarrier.dstAccessMask = VkAccessFlags.ShaderRead;
+                               break;
+                       }
+
+                       // Put barrier inside setup command buffer
+                       Vk.vkCmdPipelineBarrier (
+                               cmdbuffer.Handle,
+                               srcStageMask,
+                               dstStageMask,
+                               0,
+                               0, IntPtr.Zero,
+                               0, IntPtr.Zero,
+                               1, ref imageMemoryBarrier);
 
                        lastKnownLayout = newImageLayout;
-        }
+               }
 
                public void BuildMipmaps (Queue copyQ, CommandPool copyCmdPool) {
                        if (info.mipLevels == 1) {
@@ -598,6 +649,10 @@ namespace vke {
 
                        cmd.Free ();
                }
+               /// <summary>
+               /// Build mipmap chain for this image. Final layout will be ShaderReadOnlyOptimal.
+               /// </summary>
+               /// <param name="cmd">a command buffer to handle the operation.</param>
                public void BuildMipmaps (CommandBuffer cmd) {
 
                        VkImageSubresourceRange mipSubRange = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, 1, 0, info.arrayLayers);
@@ -605,7 +660,7 @@ namespace vke {
 
                        for (int i = 1; i < info.mipLevels; i++) {
                                VkImageBlit imageBlit = new VkImageBlit {
-                                       srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, info.arrayLayers, (uint)i - 1),
+                                       srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, (uint)i - 1),
                                        srcOffsets_1 = new VkOffset3D ((int)info.extent.width >> (i - 1), (int)info.extent.height >> (i - 1), 1),
                                        dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, (uint)i),
                                        dstOffsets_1 = new VkOffset3D ((int)info.extent.width >> i, (int)info.extent.height >> i, 1)
@@ -621,14 +676,20 @@ namespace vke {
                        SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal,
                                        VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);
                }
-               public void BlitTo (CommandBuffer cmd, Image dest) {
+               /// <summary>
+               /// Blit this image into another.
+               /// </summary>
+               /// <param name="cmd">a command buffer to handle the blit operation.</param>
+               /// <param name="dest">the destination image to blit to.</param>
+               /// <param name="filter">filtering for the blit operation.</param>
+               public void BlitTo (CommandBuffer cmd, Image dest, VkFilter filter = VkFilter.Linear) {
                        VkImageBlit imageBlit = new VkImageBlit {
                                srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, 0),
                                srcOffsets_1 = new VkOffset3D ((int)info.extent.width, (int)info.extent.height, 1),
                                dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, info.arrayLayers, 0),
                                dstOffsets_1 = new VkOffset3D ((int)dest.info.extent.width, (int)dest.info.extent.height, 1)
                        };
-                       vkCmdBlitImage (cmd.Handle, handle, VkImageLayout.TransferSrcOptimal, dest.handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear);
+                       vkCmdBlitImage (cmd.Handle, handle, VkImageLayout.TransferSrcOptimal, dest.handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, filter);
                }
                public VkSubresourceLayout GetSubresourceLayout (VkImageAspectFlags aspectMask = VkImageAspectFlags.Color, uint mipLevel = 0, uint arrayLayer = 0) {
                        VkImageSubresource subresource = new VkImageSubresource {
@@ -641,22 +702,22 @@ namespace vke {
                }
 
                public override string ToString () {
-                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString("x")}]");
+                       return string.Format ($"{base.ToString ()}[0x{handle.Handle.ToString ("x")}]");
                }
                #region IDisposable Support
-        protected override void Dispose (bool disposing) {
+               protected override void Dispose (bool disposing) {
                        if (state == ActivableState.Activated) {
                                if (Descriptor.sampler.Handle != 0)
-                    Dev.DestroySampler (Descriptor.sampler);
-                if (Descriptor.imageView.Handle != 0)
-                    Dev.DestroyImageView (Descriptor.imageView);
+                                       Dev.DestroySampler (Descriptor.sampler);
+                               if (Descriptor.imageView.Handle != 0)
+                                       Dev.DestroyImageView (Descriptor.imageView);
                                if (!imported) {
                                        base.Dispose (disposing);
                                        Dev.DestroyImage (handle);
                                }
                        }
                        state = ActivableState.Disposed;
-        }
+               }
                #endregion
        }
 }
index b37bd94f32a66dd4ab7175589c381b899ed9ae1a..0f9cd69b59bc1827717abeaa397c8801ea355ea8 100644 (file)
@@ -86,7 +86,7 @@ namespace vke {
                        if (freeCommandBuffer)
                                cmd.Free ();
                }
-        public void Submit (CommandBuffer cmd, VkSemaphore wait = default(VkSemaphore), VkSemaphore signal = default (VkSemaphore), VkFence fence = default (VkFence)) {
+        public void Submit (CommandBuffer cmd, VkSemaphore wait = default, VkSemaphore signal = default, Fence fence = null) {
             cmd.Submit (handle, wait, signal, fence);
         }
         public void WaitIdle () {
index 57ceddbd709de11ee89d63b2087eb0ce2593f3bd..ddbaa645817196088fef5ef9300b750a1ff94df6 100644 (file)
@@ -221,12 +221,10 @@ namespace vke {
             vkCmdEndRenderPass (cmd.Handle);
         }
                /// <summary>
-               /// Create a one framebuffer per swapchain images of the supplied swapChain.
-               /// The presentable attachment of this renderpass is found searching for its final layout that could be
-               /// PresentSrcKHR or SharedPresentKHR.
+               /// Create one framebuffer per swapchain images. The presentable attachment of this renderpass is found searching for its final layout that could be PresentSrcKHR or SharedPresentKHR.
                /// </summary>
                /// <returns>A collection of FrameBuffer</returns>
-               /// <param name="swapChain">Swap chain.</param>
+               /// <param name="swapChain">a managed SwapChain instance.</param>
                public FrameBuffers CreateFrameBuffers (SwapChain swapChain) {
                        FrameBuffers fbs = new FrameBuffers();
                        Image[] images = new Image[attachments.Count];
index e489e350c58e0f7bcc9156ed1cae1ef05264973c..8da99ec013173cc3c9d324647b5267b6dec927ba 100644 (file)
@@ -10,6 +10,9 @@ using Vulkan;
 using static Vulkan.Vk;
 
 namespace vke {
+       /// <summary>
+       /// Abstract base class for Images and Buffers resources.
+       /// </summary>
        [DebuggerDisplay ("{previous.name} <- {name} -> {next.name}")]
        public abstract class Resource : Activable {
                protected VkMemoryRequirements memReqs;
@@ -20,13 +23,16 @@ namespace vke {
                protected VkDeviceMemory vkMemory;
 #endif
 
-               /// <summary> double linked list in memory pool </summary>
+               /// <summary> Double linked list in memory pool </summary>
                internal Resource previous;
                public Resource next;
 
+               /// <summary> Effective memory allocation for the resource. </summary>
                public ulong AllocatedDeviceMemorySize => memReqs.size;
                public uint TypeBits => memReqs.memoryTypeBits;
+               /// <summary> Alignment constraint of the memory to allocate for the resource. </summary>
                public ulong MemoryAlignment => memReqs.alignment;
+               /// <summary>Boolean indicating if used memory for the resource is linear.</summary>
                public abstract bool IsLinar { get; }
 
                protected IntPtr mappedData;
@@ -34,25 +40,25 @@ namespace vke {
 
                public readonly VkMemoryPropertyFlags MemoryFlags;
 
-        protected Resource (Device device, VkMemoryPropertyFlags memoryFlags) : base (device) {            
-            MemoryFlags = memoryFlags;
-        }
+               protected Resource (Device device, VkMemoryPropertyFlags memoryFlags) : base (device) {
+                       MemoryFlags = memoryFlags;
+               }
 
-        internal abstract void updateMemoryRequirements ();
+               internal abstract void updateMemoryRequirements ();
 
                internal abstract void bindMemory ();
 
                internal VkMappedMemoryRange MapRange => new VkMappedMemoryRange {
-                               sType = VkStructureType.MappedMemoryRange,
+                       sType = VkStructureType.MappedMemoryRange,
 #if MEMORY_POOLS
-                               memory = memoryPool.vkMemory,
-                               offset = poolOffset,
+                       memory = memoryPool.vkMemory,
+                       offset = poolOffset,
 #else
                                memory = vkMemory,
                                offset = 0,
 #endif
-                               size = AllocatedDeviceMemorySize
-                       };
+                       size = AllocatedDeviceMemorySize
+               };
 #if !MEMORY_POOLS
                protected void allocateMemory () {
                        VkMemoryAllocateInfo memInfo = VkMemoryAllocateInfo.New ();
@@ -67,7 +73,7 @@ namespace vke {
 #if MEMORY_POOLS
                        if (!memoryPool.IsMapped)
                                memoryPool.Map ();
-                       mappedData = new IntPtr(memoryPool.MappedData.ToInt64() + (long)(poolOffset + offset));
+                       mappedData = new IntPtr (memoryPool.MappedData.ToInt64 () + (long)(poolOffset + offset));
 #else
                        Utils.CheckResult (vkMapMemory (Dev.VkDev, vkMemory, offset, AllocatedDeviceMemorySize, 0, ref mappedData));
 #endif
@@ -80,19 +86,19 @@ namespace vke {
 #endif
                }
                public void Update (object data, ulong size, ulong offset = 0) {
-            GCHandle ptr = GCHandle.Alloc (data, GCHandleType.Pinned);
-            unsafe {
-                System.Buffer.MemoryCopy (ptr.AddrOfPinnedObject ().ToPointer (), (mappedData + (int)offset).ToPointer (), size, size);
-            }
-            ptr.Free ();
-        }
-        public void Flush () {
+                       GCHandle ptr = GCHandle.Alloc (data, GCHandleType.Pinned);
+                       unsafe {
+                               System.Buffer.MemoryCopy (ptr.AddrOfPinnedObject ().ToPointer (), (mappedData + (int)offset).ToPointer (), size, size);
+                       }
+                       ptr.Free ();
+               }
+               public void Flush () {
                        VkMappedMemoryRange range = MapRange;
-            vkFlushMappedMemoryRanges (Dev.VkDev, 1, ref range);
-        }
+                       vkFlushMappedMemoryRanges (Dev.VkDev, 1, ref range);
+               }
 
-#region IDisposable Support        
-        protected override void Dispose (bool disposing) {
+               #region IDisposable Support
+               protected override void Dispose (bool disposing) {
                        if (!disposing)
                                System.Diagnostics.Debug.WriteLine ("VKE Activable object disposed by finalizer");
                        if (state == ActivableState.Activated) {
@@ -106,7 +112,7 @@ namespace vke {
 
                        }
                        base.Dispose (disposing);
-        }
-#endregion
+               }
+               #endregion
        }
 }
\ No newline at end of file
index eba607dc117bde9d649e9e82a38fe6ebc4263fff..f9d5619699137213fc2d3d51baf20ce1ad203549 100644 (file)
@@ -7,7 +7,7 @@ using Vulkan;
 using static Vulkan.Vk;
 
 namespace vke {
-    public class SwapChain : Activable {
+       public class SwapChain : Activable {
                /// <summary>
                /// Set the default swapchain image format.
                /// </summary>
@@ -24,7 +24,7 @@ namespace vke {
                PresentQueue presentQueue;
 
                public VkSemaphore presentComplete;
-        public Image[] images;
+               public Image[] images;
 
                protected override VkDebugUtilsObjectNameInfoEXT DebugUtilsInfo
                                        => new VkDebugUtilsObjectNameInfoEXT (VkObjectType.SwapchainKHR, Handle.Handle);
@@ -32,47 +32,47 @@ namespace vke {
                /// <summary>Swapchain images count.</summary>
                public uint ImageCount => (uint)images?.Length;
                public uint Width => createInfos.imageExtent.width;
-        public uint Height => createInfos.imageExtent.height;
-        public VkFormat ColorFormat => createInfos.imageFormat;
-        public VkImageUsageFlags ImageUsage => createInfos.imageUsage;
-
-        public SwapChain (PresentQueue _presentableQueue, uint width = 800, uint height = 600, VkFormat format = VkFormat.B8g8r8a8Unorm,
-               VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR)
-        : base (_presentableQueue.dev){
-
-            presentQueue = _presentableQueue;            
-            createInfos = VkSwapchainCreateInfoKHR.New();
-
-            VkSurfaceFormatKHR[] formats = Dev.phy.GetSurfaceFormats (presentQueue.Surface);
-            for (int i = 0; i < formats.Length; i++) {
-                if (formats[i].format == format) {
-                    createInfos.imageFormat = format;
-                    createInfos.imageColorSpace = formats[i].colorSpace;
-                    break;
-                }
-            }
-            if (createInfos.imageFormat == VkFormat.Undefined) 
-                throw new Exception ("Invalid format for swapchain: " + format);
-
-            VkPresentModeKHR[] presentModes = Dev.phy.GetSurfacePresentModes (presentQueue.Surface);
-            for (int i = 0; i < presentModes.Length; i++) {
-                if (presentModes[i] == presentMode) {
-                    createInfos.presentMode = presentMode;
-                    break;
-                }
-            }
-            if (createInfos.presentMode != presentMode)
-                throw new Exception ("Invalid presentMode for swapchain: " + presentMode);
-
-            createInfos.surface = presentQueue.Surface;
-            createInfos.imageExtent = new VkExtent2D (width, height);
-            createInfos.imageArrayLayers = 1;
-            createInfos.imageUsage = IMAGES_USAGE;
-            createInfos.imageSharingMode = VkSharingMode.Exclusive;
-            createInfos.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR;
-            createInfos.presentMode = presentMode;
-            createInfos.clipped = 1;            
-        }
+               public uint Height => createInfos.imageExtent.height;
+               public VkFormat ColorFormat => createInfos.imageFormat;
+               public VkImageUsageFlags ImageUsage => createInfos.imageUsage;
+
+               public SwapChain (PresentQueue _presentableQueue, uint width = 800, uint height = 600, VkFormat format = VkFormat.B8g8r8a8Unorm,
+                       VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR)
+               : base (_presentableQueue.dev) {
+
+                       presentQueue = _presentableQueue;
+                       createInfos = VkSwapchainCreateInfoKHR.New ();
+
+                       VkSurfaceFormatKHR[] formats = Dev.phy.GetSurfaceFormats (presentQueue.Surface);
+                       for (int i = 0; i < formats.Length; i++) {
+                               if (formats[i].format == format) {
+                                       createInfos.imageFormat = format;
+                                       createInfos.imageColorSpace = formats[i].colorSpace;
+                                       break;
+                               }
+                       }
+                       if (createInfos.imageFormat == VkFormat.Undefined)
+                               throw new Exception ("Invalid format for swapchain: " + format);
+
+                       VkPresentModeKHR[] presentModes = Dev.phy.GetSurfacePresentModes (presentQueue.Surface);
+                       for (int i = 0; i < presentModes.Length; i++) {
+                               if (presentModes[i] == presentMode) {
+                                       createInfos.presentMode = presentMode;
+                                       break;
+                               }
+                       }
+                       if (createInfos.presentMode != presentMode)
+                               throw new Exception ("Invalid presentMode for swapchain: " + presentMode);
+
+                       createInfos.surface = presentQueue.Surface;
+                       createInfos.imageExtent = new VkExtent2D (width, height);
+                       createInfos.imageArrayLayers = 1;
+                       createInfos.imageUsage = IMAGES_USAGE;
+                       createInfos.imageSharingMode = VkSharingMode.Exclusive;
+                       createInfos.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR;
+                       createInfos.presentMode = presentMode;
+                       createInfos.clipped = 1;
+               }
                public override void Activate () {
                        if (state != ActivableState.Activated) {
                                presentComplete = Dev.CreateSemaphore ();
@@ -87,63 +87,69 @@ namespace vke {
 
                        Dev.WaitIdle ();
 
-            VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities (presentQueue.Surface);
+                       VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities (presentQueue.Surface);
 
-            createInfos.minImageCount = capabilities.minImageCount;
-            createInfos.preTransform = capabilities.currentTransform;
-            createInfos.oldSwapchain = Handle;
+                       createInfos.minImageCount = capabilities.minImageCount;
+                       createInfos.preTransform = capabilities.currentTransform;
+                       createInfos.oldSwapchain = Handle;
 
-            if (capabilities.currentExtent.width == 0xFFFFFFFF) {
-                if (createInfos.imageExtent.width < capabilities.minImageExtent.width)
-                    createInfos.imageExtent.width = capabilities.minImageExtent.width;
-                else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width)
-                    createInfos.imageExtent.width = capabilities.maxImageExtent.width;
+                       if (capabilities.currentExtent.width == 0xFFFFFFFF) {
+                               if (createInfos.imageExtent.width < capabilities.minImageExtent.width)
+                                       createInfos.imageExtent.width = capabilities.minImageExtent.width;
+                               else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width)
+                                       createInfos.imageExtent.width = capabilities.maxImageExtent.width;
 
-                if (createInfos.imageExtent.height < capabilities.minImageExtent.height)
-                    createInfos.imageExtent.height = capabilities.minImageExtent.height;
-                else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height)
-                    createInfos.imageExtent.height = capabilities.maxImageExtent.height;
-            } else 
-                createInfos.imageExtent = capabilities.currentExtent;
+                               if (createInfos.imageExtent.height < capabilities.minImageExtent.height)
+                                       createInfos.imageExtent.height = capabilities.minImageExtent.height;
+                               else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height)
+                                       createInfos.imageExtent.height = capabilities.maxImageExtent.height;
+                       } else
+                               createInfos.imageExtent = capabilities.currentExtent;
 
-            VkSwapchainKHR newSwapChain = Dev.CreateSwapChain (createInfos);
-            if (Handle.Handle != 0)
-                _destroy ();
-            Handle = newSwapChain;
+                       Utils.CheckResult (vkCreateSwapchainKHR (Dev.VkDev, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain));
+
+                       if (Handle.Handle != 0)
+                               _destroy ();
+                       Handle = newSwapChain;
 
                        if (state != ActivableState.Activated)
                                Activate ();
-
-                       VkImage[] tmp = Dev.GetSwapChainImages (Handle);
-            images = new Image[tmp.Length];
-            for (int i = 0; i < tmp.Length; i++) {
-                images[i] = new Image (Dev, tmp[i], ColorFormat, ImageUsage, Width, Height);
-                images[i].CreateView ();
+                               
+                       Utils.CheckResult (vkGetSwapchainImagesKHR (Dev.VkDev, Handle, out uint imageCount, IntPtr.Zero));
+                       if (imageCount == 0)
+                               throw new Exception ("Swapchain image count is 0.");
+                       VkImage[] imgs = new VkImage[imageCount];
+                       Utils.CheckResult (vkGetSwapchainImagesKHR (Dev.VkDev, Handle, out imageCount, imgs.Pin ()));
+                       imgs.Unpin ();
+
+                       images = new Image[imgs.Length];
+                       for (int i = 0; i < imgs.Length; i++) {
+                               images[i] = new Image (Dev, imgs[i], ColorFormat, ImageUsage, Width, Height);
+                               images[i].CreateView ();
                                images[i].SetName ("SwapChain Img" + i);
                                images[i].Descriptor.imageView.SetDebugMarkerName (Dev, "SwapChain Img" + i + " view");
-            }
-        }
+                       }
+               }
                /// <summary>
                /// Acquire next image, recreate swapchain if out of date or suboptimal error.
                /// </summary>
                /// <returns>Swapchain image index or -1 if failed</returns>
                /// <param name="fence">Fence param of 'vkAcquireNextImageKHR'</param>
-        public int GetNextImage (VkFence fence = default(VkFence)) {
-            VkResult res = vkAcquireNextImageKHR (Dev.VkDev, Handle, UInt64.MaxValue, presentComplete, fence, out currentImageIndex);
-            if (res == VkResult.ErrorOutOfDateKHR || res == VkResult.SuboptimalKHR) {
-                Create ();
-                return -1;
-            }
-            Utils.CheckResult (res);
-            return (int)currentImageIndex;
-        }
+               public int GetNextImage (VkFence fence = default (VkFence)) {
+                       VkResult res = vkAcquireNextImageKHR (Dev.VkDev, Handle, UInt64.MaxValue, presentComplete, fence, out currentImageIndex);
+                       if (res == VkResult.ErrorOutOfDateKHR || res == VkResult.SuboptimalKHR) {
+                               Create ();
+                               return -1;
+                       }
+                       Utils.CheckResult (res);
+                       return (int)currentImageIndex;
+               }
 
                void _destroy () {
-            for (int i = 0; i < ImageCount; i++) 
-                images[i].Dispose ();
-
-            Dev.DestroySwapChain (Handle);
-        }
+                       for (int i = 0; i < ImageCount; i++)
+                               images[i].Dispose ();
+                       vkDestroySwapchainKHR (Dev.VkDev, Handle, IntPtr.Zero);
+               }
 
                public override string ToString () {
                        return string.Format ($"{base.ToString ()}[0x{Handle.Handle.ToString ("x")}]");
diff --git a/vke/src/glfw/CodePoint.cs b/vke/src/glfw/CodePoint.cs
deleted file mode 100644 (file)
index a081e9f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Glfw
-{
-       /// <summary>
-       /// Represents a native UTF32 codepoint.
-       /// </summary>
-       [StructLayout (LayoutKind.Explicit)]
-       public struct CodePoint
-    {
-               /// <summary>
-               /// The numeric value of the codepoint.
-               /// </summary>
-               [FieldOffset (0)] public readonly uint Value;
-               [FieldOffset (0)] readonly byte byte0;
-               [FieldOffset (1)] readonly byte byte1;
-               [FieldOffset (2)] readonly byte byte2;
-               [FieldOffset (3)] readonly byte byte3;
-               /// <summary>
-               /// Casts the codepoint to System.Char.
-               /// </summary>
-               /// <returns>
-               /// The character representation of the codepoint.
-               /// </returns>
-               public char ToChar() => Encoding.UTF32.GetChars (new byte[] { byte0, byte1, byte2, byte3 })[0];
-        /// <summary>
-        /// Converts the value of this instance to its equivalent string representation.
-        /// </summary>
-        /// <returns>
-        /// A string containing the character representation of the codepoint.
-        /// </returns>
-        public override string ToString() => ToChar().ToString();
-    }
-}
diff --git a/vke/src/glfw/Delegates.cs b/vke/src/glfw/Delegates.cs
deleted file mode 100644 (file)
index bfcbb0e..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)using System;
-using System;
-using System.Runtime.InteropServices;
-
-namespace Glfw {
-    /// <summary>
-    /// The function signature for keyboard key callback functions.
-    /// </summary>
-    /// <param name="window">
-    /// The window that received the event.
-    /// </param>
-    /// <param name="key">
-    /// The keyboard key that was pressed or released.
-    /// </param>
-    /// <param name="scanCode">
-    /// The system-specific scancode of the key.
-    /// </param>
-    /// <param name="action">
-    /// The input action that occured.
-    /// </param>
-    /// <param name="modifiers">
-    /// Bit field describing which modifier keys were held down.
-    /// </param>
-    public delegate void KeyDelegate (IntPtr window, Key key, int scanCode, InputAction action, Modifier modifiers);
-    /// <summary>
-    /// A delegate representing character events on a WindowHandle.
-    /// </summary>
-    /// <param name="window">
-    /// The window raising the event.
-    /// </param>
-    /// <param name="codepoint">
-    /// The Unicode codepoint of the character.
-    /// </param>
-    public delegate void CharDelegate (IntPtr window, CodePoint codepoint);
-    /// <summary>
-    /// A delegate representing character events with modifiers on a WindowHandle.
-    /// </summary>
-    /// <param name="window">
-    /// The window raising the event.
-    /// </param>
-    /// <param name="codepoint">
-    /// The Unicode codepoint of the character.
-    /// </param>
-    /// <param name="modifiers">
-    /// The modifiers applied to the character.
-    /// </param>
-    public delegate void CharModsDelegate (IntPtr window, CodePoint codepoint, Modifier modifiers);
-    /// <summary>
-    /// The function signature for cursor position callback functions.
-    /// </summary>
-    /// <param name="window">
-    /// The window that received the event.
-    /// </param>
-    /// <param name="xPosition">
-    /// The new cursor x-coordinate, relative to the left edge of the client area.
-    /// </param>
-    /// <param name="yPosition">
-    /// The new cursor y-coordinate, relative to the top edge of the client area.
-    /// </param>
-    public delegate void CursorPosDelegate (IntPtr window, double xPosition, double yPosition);
-    /// <summary>
-    /// The function signature for error callbacks.
-    /// </summary>
-    /// <param name="error">An error code giving the general category of the error.</param>
-    /// <param name="description">A string description of the error.</param>
-    [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
-    public delegate void ErrorDelegate (ErrorCode error, [MarshalAs (UnmanagedType.LPStr)] string description);
-    /// <summary>
-    /// The function signature for monitor configuration callback functions.
-    /// </summary>
-    /// <param name="monitor">
-    /// The monitor that was connected or disconnected.
-    /// </param>
-    /// <param name="eventStatus">
-    /// The event that was raised.
-    /// </param>
-    [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
-    public delegate void MonitorEventDelegate (MonitorHandle monitor, MonitorEvent eventStatus);
-    /// <summary>
-    /// The function signature for mouse button callback functions.
-    /// </summary>
-    /// <param name="window">
-    /// The window that received the event.
-    /// </param>
-    /// <param name="button">
-    /// The mouse button that was pressed or released.
-    /// </param>
-    /// <param name="action">
-    /// One of <see cref="InputAction.Press"/> or <see cref="InputAction.Release"/>.
-    /// </param>
-    /// <param name="mods">
-    /// Bit field describing which modifier keys were held down.
-    /// </param>
-    public delegate void MouseButtonDelegate (IntPtr window, MouseButton button, InputAction action, Modifier mods);
-    /// <summary>
-    /// The function signature for scroll callback functions.
-    /// </summary>
-    /// <param name="window">
-    /// The window that received the event.
-    /// </param>
-    /// <param name="xOffset">
-    /// The scroll offset along the x-axis.
-    /// </param>
-    /// <param name="yOffset">
-    /// The scroll offset along the y-axis.
-    /// </param>
-    public delegate void ScrollDelegate (IntPtr window, double xOffset, double yOffset);
-    /// <summary>
-    /// The function signature for window size callback functions.
-    /// </summary>
-    /// <param name="window">
-    /// The window that was resized.
-    /// </param>
-    /// <param name="width">
-    /// The new width, in screen coordinates, of the window.
-    /// </param>
-    /// <param name="height">
-    /// The new height, in screen coordinates, of the window.
-    /// </param>
-    [UnmanagedFunctionPointer (CallingConvention.Cdecl)]
-    public delegate void WindowSizeDelegate (IntPtr window, int width, int height);
-
-}
-
diff --git a/vke/src/glfw/ErrorCode.cs b/vke/src/glfw/ErrorCode.cs
deleted file mode 100644 (file)
index ef76890..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Indicates the general category of an error.
-    /// </summary>
-    public enum ErrorCode
-    {
-        /// <summary>
-        /// GLFW has not been initialized.
-        /// </summary>
-        NotInitialised = 0x00010001,
-        /// <summary>
-        /// No context is current for this thread.
-        /// </summary>
-        NoCurrentContext,
-        /// <summary>
-        /// One of the arguments to the function was an invalid enum value.
-        /// </summary>
-        InvalidEnum,
-        /// <summary>
-        /// One of the arguments to the function was an invalid value.
-        /// </summary>
-        InvalidValue,
-        /// <summary>
-        /// A memory allocation failed.
-        /// </summary>
-        OutOfMemory,
-        /// <summary>
-        /// GLFW could not find support for the requested API on the system.
-        /// </summary>
-        ApiUnavailable,
-        /// <summary>
-        /// The requested OpenGL or OpenGL ES version is not available.
-        /// </summary>
-        VersionUnavailable,
-        /// <summary>
-        /// A platform-specific error occurred that does not match any of the more specific categories.
-        /// </summary>
-        PlatformError,
-        /// <summary>
-        /// The requested format is not supported or available.
-        /// </summary>
-        FormatUnavailable,
-        /// <summary>
-        /// The specified window does not have an OpenGL or OpenGL ES context.
-        /// </summary>
-        NoWindowContext
-    }
-}
diff --git a/vke/src/glfw/Glfw3.cs b/vke/src/glfw/Glfw3.cs
deleted file mode 100644 (file)
index 081ec5c..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Runtime.InteropServices;
-
-namespace Glfw {
-       public enum CursorShape
-       {
-               Arrow           = 0x00036001,
-               IBeam           = 0x00036002,
-               Crosshair       = 0x00036003,
-               Hand            = 0x00036004,
-               HResize         = 0x00036005,
-               VResize         = 0x00036006
-       }
-       /// <summary>
-       /// Interop functions for the GLFW3 API.
-       /// </summary>
-       public static class Glfw3
-    {
-        /// <summary>
-        /// The base name for the GLFW3 library.
-        /// </summary>
-        public const string GlfwDll = "glfw";
-
-        /// <summary>
-        /// Initializes the GLFW library.
-        /// </summary>
-        /// <returns>
-        /// True if successful, otherwise false.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwInit")]
-        [return: MarshalAs(UnmanagedType.Bool)]
-        public static extern bool Init();
-
-        /// <summary>
-        /// This function destroys all remaining windows and cursors, restores
-        /// any modified gamma ramps and frees any other allocated resources.
-        /// </summary>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwTerminate")]
-        public static extern void Terminate();
-
-        /// <summary>
-        /// This function retrieves the major, minor and revision numbers of
-        /// the GLFW library.
-        /// </summary>
-        /// <param name="major">
-        /// The major version number.
-        /// </param>
-        /// <param name="minor">
-        /// The minor version number.
-        /// </param>
-        /// <param name="rev">
-        /// The revision number.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetVersion")]
-        public static extern void GetVersion(out int major, out int minor, out int rev);
-
-
-        /// <summary>
-        /// Returns the compile-time generated version string of the GLFW
-        /// library binary. It describes the version, platform, compiler and
-        /// any platform-specific compile-time options.
-        /// </summary>
-        /// <returns>
-        /// The compile-time generated version string of the GLFW library
-        /// binary.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetVersionString")]
-        public static extern NativeString GetVersionString();
-
-        /// <summary>
-        /// Creates a window and its associated OpenGL or OpenGL ES context.
-        /// Most of the options controlling how the window and its context
-        /// should be created are specified with window hints.
-        /// </summary>
-        /// <param name="width">
-        /// The desired width, in screen coordinates, of the window. This must
-        /// be greater than zero.
-        /// </param>
-        /// <param name="height">
-        /// The desired height, in screen coordinates, of the window. This must
-        /// be greater than zero.
-        /// </param>
-        /// <param name="title">
-        /// The initial window title.
-        /// </param>
-        /// <param name="monitor">
-        /// The monitor to use for full screen mode, or Null for windowed mode.
-        /// </param>
-        /// <param name="share">
-        /// The window whose context to share resources with, or Null to not share resources.
-        /// </param>
-        /// <returns>
-        /// The handle of the created window, or Null if an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwCreateWindow")]
-        public static extern IntPtr CreateWindow(int width, int height, [MarshalAs(UnmanagedType.LPStr)] string title, MonitorHandle monitor, IntPtr share);
-
-        /// <summary>
-        /// Destroys the specified window and its context. On calling this
-        /// function, no further callbacks will be called for that window.
-        /// </summary>
-        /// <param name="window">
-        /// The window to destroy.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwDestroyWindow")]
-        public static extern void DestroyWindow(IntPtr window);
-
-        /// <summary>
-        /// Processes events in the event queue and then returns immediately.
-        /// Processing events will cause the window and input callbacks
-        /// associated with those events to be called.
-        /// </summary>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwPollEvents")]
-        public static extern void PollEvents();
-
-        /// <summary>
-        /// Sets hints for the next call to CreateWindow. The hints, once set,
-        /// retain their values until changed by a call to WindowHint or
-        /// DefaultWindowHints, or until the library is terminated.
-        /// </summary>
-        /// <param name="hint">
-        /// The window hint to set.
-        /// </param>
-        /// <param name="value">
-        /// The new value of the window hint.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwWindowHint")]
-        public static extern void WindowHint(WindowAttribute hint, int value);
-
-        /// <summary>
-        /// Returns the value of the close flag of the specified window.
-        /// </summary>
-        /// <param name="window">
-        /// The window to query.
-        /// </param>
-        /// <returns>
-        /// The value of the close flag.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwWindowShouldClose")]
-        public static extern bool WindowShouldClose(IntPtr window);
-
-        [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetWindowShouldClose")]
-        public static extern void SetWindowShouldClose (IntPtr window, int value);
-
-        [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetWindowTitle")]
-        public static extern void SetWindowTitle (IntPtr window, [MarshalAs (UnmanagedType.LPStr)] string title);
-
-        /// <summary>
-        /// Creates a Vulkan surface for the specified window.
-        /// </summary>
-        /// <param name="instance">
-        /// The Vulkan instance to create the surface in.
-        /// </param>
-        /// <param name="window">
-        /// The window to create the surface for.
-        /// </param>
-        /// <param name="pAllocator">
-        /// The allocator to use, or NULL to use the default allocator.
-        /// </param>
-        /// <param name="surface">
-        /// Where to store the handle of the surface. This is set to
-        /// VK_NULL_HANDLE if an error occurred.
-        /// </param>
-        /// <returns>
-        /// Result.Success if successful, or a Vulkan error code if an error
-        /// occurred.
-        /// </returns>
-        [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwCreateWindowSurface")]
-        public static extern int CreateWindowSurface(IntPtr instance, IntPtr window, IntPtr pAllocator, out ulong surface);
-
-        /// <summary>
-        /// Returns an array of names of Vulkan instance extensions required by
-        /// GLFW for creating Vulkan surfaces for GLFW windows. If successful,
-        /// the list will always contains VK_KHR_surface, so if you don't
-        /// require any additional extensions you can pass this list directly
-        /// to the InstanceCreateInfo struct.
-        /// </summary>
-        /// <param name="count">
-        /// Where to store the number of extensions in the returned array. This
-        /// is set to zero if an error occurred.
-        /// </param>
-        /// <returns>
-        /// An array of extension names, or Null if an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetRequiredInstanceExtensions")]
-        public static extern IntPtr GetRequiredInstanceExtensions(out int count);
-
-        /// <summary>
-        /// Sets the size callback of the specified window, which is called
-        /// when the window is resized. The callback is provided with the size,
-        /// in screen coordinates, of the client area of the window.
-        /// </summary>
-        /// <param name="window">
-        /// The window whose callback to set.
-        /// </param>
-        /// <param name="callback">
-        /// The new callback, or Null to remove the currently set callback.
-        /// </param>
-        /// <returns></returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetWindowSizeCallback")]
-        public static extern WindowSizeDelegate SetWindowSizeCallback(IntPtr window, WindowSizeDelegate callback);
-
-        /// <summary>
-        /// Sets the error callback, which is called with an error code and a
-        /// human-readable description each time a GLFW error occurs.
-        /// </summary>
-        /// <param name="callback">
-        /// The new callback, or Null to remove the currently set callback.
-        /// </param>
-        /// <returns>
-        /// The previously set callback, or Null if no callback was set.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetErrorCallback")]
-        public static extern ErrorDelegate SetErrorCallback(ErrorDelegate callback);
-
-        /// <summary>
-        /// Returns an array of handles for all currently connected monitors.
-        /// The primary monitor is always first in the returned array. If no
-        /// monitors were found, this function returns Null.
-        /// </summary>
-        /// <param name="count">
-        /// Where to store the number of monitors in the returned array. This
-        /// is set to zero if an error occurred.
-        /// </param>
-        /// <returns>
-        /// An array of monitor handles, or Null if no monitors were found or
-        /// if an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetMonitors")]
-        public static extern IntPtr GetMonitors(out int count);
-
-        /// <summary>
-        /// Returns the primary monitor. This is usually the monitor where
-        /// elements like the task bar or global menu bar are located.
-        /// </summary>
-        /// <returns>
-        /// The primary monitor, or Null if no monitors were found or if an
-        /// error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetPrimaryMonitor")]
-        public static extern MonitorHandle GetPrimaryMonitor();
-
-        /// <summary>
-        /// Returns the position, in screen coordinates, of the upper-left
-        /// corner of the specified monitor.
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <param name="xPos">
-        /// Returns the monitor x-coordinate.
-        /// </param>
-        /// <param name="yPos">
-        /// Returns the monitor y-coordinate.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetMonitorPos")]
-        public static extern void GetMonitorPos(MonitorHandle monitor, out int xPos, out int yPos);
-
-        /// <summary>
-        /// Returns the size, in millimetres, of the display area of the
-        /// specified monitor.
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <param name="widthMm">
-        /// The width, in millimetres, of the monitor's display area.
-        /// </param>
-        /// <param name="heightMm">
-        /// The width, in millimetres, of the monitor's display area.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetMonitorPhysicalSize")]
-        public static extern void GetMonitorPhysicalSize(MonitorHandle monitor, out int widthMm, out int heightMm);
-
-        /// <summary>
-        /// Returns a human-readable name, of the specified monitor. The name
-        /// typically reflects the make and model of the monitor and is not
-        /// guaranteed to be unique among the connected monitors.
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <returns>
-        /// The name of the monitor, or Null if an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetMonitorName")]
-        public static extern NativeString GetMonitorName(MonitorHandle monitor);
-
-        /// <summary>
-        /// Sets the monitor configuration callback, or removes the currently
-        /// set callback. This is called when a monitor is connected to or
-        /// disconnected from the system.
-        /// </summary>
-        /// <param name="callback">
-        /// The new callback, or Null to remove the currently set callback.
-        /// </param>
-        /// <returns>
-        /// The previously set callback, or NULL if no callback was set or the
-        /// library had not been initialized.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetMonitorCallback")]
-        public static extern MonitorEventDelegate SetMonitorCallback(MonitorEventDelegate callback);
-
-        /// <summary>
-        /// Returns an array of all video modes supported by the specified
-        /// monitor. The returned array is sorted in ascending order, first by
-        /// color bit depth (the sum of all channel depths) and then by
-        /// resolution area (the product of width and height).
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <param name="count">
-        /// Tthe number of video modes in the returned array. This is set to
-        /// zero if an error occurred.
-        /// </param>
-        /// <returns>
-        /// An array of video modes, or Null if an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetVideoModes")]
-        public static extern IntPtr GetVideoModes(MonitorHandle monitor, out int count);
-
-        /// <summary>
-        /// Returns the current video mode of the specified monitor. If you
-        /// have created a full screen window for that monitor, the return
-        /// value will depend on whether that window is iconified.
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <returns>
-        /// A wrapped pointer to the current mode of the monitor, or Null if
-        /// an error occurred.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetVideoMode")]
-        public static extern VideoModePointer GetVideoMode(MonitorHandle monitor);
-
-        /// <summary>
-        /// Generates a 256-element gamma ramp from the specified exponent and
-        /// then calls glfwSetGammaRamp with it. The value must be a finite
-        /// number greater than zero.
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor whose gamma ramp to set.
-        /// </param>
-        /// <param name="gamma">
-        /// The desired exponent.
-        /// </param>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetGamma")]
-        public static extern void SetGamma(MonitorHandle monitor, float gamma);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetInputMode")]
-        public static extern int GetInputMode(IntPtr window, int mode);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetInputMode")]
-        public static extern void SetInputMode(IntPtr window, int mode, int value);
-
-        /// <summary>
-        /// Returns the localized name of the specified printable key. This is
-        /// intended for displaying key bindings to the user.
-        /// </summary>
-        /// <param name="key">
-        /// The key to query, or Key.Unknown.
-        /// </param>
-        /// <param name="scancode">
-        /// The scancode of the key to query, if key is Key.Unknown.
-        /// </param>
-        /// <returns>
-        /// The localized name of the key, or Null.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetKeyName")]
-        public static extern NativeString GetKeyName(Key key, int scancode);
-        
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetKey")]
-        public static extern InputAction GetKey(IntPtr window, Key key);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetMouseButton")]
-        public static extern InputAction GetMouseButton(IntPtr window, MouseButton button);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwGetCursorPos")]
-        public static extern void GetCursorPosition(IntPtr window, out double xPosition, out double yPosition);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetCursorPos")]
-        public static extern void SetCursorPosition(IntPtr window, double xPosition, double yPosition);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetKeyCallback")]
-        public static extern KeyDelegate SetKeyCallback(IntPtr window, KeyDelegate callback);
-
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetCharCallback")]
-        public static extern KeyDelegate SetCharCallback(IntPtr window, CharDelegate callback);
-
-        /// <summary>
-        /// <para>Sets a callback for Mouse movement events. Use this for full
-        /// mouse path resolution between PollEvents() calls.</para>
-        /// <para>From GLFW Documentation: The callback functions receives the
-        /// cursor position, measured in screen coordinates but relative to the
-        /// top-left corner of the window client area. On platforms that
-        /// provide it, the full sub-pixel cursor position is passed on.</para>
-        /// </summary>
-        /// <returns>
-        /// The previously set callback, or NULL if no callback was set or the
-        /// library had not been initialized.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetCursorPosCallback")]
-        public static extern CursorPosDelegate SetCursorPosCallback(IntPtr window, CursorPosDelegate callback);
-
-        /// <summary>
-        /// <para>Sets a Callback for Button Events (i.e. clicks). This also
-        /// detects mouse press and release events done between PollEvents()
-        /// calls.</para>
-        /// <para>From GLFW Documentation: Whenever you poll state, you risk
-        /// missing the state change you are looking for. If a pressed mouse
-        /// button is released again before you poll its state, you will have
-        /// missed the button press. The recommended solution for this is to
-        /// use a mouse button callback, but there is also the
-        /// GLFW_STICKY_MOUSE_BUTTONS input mode.</para>
-        /// </summary>
-        /// <returns>
-        /// The previously set callback, or NULL if no callback was set or the
-        /// library had not been initialized.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetMouseButtonCallback")]
-        public static extern MouseButtonDelegate SetMouseButtonPosCallback(IntPtr window, MouseButtonDelegate callback);
-
-        /// <summary>
-        /// Sets a Callback for Mouse Scrolling Events. (i.e. scroll wheel)
-        /// There is no polling support for this, so if youre interested in the wheel, you have to set this callback
-        /// NOTE: your normal desktop mouse variant likely only reports Y-Coordinate
-        /// </summary>
-        /// <returns>
-        /// The previously set callback, or NULL if no callback was set or the
-        /// library had not been initialized.
-        /// </returns>
-        [DllImport(GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetScrollCallback")]
-        public static extern ScrollDelegate SetScrollCallback(IntPtr window, ScrollDelegate callback);
-
-        /// <summary>
-        /// Returns an array of names of Vulkan instance extensions required by
-        /// GLFW for creating Vulkan surfaces for GLFW windows. If successful,
-        /// the list will always contains VK_KHR_surface, so if you don't
-        /// require any additional extensions you can pass this list directly
-        /// to the InstanceCreateInfo struct.
-        /// </summary>
-        /// <returns>
-        /// An array of extension names, or Null if an error occurred.
-        /// </returns>
-        public static string[] GetRequiredInstanceExtensions()
-        {
-            IntPtr names = GetRequiredInstanceExtensions(out int count);
-
-            string[] result = new string[count];
-
-            for (int nameIndex = 0; nameIndex < count; nameIndex++)
-            {
-                               IntPtr name = Marshal.ReadIntPtr (names, nameIndex * Marshal.SizeOf<IntPtr>());
-                result[nameIndex] = Marshal.PtrToStringAnsi(name);
-            }
-
-            return result;
-        }
-
-        /// <summary>
-        /// Returns an array of handles for all currently connected monitors.
-        /// The primary monitor is always first in the returned array. If no
-        /// monitors were found, this function returns Null.
-        /// </summary>
-        /// <returns>
-        /// An array of monitor handles, or Null if no monitors were found or
-        /// if an error occurred.
-        /// </returns>
-        public static MonitorHandle[] GetMonitors()
-        {
-            IntPtr monitors = GetMonitors(out int count);
-
-            var result = new MonitorHandle[count];
-
-            for (int i = 0; i < count; i++)            
-                result[i] = new MonitorHandle(Marshal.ReadIntPtr(monitors, i));            
-
-            return result;
-        }
-
-        /// <summary>
-        /// Returns an array of all video modes supported by the specified
-        /// monitor. The returned array is sorted in ascending order, first by
-        /// color bit depth (the sum of all channel depths) and then by
-        /// resolution area (the product of width and height).
-        /// </summary>
-        /// <param name="monitor">
-        /// The monitor to query.
-        /// </param>
-        /// <returns>
-        /// An array of video modes, or Null if an error occurred.
-        /// </returns>
-        public static VideoMode[] GetVideoModes(MonitorHandle monitor)
-        {
-            IntPtr videoModes = GetVideoModes(monitor, out int count);
-
-            var result = new VideoMode[count];
-
-            for (int i = 0; i < count; i++)            
-                result[i] = Marshal.PtrToStructure<VideoMode>(Marshal.ReadIntPtr(videoModes, i));            
-
-            return result;
-        }
-
-        /// <summary>
-        /// This function retrieves the version number of the GLFW library.
-        /// </summary>
-        /// <returns>
-        /// The version number of the GLFW library.
-        /// </returns>
-        public static Version GetVersion()
-        {
-            GetVersion(out int major, out int minor, out int revision);
-
-            return new Version(major, minor, revision);
-        }
-
-               [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwCreateStandardCursor")]
-               public static extern IntPtr CreateStandardCursor (CursorShape shape);
-
-               [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwDestroyCursor")]
-               public static extern void DestroyCursor (IntPtr cursor);
-
-               [DllImport (GlfwDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "glfwSetCursor")]
-               public static extern void SetCursor (IntPtr window, IntPtr cursor);
-       }
-}
diff --git a/vke/src/glfw/InputAction.cs b/vke/src/glfw/InputAction.cs
deleted file mode 100644 (file)
index 3ee57f7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Represents the action of an input key event or the state of a key.
-    /// </summary>
-    public enum InputAction
-    {
-        /// <summary>
-        /// The key was released or is not pressed.
-        /// </summary>
-        Release = 0,
-        /// <summary>
-        /// The key was or is pressed.
-        /// </summary>
-        Press = 1,
-        /// <summary>
-        /// The key has been held down long enough to repeat.
-        /// </summary>
-        Repeat = 2
-    }
-}
diff --git a/vke/src/glfw/Key.cs b/vke/src/glfw/Key.cs
deleted file mode 100644 (file)
index 1e8c19d..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Represents a key on a keyboard.
-    /// </summary>
-    public enum Key
-    {
-        Unknown = -1,
-        Space = 32,
-        Apostrophe = 39,
-        Comma = 44,
-        Minus = 45,
-        Period = 46,
-        Slash = 47,
-        Num0 = 48,
-        Num1 = 49,
-        Num2 = 50,
-        Num3 = 51,
-        Num4 = 52,
-        Num5 = 53,
-        Num6 = 54,
-        Num7 = 55,
-        Num8 = 56,
-        Num9 = 57,
-        Semicolon = 59,
-        Equal = 61,
-        A = 65,
-        B = 66,
-        C = 67,
-        D = 68,
-        E = 69,
-        F = 70,
-        G = 71,
-        H = 72,
-        I = 73,
-        J = 74,
-        K = 75,
-        L = 76,
-        M = 77,
-        N = 78,
-        O = 79,
-        P = 80,
-        Q = 81,
-        R = 82,
-        S = 83,
-        T = 84,
-        U = 85,
-        V = 86,
-        W = 87,
-        X = 88,
-        Y = 89,
-        Z = 90,
-        LeftBracket = 91,
-        Backslash = 92,
-        RightBracket = 93,
-        GraveAccent = 96,
-        World1 = 161,
-        World2 = 162,
-        Escape = 256,
-        Enter = 257,
-        Tab = 258,
-        Backspace = 259,
-        Insert = 260,
-        Delete = 261,
-        Right = 262,
-        Left = 263,
-        Down = 264,
-        Up = 265,
-        PageUp = 266,
-        PageDown = 267,
-        Home = 268,
-        End = 269,
-        CapsLock = 280,
-        ScrollLock = 281,
-        NumLock = 282,
-        PrintScreen = 283,
-        Pause = 284,
-        F1 = 290,
-        F2 = 291,
-        F3 = 292,
-        F4 = 293,
-        F5 = 294,
-        F6 = 295,
-        F7 = 296,
-        F8 = 297,
-        F9 = 298,
-        F10 = 299,
-        F11 = 300,
-        F12 = 301,
-        F13 = 302,
-        F14 = 303,
-        F15 = 304,
-        F16 = 305,
-        F17 = 306,
-        F18 = 307,
-        F19 = 308,
-        F20 = 309,
-        F21 = 310,
-        F22 = 311,
-        F23 = 312,
-        F24 = 313,
-        F25 = 314,
-        Keypad0 = 320,
-        Keypad1 = 321,
-        Keypad2 = 322,
-        Keypad3 = 323,
-        Keypad4 = 324,
-        Keypad5 = 325,
-        Keypad6 = 326,
-        Keypad7 = 327,
-        Keypad8 = 328,
-        Keypad9 = 329,
-        KeypadDecimal = 330,
-        KeypadDivide = 331,
-        KeypadMultiply = 332,
-        KeypadSubtract = 333,
-        KeypadAdd = 334,
-        KeypadEnter = 335,
-        KeypadEqual = 336,
-        LeftShift = 340,
-        LeftControl = 341,
-        LeftAlt = 342,
-        LeftSuper = 343,
-        RightShift = 344,
-        RightControl = 345,
-        RightAlt = 346,
-        RightSuper = 347,
-        Menu = 348,
-    }
-}
diff --git a/vke/src/glfw/Modifier.cs b/vke/src/glfw/Modifier.cs
deleted file mode 100644 (file)
index 98205c7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-
-namespace Glfw
-{
-    /// <summary>
-    /// Bitmask indicating modifer keys.
-    /// </summary>
-    [Flags]
-    public enum Modifier
-    {
-        Shift = 0x1,
-        Control = 0x2,
-        Alt = 0x4,
-        Super = 0x8,
-    }
-}
\ No newline at end of file
diff --git a/vke/src/glfw/MonitorEvent.cs b/vke/src/glfw/MonitorEvent.cs
deleted file mode 100644 (file)
index d93397b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Events that may be raised from a monitor callback.
-    /// </summary>
-    public enum  MonitorEvent
-    {
-        /// <summary>
-        /// The monitor was connected.
-        /// </summary>
-        Connected = 0x00040001,
-        /// <summary>
-        /// The monitor was disconnected.
-        /// </summary>
-        Disconnected = 0x00040002
-    }
-}
diff --git a/vke/src/glfw/MonitorHandle.cs b/vke/src/glfw/MonitorHandle.cs
deleted file mode 100644 (file)
index 38ed035..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-
-namespace Glfw
-{
-    /// <summary>
-    /// Opaque monitor handle.
-    /// </summary>
-    public struct MonitorHandle
-    {
-               readonly IntPtr handle;
-
-               internal MonitorHandle(IntPtr handle)
-        {
-            this.handle = handle;
-        }
-               /// <summary>
-               /// Gets the underlying native pointer to the monitor object.
-               /// </summary>
-               public IntPtr RawHandle => handle;
-        /// <summary>
-        /// A read-only field that represents a MonitorHandle that has been
-        /// inititalised to zero.
-        /// </summary>
-        public static readonly MonitorHandle Zero = new MonitorHandle (IntPtr.Zero);
-    }
-}
diff --git a/vke/src/glfw/MouseButton.cs b/vke/src/glfw/MouseButton.cs
deleted file mode 100644 (file)
index b29184a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// The index and name of mouse buttons for callbacks.
-    /// </summary>
-    public enum MouseButton
-    {
-        /// <summary>
-        /// The first mouse button.
-        /// </summary>
-        Button1 = 0,
-        /// <summary>
-        /// The second mouse button.
-        /// </summary>
-        Button2 = 1,
-        /// <summary>
-        /// The third mouse button.
-        /// </summary>
-        Button3 = 2,
-        /// <summary>
-        /// The fourth mouse button.
-        /// </summary>
-        Button4 = 3,
-        /// <summary>
-        /// The fifth mouse button.
-        /// </summary>
-        Button5 = 4,
-        /// <summary>
-        /// The sixth mouse button.
-        /// </summary>
-        Button6 = 5,
-        /// <summary>
-        /// The seven mouse button.
-        /// </summary>
-        Button7 = 6,
-        /// <summary>
-        /// The eighth mouse button.
-        /// </summary>
-        Button8 = 7,
-        /// <summary>
-        /// The left mouse button.
-        /// </summary>
-        Left = Button1,
-        /// <summary>
-        /// The right mouse button.
-        /// </summary>
-        Right = Button2,
-        /// <summary>
-        /// The middle mouse button.
-        /// </summary>
-        Middle = Button3,
-        /// <summary>
-        /// The highest-indexed mouse button.
-        /// </summary>
-        Last = Button8
-    }
-}
diff --git a/vke/src/glfw/NativeString.cs b/vke/src/glfw/NativeString.cs
deleted file mode 100644 (file)
index 02181cb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Wraps a pointer to a native, null-terminated ANSI string.
-    /// </summary>
-    public struct NativeString
-    {
-        internal NativeString(IntPtr pointer)
-        {
-            this.pointer = pointer;
-        }
-
-        readonly IntPtr pointer;
-
-               /// <summary>
-               /// Gets the marshalled string value for this native string.
-               /// </summary>
-               public string Value => IsNull ? throw new NullReferenceException () : Marshal.PtrToStringAnsi (this.pointer);
-        /// <summary>
-        /// Gets a value indicating whether the pointer wrapped by this
-        /// instance is null.
-        /// </summary>
-        public bool IsNull => pointer == IntPtr.Zero;
-
-        /// <summary>
-        /// The underlying pointer wrapped by this instance.
-        /// </summary>
-        public IntPtr RawPointer => pointer;
-
-        public override string ToString()
-        {
-            return Value;
-        }
-    }
-}
diff --git a/vke/src/glfw/VideoMode.cs b/vke/src/glfw/VideoMode.cs
deleted file mode 100644 (file)
index baeb196..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Glfw
-{
-    /// <summary>
-    /// Represents a single video mode.
-    /// </summary>
-    [StructLayout(LayoutKind.Sequential)]
-    public struct VideoMode
-    {
-        private readonly int width;
-        private readonly int height;
-        private readonly int redBits;
-        private readonly int greenBits;
-        private readonly int blueBits;
-
-        /// <summary>
-        /// The resolution, in screen coordinates, of the video mode.
-        /// </summary>
-        public (int Width, int Height) Resolution => (this.width, this.height);
-
-        /// <summary>
-        /// The bit depth of the red channel of the video mode.
-        /// </summary>
-        public (int Red, int Green, int Blue) Bits => (this.redBits, this.greenBits, this.blueBits);
-
-        /// <summary>
-        /// The refresh rate, in Hz, of the video mode.
-        /// </summary>
-        public int RefreshRate;
-
-        /// <summary>
-        /// Returns a string representation of this video mode.
-        /// </summary>
-        /// <returns>
-        /// A string representation of this video mode.
-        /// </returns>
-        public override string ToString()
-        {
-            return $"[Resolution: {this.Resolution}, Bit Depth: {this.Bits}, Refresh Rate: {this.RefreshRate}Hz]";
-        }
-    }
-}
diff --git a/vke/src/glfw/VideoModePointer.cs b/vke/src/glfw/VideoModePointer.cs
deleted file mode 100644 (file)
index 66631c6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Runtime.InteropServices;
-
-namespace Glfw
-{
-    /// <summary>
-    /// Wraps a pointer to a VideoMode struct.
-    /// </summary>
-    public struct VideoModePointer
-    {
-               private readonly IntPtr pointer;
-               internal VideoModePointer (IntPtr pointer)
-        {
-            this.pointer = pointer;
-        }
-        /// <summary>
-        /// Gets the VideoMode value at the referenced memory location.
-        /// </summary>
-        public VideoMode Value => IsNull ? throw new NullReferenceException() : Marshal.PtrToStructure<VideoMode>(pointer);
-        /// <summary>
-        /// Gets a value indicating whether the pointer wrapped by this
-        /// instance is null.
-        /// </summary>
-        public bool IsNull => pointer == IntPtr.Zero;
-        /// <summary>
-        /// The underlying pointer wrapped by this instance.
-        /// </summary>
-        public IntPtr RawPointer => pointer;
-    }
-}
diff --git a/vke/src/glfw/WindowAttribute.cs b/vke/src/glfw/WindowAttribute.cs
deleted file mode 100644 (file)
index f772667..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2019 Andrew Armstrong/FacticiusVir
-// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-namespace Glfw
-{
-    /// <summary>
-    /// Attributes of a window or its framebuffer or context, that can be
-    /// configured/queried at runtime or hinted at creation.
-    /// </summary>
-    public enum WindowAttribute
-    {
-        /// <summary>
-        /// Whether the specified window has input focus. This hint is ignored
-        /// for full screen and initially hidden windows.
-        /// </summary>
-        Focused = 0x00020001,
-        /// <summary>
-        /// Whether the specified window is iconified (minimized).
-        /// </summary>
-        Iconified = 0x00020002,
-        /// <summary>
-        /// Whether the specified window is resizable by the user. This is set
-        /// on creation.
-        /// </summary>
-        Resizable = 0x00020003,
-        /// <summary>
-        /// Whether the specified window is visible.
-        /// </summary>
-        Visible = 0x00020004,
-        /// <summary>
-        /// Whether the specified window has decorations such as a border, a
-        /// close widget, etc. This is set on creation.
-        /// </summary>
-        Decorated = 0x00020005,
-        /// <summary>
-        /// Whether the full screen window will automatically iconify and
-        /// restore the previous default framebuffer on input focus loss. This hint is
-        /// ignored for windowed mode windows.
-        /// </summary>
-        AutoIconify = 0x00020006,
-        /// <summary>
-        /// Whether the windowed mode window will be floating above other
-        /// regular windows, also called topmost or always-on-top. This is
-        /// intended primarily for debugging purposes and cannot be used to
-        /// implement proper full screen windows. This hint is ignored for full
-        /// screen windows.
-        /// </summary>
-        Floating = 0x00020007,
-        /// <summary>
-        /// Whether the specified window is maximized.
-        /// </summary>
-        Maximized = 0x00020008,
-        /// <summary>
-        /// The bit depth of the red channel of the default framebuffer.
-        /// </summary>
-        RedBits = 0x00021001,
-        /// <summary>
-        /// The bit depth of the green channel of the default framebuffer.
-        /// </summary>
-        GreenBits = 0x00021002,
-        /// <summary>
-        /// The bit depth of the blue channel of the default framebuffer.
-        /// </summary>
-        BlueBits = 0x00021003,
-        /// <summary>
-        /// The bit depth of the alpha channel of the default framebuffer.
-        /// </summary>
-        AlphaBits = 0x00021004,
-        /// <summary>
-        /// The bit depth of the depth channel of the default framebuffer.
-        /// </summary>
-        DepthBits = 0x00021005,
-        /// <summary>
-        /// The bit depth of the stencil channel of the default framebuffer.
-        /// </summary>
-        StencilBits = 0x00021006,
-        /// <summary>
-        /// The desired bit depth of the red channel of the accumulation
-        /// buffer. Accumulation buffers are a legacy OpenGL feature and
-        /// should not be used in new code.
-        /// </summary>
-        AccumRedBits = 0x00021007,
-        /// <summary>
-        /// The desired bit depth of the green channel of the accumulation
-        /// buffer. Accumulation buffers are a legacy OpenGL feature and
-        /// should not be used in new code.
-        /// </summary>
-        AccumGreenBits = 0x00021008,
-        /// <summary>
-        /// The desired bit depth of the blue channel of the accumulation
-        /// buffer. Accumulation buffers are a legacy OpenGL feature and
-        /// should not be used in new code.
-        /// </summary>
-        AccumBlueBits = 0x00021009,
-        /// <summary>
-        /// The desired bit depth of the alpha channel of the accumulation
-        /// buffer. Accumulation buffers are a legacy OpenGL feature and
-        /// should not be used in new code.
-        /// </summary>
-        AccumAlphaBits = 0x0002100A,
-        /// <summary>
-        ///  The desired number of auxiliary buffers. Auxiliary buffers are a
-        ///  legacy OpenGL feature and should not be used in new code.
-        /// </summary>
-        AuxBuffers = 0x0002100B,
-        /// <summary>
-        /// Whether to use stereoscopic rendering. 
-        /// </summary>
-        Stereo = 0x0002100C,
-        /// <summary>
-        /// The desired number of samples to use for multisampling. Zero
-        /// disables multisampling.
-        /// </summary>
-        Samples = 0x0002100D,
-        /// <summary>
-        /// Whether the framebuffer should be sRGB capable.
-        /// </summary>
-        SrgbCapable = 0x0002100E,
-        /// <summary>
-        /// The desired refresh rate for full screen windows. This hint is
-        /// ignored for windowed mode windows.
-        /// </summary>
-        RefreshRate = 0x0002100F,
-        /// <summary>
-        /// Whether the framebuffer should be double buffered.
-        /// </summary>
-        DoubleBuffer = 0x00021010,
-        /// <summary>
-        /// Specifies which client API to create the context for.
-        /// </summary>
-        ClientApi = 0x00022001,
-        /// <summary>
-        /// Specifies the major component of the client API version of the
-        /// window's context.
-        /// </summary>
-        ContextVersionMajor = 0x00022002,
-        /// <summary>
-        /// Specifies the minor component of the client API version of the
-        /// window's context.
-        /// </summary>
-        ContextVersionMinor = 0x00022003,
-        /// <summary>
-        /// Specifies the revision component of the client API version of the
-        /// window's context.
-        /// </summary>
-        ContextRevision = 0x00022004,
-        /// <summary>
-        /// The robustness strategy used by the context.
-        /// </summary>
-        ContextRobustness = 0x00022005,
-        /// <summary>
-        /// Specifies whether the OpenGL context should be forward-compatible,
-        /// i.e. one where all functionality deprecated in the requested
-        /// version of OpenGL is removed. If OpenGL ES is requested, this hint
-        /// is ignored.
-        /// </summary>
-        OpenGlForwardCompat = 0x00022006,
-        /// <summary>
-        /// Specifies whether to create a debug OpenGL context, which may have
-        /// additional error and performance issue reporting functionality. If
-        /// OpenGL ES is requested, this hint is ignored.
-        /// </summary>
-        OpenGlDebugContext = 0x00022007,
-        /// <summary>
-        /// The OpenGL profile used by the context.
-        /// </summary>
-        OpenGlProfile = 0x00022008,
-        /// <summary>
-        /// Specifies the release behavior to be used by the context.
-        /// </summary>
-        ContextReleaseBehavior = 0x00022009,
-        /// <summary>
-        /// Specifies whether errors should be generated by the context. If
-        /// enabled, situations that would have generated errors instead cause
-        /// undefined behavior.
-        /// </summary>
-        ContextNoError = 0x0002200A,
-        /// <summary>
-        /// The context creation API used to create the window's context.
-        /// </summary>
-        ContextCreationApi = 0x0002200B
-    }
-}
index 2e3a86bc9941b65651a9a4ed5187bf7ee79763de..c81f77b1f81009b75a6111482a4a6576677188e4 100644 (file)
                <RepositoryUrl>https://github.com/jpbruyere/vke.net</RepositoryUrl>
                <PackageTags>vulkan game engine compute glfw c#</PackageTags>
                <PackageVersion>$(VkePackageVersion)</PackageVersion>
+               
                <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
                <GenerateDocumentationFile>true</GenerateDocumentationFile>
+               
                <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
                <PackageProjectUrl>https://github.com/jpbruyere/vke.net/blob/master/README.md</PackageProjectUrl>
                <License>MIT</License>
                <Authors>Jean-Philippe Bruyère</Authors>
                <PackageReleaseNotes>                   
                </PackageReleaseNotes>
+
                <!--<PackageIconUrl>https://github.com/KhronosGroup/glTF/blob/master/specification/figures/gltf.png</PackageIconUrl>-->
                <SynchReleaseVersion>false</SynchReleaseVersion>
                
        
        <ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
                <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />          
+               <PackageReference Include="glfw-sharp" Version="0.2.0" />
        </ItemGroup>
                
        <ItemGroup>
                <PackageReference Include="SpirVTasks" Version="$(SpirVTasksPackageVersion)" />
-               <PackageReference Include="Vulkan" Version="0.2.1-beta" />
+               <PackageReference Include="Vulkan" Version="0.2.1" />
        </ItemGroup>
        <ItemGroup>
                <GLSLShader Include="shaders\**\*.frag;shaders\**\*.vert;shaders\**\*.comp;shaders\**\*.geom" />